| author | Glenn Watson <gw@intuitionlibrary.com> |
| Tue, 18 Feb 2020 08:21:16 +0000 | |
| changeset 514368 | bde7c898937d877132b5d2aaeae022227c9da7af |
| parent 514367 | 2b174daed07cadbcdf81bb4e128aad8ac77085ca |
| child 514369 | 813b494a8388485c900045d829c603d45acdd106 |
| push id | 37134 |
| push user | ncsoregi@mozilla.com |
| push date | Tue, 18 Feb 2020 16:57:22 +0000 |
| treeherder | mozilla-central@a5e2eb343af7 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | nical |
| bugs | 1579235 |
| milestone | 75.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| gfx/wr/webrender/res/brush_yuv_image.glsl | file | annotate | diff | comparison | revisions | |
| gfx/wr/webrender/res/yuv.glsl | file | annotate | diff | comparison | revisions |
--- a/gfx/wr/webrender/res/brush_yuv_image.glsl +++ b/gfx/wr/webrender/res/brush_yuv_image.glsl @@ -3,98 +3,42 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #define VECS_PER_YUV_BRUSH 1 #define VECS_PER_SPECIFIC_BRUSH VECS_PER_YUV_BRUSH #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; #endif varying vec3 vUv_Y; flat varying vec4 vUvBounds_Y; varying vec3 vUv_U; 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, vec2 f, vec2 texture_size, out vec3 uv, out vec4 uv_bounds ) { @@ -136,23 +80,17 @@ void yuv_brush_vs( int brush_flags, vec4 unused ) { vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size; 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 vLocalPos = vi.local_pos; #endif if (vFormat == YUV_FORMAT_PLANAR) { write_uv_rect(prim_user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y); @@ -165,44 +103,27 @@ void yuv_brush_vs( write_uv_rect(prim_user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y); } } #endif #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); #endif return Fragment(color); } #endif
new file mode 100644 --- /dev/null +++ b/gfx/wr/webrender/res/yuv.glsl @@ -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