Index: cc/output/shader.cc |
diff --git a/cc/output/shader.cc b/cc/output/shader.cc |
index ea5288b7a59564cbf3d2a56cf4a26a5306e53f10..6d6edb4bd3816730ce45f5d2637b111208760a7c 100644 |
--- a/cc/output/shader.cc |
+++ b/cc/output/shader.cc |
@@ -30,6 +30,15 @@ std::string StripLambda(const char(&shader)[size]) { |
// handling them correctly. StipLambda removes this. |
#define SHADER0(Src) StripLambda(#Src) |
+#define HDR(x) \ |
+ do { \ |
+ header += x + std::string("\n"); \ |
+ } while (0) |
+#define SRC(x) \ |
+ do { \ |
+ source += std::string(" ") + x + std::string("\n"); \ |
+ } while (0) |
+ |
using gpu::gles2::GLES2Interface; |
namespace cc { |
@@ -168,13 +177,18 @@ void VertexShaderBase::Init(GLES2Interface* context, |
std::vector<const char*> uniforms; |
std::vector<int> locations; |
- if (has_tex_transform_) |
- uniforms.push_back("texTransform"); |
- if (has_vertex_tex_transform_) |
- uniforms.push_back("vertexTexTransform"); |
- if (has_tex_matrix_) |
- uniforms.push_back("texMatrix"); |
- if (has_ya_uv_tex_scale_offset_) { |
+ switch (tex_coord_transform_) { |
+ case TEX_COORD_TRANSFORM_NONE: |
+ break; |
+ case TEX_COORD_TRANSFORM_VEC4: |
+ case TEX_COORD_TRANSFORM_TRANSLATED_VEC4: |
+ uniforms.push_back("vertexTexTransform"); |
+ break; |
+ case TEX_COORD_TRANSFORM_MATRIX: |
+ uniforms.push_back("texMatrix"); |
+ break; |
+ } |
+ if (is_ya_uv_) { |
uniforms.push_back("yaTexScale"); |
uniforms.push_back("yaTexOffset"); |
uniforms.push_back("uvTexScale"); |
@@ -188,7 +202,7 @@ void VertexShaderBase::Init(GLES2Interface* context, |
uniforms.push_back("viewport"); |
uniforms.push_back("edge"); |
} |
- if (has_quad_) |
+ if (position_source_ == POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM) |
uniforms.push_back("quad"); |
locations.resize(uniforms.size()); |
@@ -197,13 +211,18 @@ void VertexShaderBase::Init(GLES2Interface* context, |
locations.data(), base_uniform_index); |
size_t index = 0; |
- if (has_tex_transform_) |
- tex_transform_location_ = locations[index++]; |
- if (has_vertex_tex_transform_) |
- vertex_tex_transform_location_ = locations[index++]; |
- if (has_tex_matrix_) |
- tex_matrix_location_ = locations[index++]; |
- if (has_ya_uv_tex_scale_offset_) { |
+ switch (tex_coord_transform_) { |
+ case TEX_COORD_TRANSFORM_NONE: |
+ break; |
+ case TEX_COORD_TRANSFORM_VEC4: |
+ case TEX_COORD_TRANSFORM_TRANSLATED_VEC4: |
+ vertex_tex_transform_location_ = locations[index++]; |
+ break; |
+ case TEX_COORD_TRANSFORM_MATRIX: |
+ tex_matrix_location_ = locations[index++]; |
+ break; |
+ } |
+ if (is_ya_uv_) { |
ya_tex_scale_location_ = locations[index++]; |
ya_tex_offset_location_ = locations[index++]; |
uv_tex_scale_location_ = locations[index++]; |
@@ -217,7 +236,7 @@ void VertexShaderBase::Init(GLES2Interface* context, |
viewport_location_ = locations[index++]; |
edge_location_ = locations[index++]; |
} |
- if (has_quad_) |
+ if (position_source_ == POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM) |
quad_location_ = locations[index++]; |
} |
@@ -226,7 +245,7 @@ void VertexShaderBase::FillLocations(ShaderLocations* locations) const { |
locations->edge = edge_location(); |
locations->viewport = viewport_location(); |
locations->matrix = matrix_location(); |
- locations->tex_transform = tex_transform_location(); |
+ locations->vertex_tex_transform = vertex_tex_transform_location(); |
} |
std::string VertexShaderBase::GetShaderString() const { |
@@ -234,238 +253,146 @@ std::string VertexShaderBase::GetShaderString() const { |
// we are unlikely to be vertex shader bound when drawing large quads. |
// Also, some vertex shaders mutate the texture coordinate in such a |
// way that the effective precision might be lower than expected. |
- return base::StringPrintf( |
- "#define TexCoordPrecision highp\n" |
- "#define NUM_STATIC_QUADS %d\n", |
- StaticGeometryBinding::NUM_QUADS) + |
- GetShaderSource(); |
-} |
- |
-std::string VertexShaderPosTex::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute vec4 a_position; |
- attribute TexCoordPrecision vec2 a_texCoord; |
- uniform mat4 matrix; |
- varying TexCoordPrecision vec2 v_texCoord; |
- void main() { |
- gl_Position = matrix * a_position; |
- v_texCoord = a_texCoord; |
- } |
- }); |
-} |
- |
-std::string VertexShaderPosTexYUVStretchOffset::GetShaderSource() const { |
- return SHADER0([]() { |
- precision mediump float; |
- attribute vec4 a_position; |
- attribute TexCoordPrecision vec2 a_texCoord; |
- uniform mat4 matrix; |
- varying TexCoordPrecision vec2 v_yaTexCoord; |
- varying TexCoordPrecision vec2 v_uvTexCoord; |
- uniform TexCoordPrecision vec2 yaTexScale; |
- uniform TexCoordPrecision vec2 yaTexOffset; |
- uniform TexCoordPrecision vec2 uvTexScale; |
- uniform TexCoordPrecision vec2 uvTexOffset; |
- void main() { |
- gl_Position = matrix * a_position; |
- v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset; |
- v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset; |
- } |
- }); |
-} |
+ std::string header = "#define TexCoordPrecision highp\n"; |
+ std::string source = "void main() {\n"; |
-std::string VertexShaderPos::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute vec4 a_position; |
- uniform mat4 matrix; |
- void main() { gl_Position = matrix * a_position; } |
- }); |
-} |
+ // Define the size of quads for attribute indexed uniform arrays. |
+ if (use_uniform_arrays_) { |
+ header += base::StringPrintf("#define NUM_QUADS %d\n", |
+ StaticGeometryBinding::NUM_QUADS); |
+ } |
-std::string VertexShaderPosTexTransform::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute vec4 a_position; |
- attribute TexCoordPrecision vec2 a_texCoord; |
- attribute float a_index; |
- uniform mat4 matrix[NUM_STATIC_QUADS]; |
- uniform TexCoordPrecision vec4 texTransform[NUM_STATIC_QUADS]; |
- uniform float opacity[NUM_STATIC_QUADS * 4]; |
- varying TexCoordPrecision vec2 v_texCoord; |
- varying float v_alpha; |
- void main() { |
- int quad_index = int(a_index * 0.25); // NOLINT |
- gl_Position = matrix[quad_index] * a_position; |
- TexCoordPrecision vec4 texTrans = texTransform[quad_index]; |
- v_texCoord = a_texCoord * texTrans.zw + texTrans.xy; |
- v_alpha = opacity[int(a_index)]; // NOLINT |
- } |
- }); |
-} |
+ // Read the index variables. |
+ if (use_uniform_arrays_ || |
+ position_source_ == POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM) { |
+ HDR("attribute float a_index;"); |
+ SRC("// Compute indices for uniform arrays."); |
+ SRC("int vertex_index = int(a_index);"); |
+ if (use_uniform_arrays_) |
+ SRC("int quad_index = int(a_index * 0.25);"); |
+ SRC(""); |
+ } |
-std::string VertexShaderPosTexIdentity::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute vec4 a_position; |
- varying TexCoordPrecision vec2 v_texCoord; |
- void main() { |
- gl_Position = a_position; |
- v_texCoord = (a_position.xy + vec2(1.0)) * 0.5; |
+ // Read the position and compute gl_Position. |
+ HDR("attribute TexCoordPrecision vec4 a_position;"); |
+ SRC("// Compute the position."); |
+ switch (position_source_) { |
+ case POSITION_SOURCE_ATTRIBUTE: |
+ SRC("vec4 pos = a_position;"); |
+ break; |
+ case POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM: |
+ HDR("uniform TexCoordPrecision vec2 quad[4];"); |
+ SRC("vec4 pos = vec4(quad[vertex_index], a_position.z, a_position.w);"); |
+ break; |
+ } |
+ if (has_matrix_) { |
+ if (use_uniform_arrays_) { |
+ HDR("uniform mat4 matrix[NUM_QUADS];"); |
+ SRC("gl_Position = matrix[quad_index] * pos;"); |
+ } else { |
+ HDR("uniform mat4 matrix;"); |
+ SRC("gl_Position = matrix * pos;"); |
} |
- }); |
-} |
+ } else { |
+ SRC("gl_Position = pos;"); |
+ } |
-std::string VertexShaderQuad::GetShaderSource() const { |
-#if defined(OS_ANDROID) |
- // TODO(epenner): Find the cause of this 'quad' uniform |
- // being missing if we don't add dummy variables. |
- // http://crbug.com/240602 |
- return SHADER0([]() { |
- attribute TexCoordPrecision vec4 a_position; |
- attribute float a_index; |
- uniform mat4 matrix; |
- uniform TexCoordPrecision vec2 quad[4]; |
- uniform TexCoordPrecision vec2 dummy_uniform; |
- varying TexCoordPrecision vec2 dummy_varying; |
- void main() { |
- vec2 pos = quad[int(a_index)]; // NOLINT |
- gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
- dummy_varying = dummy_uniform; |
- } |
- }); |
-#else |
- return SHADER0([]() { |
- attribute TexCoordPrecision vec4 a_position; |
- attribute float a_index; |
- uniform mat4 matrix; |
- uniform TexCoordPrecision vec2 quad[4]; |
- void main() { |
- vec2 pos = quad[int(a_index)]; // NOLINT |
- gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
- } |
- }); |
-#endif |
-} |
+ // Compute the anti-aliasing edge distances. |
+ if (has_aa_) { |
+ HDR("uniform TexCoordPrecision vec3 edge[8];"); |
+ HDR("uniform vec4 viewport;"); |
+ HDR("varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances."); |
+ SRC("// Compute anti-aliasing properties.\n"); |
+ SRC("vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);"); |
+ SRC("vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);"); |
+ SRC("edge_dist[0] = vec4(dot(edge[0], screen_pos),"); |
+ SRC(" dot(edge[1], screen_pos),"); |
+ SRC(" dot(edge[2], screen_pos),"); |
+ SRC(" dot(edge[3], screen_pos)) * gl_Position.w;"); |
+ SRC("edge_dist[1] = vec4(dot(edge[4], screen_pos),"); |
+ SRC(" dot(edge[5], screen_pos),"); |
+ SRC(" dot(edge[6], screen_pos),"); |
+ SRC(" dot(edge[7], screen_pos)) * gl_Position.w;"); |
+ } |
-std::string VertexShaderQuadAA::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute TexCoordPrecision vec4 a_position; |
- attribute float a_index; |
- uniform mat4 matrix; |
- uniform vec4 viewport; |
- uniform TexCoordPrecision vec2 quad[4]; |
- uniform TexCoordPrecision vec3 edge[8]; |
- varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
- void main() { |
- vec2 pos = quad[int(a_index)]; // NOLINT |
- gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
- vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
- vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
- edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
- dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
- gl_Position.w; |
- edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
- dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
- gl_Position.w; |
+ // Read, transform, and write texture coordinates. |
+ if (tex_coord_source_ != TEX_COORD_SOURCE_NONE) { |
+ if (is_ya_uv_) { |
+ HDR("varying TexCoordPrecision vec2 v_uvTexCoord;"); |
+ HDR("varying TexCoordPrecision vec2 v_yaTexCoord;"); |
+ } else { |
+ HDR("varying TexCoordPrecision vec2 v_texCoord;"); |
} |
- }); |
-} |
-std::string VertexShaderQuadTexTransformAA::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute TexCoordPrecision vec4 a_position; |
- attribute float a_index; |
- uniform mat4 matrix; |
- uniform vec4 viewport; |
- uniform TexCoordPrecision vec2 quad[4]; |
- uniform TexCoordPrecision vec3 edge[8]; |
- uniform TexCoordPrecision vec4 texTransform; |
- varying TexCoordPrecision vec2 v_texCoord; |
- varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
- void main() { |
- vec2 pos = quad[int(a_index)]; // NOLINT |
- gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
- vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
- vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
- edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
- dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
- gl_Position.w; |
- edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
- dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
- gl_Position.w; |
- v_texCoord = (pos.xy + vec2(0.5)) * texTransform.zw + texTransform.xy; |
+ SRC("// Compute texture coordinates."); |
+ // Read coordinates. |
+ switch (tex_coord_source_) { |
+ case TEX_COORD_SOURCE_NONE: |
+ break; |
+ case TEX_COORD_SOURCE_POSITION: |
+ SRC("vec2 texCoord = pos.xy;"); |
+ break; |
+ case TEX_COORD_SOURCE_ATTRIBUTE: |
+ HDR("attribute TexCoordPrecision vec2 a_texCoord;"); |
+ SRC("vec2 texCoord = a_texCoord;"); |
+ break; |
} |
- }); |
-} |
- |
-std::string VertexShaderTile::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute TexCoordPrecision vec4 a_position; |
- attribute TexCoordPrecision vec2 a_texCoord; |
- attribute float a_index; |
- uniform mat4 matrix; |
- uniform TexCoordPrecision vec2 quad[4]; |
- uniform TexCoordPrecision vec4 vertexTexTransform; |
- varying TexCoordPrecision vec2 v_texCoord; |
- void main() { |
- vec2 pos = quad[int(a_index)]; // NOLINT |
- gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
- v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy; |
+ // Transform coordinates (except YUV). |
+ switch (tex_coord_transform_) { |
+ case TEX_COORD_TRANSFORM_NONE: |
+ break; |
+ case TEX_COORD_TRANSFORM_TRANSLATED_VEC4: |
+ SRC("texCoord = texCoord + vec2(0.5);"); |
+ // Fall through... |
+ case TEX_COORD_TRANSFORM_VEC4: |
+ if (use_uniform_arrays_) { |
+ HDR("uniform TexCoordPrecision vec4 vertexTexTransform[NUM_QUADS];"); |
+ SRC("TexCoordPrecision vec4 texTrans ="); |
+ SRC(" vertexTexTransform[quad_index];"); |
+ SRC("texCoord = texCoord * texTrans.zw + texTrans.xy;"); |
+ } else { |
+ HDR("uniform TexCoordPrecision vec4 vertexTexTransform;"); |
+ SRC("texCoord = texCoord * vertexTexTransform.zw +"); |
+ SRC(" vertexTexTransform.xy;"); |
+ } |
+ break; |
+ case TEX_COORD_TRANSFORM_MATRIX: |
+ HDR("uniform TexCoordPrecision mat4 texMatrix;"); |
+ SRC("texCoord = (texMatrix * vec4(texCoord.xy, 0.0, 1.0)).xy;"); |
+ break; |
} |
- }); |
-} |
- |
-std::string VertexShaderTileAA::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute TexCoordPrecision vec4 a_position; |
- attribute float a_index; |
- uniform mat4 matrix; |
- uniform vec4 viewport; |
- uniform TexCoordPrecision vec2 quad[4]; |
- uniform TexCoordPrecision vec3 edge[8]; |
- uniform TexCoordPrecision vec4 vertexTexTransform; |
- varying TexCoordPrecision vec2 v_texCoord; |
- varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
- void main() { |
- vec2 pos = quad[int(a_index)]; // NOLINT |
- gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
- vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
- vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
- edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
- dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
- gl_Position.w; |
- edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
- dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
- gl_Position.w; |
- v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy; |
+ // Write the output texture coordinates. |
+ if (is_ya_uv_) { |
+ HDR("uniform TexCoordPrecision vec2 uvTexOffset;"); |
+ HDR("uniform TexCoordPrecision vec2 uvTexScale;"); |
+ HDR("uniform TexCoordPrecision vec2 yaTexOffset;"); |
+ HDR("uniform TexCoordPrecision vec2 yaTexScale;"); |
+ SRC("v_yaTexCoord = texCoord * yaTexScale + yaTexOffset;"); |
+ SRC("v_uvTexCoord = texCoord * uvTexScale + uvTexOffset;"); |
+ } else { |
+ SRC("v_texCoord = texCoord;"); |
} |
- }); |
-} |
+ } |
-std::string VertexShaderVideoTransform::GetShaderSource() const { |
- return SHADER0([]() { |
- attribute vec4 a_position; |
- attribute TexCoordPrecision vec2 a_texCoord; |
- uniform mat4 matrix; |
- uniform TexCoordPrecision mat4 texMatrix; |
- varying TexCoordPrecision vec2 v_texCoord; |
- void main() { |
- gl_Position = matrix * a_position; |
- v_texCoord = (texMatrix * vec4(a_texCoord.xy, 0.0, 1.0)).xy; |
- } |
- }); |
-} |
+ // Write varying vertex opacity. |
+ if (has_vertex_opacity_) { |
+ DCHECK(use_uniform_arrays_); |
+ HDR("uniform float opacity[NUM_QUADS * 4];"); |
+ HDR("varying float v_alpha;"); |
+ SRC("v_alpha = opacity[quad_index];"); |
+ } |
-#define BLEND_MODE_UNIFORMS "s_backdropTexture", \ |
- "s_originalBackdropTexture", \ |
- "backdropRect" |
-#define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 3 : 0) |
-#define BLEND_MODE_SET_LOCATIONS(X, POS) \ |
- if (has_blend_mode()) { \ |
- DCHECK_LT(static_cast<size_t>(POS) + 2, arraysize(X)); \ |
- backdrop_location_ = locations[POS]; \ |
- original_backdrop_location_ = locations[POS + 1]; \ |
- backdrop_rect_location_ = locations[POS + 2]; \ |
+ // Add cargo-culted dummy variables for Android. |
+ if (has_dummy_variables_) { |
+ HDR("uniform TexCoordPrecision vec2 dummy_uniform;"); |
+ HDR("varying TexCoordPrecision vec2 dummy_varying;"); |
+ SRC("dummy_varying = dummy_uniform;"); |
} |
+ source += "}\n"; |
+ return header + source; |
+} |
+ |
FragmentShaderBase::FragmentShaderBase() {} |
std::string FragmentShaderBase::GetShaderString(TexCoordPrecision precision, |
@@ -875,15 +802,6 @@ std::string FragmentShaderBase::GetShaderSource() const { |
std::string header = "precision mediump float;\n"; |
std::string source = "void main() {\n"; |
-#define HDR(x) \ |
- do { \ |
- header += x + std::string("\n"); \ |
- } while (0) |
-#define SRC(x) \ |
- do { \ |
- source += std::string(" ") + x + std::string("\n"); \ |
- } while (0) |
- |
// Read the input into vec4 texColor. |
switch (input_color_type_) { |
case INPUT_COLOR_SOURCE_RGBA_TEXTURE: |
@@ -1013,9 +931,6 @@ std::string FragmentShaderBase::GetShaderSource() const { |
} |
source += "}\n"; |
-#undef HDR |
-#undef SRC |
- |
return header + source; |
} |