Chromium Code Reviews| Index: cc/output/shader.cc |
| diff --git a/cc/output/shader.cc b/cc/output/shader.cc |
| index b5d163862d14e010aa19d5bcd083278366ed34b4..f06f07415740a0bb392b45a31c51ad68e5fae635 100644 |
| --- a/cc/output/shader.cc |
| +++ b/cc/output/shader.cc |
| @@ -2023,6 +2023,9 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo() |
| alpha_location_(-1), |
| yuv_matrix_location_(-1), |
| yuv_adj_location_(-1), |
| + max_channel_value_location_(-1), |
| + ya_size_location_(-1), |
| + uv_size_location_(-1), |
| ya_clamp_rect_location_(-1), |
| uv_clamp_rect_location_(-1), |
| resource_multiplier_location_(-1), |
| @@ -2030,10 +2033,12 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo() |
| void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, |
| bool use_nv12, |
| - bool use_color_lut) { |
| + bool use_color_lut, |
| + HighbitTexture highbit_texture) { |
| use_alpha_texture_ = use_alpha_texture; |
| use_nv12_ = use_nv12; |
| use_color_lut_ = use_color_lut; |
| + highbit_texture_ = highbit_texture; |
| } |
| void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
| @@ -2046,10 +2051,13 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
| "uv_texture", |
| "a_texture", |
| "lut_texture", |
| - "resource_multiplier", |
| - "resource_offset", |
| "yuv_matrix", |
| "yuv_adj", |
| + "resource_multiplier", |
| + "resource_offset", |
| + "max_channel_value", |
| + "ya_size", |
| + "uv_size", |
| "alpha", |
| "ya_clamp_rect", |
| "uv_clamp_rect", |
| @@ -2074,15 +2082,21 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
| } |
| if (use_color_lut_) { |
| lut_texture_location_ = locations[5]; |
| - resource_multiplier_location_ = locations[6]; |
| - resource_offset_location_ = locations[7]; |
| } else { |
| - yuv_matrix_location_ = locations[8]; |
| - yuv_adj_location_ = locations[9]; |
| + yuv_matrix_location_ = locations[6]; |
| + yuv_adj_location_ = locations[7]; |
| } |
| - alpha_location_ = locations[10]; |
| - ya_clamp_rect_location_ = locations[11]; |
| - uv_clamp_rect_location_ = locations[12]; |
| + if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { |
| + resource_multiplier_location_ = locations[8]; |
| + resource_offset_location_ = locations[9]; |
| + } else if (highbit_texture_ == HIGHBIT_RG88) { |
| + max_channel_value_location_ = locations[10]; |
| + ya_size_location_ = locations[11]; |
| + uv_size_location_ = locations[12]; |
| + } |
| + alpha_location_ = locations[13]; |
| + ya_clamp_rect_location_ = locations[14]; |
| + uv_clamp_rect_location_ = locations[15]; |
| } |
| std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
| @@ -2099,41 +2113,103 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
| }); |
| std::string functions = ""; |
| + if (highbit_texture_ == HIGHBIT_RG88) { |
|
hubbe
2016/09/27 20:49:51
Can we make it so that the if and else branches pr
dshwang
2016/09/28 10:33:27
GetY() and GetUV() is kind of public function. Fol
hubbe
2016/09/28 17:57:44
Hmm, you're right. I was hoping to make this a bit
|
| + head += " uniform int max_channel_value;\n"; |
|
hubbe
2016/09/28 17:57:44
How about reusing resource_multiplier?
The calling
dshwang
2016/09/29 18:52:28
It needs 2048 hardcode or interact code between vi
|
| + head += " uniform vec2 ya_size;\n"; |
| + head += " uniform vec2 uv_size;\n"; |
| + functions += SHADER0([]() { |
| + float GetFloat(vec2 rg) { |
| + return ((rg.g * 65536.0) + (rg.r * 256.0)) / float(max_channel_value); |
|
hubbe
2016/09/28 17:57:44
should be (rg.g * 65280.0) + (rg.r * 255.0)
This
dshwang
2016/09/29 18:52:27
oh, you are right. I'm extending renderer_pixeltes
|
| + } |
| + |
| + float RGTextureLookupBilinear(SamplerType sampler, vec2 tex_coord, |
| + vec4 clamp_rect, vec2 tex_size) { |
| + vec2 unit_texel = 1.0 / tex_size; |
| + vec2 tex_coord_clamped1 = |
| + max(clamp_rect.xy, min(clamp_rect.zw, tex_coord)); |
| + float s1 = GetFloat(TextureLookup(sampler, tex_coord_clamped1).xy); |
| + vec2 tex_coord_clamped2 = |
| + max(clamp_rect.xy, |
| + min(clamp_rect.zw, tex_coord + vec2(unit_texel.x, 0.))); |
|
hubbe
2016/09/28 17:57:44
This doesn't actually work, because there is no gu
dshwang
2016/09/29 18:52:28
Ok, I added snapping code inspired by http://http.
hubbe
2016/09/29 23:36:50
If snapping is not needed, I'd like to understand
dshwang
2016/10/05 15:13:39
I found snapping is needed when I made pixel test.
|
| + float s2 = GetFloat(TextureLookup(sampler, tex_coord_clamped2).xy); |
| + vec2 tex_coord_clamped3 = |
| + max(clamp_rect.xy, |
|
hubbe
2016/09/28 17:57:44
Do we really need to do the clamping for every sub
dshwang
2016/09/29 18:52:27
make sense. it's not really needed.
|
| + min(clamp_rect.zw, tex_coord + vec2(0., unit_texel.y))); |
| + float s3 = GetFloat(TextureLookup(sampler, tex_coord_clamped3).xy); |
| + vec2 tex_coord_clamped4 = |
| + max(clamp_rect.xy, min(clamp_rect.zw, tex_coord + unit_texel)); |
| + float s4 = GetFloat(TextureLookup(sampler, tex_coord_clamped4).xy); |
| + vec2 f = fract(tex_coord * tex_size); |
| + return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y); |
| + } |
| + |
| + float GetY() { |
| + return RGTextureLookupBilinear(y_texture, v_yaTexCoord, ya_clamp_rect, |
| + ya_size); |
| + } |
| + }); |
| + } else { |
| + functions += SHADER0([]() { |
| + float GetY() { |
| + vec2 ya_clamped = |
| + max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); |
| + return TextureLookup(y_texture, ya_clamped).x; |
| + } |
| + }); |
| + } |
| + |
| if (use_nv12_) { |
| head += " uniform SamplerType uv_texture;\n"; |
| functions += SHADER0([]() { |
| - vec2 GetUV(vec2 uv_clamped) { |
| + vec2 GetUV(vec2 uv_tex_coord) { |
| + vec2 uv_clamped = |
| + max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, uv_tex_coord)); |
| return TextureLookup(uv_texture, uv_clamped).xy; |
| } |
| }); |
| } else { |
| head += " uniform SamplerType u_texture;\n"; |
| head += " uniform SamplerType v_texture;\n"; |
| - functions += SHADER0([]() { |
| - vec2 GetUV(vec2 uv_clamped) { |
| - return vec2(TextureLookup(u_texture, uv_clamped).x, |
| - TextureLookup(v_texture, uv_clamped).x); |
| - } |
| - }); |
| + if (highbit_texture_ == HIGHBIT_RG88) { |
| + functions += SHADER0([]() { |
| + vec2 GetUV(vec2 uv_tex_coord) { |
|
hubbe
2016/09/27 20:49:51
I think it would be more efficient if this was a a
dshwang
2016/09/28 10:33:27
That's good idea. 8888 texture could be fallback o
hubbe
2016/09/29 23:36:51
Almost everything supports RG88 I think.
|
| + vec2 uv = vec2(RGTextureLookupBilinear(u_texture, uv_tex_coord, |
| + uv_clamp_rect, uv_size), |
| + RGTextureLookupBilinear(v_texture, uv_tex_coord, |
| + uv_clamp_rect, uv_size)); |
| + return uv; |
| + } |
| + }); |
| + } else { |
| + functions += SHADER0([]() { |
| + vec2 GetUV(vec2 uv_tex_coord) { |
| + vec2 uv_clamped = |
| + max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, uv_tex_coord)); |
| + vec2 uv = vec2(TextureLookup(u_texture, uv_clamped).x, |
| + TextureLookup(v_texture, uv_clamped).x); |
| + return uv; |
| + } |
| + }); |
| + } |
| } |
| if (use_alpha_texture_) { |
| head += " uniform SamplerType a_texture;\n"; |
| functions += SHADER0([]() { |
| - float GetAlpha(vec2 ya_clamped) { |
| + float GetAlpha(vec2 ya_tex_coord) { |
| + vec2 ya_clamped = |
| + max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, ya_tex_coord)); |
| return alpha * TextureLookup(a_texture, ya_clamped).x; |
| } |
| }); |
| } else { |
| functions += SHADER0([]() { |
| - float GetAlpha(vec2 ya_clamped) { return alpha; } |
| + float GetAlpha(vec2 ya_tex_coord) { return alpha; } |
| }); |
| } |
| if (use_color_lut_) { |
| head += " uniform sampler2D lut_texture;\n"; |
| - head += " uniform float resource_multiplier;\n"; |
| - head += " uniform float resource_offset;\n"; |
| functions += SHADER0([]() { |
| vec4 LUT(sampler2D sampler, vec3 pos, float size) { |
| pos *= size - 1.0; |
| @@ -2147,12 +2223,21 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
| texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), |
| pos.x - layer); |
| } |
| - |
| - vec3 yuv2rgb(vec3 yuv) { |
| - yuv = (yuv - vec3(resource_offset)) * resource_multiplier; |
| - return LUT(lut_texture, yuv, 32.0).xyz; |
| - } |
| }); |
| + if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { |
| + head += " uniform float resource_multiplier;\n"; |
| + head += " uniform float resource_offset;\n"; |
| + functions += SHADER0([]() { |
| + vec3 yuv2rgb(vec3 yuv) { |
| + yuv = (yuv - vec3(resource_offset)) * resource_multiplier; |
| + return LUT(lut_texture, yuv, 32.0).xyz; |
| + } |
| + }); |
| + } else { |
| + functions += SHADER0([]() { |
| + vec3 yuv2rgb(vec3 yuv) { return LUT(lut_texture, yuv, 32.0).xyz; } |
| + }); |
| + } |
| } else { |
| head += " uniform mat3 yuv_matrix;\n"; |
| head += " uniform vec3 yuv_adj;\n"; |
| @@ -2163,13 +2248,9 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
| functions += SHADER0([]() { |
| void main() { |
| - vec2 ya_clamped = |
| - max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); |
| - float y_raw = TextureLookup(y_texture, ya_clamped).x; |
| - vec2 uv_clamped = |
| - max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); |
| - vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); |
| - gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); |
| + float y_raw = GetY(); |
|
hubbe
2016/09/28 17:57:44
GetUV and GetAlpha takes a parameter, probably Get
dshwang
2016/09/29 18:52:28
to make consistent, let me change it to get |v_yaT
|
| + vec3 yuv = vec3(y_raw, GetUV(v_uvTexCoord)); |
| + gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(v_yaTexCoord); |
| } |
| }); |