Index: cc/output/shader.cc |
diff --git a/cc/output/shader.cc b/cc/output/shader.cc |
index b5d163862d14e010aa19d5bcd083278366ed34b4..9e1b7dbb8c599d5c3114d214915469115f387984 100644 |
--- a/cc/output/shader.cc |
+++ b/cc/output/shader.cc |
@@ -2023,6 +2023,8 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo() |
alpha_location_(-1), |
yuv_matrix_location_(-1), |
yuv_adj_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 +2032,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, |
@@ -2050,6 +2054,8 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
"resource_offset", |
"yuv_matrix", |
"yuv_adj", |
+ "ya_size", |
+ "uv_size", |
"alpha", |
"ya_clamp_rect", |
"uv_clamp_rect", |
@@ -2074,15 +2080,24 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
} |
if (use_color_lut_) { |
lut_texture_location_ = locations[5]; |
- resource_multiplier_location_ = locations[6]; |
- resource_offset_location_ = locations[7]; |
+ if (highbit_texture_ == HIGHBIT_LUMINANCE_F16 || |
+ highbit_texture_ == HIGHBIT_RG88) { |
+ resource_multiplier_location_ = locations[6]; |
+ } |
+ if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { |
+ resource_offset_location_ = locations[7]; |
+ } |
} else { |
yuv_matrix_location_ = locations[8]; |
yuv_adj_location_ = locations[9]; |
} |
- alpha_location_ = locations[10]; |
- ya_clamp_rect_location_ = locations[11]; |
- uv_clamp_rect_location_ = locations[12]; |
+ if (highbit_texture_ == HIGHBIT_RG88) { |
+ ya_size_location_ = locations[10]; |
+ uv_size_location_ = locations[11]; |
+ } |
+ alpha_location_ = locations[12]; |
+ ya_clamp_rect_location_ = locations[13]; |
+ uv_clamp_rect_location_ = locations[14]; |
} |
std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
@@ -2099,6 +2114,42 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
}); |
std::string functions = ""; |
+ if (highbit_texture_ == HIGHBIT_RG88) { |
+ head += " uniform vec2 ya_size;\n"; |
+ head += " uniform vec2 uv_size;\n"; |
+ functions += SHADER0([]() { |
+ float GetFloat(SamplerType sampler, vec2 tex_coord) { |
+ vec2 rg = TextureLookup(sampler, tex_coord).xy; |
+ return (rg.g * 256.0) + rg.r; |
+ } |
+ |
+ // refer to Mesa sample_2d_linear() in s_texfilter.c |
+ // https://cs.chromium.org/chromium/src/third_party/mesa/src/src/mesa/swrast/s_texfilter.c?q=sample_2d_linear&sq=package:chromium |
+ float RGTextureLookupBilinear(SamplerType sampler, vec2 tex_coord, |
+ vec2 tex_size) { |
+ vec2 unit_texel = 1.0 / tex_size; |
+ vec2 unnorm_tex_coord = (tex_coord * tex_size) - vec2(0.5); |
+ vec2 f = fract(unnorm_tex_coord); |
+ vec2 snap_tex_coord = (floor(unnorm_tex_coord) + vec2(0.5)) / tex_size; |
+ float s1 = GetFloat(sampler, snap_tex_coord); |
+ float s2 = GetFloat(sampler, snap_tex_coord + vec2(unit_texel.x, 0.)); |
+ float s3 = GetFloat(sampler, snap_tex_coord + vec2(0., unit_texel.y)); |
+ float s4 = GetFloat(sampler, snap_tex_coord + unit_texel); |
+ return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y); |
+ } |
+ |
+ float GetY(vec2 ya_clamped) { |
+ return RGTextureLookupBilinear(y_texture, ya_clamped, ya_size); |
+ } |
+ }); |
+ } else { |
+ functions += SHADER0([]() { |
+ float GetY(vec2 ya_clamped) { |
+ return TextureLookup(y_texture, ya_clamped).x; |
+ } |
+ }); |
+ } |
+ |
if (use_nv12_) { |
head += " uniform SamplerType uv_texture;\n"; |
functions += SHADER0([]() { |
@@ -2109,12 +2160,24 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
} 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_clamped) { |
+ vec2 uv = |
+ vec2(RGTextureLookupBilinear(u_texture, uv_clamped, uv_size), |
+ RGTextureLookupBilinear(v_texture, uv_clamped, uv_size)); |
+ return uv; |
+ } |
+ }); |
+ } else { |
+ functions += SHADER0([]() { |
+ vec2 GetUV(vec2 uv_clamped) { |
+ vec2 uv = vec2(TextureLookup(u_texture, uv_clamped).x, |
+ TextureLookup(v_texture, uv_clamped).x); |
+ return uv; |
+ } |
+ }); |
+ } |
} |
if (use_alpha_texture_) { |
@@ -2132,8 +2195,6 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
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 +2208,29 @@ 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 if (highbit_texture_ == HIGHBIT_RG88) { |
+ head += " uniform float resource_multiplier;\n"; |
+ functions += SHADER0([]() { |
+ vec3 yuv2rgb(vec3 yuv) { |
+ yuv = yuv * 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"; |
@@ -2165,7 +2243,7 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
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; |
+ float y_raw = GetY(ya_clamped); |
vec2 uv_clamped = |
max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); |
vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); |