Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/// This shader renders YUV images in a color target.
#include ps_quad,yuv
varying highp vec2 vUv_Y;
flat varying highp vec4 vUvBounds_Y;
varying highp vec2 vUv_U;
flat varying highp vec4 vUvBounds_U;
varying highp vec2 vUv_V;
flat varying highp vec4 vUvBounds_V;
flat varying YUV_PRECISION vec3 vYcbcrBias;
flat varying YUV_PRECISION mat3 vRgbFromDebiasedYcbcr;
// YUV format. Packed in to vector to work around bug 1630356.
flat varying mediump ivec2 vFormat;
#ifdef SWGL_DRAW_SPAN
flat varying mediump int vRescaleFactor;
#endif
#ifdef WR_VERTEX_SHADER
struct YuvQuadData {
RectWithEndpoint uv_rect_u;
RectWithEndpoint uv_rect_v;
YUV_PRECISION vec3 ycbcr_bias;
YUV_PRECISION mat3 rgb_from_debiased_ycbcr;
int format;
int rescale_factor;
};
// See YuvPattern::build in src/pattern/yuv.rs.
//
// The YUV-to-RGB conversion parameters are computed on the CPU and fetched here.
YuvQuadData fetch_yuv_quad_data(int address) {
vec4 d[3] = fetch_from_gpu_buffer_3f(address);
vec4 e[3] = fetch_from_gpu_buffer_3f(address + 3);
YuvQuadData yuv;
yuv.uv_rect_u = RectWithEndpoint(d[0].xy, d[0].zw);
yuv.uv_rect_v = RectWithEndpoint(d[1].xy, d[1].zw);
yuv.ycbcr_bias = d[2].xyz;
yuv.format = int(d[2].w);
yuv.rgb_from_debiased_ycbcr = mat3(e[0].xyz, e[1].xyz, e[2].xyz);
yuv.rescale_factor = int(e[0].w);
return yuv;
}
void pattern_vertex(PrimitiveInfo info) {
YuvQuadData yuv = fetch_yuv_quad_data(info.pattern_input.x);
#ifdef SWGL_DRAW_SPAN
vRescaleFactor = yuv.rescale_factor;
#endif
vYcbcrBias = yuv.ycbcr_bias;
vRgbFromDebiasedYcbcr = yuv.rgb_from_debiased_ycbcr;
vFormat.x = yuv.format;
// Normalized position within the primitive rect.
RectWithEndpoint rect = info.local_prim_rect;
vec2 f = (info.local_pos - rect.p0) / rect_size(rect);
// The Y plane uv rect travels through the standard quad primitive block (as
// the segment uv rect); the U and V plane uv rects come from the pattern's
// own gpu block.
RectWithEndpoint uv_rect_y = info.segment.uv_rect;
// The additional test for 99 works around a gen6 shader compiler bug: 1708937
if (vFormat.x == YUV_FORMAT_PLANAR || vFormat.x == 99) {
write_uv_rect(uv_rect_y.p0, uv_rect_y.p1, f, TEX_SIZE_YUV(sColor0), vUv_Y, vUvBounds_Y);
write_uv_rect(yuv.uv_rect_u.p0, yuv.uv_rect_u.p1, f, TEX_SIZE_YUV(sColor1), vUv_U, vUvBounds_U);
write_uv_rect(yuv.uv_rect_v.p0, yuv.uv_rect_v.p1, f, TEX_SIZE_YUV(sColor2), vUv_V, vUvBounds_V);
} else if (yuv_format_is_biplanar(vFormat.x)) {
write_uv_rect(uv_rect_y.p0, uv_rect_y.p1, f, TEX_SIZE_YUV(sColor0), vUv_Y, vUvBounds_Y);
write_uv_rect(yuv.uv_rect_u.p0, yuv.uv_rect_u.p1, f, TEX_SIZE_YUV(sColor1), vUv_U, vUvBounds_U);
} else if (vFormat.x == YUV_FORMAT_INTERLEAVED) {
write_uv_rect(uv_rect_y.p0, uv_rect_y.p1, f, TEX_SIZE_YUV(sColor0), vUv_Y, vUvBounds_Y);
}
}
#endif
#ifdef WR_FRAGMENT_SHADER
vec4 pattern_fragment(vec4 color) {
vec4 yuv_color = sample_yuv(
vFormat.x,
vYcbcrBias,
vRgbFromDebiasedYcbcr,
vUv_Y,
vUv_U,
vUv_V,
vUvBounds_Y,
vUvBounds_U,
vUvBounds_V
);
return color * yuv_color;
}
#if defined(SWGL_DRAW_SPAN)
void swgl_drawSpanRGBA8() {
if (vFormat.x == YUV_FORMAT_PLANAR) {
swgl_commitTextureLinearYUV(sColor0, vUv_Y, vUvBounds_Y,
sColor1, vUv_U, vUvBounds_U,
sColor2, vUv_V, vUvBounds_V,
vYcbcrBias,
vRgbFromDebiasedYcbcr,
vRescaleFactor);
} else if (yuv_format_is_biplanar(vFormat.x)) {
swgl_commitTextureLinearYUV(sColor0, vUv_Y, vUvBounds_Y,
sColor1, vUv_U, vUvBounds_U,
vYcbcrBias,
vRgbFromDebiasedYcbcr,
vRescaleFactor);
} else if (vFormat.x == YUV_FORMAT_INTERLEAVED) {
swgl_commitTextureLinearYUV(sColor0, vUv_Y, vUvBounds_Y,
vYcbcrBias,
vRgbFromDebiasedYcbcr,
vRescaleFactor);
}
}
#endif
#endif