1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/shader.h"
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "cc/output/gl_renderer.h" // For the GLC() macro.
12 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
13 #include "third_party/khronos/GLES2/gl2.h"
15 #define SHADER0(Src) #Src
16 #define VERTEX_SHADER(Src) SetVertexTexCoordPrecision(SHADER0(Src))
17 #define FRAGMENT_SHADER(Src) SetFragTexCoordPrecision(precision, SHADER0(Src))
19 using WebKit::WebGraphicsContext3D;
25 static void GetProgramUniformLocations(WebGraphicsContext3D* context,
28 const char** uniforms,
30 bool using_bind_uniform,
31 int* base_uniform_index) {
32 for (size_t i = 0; i < count; i++) {
33 if (using_bind_uniform) {
34 locations[i] = (*base_uniform_index)++;
35 context->bindUniformLocationCHROMIUM(program, locations[i], uniforms[i]);
37 locations[i] = context->getUniformLocation(program, uniforms[i]);
38 DCHECK_NE(locations[i], -1);
43 static std::string SetFragTexCoordPrecision(
44 TexCoordPrecision requested_precision, std::string shader_string) {
45 switch (requested_precision) {
46 case TexCoordPrecisionHigh:
47 DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
49 "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
50 " #define TexCoordPrecision highp\n"
52 " #define TexCoordPrecision mediump\n"
55 case TexCoordPrecisionMedium:
56 DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
57 return "#define TexCoordPrecision mediump\n" +
59 case TexCoordPrecisionNA:
60 DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos);
61 DCHECK_EQ(shader_string.find("texture2D"), std::string::npos);
67 static std::string SetVertexTexCoordPrecision(const char* shader_string) {
68 // We unconditionally use highp in the vertex shader since
69 // we are unlikely to be vertex shader bound when drawing large quads.
70 // Also, some vertex shaders mutate the texture coordinate in such a
71 // way that the effective precision might be lower than expected.
72 return "#define TexCoordPrecision highp\n" +
73 std::string(shader_string);
76 TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context,
77 int *highp_threshold_cache,
78 int highp_threshold_min,
80 if (*highp_threshold_cache == 0) {
81 // Initialize range and precision with minimum spec values for when
82 // GetShaderPrecisionFormat is a test stub.
83 // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat
85 GLint range[2] = { 14, 14 };
87 GLC(context, context->getShaderPrecisionFormat(GL_FRAGMENT_SHADER,
90 *highp_threshold_cache = 1 << precision;
93 int highp_threshold = std::max(*highp_threshold_cache, highp_threshold_min);
94 if (x > highp_threshold || y > highp_threshold)
95 return TexCoordPrecisionHigh;
96 return TexCoordPrecisionMedium;
101 TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context,
102 int *highp_threshold_cache,
103 int highp_threshold_min,
104 gfx::Point max_coordinate) {
105 return TexCoordPrecisionRequired(context,
106 highp_threshold_cache, highp_threshold_min,
107 max_coordinate.x(), max_coordinate.y());
110 TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context,
111 int *highp_threshold_cache,
112 int highp_threshold_min,
113 gfx::Size max_size) {
114 return TexCoordPrecisionRequired(context,
115 highp_threshold_cache, highp_threshold_min,
116 max_size.width(), max_size.height());
119 VertexShaderPosTex::VertexShaderPosTex()
120 : matrix_location_(-1) {}
122 void VertexShaderPosTex::Init(WebGraphicsContext3D* context,
124 bool using_bind_uniform,
125 int* base_uniform_index) {
126 static const char* uniforms[] = {
129 int locations[arraysize(uniforms)];
131 GetProgramUniformLocations(context,
138 matrix_location_ = locations[0];
141 std::string VertexShaderPosTex::GetShaderString() const {
142 return VERTEX_SHADER(
143 attribute vec4 a_position;
144 attribute TexCoordPrecision vec2 a_texCoord;
146 varying TexCoordPrecision vec2 v_texCoord;
148 gl_Position = matrix * a_position;
149 v_texCoord = a_texCoord;
151 ); // NOLINT(whitespace/parens)
154 VertexShaderPosTexYUVStretch::VertexShaderPosTexYUVStretch()
155 : matrix_location_(-1),
156 tex_scale_location_(-1) {}
158 void VertexShaderPosTexYUVStretch::Init(WebGraphicsContext3D* context,
160 bool using_bind_uniform,
161 int* base_uniform_index) {
162 static const char* uniforms[] = {
166 int locations[arraysize(uniforms)];
168 GetProgramUniformLocations(context,
175 matrix_location_ = locations[0];
176 tex_scale_location_ = locations[1];
179 std::string VertexShaderPosTexYUVStretch::GetShaderString() const {
180 return VERTEX_SHADER(
181 precision mediump float;
182 attribute vec4 a_position;
183 attribute TexCoordPrecision vec2 a_texCoord;
185 varying TexCoordPrecision vec2 v_texCoord;
186 uniform TexCoordPrecision vec2 texScale;
188 gl_Position = matrix * a_position;
189 v_texCoord = a_texCoord * texScale;
191 ); // NOLINT(whitespace/parens)
194 VertexShaderPos::VertexShaderPos()
195 : matrix_location_(-1) {}
197 void VertexShaderPos::Init(WebGraphicsContext3D* context,
199 bool using_bind_uniform,
200 int* base_uniform_index) {
201 static const char* uniforms[] = {
204 int locations[arraysize(uniforms)];
206 GetProgramUniformLocations(context,
213 matrix_location_ = locations[0];
216 std::string VertexShaderPos::GetShaderString() const {
217 return VERTEX_SHADER(
218 attribute vec4 a_position;
221 gl_Position = matrix * a_position;
223 ); // NOLINT(whitespace/parens)
226 VertexShaderPosTexTransform::VertexShaderPosTexTransform()
227 : matrix_location_(-1),
228 tex_transform_location_(-1),
229 vertex_opacity_location_(-1) {}
231 void VertexShaderPosTexTransform::Init(WebGraphicsContext3D* context,
233 bool using_bind_uniform,
234 int* base_uniform_index) {
235 static const char* uniforms[] = {
240 int locations[arraysize(uniforms)];
242 GetProgramUniformLocations(context,
249 matrix_location_ = locations[0];
250 tex_transform_location_ = locations[1];
251 vertex_opacity_location_ = locations[2];
254 std::string VertexShaderPosTexTransform::GetShaderString() const {
255 return VERTEX_SHADER(
256 attribute vec4 a_position;
257 attribute TexCoordPrecision vec2 a_texCoord;
258 attribute float a_index;
259 uniform mat4 matrix[8];
260 uniform TexCoordPrecision vec4 texTransform[8];
261 uniform float opacity[32];
262 varying TexCoordPrecision vec2 v_texCoord;
263 varying float v_alpha;
265 int quad_index = int(a_index * 0.25); // NOLINT
266 gl_Position = matrix[quad_index] * a_position;
267 TexCoordPrecision vec4 texTrans = texTransform[quad_index];
268 v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
269 v_alpha = opacity[int(a_index)]; // NOLINT
271 ); // NOLINT(whitespace/parens)
274 std::string VertexShaderPosTexIdentity::GetShaderString() const {
275 return VERTEX_SHADER(
276 attribute vec4 a_position;
277 varying TexCoordPrecision vec2 v_texCoord;
279 gl_Position = a_position;
280 v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
282 ); // NOLINT(whitespace/parens)
285 VertexShaderQuad::VertexShaderQuad()
286 : matrix_location_(-1),
287 quad_location_(-1) {}
289 void VertexShaderQuad::Init(WebGraphicsContext3D* context,
291 bool using_bind_uniform,
292 int* base_uniform_index) {
293 static const char* uniforms[] = {
297 int locations[arraysize(uniforms)];
299 GetProgramUniformLocations(context,
306 matrix_location_ = locations[0];
307 quad_location_ = locations[1];
310 std::string VertexShaderQuad::GetShaderString() const {
311 #if defined(OS_ANDROID)
312 // TODO(epenner): Find the cause of this 'quad' uniform
313 // being missing if we don't add dummy variables.
314 // http://crbug.com/240602
315 return VERTEX_SHADER(
316 attribute TexCoordPrecision vec4 a_position;
317 attribute float a_index;
319 uniform TexCoordPrecision vec2 quad[4];
320 uniform TexCoordPrecision vec2 dummy_uniform;
321 varying TexCoordPrecision vec2 dummy_varying;
323 vec2 pos = quad[int(a_index)]; // NOLINT
324 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
325 dummy_varying = dummy_uniform;
327 ); // NOLINT(whitespace/parens)
329 return VERTEX_SHADER(
330 attribute TexCoordPrecision vec4 a_position;
331 attribute float a_index;
333 uniform TexCoordPrecision vec2 quad[4];
335 vec2 pos = quad[int(a_index)]; // NOLINT
336 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
338 ); // NOLINT(whitespace/parens)
342 VertexShaderQuadAA::VertexShaderQuadAA()
343 : matrix_location_(-1),
344 viewport_location_(-1),
346 edge_location_(-1) {}
348 void VertexShaderQuadAA::Init(WebGraphicsContext3D* context,
350 bool using_bind_uniform,
351 int* base_uniform_index) {
352 static const char* uniforms[] = {
358 int locations[arraysize(uniforms)];
360 GetProgramUniformLocations(context,
367 matrix_location_ = locations[0];
368 viewport_location_ = locations[1];
369 quad_location_ = locations[2];
370 edge_location_ = locations[3];
373 std::string VertexShaderQuadAA::GetShaderString() const {
374 return VERTEX_SHADER(
375 attribute TexCoordPrecision vec4 a_position;
376 attribute float a_index;
378 uniform vec4 viewport;
379 uniform TexCoordPrecision vec2 quad[4];
380 uniform TexCoordPrecision vec3 edge[8];
381 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
384 vec2 pos = quad[int(a_index)]; // NOLINT
385 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
386 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
387 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
388 edge_dist[0] = vec4(dot(edge[0], screen_pos),
389 dot(edge[1], screen_pos),
390 dot(edge[2], screen_pos),
391 dot(edge[3], screen_pos)) * gl_Position.w;
392 edge_dist[1] = vec4(dot(edge[4], screen_pos),
393 dot(edge[5], screen_pos),
394 dot(edge[6], screen_pos),
395 dot(edge[7], screen_pos)) * gl_Position.w;
397 ); // NOLINT(whitespace/parens)
400 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
401 : matrix_location_(-1),
402 viewport_location_(-1),
405 tex_transform_location_(-1) {}
407 void VertexShaderQuadTexTransformAA::Init(WebGraphicsContext3D* context,
409 bool using_bind_uniform,
410 int* base_uniform_index) {
411 static const char* uniforms[] = {
418 int locations[arraysize(uniforms)];
420 GetProgramUniformLocations(context,
427 matrix_location_ = locations[0];
428 viewport_location_ = locations[1];
429 quad_location_ = locations[2];
430 edge_location_ = locations[3];
431 tex_transform_location_ = locations[4];
434 std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
435 return VERTEX_SHADER(
436 attribute TexCoordPrecision vec4 a_position;
437 attribute float a_index;
439 uniform vec4 viewport;
440 uniform TexCoordPrecision vec2 quad[4];
441 uniform TexCoordPrecision vec3 edge[8];
442 uniform TexCoordPrecision vec4 texTrans;
443 varying TexCoordPrecision vec2 v_texCoord;
444 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
447 vec2 pos = quad[int(a_index)]; // NOLINT
448 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
449 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
450 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
451 edge_dist[0] = vec4(dot(edge[0], screen_pos),
452 dot(edge[1], screen_pos),
453 dot(edge[2], screen_pos),
454 dot(edge[3], screen_pos)) * gl_Position.w;
455 edge_dist[1] = vec4(dot(edge[4], screen_pos),
456 dot(edge[5], screen_pos),
457 dot(edge[6], screen_pos),
458 dot(edge[7], screen_pos)) * gl_Position.w;
459 v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy;
461 ); // NOLINT(whitespace/parens)
464 VertexShaderTile::VertexShaderTile()
465 : matrix_location_(-1),
467 vertex_tex_transform_location_(-1) {}
469 void VertexShaderTile::Init(WebGraphicsContext3D* context,
471 bool using_bind_uniform,
472 int* base_uniform_index) {
473 static const char* uniforms[] = {
476 "vertexTexTransform",
478 int locations[arraysize(uniforms)];
480 GetProgramUniformLocations(context,
487 matrix_location_ = locations[0];
488 quad_location_ = locations[1];
489 vertex_tex_transform_location_ = locations[2];
492 std::string VertexShaderTile::GetShaderString() const {
493 return VERTEX_SHADER(
494 attribute TexCoordPrecision vec4 a_position;
495 attribute float a_index;
497 uniform TexCoordPrecision vec2 quad[4];
498 uniform TexCoordPrecision vec4 vertexTexTransform;
499 varying TexCoordPrecision vec2 v_texCoord;
501 vec2 pos = quad[int(a_index)]; // NOLINT
502 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
503 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
505 ); // NOLINT(whitespace/parens)
508 VertexShaderTileAA::VertexShaderTileAA()
509 : matrix_location_(-1),
510 viewport_location_(-1),
513 vertex_tex_transform_location_(-1) {}
515 void VertexShaderTileAA::Init(WebGraphicsContext3D* context,
517 bool using_bind_uniform,
518 int* base_uniform_index) {
519 static const char* uniforms[] = {
524 "vertexTexTransform",
526 int locations[arraysize(uniforms)];
528 GetProgramUniformLocations(context,
535 matrix_location_ = locations[0];
536 viewport_location_ = locations[1];
537 quad_location_ = locations[2];
538 edge_location_ = locations[3];
539 vertex_tex_transform_location_ = locations[4];
542 std::string VertexShaderTileAA::GetShaderString() const {
543 return VERTEX_SHADER(
544 attribute TexCoordPrecision vec4 a_position;
545 attribute float a_index;
547 uniform vec4 viewport;
548 uniform TexCoordPrecision vec2 quad[4];
549 uniform TexCoordPrecision vec3 edge[8];
550 uniform TexCoordPrecision vec4 vertexTexTransform;
551 varying TexCoordPrecision vec2 v_texCoord;
552 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
555 vec2 pos = quad[int(a_index)]; // NOLINT
556 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
557 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
558 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
559 edge_dist[0] = vec4(dot(edge[0], screen_pos),
560 dot(edge[1], screen_pos),
561 dot(edge[2], screen_pos),
562 dot(edge[3], screen_pos)) * gl_Position.w;
563 edge_dist[1] = vec4(dot(edge[4], screen_pos),
564 dot(edge[5], screen_pos),
565 dot(edge[6], screen_pos),
566 dot(edge[7], screen_pos)) * gl_Position.w;
567 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
569 ); // NOLINT(whitespace/parens)
572 VertexShaderVideoTransform::VertexShaderVideoTransform()
573 : matrix_location_(-1),
574 tex_matrix_location_(-1) {}
576 void VertexShaderVideoTransform::Init(WebGraphicsContext3D* context,
578 bool using_bind_uniform,
579 int* base_uniform_index) {
580 static const char* uniforms[] = {
584 int locations[arraysize(uniforms)];
586 GetProgramUniformLocations(context,
593 matrix_location_ = locations[0];
594 tex_matrix_location_ = locations[1];
597 std::string VertexShaderVideoTransform::GetShaderString() const {
598 return VERTEX_SHADER(
599 attribute vec4 a_position;
600 attribute TexCoordPrecision vec2 a_texCoord;
602 uniform TexCoordPrecision mat4 texMatrix;
603 varying TexCoordPrecision vec2 v_texCoord;
605 gl_Position = matrix * a_position;
607 vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
609 ); // NOLINT(whitespace/parens)
612 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
613 : sampler_location_(-1),
614 alpha_location_(-1) {}
616 void FragmentTexAlphaBinding::Init(WebGraphicsContext3D* context,
618 bool using_bind_uniform,
619 int* base_uniform_index) {
620 static const char* uniforms[] = {
624 int locations[arraysize(uniforms)];
626 GetProgramUniformLocations(context,
633 sampler_location_ = locations[0];
634 alpha_location_ = locations[1];
637 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
638 : sampler_location_(-1),
640 color_matrix_location_(-1),
641 color_offset_location_(-1) {}
643 void FragmentTexColorMatrixAlphaBinding::Init(WebGraphicsContext3D* context,
645 bool using_bind_uniform,
646 int* base_uniform_index) {
647 static const char* uniforms[] = {
653 int locations[arraysize(uniforms)];
655 GetProgramUniformLocations(context,
662 sampler_location_ = locations[0];
663 alpha_location_ = locations[1];
664 color_matrix_location_ = locations[2];
665 color_offset_location_ = locations[3];
668 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
669 : sampler_location_(-1) {}
671 void FragmentTexOpaqueBinding::Init(WebGraphicsContext3D* context,
673 bool using_bind_uniform,
674 int* base_uniform_index) {
675 static const char* uniforms[] = {
678 int locations[arraysize(uniforms)];
680 GetProgramUniformLocations(context,
687 sampler_location_ = locations[0];
690 FragmentShaderOESImageExternal::FragmentShaderOESImageExternal()
691 : sampler_location_(-1) {}
693 void FragmentShaderOESImageExternal::Init(WebGraphicsContext3D* context,
695 bool using_bind_uniform,
696 int* base_uniform_index) {
697 static const char* uniforms[] = {
700 int locations[arraysize(uniforms)];
702 GetProgramUniformLocations(context,
709 sampler_location_ = locations[0];
712 std::string FragmentShaderOESImageExternal::GetShaderString(
713 TexCoordPrecision precision) const {
714 // Cannot use the SHADER() macro because of the '#' char
715 return "#extension GL_OES_EGL_image_external : require\n" +
717 precision mediump float;
718 varying TexCoordPrecision vec2 v_texCoord;
719 uniform samplerExternalOES s_texture;
721 vec4 texColor = texture2D(s_texture, v_texCoord);
722 gl_FragColor = texColor;
724 ); // NOLINT(whitespace/parens)
727 std::string FragmentShaderRGBATexAlpha::GetShaderString(
728 TexCoordPrecision precision) const {
729 return FRAGMENT_SHADER(
730 precision mediump float;
731 varying TexCoordPrecision vec2 v_texCoord;
732 uniform sampler2D s_texture;
735 vec4 texColor = texture2D(s_texture, v_texCoord);
736 gl_FragColor = texColor * alpha;
738 ); // NOLINT(whitespace/parens)
741 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
742 TexCoordPrecision precision) const {
743 return FRAGMENT_SHADER(
744 precision mediump float;
745 varying TexCoordPrecision vec2 v_texCoord;
746 uniform sampler2D s_texture;
748 uniform mat4 colorMatrix;
749 uniform vec4 colorOffset;
751 vec4 texColor = texture2D(s_texture, v_texCoord);
752 float nonZeroAlpha = max(texColor.a, 0.00001);
753 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
754 texColor = colorMatrix * texColor + colorOffset;
755 texColor.rgb *= texColor.a;
756 texColor = clamp(texColor, 0.0, 1.0);
757 gl_FragColor = texColor * alpha;
759 ); // NOLINT(whitespace/parens)
762 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
763 TexCoordPrecision precision) const {
764 return FRAGMENT_SHADER(
765 precision mediump float;
766 varying TexCoordPrecision vec2 v_texCoord;
767 varying float v_alpha;
768 uniform sampler2D s_texture;
770 vec4 texColor = texture2D(s_texture, v_texCoord);
771 gl_FragColor = texColor * v_alpha;
773 ); // NOLINT(whitespace/parens)
776 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
777 TexCoordPrecision precision) const {
778 return FRAGMENT_SHADER(
779 precision mediump float;
780 varying TexCoordPrecision vec2 v_texCoord;
781 varying float v_alpha;
782 uniform sampler2D s_texture;
784 vec4 texColor = texture2D(s_texture, v_texCoord);
785 texColor.rgb *= texColor.a;
786 gl_FragColor = texColor * v_alpha;
788 ); // NOLINT(whitespace/parens)
791 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
792 : background_color_location_(-1),
793 sampler_location_(-1) {
796 void FragmentTexBackgroundBinding::Init(WebGraphicsContext3D* context,
798 bool using_bind_uniform,
799 int* base_uniform_index) {
800 static const char* uniforms[] = {
804 int locations[arraysize(uniforms)];
806 GetProgramUniformLocations(context,
814 sampler_location_ = locations[0];
815 DCHECK_NE(sampler_location_, -1);
817 background_color_location_ = locations[1];
818 DCHECK_NE(background_color_location_, -1);
821 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
822 TexCoordPrecision precision) const {
823 return FRAGMENT_SHADER(
824 precision mediump float;
825 varying TexCoordPrecision vec2 v_texCoord;
826 varying float v_alpha;
827 uniform vec4 background_color;
828 uniform sampler2D s_texture;
830 vec4 texColor = texture2D(s_texture, v_texCoord);
831 texColor += background_color * (1.0 - texColor.a);
832 gl_FragColor = texColor * v_alpha;
834 ); // NOLINT(whitespace/parens)
837 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
838 TexCoordPrecision precision) const {
839 return FRAGMENT_SHADER(
840 precision mediump float;
841 varying TexCoordPrecision vec2 v_texCoord;
842 varying float v_alpha;
843 uniform vec4 background_color;
844 uniform sampler2D s_texture;
846 vec4 texColor = texture2D(s_texture, v_texCoord);
847 texColor.rgb *= texColor.a;
848 texColor += background_color * (1.0 - texColor.a);
849 gl_FragColor = texColor * v_alpha;
851 ); // NOLINT(whitespace/parens)
854 std::string FragmentShaderRGBATexRectVaryingAlpha::GetShaderString(
855 TexCoordPrecision precision) const {
856 return "#extension GL_ARB_texture_rectangle : require\n" +
858 precision mediump float;
859 varying TexCoordPrecision vec2 v_texCoord;
860 varying float v_alpha;
861 uniform sampler2DRect s_texture;
863 vec4 texColor = texture2DRect(s_texture, v_texCoord);
864 gl_FragColor = texColor * v_alpha;
866 ); // NOLINT(whitespace/parens)
869 std::string FragmentShaderRGBATexOpaque::GetShaderString(
870 TexCoordPrecision precision) const {
871 return FRAGMENT_SHADER(
872 precision mediump float;
873 varying TexCoordPrecision vec2 v_texCoord;
874 uniform sampler2D s_texture;
876 vec4 texColor = texture2D(s_texture, v_texCoord);
877 gl_FragColor = vec4(texColor.rgb, 1.0);
879 ); // NOLINT(whitespace/parens)
882 std::string FragmentShaderRGBATex::GetShaderString(
883 TexCoordPrecision precision) const {
884 return FRAGMENT_SHADER(
885 precision mediump float;
886 varying TexCoordPrecision vec2 v_texCoord;
887 uniform sampler2D s_texture;
889 gl_FragColor = texture2D(s_texture, v_texCoord);
891 ); // NOLINT(whitespace/parens)
894 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
895 TexCoordPrecision precision) const {
896 return FRAGMENT_SHADER(
897 precision mediump float;
898 varying TexCoordPrecision vec2 v_texCoord;
899 uniform sampler2D s_texture;
902 vec4 texColor = texture2D(s_texture, v_texCoord);
904 vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
906 ); // NOLINT(whitespace/parens)
909 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
910 TexCoordPrecision precision) const {
911 return FRAGMENT_SHADER(
912 precision mediump float;
913 varying TexCoordPrecision vec2 v_texCoord;
914 uniform sampler2D s_texture;
916 vec4 texColor = texture2D(s_texture, v_texCoord);
917 gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
919 ); // NOLINT(whitespace/parens)
922 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
923 : sampler_location_(-1),
924 alpha_location_(-1) {}
926 void FragmentShaderRGBATexAlphaAA::Init(WebGraphicsContext3D* context,
928 bool using_bind_uniform,
929 int* base_uniform_index) {
930 static const char* uniforms[] = {
934 int locations[arraysize(uniforms)];
936 GetProgramUniformLocations(context,
943 sampler_location_ = locations[0];
944 alpha_location_ = locations[1];
947 std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
948 TexCoordPrecision precision) const {
949 return FRAGMENT_SHADER(
950 precision mediump float;
951 uniform sampler2D s_texture;
953 varying TexCoordPrecision vec2 v_texCoord;
954 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
957 vec4 texColor = texture2D(s_texture, v_texCoord);
958 vec4 d4 = min(edge_dist[0], edge_dist[1]);
959 vec2 d2 = min(d4.xz, d4.yw);
960 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
961 gl_FragColor = texColor * alpha * aa;
963 ); // NOLINT(whitespace/parens)
966 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
967 : sampler_location_(-1),
969 fragment_tex_transform_location_(-1) {}
971 void FragmentTexClampAlphaAABinding::Init(WebGraphicsContext3D* context,
973 bool using_bind_uniform,
974 int* base_uniform_index) {
975 static const char* uniforms[] = {
978 "fragmentTexTransform",
980 int locations[arraysize(uniforms)];
982 GetProgramUniformLocations(context,
989 sampler_location_ = locations[0];
990 alpha_location_ = locations[1];
991 fragment_tex_transform_location_ = locations[2];
994 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
995 TexCoordPrecision precision) const {
996 return FRAGMENT_SHADER(
997 precision mediump float;
998 uniform sampler2D s_texture;
1000 uniform TexCoordPrecision vec4 fragmentTexTransform;
1001 varying TexCoordPrecision vec2 v_texCoord;
1002 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1005 TexCoordPrecision vec2 texCoord =
1006 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
1007 fragmentTexTransform.xy;
1008 vec4 texColor = texture2D(s_texture, texCoord);
1009 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1010 vec2 d2 = min(d4.xz, d4.yw);
1011 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1012 gl_FragColor = texColor * alpha * aa;
1014 ); // NOLINT(whitespace/parens)
1017 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
1018 TexCoordPrecision precision) const {
1019 return FRAGMENT_SHADER(
1020 precision mediump float;
1021 uniform sampler2D s_texture;
1022 uniform float alpha;
1023 uniform TexCoordPrecision vec4 fragmentTexTransform;
1024 varying TexCoordPrecision vec2 v_texCoord;
1025 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1028 TexCoordPrecision vec2 texCoord =
1029 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
1030 fragmentTexTransform.xy;
1031 vec4 texColor = texture2D(s_texture, texCoord);
1032 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1033 vec2 d2 = min(d4.xz, d4.yw);
1034 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1035 gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) *
1038 ); // NOLINT(whitespace/parens)
1041 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
1042 : sampler_location_(-1),
1043 mask_sampler_location_(-1),
1044 alpha_location_(-1),
1045 mask_tex_coord_scale_location_(-1) {}
1047 void FragmentShaderRGBATexAlphaMask::Init(WebGraphicsContext3D* context,
1049 bool using_bind_uniform,
1050 int* base_uniform_index) {
1051 static const char* uniforms[] = {
1055 "maskTexCoordScale",
1056 "maskTexCoordOffset",
1058 int locations[arraysize(uniforms)];
1060 GetProgramUniformLocations(context,
1062 arraysize(uniforms),
1066 base_uniform_index);
1067 sampler_location_ = locations[0];
1068 mask_sampler_location_ = locations[1];
1069 alpha_location_ = locations[2];
1070 mask_tex_coord_scale_location_ = locations[3];
1071 mask_tex_coord_offset_location_ = locations[4];
1074 std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
1075 TexCoordPrecision precision) const {
1076 return FRAGMENT_SHADER(
1077 precision mediump float;
1078 varying TexCoordPrecision vec2 v_texCoord;
1079 uniform sampler2D s_texture;
1080 uniform sampler2D s_mask;
1081 uniform TexCoordPrecision vec2 maskTexCoordScale;
1082 uniform TexCoordPrecision vec2 maskTexCoordOffset;
1083 uniform float alpha;
1085 vec4 texColor = texture2D(s_texture, v_texCoord);
1086 TexCoordPrecision vec2 maskTexCoord =
1087 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1088 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1089 vec4 maskColor = texture2D(s_mask, maskTexCoord);
1090 gl_FragColor = texColor * alpha * maskColor.w;
1092 ); // NOLINT(whitespace/parens)
1095 FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
1096 : sampler_location_(-1),
1097 mask_sampler_location_(-1),
1098 alpha_location_(-1),
1099 mask_tex_coord_scale_location_(-1),
1100 mask_tex_coord_offset_location_(-1) {}
1102 void FragmentShaderRGBATexAlphaMaskAA::Init(WebGraphicsContext3D* context,
1104 bool using_bind_uniform,
1105 int* base_uniform_index) {
1106 static const char* uniforms[] = {
1110 "maskTexCoordScale",
1111 "maskTexCoordOffset",
1113 int locations[arraysize(uniforms)];
1115 GetProgramUniformLocations(context,
1117 arraysize(uniforms),
1121 base_uniform_index);
1122 sampler_location_ = locations[0];
1123 mask_sampler_location_ = locations[1];
1124 alpha_location_ = locations[2];
1125 mask_tex_coord_scale_location_ = locations[3];
1126 mask_tex_coord_offset_location_ = locations[4];
1129 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
1130 TexCoordPrecision precision) const {
1131 return FRAGMENT_SHADER(
1132 precision mediump float;
1133 uniform sampler2D s_texture;
1134 uniform sampler2D s_mask;
1135 uniform TexCoordPrecision vec2 maskTexCoordScale;
1136 uniform TexCoordPrecision vec2 maskTexCoordOffset;
1137 uniform float alpha;
1138 varying TexCoordPrecision vec2 v_texCoord;
1139 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1142 vec4 texColor = texture2D(s_texture, v_texCoord);
1143 TexCoordPrecision vec2 maskTexCoord =
1144 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1145 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1146 vec4 maskColor = texture2D(s_mask, maskTexCoord);
1147 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1148 vec2 d2 = min(d4.xz, d4.yw);
1149 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1150 gl_FragColor = texColor * alpha * maskColor.w * aa;
1152 ); // NOLINT(whitespace/parens)
1155 FragmentShaderRGBATexAlphaMaskColorMatrixAA::
1156 FragmentShaderRGBATexAlphaMaskColorMatrixAA()
1157 : sampler_location_(-1),
1158 mask_sampler_location_(-1),
1159 alpha_location_(-1),
1160 mask_tex_coord_scale_location_(-1),
1161 color_matrix_location_(-1),
1162 color_offset_location_(-1) {}
1164 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
1165 WebGraphicsContext3D* context,
1167 bool using_bind_uniform,
1168 int* base_uniform_index) {
1169 static const char* uniforms[] = {
1173 "maskTexCoordScale",
1174 "maskTexCoordOffset",
1178 int locations[arraysize(uniforms)];
1180 GetProgramUniformLocations(context,
1182 arraysize(uniforms),
1186 base_uniform_index);
1187 sampler_location_ = locations[0];
1188 mask_sampler_location_ = locations[1];
1189 alpha_location_ = locations[2];
1190 mask_tex_coord_scale_location_ = locations[3];
1191 mask_tex_coord_offset_location_ = locations[4];
1192 color_matrix_location_ = locations[5];
1193 color_offset_location_ = locations[6];
1196 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
1197 TexCoordPrecision precision) const {
1198 return FRAGMENT_SHADER(
1199 precision mediump float;
1200 uniform sampler2D s_texture;
1201 uniform sampler2D s_mask;
1202 uniform vec2 maskTexCoordScale;
1203 uniform vec2 maskTexCoordOffset;
1204 uniform mat4 colorMatrix;
1205 uniform vec4 colorOffset;
1206 uniform float alpha;
1207 varying TexCoordPrecision vec2 v_texCoord;
1208 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1211 vec4 texColor = texture2D(s_texture, v_texCoord);
1212 float nonZeroAlpha = max(texColor.a, 0.00001);
1213 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1214 texColor = colorMatrix * texColor + colorOffset;
1215 texColor.rgb *= texColor.a;
1216 texColor = clamp(texColor, 0.0, 1.0);
1217 TexCoordPrecision vec2 maskTexCoord =
1218 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1219 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1220 vec4 maskColor = texture2D(s_mask, maskTexCoord);
1221 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1222 vec2 d2 = min(d4.xz, d4.yw);
1223 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1224 gl_FragColor = texColor * alpha * maskColor.w * aa;
1226 ); // NOLINT(whitespace/parens)
1229 FragmentShaderRGBATexAlphaColorMatrixAA::
1230 FragmentShaderRGBATexAlphaColorMatrixAA()
1231 : sampler_location_(-1),
1232 alpha_location_(-1),
1233 color_matrix_location_(-1),
1234 color_offset_location_(-1) {}
1236 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(
1237 WebGraphicsContext3D* context,
1239 bool using_bind_uniform,
1240 int* base_uniform_index) {
1241 static const char* uniforms[] = {
1247 int locations[arraysize(uniforms)];
1249 GetProgramUniformLocations(context,
1251 arraysize(uniforms),
1255 base_uniform_index);
1256 sampler_location_ = locations[0];
1257 alpha_location_ = locations[1];
1258 color_matrix_location_ = locations[2];
1259 color_offset_location_ = locations[3];
1262 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
1263 TexCoordPrecision precision) const {
1264 return FRAGMENT_SHADER(
1265 precision mediump float;
1266 uniform sampler2D s_texture;
1267 uniform float alpha;
1268 uniform mat4 colorMatrix;
1269 uniform vec4 colorOffset;
1270 varying TexCoordPrecision vec2 v_texCoord;
1271 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1274 vec4 texColor = texture2D(s_texture, v_texCoord);
1275 float nonZeroAlpha = max(texColor.a, 0.00001);
1276 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1277 texColor = colorMatrix * texColor + colorOffset;
1278 texColor.rgb *= texColor.a;
1279 texColor = clamp(texColor, 0.0, 1.0);
1280 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1281 vec2 d2 = min(d4.xz, d4.yw);
1282 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1283 gl_FragColor = texColor * alpha * aa;
1285 ); // NOLINT(whitespace/parens)
1288 FragmentShaderRGBATexAlphaMaskColorMatrix::
1289 FragmentShaderRGBATexAlphaMaskColorMatrix()
1290 : sampler_location_(-1),
1291 mask_sampler_location_(-1),
1292 alpha_location_(-1),
1293 mask_tex_coord_scale_location_(-1) {}
1295 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(
1296 WebGraphicsContext3D* context,
1298 bool using_bind_uniform,
1299 int* base_uniform_index) {
1300 static const char* uniforms[] = {
1304 "maskTexCoordScale",
1305 "maskTexCoordOffset",
1309 int locations[arraysize(uniforms)];
1311 GetProgramUniformLocations(context,
1313 arraysize(uniforms),
1317 base_uniform_index);
1318 sampler_location_ = locations[0];
1319 mask_sampler_location_ = locations[1];
1320 alpha_location_ = locations[2];
1321 mask_tex_coord_scale_location_ = locations[3];
1322 mask_tex_coord_offset_location_ = locations[4];
1323 color_matrix_location_ = locations[5];
1324 color_offset_location_ = locations[6];
1327 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
1328 TexCoordPrecision precision) const {
1329 return FRAGMENT_SHADER(
1330 precision mediump float;
1331 varying TexCoordPrecision vec2 v_texCoord;
1332 uniform sampler2D s_texture;
1333 uniform sampler2D s_mask;
1334 uniform vec2 maskTexCoordScale;
1335 uniform vec2 maskTexCoordOffset;
1336 uniform mat4 colorMatrix;
1337 uniform vec4 colorOffset;
1338 uniform float alpha;
1340 vec4 texColor = texture2D(s_texture, v_texCoord);
1341 float nonZeroAlpha = max(texColor.a, 0.00001);
1342 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1343 texColor = colorMatrix * texColor + colorOffset;
1344 texColor.rgb *= texColor.a;
1345 texColor = clamp(texColor, 0.0, 1.0);
1346 TexCoordPrecision vec2 maskTexCoord =
1347 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1348 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1349 vec4 maskColor = texture2D(s_mask, maskTexCoord);
1350 gl_FragColor = texColor * alpha * maskColor.w;
1352 ); // NOLINT(whitespace/parens)
1355 FragmentShaderYUVVideo::FragmentShaderYUVVideo()
1356 : y_texture_location_(-1),
1357 u_texture_location_(-1),
1358 v_texture_location_(-1),
1359 alpha_location_(-1),
1360 yuv_matrix_location_(-1),
1361 yuv_adj_location_(-1) {}
1363 void FragmentShaderYUVVideo::Init(WebGraphicsContext3D* context,
1365 bool using_bind_uniform,
1366 int* base_uniform_index) {
1367 static const char* uniforms[] = {
1375 int locations[arraysize(uniforms)];
1377 GetProgramUniformLocations(context,
1379 arraysize(uniforms),
1383 base_uniform_index);
1384 y_texture_location_ = locations[0];
1385 u_texture_location_ = locations[1];
1386 v_texture_location_ = locations[2];
1387 alpha_location_ = locations[3];
1388 yuv_matrix_location_ = locations[4];
1389 yuv_adj_location_ = locations[5];
1392 std::string FragmentShaderYUVVideo::GetShaderString(
1393 TexCoordPrecision precision) const {
1394 return FRAGMENT_SHADER(
1395 precision mediump float;
1396 precision mediump int;
1397 varying TexCoordPrecision vec2 v_texCoord;
1398 uniform sampler2D y_texture;
1399 uniform sampler2D u_texture;
1400 uniform sampler2D v_texture;
1401 uniform float alpha;
1402 uniform vec3 yuv_adj;
1403 uniform mat3 yuv_matrix;
1405 float y_raw = texture2D(y_texture, v_texCoord).x;
1406 float u_unsigned = texture2D(u_texture, v_texCoord).x;
1407 float v_unsigned = texture2D(v_texture, v_texCoord).x;
1408 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
1409 vec3 rgb = yuv_matrix * yuv;
1410 gl_FragColor = vec4(rgb, 1.0) * alpha;
1412 ); // NOLINT(whitespace/parens)
1415 FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
1416 : y_texture_location_(-1),
1417 u_texture_location_(-1),
1418 v_texture_location_(-1),
1419 a_texture_location_(-1),
1420 alpha_location_(-1),
1421 yuv_matrix_location_(-1),
1422 yuv_adj_location_(-1) {
1425 void FragmentShaderYUVAVideo::Init(WebGraphicsContext3D* context,
1427 bool using_bind_uniform,
1428 int* base_uniform_index) {
1429 static const char* uniforms[] = {
1438 int locations[arraysize(uniforms)];
1440 GetProgramUniformLocations(context,
1442 arraysize(uniforms),
1446 base_uniform_index);
1447 y_texture_location_ = locations[0];
1448 u_texture_location_ = locations[1];
1449 v_texture_location_ = locations[2];
1450 a_texture_location_ = locations[3];
1451 alpha_location_ = locations[4];
1452 yuv_matrix_location_ = locations[5];
1453 yuv_adj_location_ = locations[6];
1456 std::string FragmentShaderYUVAVideo::GetShaderString(
1457 TexCoordPrecision precision) const {
1458 return FRAGMENT_SHADER(
1459 precision mediump float;
1460 precision mediump int;
1461 varying TexCoordPrecision vec2 v_texCoord;
1462 uniform sampler2D y_texture;
1463 uniform sampler2D u_texture;
1464 uniform sampler2D v_texture;
1465 uniform sampler2D a_texture;
1466 uniform float alpha;
1467 uniform vec3 yuv_adj;
1468 uniform mat3 yuv_matrix;
1470 float y_raw = texture2D(y_texture, v_texCoord).x;
1471 float u_unsigned = texture2D(u_texture, v_texCoord).x;
1472 float v_unsigned = texture2D(v_texture, v_texCoord).x;
1473 float a_raw = texture2D(a_texture, v_texCoord).x;
1474 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
1475 vec3 rgb = yuv_matrix * yuv;
1476 gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);
1478 ); // NOLINT(whitespace/parens)
1481 FragmentShaderColor::FragmentShaderColor()
1482 : color_location_(-1) {}
1484 void FragmentShaderColor::Init(WebGraphicsContext3D* context,
1486 bool using_bind_uniform,
1487 int* base_uniform_index) {
1488 static const char* uniforms[] = {
1491 int locations[arraysize(uniforms)];
1493 GetProgramUniformLocations(context,
1495 arraysize(uniforms),
1499 base_uniform_index);
1500 color_location_ = locations[0];
1503 std::string FragmentShaderColor::GetShaderString(
1504 TexCoordPrecision precision) const {
1505 return FRAGMENT_SHADER(
1506 precision mediump float;
1509 gl_FragColor = color;
1511 ); // NOLINT(whitespace/parens)
1514 FragmentShaderColorAA::FragmentShaderColorAA()
1515 : color_location_(-1) {}
1517 void FragmentShaderColorAA::Init(WebGraphicsContext3D* context,
1519 bool using_bind_uniform,
1520 int* base_uniform_index) {
1521 static const char* uniforms[] = {
1524 int locations[arraysize(uniforms)];
1526 GetProgramUniformLocations(context,
1528 arraysize(uniforms),
1532 base_uniform_index);
1533 color_location_ = locations[0];
1536 std::string FragmentShaderColorAA::GetShaderString(
1537 TexCoordPrecision precision) const {
1538 return FRAGMENT_SHADER(
1539 precision mediump float;
1541 varying vec4 edge_dist[2]; // 8 edge distances.
1544 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1545 vec2 d2 = min(d4.xz, d4.yw);
1546 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1547 gl_FragColor = color * aa;
1549 ); // NOLINT(whitespace/parens)
1552 FragmentShaderCheckerboard::FragmentShaderCheckerboard()
1553 : alpha_location_(-1),
1554 tex_transform_location_(-1),
1555 frequency_location_(-1) {}
1557 void FragmentShaderCheckerboard::Init(WebGraphicsContext3D* context,
1559 bool using_bind_uniform,
1560 int* base_uniform_index) {
1561 static const char* uniforms[] = {
1567 int locations[arraysize(uniforms)];
1569 GetProgramUniformLocations(context,
1571 arraysize(uniforms),
1575 base_uniform_index);
1576 alpha_location_ = locations[0];
1577 tex_transform_location_ = locations[1];
1578 frequency_location_ = locations[2];
1579 color_location_ = locations[3];
1582 std::string FragmentShaderCheckerboard::GetShaderString(
1583 TexCoordPrecision precision) const {
1584 // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
1585 // by Munshi, Ginsburg, Shreiner.
1586 return FRAGMENT_SHADER(
1587 precision mediump float;
1588 precision mediump int;
1589 varying vec2 v_texCoord;
1590 uniform float alpha;
1591 uniform float frequency;
1592 uniform vec4 texTransform;
1595 vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0);
1596 vec4 color2 = color;
1598 clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy;
1599 vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0);
1600 float picker = abs(coord.x - coord.y); // NOLINT
1601 gl_FragColor = mix(color1, color2, picker) * alpha;
1603 ); // NOLINT(whitespace/parens)