| Index: cc/output/shader.cc
|
| diff --git a/cc/output/shader.cc b/cc/output/shader.cc
|
| index 9b54c544e4894cecd83ca73afbfd417b5aff7940..8a17e36022520448c7c4c8995a15dc704d697cbd 100644
|
| --- a/cc/output/shader.cc
|
| +++ b/cc/output/shader.cc
|
| @@ -2019,24 +2019,41 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo()
|
| v_texture_location_(-1),
|
| uv_texture_location_(-1),
|
| a_texture_location_(-1),
|
| + lut_texture_location_(-1),
|
| alpha_location_(-1),
|
| yuv_matrix_location_(-1),
|
| yuv_adj_location_(-1),
|
| ya_clamp_rect_location_(-1),
|
| - uv_clamp_rect_location_(-1) {}
|
| + uv_clamp_rect_location_(-1),
|
| + resource_multiplier_location_(-1),
|
| + resource_offset_location_(-1) {}
|
|
|
| void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture,
|
| - bool use_nv12) {
|
| + bool use_nv12,
|
| + bool use_color_lut) {
|
| use_alpha_texture_ = use_alpha_texture;
|
| use_nv12_ = use_nv12;
|
| + use_color_lut_ = use_color_lut;
|
| }
|
|
|
| void FragmentShaderYUVVideo::Init(GLES2Interface* context,
|
| unsigned program,
|
| int* base_uniform_index) {
|
| static const char* uniforms[] = {
|
| - "y_texture", "u_texture", "v_texture", "uv_texture", "a_texture",
|
| - "alpha", "yuv_matrix", "yuv_adj", "ya_clamp_rect", "uv_clamp_rect"};
|
| + "y_texture",
|
| + "u_texture",
|
| + "v_texture",
|
| + "uv_texture",
|
| + "a_texture",
|
| + "lut_texture",
|
| + "resource_multiplier",
|
| + "resource_offset",
|
| + "yuv_matrix",
|
| + "yuv_adj",
|
| + "alpha",
|
| + "ya_clamp_rect",
|
| + "uv_clamp_rect",
|
| + };
|
| int locations[arraysize(uniforms)];
|
|
|
| GetProgramUniformLocations(context,
|
| @@ -2046,15 +2063,26 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context,
|
| locations,
|
| base_uniform_index);
|
| y_texture_location_ = locations[0];
|
| - u_texture_location_ = locations[1];
|
| - v_texture_location_ = locations[2];
|
| - uv_texture_location_ = locations[3];
|
| - a_texture_location_ = locations[4];
|
| - alpha_location_ = locations[5];
|
| - yuv_matrix_location_ = locations[6];
|
| - yuv_adj_location_ = locations[7];
|
| - ya_clamp_rect_location_ = locations[8];
|
| - uv_clamp_rect_location_ = locations[9];
|
| + if (!use_nv12_) {
|
| + u_texture_location_ = locations[1];
|
| + v_texture_location_ = locations[2];
|
| + } else {
|
| + uv_texture_location_ = locations[3];
|
| + }
|
| + if (use_alpha_texture_) {
|
| + a_texture_location_ = locations[4];
|
| + }
|
| + 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];
|
| + }
|
| + alpha_location_ = locations[10];
|
| + ya_clamp_rect_location_ = locations[11];
|
| + uv_clamp_rect_location_ = locations[12];
|
| }
|
|
|
| std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
|
| @@ -2066,44 +2094,22 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
|
| varying TexCoordPrecision vec2 v_uvTexCoord;
|
| uniform SamplerType y_texture;
|
| uniform float alpha;
|
| - uniform vec3 yuv_adj;
|
| - uniform mat3 yuv_matrix;
|
| uniform vec4 ya_clamp_rect;
|
| uniform vec4 uv_clamp_rect;
|
| });
|
| - if (use_nv12_) {
|
| - head += " uniform SamplerType uv_texture;\n";
|
| - } else {
|
| - head += " uniform SamplerType u_texture;\n";
|
| - head += " uniform SamplerType v_texture;\n";
|
| - }
|
| - if (use_alpha_texture_) {
|
| - head += " uniform SamplerType a_texture;\n";
|
| - }
|
|
|
| - std::string main = 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));
|
| - vec2 uv_unsigned = GetUV(uv_clamped);
|
| - vec3 yuv = vec3(y_raw, uv_unsigned) + yuv_adj;
|
| - vec3 rgb = yuv_matrix * yuv;
|
| - gl_FragColor = vec4(rgb, 1.0) * GetAlpha(ya_clamped);
|
| - }
|
| - });
|
| -
|
| - std::string get_uv;
|
| + std::string functions = "";
|
| if (use_nv12_) {
|
| - get_uv = SHADER0([]() {
|
| + head += " uniform SamplerType uv_texture;\n";
|
| + functions += SHADER0([]() {
|
| vec2 GetUV(vec2 uv_clamped) {
|
| return TextureLookup(uv_texture, uv_clamped).xy;
|
| }
|
| });
|
| } else {
|
| - get_uv = SHADER0([]() {
|
| + 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);
|
| @@ -2111,20 +2117,63 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
|
| });
|
| }
|
|
|
| - std::string get_alpha;
|
| if (use_alpha_texture_) {
|
| - get_alpha = SHADER0([]() {
|
| + head += " uniform SamplerType a_texture;\n";
|
| + functions += SHADER0([]() {
|
| float GetAlpha(vec2 ya_clamped) {
|
| return alpha * TextureLookup(a_texture, ya_clamped).x;
|
| }
|
| });
|
| } else {
|
| - get_alpha = SHADER0([]() {
|
| + functions += SHADER0([]() {
|
| float GetAlpha(vec2 ya_clamped) { return alpha; }
|
| });
|
| }
|
|
|
| - return FRAGMENT_SHADER(head, get_uv + get_alpha + main);
|
| + 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;
|
| + // Select layer
|
| + float layer = min(floor(pos.x), size - 2.0);
|
| + // Compress the yz coordinates so they stay within
|
| + // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3)
|
| + pos.yz = (pos.yz + vec2(0.5)) / size;
|
| + pos.z = (pos.z + layer) / size;
|
| + return mix(texture2D(sampler, pos.yz),
|
| + texture2D(sampler, pos.yz + vec2(0, 1.0 / size)),
|
| + pos.x - layer);
|
| + }
|
| +
|
| + vec3 yuv2rgb(vec3 yuv) {
|
| + yuv = yuv * resource_multiplier - vec3(resource_offset);
|
| + return LUT(lut_texture, yuv, 32.0).xyz;
|
| + }
|
| + });
|
| + } else {
|
| + head += " uniform mat3 yuv_matrix;\n";
|
| + head += " uniform vec3 yuv_adj;\n";
|
| + functions += SHADER0([]() {
|
| + vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); }
|
| + });
|
| + }
|
| +
|
| + 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);
|
| + }
|
| + });
|
| +
|
| + return FRAGMENT_SHADER(head, functions);
|
| }
|
|
|
| FragmentShaderColor::FragmentShaderColor() : color_location_(-1) {
|
|
|