Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync changes from mozilla-central gfx/wr #3863

Merged
merged 1 commit into from Feb 18, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Bug 1579235 - Part 3 - Abstract some parts of yuv shader logic. r=nical

Factor some parts of the YUV brush shader out into a shared
yuv.glsl shader include.

In future, this shader code will also be referenced by the
composite.glsl shader when using the simple (Draw) compositing
mode, to composite video surfaces directly into the framebuffer
where possible.

Differential Revision: https://phabricator.services.mozilla.com/D63123

[ghsync] From https://hg.mozilla.org/mozilla-central/rev/bde7c898937d877132b5d2aaeae022227c9da7af
  • Loading branch information
gw3583 authored and moz-gfx committed Feb 18, 2020
commit eab2fc6cfa4c1f46d1142531dc73af9a750d7402
@@ -8,20 +8,7 @@
#define WR_BRUSH_VS_FUNCTION yuv_brush_vs
#define WR_BRUSH_FS_FUNCTION yuv_brush_fs

#include shared,prim_shared,brush

// TODO(gw): Consider whether we should even have separate shader compilations
// for the various YUV modes. To save on the number of shaders we
// need to compile, it might be worth just doing this as an
// uber-shader instead.

#define YUV_COLOR_SPACE_REC601 0
#define YUV_COLOR_SPACE_REC709 1
#define YUV_COLOR_SPACE_REC2020 2

#define YUV_FORMAT_NV12 0
#define YUV_FORMAT_PLANAR 1
#define YUV_FORMAT_INTERLEAVED 2
#include shared,prim_shared,brush,yuv

#ifdef WR_FEATURE_ALPHA_PASS
varying vec2 vLocalPos;
@@ -36,60 +23,17 @@ flat varying vec4 vUvBounds_U;
varying vec3 vUv_V;
flat varying vec4 vUvBounds_V;

#ifdef WR_FEATURE_TEXTURE_RECT
#define TEX_SIZE(sampler) vec2(1.0)
#else
#define TEX_SIZE(sampler) vec2(textureSize(sampler, 0).xy)
#endif

flat varying float vCoefficient;
flat varying mat3 vYuvColorMatrix;
flat varying int vFormat;

#ifdef WR_VERTEX_SHADER
// The constants added to the Y, U and V components are applied in the fragment shader.

// From Rec601:
// [R] [1.1643835616438356, 0.0, 1.5960267857142858 ] [Y - 16]
// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708 ] x [U - 128]
// [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [V - 128]
//
// For the range [0,1] instead of [0,255].
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec601 = mat3(
1.16438, 1.16438, 1.16438,
0.0, -0.39176, 2.01723,
1.59603, -0.81297, 0.0
);

// From Rec709:
// [R] [1.1643835616438356, 0.0, 1.7927410714285714] [Y - 16]
// [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444 ] x [U - 128]
// [B] [1.1643835616438356, 2.1124017857142854, 0.0 ] [V - 128]
//
// For the range [0,1] instead of [0,255]:
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec709 = mat3(
1.16438, 1.16438, 1.16438,
0.0 , -0.21325, 2.11240,
1.79274, -0.53291, 0.0
);

// From Re2020:
// [R] [1.16438356164384, 0.0, 1.678674107142860 ] [Y - 16]
// [G] = [1.16438356164384, -0.187326104219343, -0.650424318505057 ] x [U - 128]
// [B] [1.16438356164384, 2.14177232142857, 0.0 ] [V - 128]
//
// For the range [0,1] instead of [0,255]:
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec2020 = mat3(
1.16438356164384 , 1.164383561643840, 1.16438356164384,
0.0 , -0.187326104219343, 2.14177232142857,
1.67867410714286 , -0.650424318505057, 0.0
);

#ifdef WR_FEATURE_TEXTURE_RECT
#define TEX_SIZE(sampler) vec2(1.0)
#else
#define TEX_SIZE(sampler) vec2(textureSize(sampler, 0).xy)
#endif

void write_uv_rect(
int resource_id,
@@ -141,13 +85,7 @@ void yuv_brush_vs(
YuvPrimitive prim = fetch_yuv_primitive(prim_address);
vCoefficient = prim.coefficient;

if (prim.color_space == YUV_COLOR_SPACE_REC601) {
vYuvColorMatrix = YuvColorMatrixRec601;
} else if (prim.color_space == YUV_COLOR_SPACE_REC709) {
vYuvColorMatrix = YuvColorMatrixRec709;
} else {
vYuvColorMatrix = YuvColorMatrixRec2020;
}
vYuvColorMatrix = get_yuv_color_matrix(prim.color_space);
vFormat = prim.yuv_format;

#ifdef WR_FEATURE_ALPHA_PASS
@@ -170,34 +108,17 @@ void yuv_brush_vs(
#ifdef WR_FRAGMENT_SHADER

Fragment yuv_brush_fs() {
vec3 yuv_value;

if (vFormat == YUV_FORMAT_PLANAR) {
// The yuv_planar format should have this third texture coordinate.
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
vec2 uv_u = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
vec2 uv_v = clamp(vUv_V.xy, vUvBounds_V.xy, vUvBounds_V.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
yuv_value.y = TEX_SAMPLE(sColor1, vec3(uv_u, vUv_U.z)).r;
yuv_value.z = TEX_SAMPLE(sColor2, vec3(uv_v, vUv_V.z)).r;
} else if (vFormat == YUV_FORMAT_NV12) {
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
vec2 uv_uv = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
yuv_value.yz = TEX_SAMPLE(sColor1, vec3(uv_uv, vUv_U.z)).rg;
} else if (vFormat == YUV_FORMAT_INTERLEAVED) {
// "The Y, Cb and Cr color channels within the 422 data are mapped into
// the existing green, blue and red color channels."
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
yuv_value = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).gbr;
} else {
yuv_value = vec3(0.0);
}

// See the YuvColorMatrix definition for an explanation of where the constants come from.
vec3 rgb = vYuvColorMatrix * (yuv_value * vCoefficient - vec3(0.06275, 0.50196, 0.50196));
vec4 color = vec4(rgb, 1.0);
vec4 color = sample_yuv(
vFormat,
vYuvColorMatrix,
vCoefficient,
vUv_Y,
vUv_U,
vUv_V,
vUvBounds_Y,
vUvBounds_U,
vUvBounds_V
);

#ifdef WR_FEATURE_ALPHA_PASS
color *= init_transform_fs(vLocalPos);
@@ -0,0 +1,131 @@
/* 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/. */

#include shared

#define YUV_FORMAT_NV12 0
#define YUV_FORMAT_PLANAR 1
#define YUV_FORMAT_INTERLEAVED 2

#ifdef WR_VERTEX_SHADER

#define YUV_COLOR_SPACE_REC601 0
#define YUV_COLOR_SPACE_REC709 1
#define YUV_COLOR_SPACE_REC2020 2

// The constants added to the Y, U and V components are applied in the fragment shader.

// From Rec601:
// [R] [1.1643835616438356, 0.0, 1.5960267857142858 ] [Y - 16]
// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708 ] x [U - 128]
// [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [V - 128]
//
// For the range [0,1] instead of [0,255].
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec601 = mat3(
1.16438, 1.16438, 1.16438,
0.0, -0.39176, 2.01723,
1.59603, -0.81297, 0.0
);

// From Rec709:
// [R] [1.1643835616438356, 0.0, 1.7927410714285714] [Y - 16]
// [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444 ] x [U - 128]
// [B] [1.1643835616438356, 2.1124017857142854, 0.0 ] [V - 128]
//
// For the range [0,1] instead of [0,255]:
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec709 = mat3(
1.16438, 1.16438, 1.16438,
0.0 , -0.21325, 2.11240,
1.79274, -0.53291, 0.0
);

// From Re2020:
// [R] [1.16438356164384, 0.0, 1.678674107142860 ] [Y - 16]
// [G] = [1.16438356164384, -0.187326104219343, -0.650424318505057 ] x [U - 128]
// [B] [1.16438356164384, 2.14177232142857, 0.0 ] [V - 128]
//
// For the range [0,1] instead of [0,255]:
//
// The matrix is stored in column-major.
const mat3 YuvColorMatrixRec2020 = mat3(
1.16438356164384 , 1.164383561643840, 1.16438356164384,
0.0 , -0.187326104219343, 2.14177232142857,
1.67867410714286 , -0.650424318505057, 0.0
);

mat3 get_yuv_color_matrix(int color_space) {
switch (color_space) {
case YUV_COLOR_SPACE_REC601:
return YuvColorMatrixRec601;
case YUV_COLOR_SPACE_REC709:
return YuvColorMatrixRec709;
default:
return YuvColorMatrixRec2020;
}
}
#endif

#ifdef WR_FRAGMENT_SHADER

vec4 sample_yuv(
int format,
mat3 yuv_color_matrix,
float coefficient,
vec3 in_uv_y,
vec3 in_uv_u,
vec3 in_uv_v,
vec4 uv_bounds_y,
vec4 uv_bounds_u,
vec4 uv_bounds_v
) {
vec3 yuv_value;

switch (format) {
case YUV_FORMAT_PLANAR:
{
// The yuv_planar format should have this third texture coordinate.
vec2 uv_y = clamp(in_uv_y.xy, uv_bounds_y.xy, uv_bounds_y.zw);
vec2 uv_u = clamp(in_uv_u.xy, uv_bounds_u.xy, uv_bounds_u.zw);
vec2 uv_v = clamp(in_uv_v.xy, uv_bounds_v.xy, uv_bounds_v.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, in_uv_y.z)).r;
yuv_value.y = TEX_SAMPLE(sColor1, vec3(uv_u, in_uv_u.z)).r;
yuv_value.z = TEX_SAMPLE(sColor2, vec3(uv_v, in_uv_v.z)).r;
}
break;

case YUV_FORMAT_NV12:
{
vec2 uv_y = clamp(in_uv_y.xy, uv_bounds_y.xy, uv_bounds_y.zw);
vec2 uv_uv = clamp(in_uv_u.xy, uv_bounds_u.xy, uv_bounds_u.zw);
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, in_uv_y.z)).r;
yuv_value.yz = TEX_SAMPLE(sColor1, vec3(uv_uv, in_uv_u.z)).rg;
}
break;

case YUV_FORMAT_INTERLEAVED:
{
// "The Y, Cb and Cr color channels within the 422 data are mapped into
// the existing green, blue and red color channels."
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
vec2 uv_y = clamp(in_uv_y.xy, uv_bounds_y.xy, uv_bounds_y.zw);
yuv_value = TEX_SAMPLE(sColor0, vec3(uv_y, in_uv_y.z)).gbr;
}
break;

default:
yuv_value = vec3(0.0);
break;
}

// See the YuvColorMatrix definition for an explanation of where the constants come from.
vec3 rgb = yuv_color_matrix * (yuv_value * coefficient - vec3(0.06275, 0.50196, 0.50196));
vec4 color = vec4(rgb, 1.0);

return color;
}
#endif
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.