| 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));
|
|
|