Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3021)

Unified Diff: cc/output/shader.cc

Issue 2647743002: The great shader refactor: Finish merging YUV shaders (Closed)
Patch Set: Rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/output/shader.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/shader.cc
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index ccc5cceeb1b24158739e961424a094278a0577b0..3bd260f4a3deee18948fe883f19a62e9ef5b164d 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -385,31 +385,18 @@ std::string VertexShader::GetShaderString() const {
FragmentShader::FragmentShader() {}
std::string FragmentShader::GetShaderString() const {
- // TODO(ccameron): Merge YUV shaders into the main shader generator.
- std::string source;
- if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV)
- source = GetShaderStringYUVVideo();
- else
- source = GetShaderSource();
-
TexCoordPrecision precision = tex_coord_precision_;
// The AA shader values will use TexCoordPrecision.
if (aa_mode_ == USE_AA && precision == TEX_COORD_PRECISION_NA)
precision = TEX_COORD_PRECISION_MEDIUM;
return SetFragmentTexCoordPrecision(
- precision,
- SetFragmentSamplerType(sampler_type_, SetBlendModeFunctions(source)));
+ precision, SetFragmentSamplerType(
+ sampler_type_, SetBlendModeFunctions(GetShaderSource())));
}
void FragmentShader::Init(GLES2Interface* context,
unsigned program,
int* base_uniform_index) {
- // TODO(ccameron): Merge YUV shaders into the main shader generator.
- if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV) {
- InitYUVVideo(context, program, base_uniform_index);
- return;
- }
-
std::vector<const char*> uniforms;
std::vector<int> locations;
if (has_blend_mode()) {
@@ -448,8 +435,15 @@ void FragmentShader::Init(GLES2Interface* context,
uniforms.push_back("a_texture");
uniforms.push_back("ya_clamp_rect");
uniforms.push_back("uv_clamp_rect");
- uniforms.push_back("yuv_matrix");
- uniforms.push_back("yuv_adj");
+ if (color_conversion_mode_ == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
+ uniforms.push_back("lut_texture");
+ uniforms.push_back("lut_size");
+ uniforms.push_back("resource_multiplier");
+ uniforms.push_back("resource_offset");
+ } else {
+ uniforms.push_back("yuv_matrix");
+ uniforms.push_back("yuv_adj");
+ }
break;
case INPUT_COLOR_SOURCE_UNIFORM:
uniforms.push_back("color");
@@ -498,8 +492,15 @@ void FragmentShader::Init(GLES2Interface* context,
a_texture_location_ = locations[index++];
ya_clamp_rect_location_ = locations[index++];
uv_clamp_rect_location_ = locations[index++];
- yuv_matrix_location_ = locations[index++];
- yuv_adj_location_ = locations[index++];
+ if (color_conversion_mode_ == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
+ lut_texture_location_ = locations[index++];
+ lut_size_location_ = locations[index++];
+ resource_multiplier_location_ = locations[index++];
+ resource_offset_location_ = locations[index++];
+ } else {
+ yuv_matrix_location_ = locations[index++];
+ yuv_adj_location_ = locations[index++];
+ }
break;
case INPUT_COLOR_SOURCE_UNIFORM:
color_location_ = locations[index++];
@@ -832,11 +833,14 @@ std::string FragmentShader::GetShaderSource() const {
}
break;
case INPUT_COLOR_SOURCE_YUV_TEXTURES:
+ // Compute the clamped texture coordinates for the YA and UV textures.
HDR("uniform SamplerType y_texture;");
+ SRC("// YUV texture lookup and conversion to RGB.");
SRC("vec2 ya_clamped =");
SRC(" max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));");
SRC("vec2 uv_clamped =");
SRC(" max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));");
+ // Read the Y and UV or U and V textures into |yuv|.
SRC("vec3 yuv;");
SRC("yuv.x = TextureLookup(y_texture, ya_clamped).x;");
if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) {
@@ -853,11 +857,38 @@ std::string FragmentShader::GetShaderSource() const {
HDR("uniform SamplerType a_texture;");
HDR("uniform vec4 ya_clamp_rect;");
HDR("uniform vec4 uv_clamp_rect;");
- HDR("uniform mat3 yuv_matrix;");
- HDR("uniform vec3 yuv_adj;");
+ // Convert YUV to RGB.
+ if (color_conversion_mode_ == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
+ HDR("uniform sampler2D lut_texture;");
+ HDR("uniform float lut_size;");
+ HDR("uniform float resource_multiplier;");
+ HDR("uniform float resource_offset;");
+ HDR("vec4 LUT(sampler2D sampler, vec3 pos, float size) {");
+ HDR(" pos *= size - 1.0;");
+ HDR(" // Select layer");
+ HDR(" float layer = min(floor(pos.z), size - 2.0);");
+ HDR(" // Compress the xy coordinates so they stay within");
+ HDR(" // [0.5 .. 31.5] / N (assuming a LUT size of 17^3)");
+ HDR(" pos.xy = (pos.xy + vec2(0.5)) / size;");
+ HDR(" pos.y = (pos.y + layer) / size;");
+ HDR(" return mix(texture2D(sampler, pos.xy),");
+ HDR(" texture2D(sampler, pos.xy + vec2(0, 1.0 / size)),");
+ HDR(" pos.z - layer);");
+ HDR("}");
+ HDR("vec3 yuv2rgb(vec3 yuv) {");
+ HDR(" yuv = (yuv - vec3(resource_offset)) * resource_multiplier;");
+ HDR(" return LUT(lut_texture, yuv, lut_size).xyz;");
+ HDR("}");
+ } else {
+ HDR("uniform mat3 yuv_matrix;");
+ HDR("uniform vec3 yuv_adj;");
+ HDR("vec3 yuv2rgb(vec3 yuv) {");
+ HDR(" return yuv_matrix * (yuv + yuv_adj);");
+ HDR("}");
+ }
HDR("varying TexCoordPrecision vec2 v_yaTexCoord;");
HDR("varying TexCoordPrecision vec2 v_uvTexCoord;");
- SRC("vec4 texColor = vec4(yuv_matrix * (yuv + yuv_adj), 1.0);");
+ SRC("vec4 texColor = vec4(yuv2rgb(yuv), 1.0);");
break;
case INPUT_COLOR_SOURCE_UNIFORM:
DCHECK(!ignore_sampler_type_);
@@ -969,147 +1000,4 @@ std::string FragmentShader::GetShaderSource() const {
return header + source;
}
-void FragmentShader::InitYUVVideo(GLES2Interface* context,
- unsigned program,
- int* base_uniform_index) {
- static const char* uniforms[] = {
- "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,
- program,
- arraysize(uniforms),
- uniforms,
- locations,
- base_uniform_index);
- y_texture_location_ = locations[0];
- if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
- u_texture_location_ = locations[1];
- v_texture_location_ = locations[2];
- }
- if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) {
- uv_texture_location_ = locations[3];
- }
- if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) {
- a_texture_location_ = locations[4];
- }
- if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV) {
- lut_texture_location_ = locations[5];
- resource_multiplier_location_ = locations[6];
- resource_offset_location_ = locations[7];
- }
- if (color_conversion_mode_ == COLOR_CONVERSION_MODE_NONE) {
- 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 FragmentShader::GetShaderStringYUVVideo() const {
- std::string head = SHADER0([]() {
- precision mediump float;
- precision mediump int;
- varying TexCoordPrecision vec2 v_yaTexCoord;
- varying TexCoordPrecision vec2 v_uvTexCoord;
- uniform SamplerType y_texture;
- uniform float alpha;
- uniform vec4 ya_clamp_rect;
- uniform vec4 uv_clamp_rect;
- });
-
- std::string functions = "";
- if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) {
- head += " uniform SamplerType uv_texture;\n";
- functions += SHADER0([]() {
- vec2 GetUV(vec2 uv_clamped) {
- return TextureLookup(uv_texture, uv_clamped).xy;
- }
- });
- }
- if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
- 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 (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) {
- head += " uniform SamplerType a_texture;\n";
- functions += SHADER0([]() {
- float GetAlpha(vec2 ya_clamped) {
- return alpha * TextureLookup(a_texture, ya_clamped).x;
- }
- });
- } else {
- functions += SHADER0([]() {
- float GetAlpha(vec2 ya_clamped) { return alpha; }
- });
- }
-
- if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV) {
- 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.z), size - 2.0);
- // Compress the xy coordinates so they stay within
- // [0.5 .. 31.5] / 17 (assuming a LUT size of 17^3)
- pos.xy = (pos.xy + vec2(0.5)) / size;
- pos.y = (pos.y + layer) / size;
- return mix(texture2D(sampler, pos.xy),
- texture2D(sampler, pos.xy + vec2(0, 1.0 / size)),
- pos.z - layer);
- }
-
- vec3 yuv2rgb(vec3 yuv) {
- yuv = (yuv - vec3(resource_offset)) * resource_multiplier;
- return LUT(lut_texture, yuv, 17.0).xyz;
- }
- });
- }
- if (color_conversion_mode_ == COLOR_CONVERSION_MODE_NONE) {
- 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 head + functions;
-}
-
} // namespace cc
« no previous file with comments | « cc/output/shader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698