- add sources.
[platform/framework/web/crosswalk.git] / src / cc / output / shader.cc
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.
4
5 #include "cc/output/shader.h"
6
7 #include <algorithm>
8
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"
14
15 #define SHADER0(Src) #Src
16 #define VERTEX_SHADER(Src) SetVertexTexCoordPrecision(SHADER0(Src))
17 #define FRAGMENT_SHADER(Src) SetFragTexCoordPrecision(precision, SHADER0(Src))
18
19 using WebKit::WebGraphicsContext3D;
20
21 namespace cc {
22
23 namespace {
24
25 static void GetProgramUniformLocations(WebGraphicsContext3D* context,
26                                        unsigned program,
27                                        size_t count,
28                                        const char** uniforms,
29                                        int* locations,
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]);
36     } else {
37       locations[i] = context->getUniformLocation(program, uniforms[i]);
38       DCHECK_NE(locations[i], -1);
39     }
40   }
41 }
42
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);
48       return
49           "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
50           "  #define TexCoordPrecision highp\n"
51           "#else\n"
52           "  #define TexCoordPrecision mediump\n"
53           "#endif\n" +
54           shader_string;
55     case TexCoordPrecisionMedium:
56       DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
57       return "#define TexCoordPrecision mediump\n" +
58           shader_string;
59     case TexCoordPrecisionNA:
60       DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos);
61       DCHECK_EQ(shader_string.find("texture2D"), std::string::npos);
62       return shader_string;
63   }
64   return shader_string;
65 }
66
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);
74 }
75
76 TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context,
77                                             int *highp_threshold_cache,
78                                             int highp_threshold_min,
79                                             int x, int y) {
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
84     // everywhere.
85     GLint range[2] = { 14, 14 };
86     GLint precision = 10;
87     GLC(context, context->getShaderPrecisionFormat(GL_FRAGMENT_SHADER,
88                                                    GL_MEDIUM_FLOAT,
89                                                    range, &precision));
90     *highp_threshold_cache = 1 << precision;
91   }
92
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;
97 }
98
99 }  // namespace
100
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());
108 }
109
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());
117 }
118
119 VertexShaderPosTex::VertexShaderPosTex()
120       : matrix_location_(-1) {}
121
122 void VertexShaderPosTex::Init(WebGraphicsContext3D* context,
123                               unsigned program,
124                               bool using_bind_uniform,
125                               int* base_uniform_index) {
126   static const char* uniforms[] = {
127       "matrix",
128   };
129   int locations[arraysize(uniforms)];
130
131   GetProgramUniformLocations(context,
132                              program,
133                              arraysize(uniforms),
134                              uniforms,
135                              locations,
136                              using_bind_uniform,
137                              base_uniform_index);
138   matrix_location_ = locations[0];
139 }
140
141 std::string VertexShaderPosTex::GetShaderString() const {
142   return VERTEX_SHADER(
143     attribute vec4 a_position;
144     attribute TexCoordPrecision vec2 a_texCoord;
145     uniform mat4 matrix;
146     varying TexCoordPrecision vec2 v_texCoord;
147     void main() {
148       gl_Position = matrix * a_position;
149       v_texCoord = a_texCoord;
150     }
151   );  // NOLINT(whitespace/parens)
152 }
153
154 VertexShaderPosTexYUVStretch::VertexShaderPosTexYUVStretch()
155     : matrix_location_(-1),
156       tex_scale_location_(-1) {}
157
158 void VertexShaderPosTexYUVStretch::Init(WebGraphicsContext3D* context,
159                                         unsigned program,
160                                         bool using_bind_uniform,
161                                         int* base_uniform_index) {
162   static const char* uniforms[] = {
163     "matrix",
164     "texScale",
165   };
166   int locations[arraysize(uniforms)];
167
168   GetProgramUniformLocations(context,
169                              program,
170                              arraysize(uniforms),
171                              uniforms,
172                              locations,
173                              using_bind_uniform,
174                              base_uniform_index);
175   matrix_location_ = locations[0];
176   tex_scale_location_ = locations[1];
177 }
178
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;
184     uniform mat4 matrix;
185     varying TexCoordPrecision vec2 v_texCoord;
186     uniform TexCoordPrecision vec2 texScale;
187     void main() {
188         gl_Position = matrix * a_position;
189         v_texCoord = a_texCoord * texScale;
190     }
191   );  // NOLINT(whitespace/parens)
192 }
193
194 VertexShaderPos::VertexShaderPos()
195     : matrix_location_(-1) {}
196
197 void VertexShaderPos::Init(WebGraphicsContext3D* context,
198                            unsigned program,
199                            bool using_bind_uniform,
200                            int* base_uniform_index) {
201   static const char* uniforms[] = {
202       "matrix",
203   };
204   int locations[arraysize(uniforms)];
205
206   GetProgramUniformLocations(context,
207                              program,
208                              arraysize(uniforms),
209                              uniforms,
210                              locations,
211                              using_bind_uniform,
212                              base_uniform_index);
213   matrix_location_ = locations[0];
214 }
215
216 std::string VertexShaderPos::GetShaderString() const {
217   return VERTEX_SHADER(
218     attribute vec4 a_position;
219     uniform mat4 matrix;
220     void main() {
221         gl_Position = matrix * a_position;
222     }
223   );  // NOLINT(whitespace/parens)
224 }
225
226 VertexShaderPosTexTransform::VertexShaderPosTexTransform()
227     : matrix_location_(-1),
228       tex_transform_location_(-1),
229       vertex_opacity_location_(-1) {}
230
231 void VertexShaderPosTexTransform::Init(WebGraphicsContext3D* context,
232                                        unsigned program,
233                                        bool using_bind_uniform,
234                                        int* base_uniform_index) {
235   static const char* uniforms[] = {
236     "matrix",
237     "texTransform",
238     "opacity",
239   };
240   int locations[arraysize(uniforms)];
241
242   GetProgramUniformLocations(context,
243                              program,
244                              arraysize(uniforms),
245                              uniforms,
246                              locations,
247                              using_bind_uniform,
248                              base_uniform_index);
249   matrix_location_ = locations[0];
250   tex_transform_location_ = locations[1];
251   vertex_opacity_location_ = locations[2];
252 }
253
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;
264     void main() {
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
270     }
271   );  // NOLINT(whitespace/parens)
272 }
273
274 std::string VertexShaderPosTexIdentity::GetShaderString() const {
275   return VERTEX_SHADER(
276     attribute vec4 a_position;
277     varying TexCoordPrecision vec2 v_texCoord;
278     void main() {
279       gl_Position = a_position;
280       v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
281     }
282   );  // NOLINT(whitespace/parens)
283 }
284
285 VertexShaderQuad::VertexShaderQuad()
286     : matrix_location_(-1),
287       quad_location_(-1) {}
288
289 void VertexShaderQuad::Init(WebGraphicsContext3D* context,
290                             unsigned program,
291                             bool using_bind_uniform,
292                             int* base_uniform_index) {
293   static const char* uniforms[] = {
294     "matrix",
295     "quad",
296   };
297   int locations[arraysize(uniforms)];
298
299   GetProgramUniformLocations(context,
300                              program,
301                              arraysize(uniforms),
302                              uniforms,
303                              locations,
304                              using_bind_uniform,
305                              base_uniform_index);
306   matrix_location_ = locations[0];
307   quad_location_ = locations[1];
308 }
309
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;
318     uniform mat4 matrix;
319     uniform TexCoordPrecision vec2 quad[4];
320     uniform TexCoordPrecision vec2 dummy_uniform;
321     varying TexCoordPrecision vec2 dummy_varying;
322     void main() {
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;
326     }
327   );  // NOLINT(whitespace/parens)
328 #else
329   return VERTEX_SHADER(
330     attribute TexCoordPrecision vec4 a_position;
331     attribute float a_index;
332     uniform mat4 matrix;
333     uniform TexCoordPrecision vec2 quad[4];
334     void main() {
335       vec2 pos = quad[int(a_index)];  // NOLINT
336       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
337     }
338   );  // NOLINT(whitespace/parens)
339 #endif
340 }
341
342 VertexShaderQuadAA::VertexShaderQuadAA()
343     : matrix_location_(-1),
344       viewport_location_(-1),
345       quad_location_(-1),
346       edge_location_(-1) {}
347
348 void VertexShaderQuadAA::Init(WebGraphicsContext3D* context,
349                             unsigned program,
350                             bool using_bind_uniform,
351                             int* base_uniform_index) {
352   static const char* uniforms[] = {
353     "matrix",
354     "viewport",
355     "quad",
356     "edge",
357   };
358   int locations[arraysize(uniforms)];
359
360   GetProgramUniformLocations(context,
361                              program,
362                              arraysize(uniforms),
363                              uniforms,
364                              locations,
365                              using_bind_uniform,
366                              base_uniform_index);
367   matrix_location_ = locations[0];
368   viewport_location_ = locations[1];
369   quad_location_ = locations[2];
370   edge_location_ = locations[3];
371 }
372
373 std::string VertexShaderQuadAA::GetShaderString() const {
374   return VERTEX_SHADER(
375     attribute TexCoordPrecision vec4 a_position;
376     attribute float a_index;
377     uniform mat4 matrix;
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.
382
383     void main() {
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;
396     }
397   );  // NOLINT(whitespace/parens)
398 }
399
400 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
401     : matrix_location_(-1),
402       viewport_location_(-1),
403       quad_location_(-1),
404       edge_location_(-1),
405       tex_transform_location_(-1) {}
406
407 void VertexShaderQuadTexTransformAA::Init(WebGraphicsContext3D* context,
408                                         unsigned program,
409                                         bool using_bind_uniform,
410                                         int* base_uniform_index) {
411   static const char* uniforms[] = {
412     "matrix",
413     "viewport",
414     "quad",
415     "edge",
416     "texTrans",
417   };
418   int locations[arraysize(uniforms)];
419
420   GetProgramUniformLocations(context,
421                              program,
422                              arraysize(uniforms),
423                              uniforms,
424                              locations,
425                              using_bind_uniform,
426                              base_uniform_index);
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];
432 }
433
434 std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
435   return VERTEX_SHADER(
436     attribute TexCoordPrecision vec4 a_position;
437     attribute float a_index;
438     uniform mat4 matrix;
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.
445
446     void main() {
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;
460     }
461   );  // NOLINT(whitespace/parens)
462 }
463
464 VertexShaderTile::VertexShaderTile()
465     : matrix_location_(-1),
466       quad_location_(-1),
467       vertex_tex_transform_location_(-1) {}
468
469 void VertexShaderTile::Init(WebGraphicsContext3D* context,
470                             unsigned program,
471                             bool using_bind_uniform,
472                             int* base_uniform_index) {
473   static const char* uniforms[] = {
474     "matrix",
475     "quad",
476     "vertexTexTransform",
477   };
478   int locations[arraysize(uniforms)];
479
480   GetProgramUniformLocations(context,
481                              program,
482                              arraysize(uniforms),
483                              uniforms,
484                              locations,
485                              using_bind_uniform,
486                              base_uniform_index);
487   matrix_location_ = locations[0];
488   quad_location_ = locations[1];
489   vertex_tex_transform_location_ = locations[2];
490 }
491
492 std::string VertexShaderTile::GetShaderString() const {
493   return VERTEX_SHADER(
494     attribute TexCoordPrecision vec4 a_position;
495     attribute float a_index;
496     uniform mat4 matrix;
497     uniform TexCoordPrecision vec2 quad[4];
498     uniform TexCoordPrecision vec4 vertexTexTransform;
499     varying TexCoordPrecision vec2 v_texCoord;
500     void main() {
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;
504     }
505   );  // NOLINT(whitespace/parens)
506 }
507
508 VertexShaderTileAA::VertexShaderTileAA()
509     : matrix_location_(-1),
510       viewport_location_(-1),
511       quad_location_(-1),
512       edge_location_(-1),
513       vertex_tex_transform_location_(-1) {}
514
515 void VertexShaderTileAA::Init(WebGraphicsContext3D* context,
516                               unsigned program,
517                               bool using_bind_uniform,
518                               int* base_uniform_index) {
519   static const char* uniforms[] = {
520     "matrix",
521     "viewport",
522     "quad",
523     "edge",
524     "vertexTexTransform",
525   };
526   int locations[arraysize(uniforms)];
527
528   GetProgramUniformLocations(context,
529                              program,
530                              arraysize(uniforms),
531                              uniforms,
532                              locations,
533                              using_bind_uniform,
534                              base_uniform_index);
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];
540 }
541
542 std::string VertexShaderTileAA::GetShaderString() const {
543   return VERTEX_SHADER(
544     attribute TexCoordPrecision vec4 a_position;
545     attribute float a_index;
546     uniform mat4 matrix;
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.
553
554     void main() {
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;
568     }
569   );  // NOLINT(whitespace/parens)
570 }
571
572 VertexShaderVideoTransform::VertexShaderVideoTransform()
573     : matrix_location_(-1),
574       tex_matrix_location_(-1) {}
575
576 void VertexShaderVideoTransform::Init(WebGraphicsContext3D* context,
577                                       unsigned program,
578                                       bool using_bind_uniform,
579                                       int* base_uniform_index) {
580   static const char* uniforms[] = {
581     "matrix",
582     "texMatrix",
583   };
584   int locations[arraysize(uniforms)];
585
586   GetProgramUniformLocations(context,
587                              program,
588                              arraysize(uniforms),
589                              uniforms,
590                              locations,
591                              using_bind_uniform,
592                              base_uniform_index);
593   matrix_location_ = locations[0];
594   tex_matrix_location_ = locations[1];
595 }
596
597 std::string VertexShaderVideoTransform::GetShaderString() const {
598   return VERTEX_SHADER(
599     attribute vec4 a_position;
600     attribute TexCoordPrecision vec2 a_texCoord;
601     uniform mat4 matrix;
602     uniform TexCoordPrecision mat4 texMatrix;
603     varying TexCoordPrecision vec2 v_texCoord;
604     void main() {
605         gl_Position = matrix * a_position;
606         v_texCoord =
607             vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
608     }
609   );  // NOLINT(whitespace/parens)
610 }
611
612 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
613     : sampler_location_(-1),
614       alpha_location_(-1) {}
615
616 void FragmentTexAlphaBinding::Init(WebGraphicsContext3D* context,
617                                    unsigned program,
618                                    bool using_bind_uniform,
619                                    int* base_uniform_index) {
620   static const char* uniforms[] = {
621     "s_texture",
622     "alpha",
623   };
624   int locations[arraysize(uniforms)];
625
626   GetProgramUniformLocations(context,
627                              program,
628                              arraysize(uniforms),
629                              uniforms,
630                              locations,
631                              using_bind_uniform,
632                              base_uniform_index);
633   sampler_location_ = locations[0];
634   alpha_location_ = locations[1];
635 }
636
637 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
638     : sampler_location_(-1),
639       alpha_location_(-1),
640       color_matrix_location_(-1),
641       color_offset_location_(-1) {}
642
643 void FragmentTexColorMatrixAlphaBinding::Init(WebGraphicsContext3D* context,
644                                               unsigned program,
645                                               bool using_bind_uniform,
646                                               int* base_uniform_index) {
647   static const char* uniforms[] = {
648     "s_texture",
649     "alpha",
650     "colorMatrix",
651     "colorOffset",
652   };
653   int locations[arraysize(uniforms)];
654
655   GetProgramUniformLocations(context,
656                              program,
657                              arraysize(uniforms),
658                              uniforms,
659                              locations,
660                              using_bind_uniform,
661                              base_uniform_index);
662   sampler_location_ = locations[0];
663   alpha_location_ = locations[1];
664   color_matrix_location_ = locations[2];
665   color_offset_location_ = locations[3];
666 }
667
668 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
669     : sampler_location_(-1) {}
670
671 void FragmentTexOpaqueBinding::Init(WebGraphicsContext3D* context,
672                                     unsigned program,
673                                     bool using_bind_uniform,
674                                     int* base_uniform_index) {
675   static const char* uniforms[] = {
676     "s_texture",
677   };
678   int locations[arraysize(uniforms)];
679
680   GetProgramUniformLocations(context,
681                              program,
682                              arraysize(uniforms),
683                              uniforms,
684                              locations,
685                              using_bind_uniform,
686                              base_uniform_index);
687   sampler_location_ = locations[0];
688 }
689
690 FragmentShaderOESImageExternal::FragmentShaderOESImageExternal()
691     : sampler_location_(-1) {}
692
693 void FragmentShaderOESImageExternal::Init(WebGraphicsContext3D* context,
694                                           unsigned program,
695                                           bool using_bind_uniform,
696                                           int* base_uniform_index) {
697   static const char* uniforms[] = {
698     "s_texture",
699   };
700   int locations[arraysize(uniforms)];
701
702   GetProgramUniformLocations(context,
703                              program,
704                              arraysize(uniforms),
705                              uniforms,
706                              locations,
707                              using_bind_uniform,
708                              base_uniform_index);
709   sampler_location_ = locations[0];
710 }
711
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" +
716       FRAGMENT_SHADER(
717          precision mediump float;
718          varying TexCoordPrecision vec2 v_texCoord;
719          uniform samplerExternalOES s_texture;
720          void main() {
721            vec4 texColor = texture2D(s_texture, v_texCoord);
722            gl_FragColor = texColor;
723          }
724       );  // NOLINT(whitespace/parens)
725 }
726
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;
733     uniform float alpha;
734     void main() {
735       vec4 texColor = texture2D(s_texture, v_texCoord);
736       gl_FragColor = texColor * alpha;
737     }
738   );  // NOLINT(whitespace/parens)
739 }
740
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;
747     uniform float alpha;
748     uniform mat4 colorMatrix;
749     uniform vec4 colorOffset;
750     void main() {
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;
758     }
759   );  // NOLINT(whitespace/parens)
760 }
761
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;
769     void main() {
770       vec4 texColor = texture2D(s_texture, v_texCoord);
771       gl_FragColor = texColor * v_alpha;
772     }
773   );  // NOLINT(whitespace/parens)
774 }
775
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;
783     void main() {
784       vec4 texColor = texture2D(s_texture, v_texCoord);
785       texColor.rgb *= texColor.a;
786       gl_FragColor = texColor * v_alpha;
787     }
788   );  // NOLINT(whitespace/parens)
789 }
790
791 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
792     : background_color_location_(-1),
793       sampler_location_(-1) {
794 }
795
796 void FragmentTexBackgroundBinding::Init(WebGraphicsContext3D* context,
797                                         unsigned program,
798                                         bool using_bind_uniform,
799                                         int* base_uniform_index) {
800   static const char* uniforms[] = {
801     "s_texture",
802     "background_color",
803   };
804   int locations[arraysize(uniforms)];
805
806   GetProgramUniformLocations(context,
807                              program,
808                              arraysize(uniforms),
809                              uniforms,
810                              locations,
811                              using_bind_uniform,
812                              base_uniform_index);
813
814   sampler_location_ = locations[0];
815   DCHECK_NE(sampler_location_, -1);
816
817   background_color_location_ = locations[1];
818   DCHECK_NE(background_color_location_, -1);
819 }
820
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;
829     void main() {
830       vec4 texColor = texture2D(s_texture, v_texCoord);
831       texColor += background_color * (1.0 - texColor.a);
832       gl_FragColor = texColor * v_alpha;
833     }
834   );  // NOLINT(whitespace/parens)
835 }
836
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;
845     void main() {
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;
850     }
851   );  // NOLINT(whitespace/parens)
852 }
853
854 std::string FragmentShaderRGBATexRectVaryingAlpha::GetShaderString(
855     TexCoordPrecision precision) const {
856   return "#extension GL_ARB_texture_rectangle : require\n" +
857       FRAGMENT_SHADER(
858         precision mediump float;
859         varying TexCoordPrecision vec2 v_texCoord;
860         varying float v_alpha;
861         uniform sampler2DRect s_texture;
862         void main() {
863           vec4 texColor = texture2DRect(s_texture, v_texCoord);
864           gl_FragColor = texColor * v_alpha;
865         }
866       );  // NOLINT(whitespace/parens)
867 }
868
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;
875     void main() {
876       vec4 texColor = texture2D(s_texture, v_texCoord);
877       gl_FragColor = vec4(texColor.rgb, 1.0);
878     }
879   );  // NOLINT(whitespace/parens)
880 }
881
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;
888     void main() {
889       gl_FragColor = texture2D(s_texture, v_texCoord);
890     }
891   );  // NOLINT(whitespace/parens)
892 }
893
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;
900     uniform float alpha;
901     void main() {
902         vec4 texColor = texture2D(s_texture, v_texCoord);
903         gl_FragColor =
904             vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
905     }
906   );  // NOLINT(whitespace/parens)
907 }
908
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;
915     void main() {
916       vec4 texColor = texture2D(s_texture, v_texCoord);
917       gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
918     }
919   );  // NOLINT(whitespace/parens)
920 }
921
922 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
923     : sampler_location_(-1),
924       alpha_location_(-1) {}
925
926 void FragmentShaderRGBATexAlphaAA::Init(WebGraphicsContext3D* context,
927                                         unsigned program,
928                                         bool using_bind_uniform,
929                                         int* base_uniform_index) {
930   static const char* uniforms[] = {
931     "s_texture",
932     "alpha",
933   };
934   int locations[arraysize(uniforms)];
935
936   GetProgramUniformLocations(context,
937                              program,
938                              arraysize(uniforms),
939                              uniforms,
940                              locations,
941                              using_bind_uniform,
942                              base_uniform_index);
943   sampler_location_ = locations[0];
944   alpha_location_ = locations[1];
945 }
946
947 std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
948     TexCoordPrecision precision) const {
949   return FRAGMENT_SHADER(
950     precision mediump float;
951     uniform sampler2D s_texture;
952     uniform float alpha;
953     varying TexCoordPrecision vec2 v_texCoord;
954     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
955
956     void main() {
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;
962     }
963   );  // NOLINT(whitespace/parens)
964 }
965
966 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
967     : sampler_location_(-1),
968       alpha_location_(-1),
969       fragment_tex_transform_location_(-1) {}
970
971 void FragmentTexClampAlphaAABinding::Init(WebGraphicsContext3D* context,
972                                           unsigned program,
973                                           bool using_bind_uniform,
974                                           int* base_uniform_index) {
975   static const char* uniforms[] = {
976     "s_texture",
977     "alpha",
978     "fragmentTexTransform",
979   };
980   int locations[arraysize(uniforms)];
981
982   GetProgramUniformLocations(context,
983                              program,
984                              arraysize(uniforms),
985                              uniforms,
986                              locations,
987                              using_bind_uniform,
988                              base_uniform_index);
989   sampler_location_ = locations[0];
990   alpha_location_ = locations[1];
991   fragment_tex_transform_location_ = locations[2];
992 }
993
994 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
995     TexCoordPrecision precision) const {
996   return FRAGMENT_SHADER(
997     precision mediump float;
998     uniform sampler2D s_texture;
999     uniform float alpha;
1000     uniform TexCoordPrecision vec4 fragmentTexTransform;
1001     varying TexCoordPrecision vec2 v_texCoord;
1002     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
1003
1004     void main() {
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;
1013     }
1014   );  // NOLINT(whitespace/parens)
1015 }
1016
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.
1026
1027     void main() {
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) *
1036           alpha * aa;
1037     }
1038   );  // NOLINT(whitespace/parens)
1039 }
1040
1041 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
1042     : sampler_location_(-1),
1043       mask_sampler_location_(-1),
1044       alpha_location_(-1),
1045       mask_tex_coord_scale_location_(-1) {}
1046
1047 void FragmentShaderRGBATexAlphaMask::Init(WebGraphicsContext3D* context,
1048                                           unsigned program,
1049                                           bool using_bind_uniform,
1050                                           int* base_uniform_index) {
1051   static const char* uniforms[] = {
1052     "s_texture",
1053     "s_mask",
1054     "alpha",
1055     "maskTexCoordScale",
1056     "maskTexCoordOffset",
1057   };
1058   int locations[arraysize(uniforms)];
1059
1060   GetProgramUniformLocations(context,
1061                              program,
1062                              arraysize(uniforms),
1063                              uniforms,
1064                              locations,
1065                              using_bind_uniform,
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];
1072 }
1073
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;
1084     void main() {
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;
1091     }
1092   );  // NOLINT(whitespace/parens)
1093 }
1094
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) {}
1101
1102 void FragmentShaderRGBATexAlphaMaskAA::Init(WebGraphicsContext3D* context,
1103                                             unsigned program,
1104                                             bool using_bind_uniform,
1105                                             int* base_uniform_index) {
1106   static const char* uniforms[] = {
1107     "s_texture",
1108     "s_mask",
1109     "alpha",
1110     "maskTexCoordScale",
1111     "maskTexCoordOffset",
1112   };
1113   int locations[arraysize(uniforms)];
1114
1115   GetProgramUniformLocations(context,
1116                              program,
1117                              arraysize(uniforms),
1118                              uniforms,
1119                              locations,
1120                              using_bind_uniform,
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];
1127 }
1128
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.
1140
1141     void main() {
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;
1151     }
1152   );  // NOLINT(whitespace/parens)
1153 }
1154
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) {}
1163
1164 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
1165     WebGraphicsContext3D* context,
1166     unsigned program,
1167     bool using_bind_uniform,
1168     int* base_uniform_index) {
1169   static const char* uniforms[] = {
1170     "s_texture",
1171     "s_mask",
1172     "alpha",
1173     "maskTexCoordScale",
1174     "maskTexCoordOffset",
1175     "colorMatrix",
1176     "colorOffset",
1177   };
1178   int locations[arraysize(uniforms)];
1179
1180   GetProgramUniformLocations(context,
1181                              program,
1182                              arraysize(uniforms),
1183                              uniforms,
1184                              locations,
1185                              using_bind_uniform,
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];
1194 }
1195
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.
1209
1210     void main() {
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;
1225     }
1226   );  // NOLINT(whitespace/parens)
1227 }
1228
1229 FragmentShaderRGBATexAlphaColorMatrixAA::
1230     FragmentShaderRGBATexAlphaColorMatrixAA()
1231         : sampler_location_(-1),
1232           alpha_location_(-1),
1233           color_matrix_location_(-1),
1234           color_offset_location_(-1) {}
1235
1236 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(
1237       WebGraphicsContext3D* context,
1238       unsigned program,
1239       bool using_bind_uniform,
1240       int* base_uniform_index) {
1241   static const char* uniforms[] = {
1242     "s_texture",
1243     "alpha",
1244     "colorMatrix",
1245     "colorOffset",
1246   };
1247   int locations[arraysize(uniforms)];
1248
1249   GetProgramUniformLocations(context,
1250                              program,
1251                              arraysize(uniforms),
1252                              uniforms,
1253                              locations,
1254                              using_bind_uniform,
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];
1260 }
1261
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.
1272
1273     void main() {
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;
1284     }
1285   );  // NOLINT(whitespace/parens)
1286 }
1287
1288 FragmentShaderRGBATexAlphaMaskColorMatrix::
1289     FragmentShaderRGBATexAlphaMaskColorMatrix()
1290         : sampler_location_(-1),
1291           mask_sampler_location_(-1),
1292           alpha_location_(-1),
1293           mask_tex_coord_scale_location_(-1) {}
1294
1295 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(
1296     WebGraphicsContext3D* context,
1297     unsigned program,
1298     bool using_bind_uniform,
1299     int* base_uniform_index) {
1300   static const char* uniforms[] = {
1301     "s_texture",
1302     "s_mask",
1303     "alpha",
1304     "maskTexCoordScale",
1305     "maskTexCoordOffset",
1306     "colorMatrix",
1307     "colorOffset",
1308   };
1309   int locations[arraysize(uniforms)];
1310
1311   GetProgramUniformLocations(context,
1312                              program,
1313                              arraysize(uniforms),
1314                              uniforms,
1315                              locations,
1316                              using_bind_uniform,
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];
1325 }
1326
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;
1339     void main() {
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;
1351     }
1352   );  // NOLINT(whitespace/parens)
1353 }
1354
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) {}
1362
1363 void FragmentShaderYUVVideo::Init(WebGraphicsContext3D* context,
1364                                   unsigned program,
1365                                   bool using_bind_uniform,
1366                                   int* base_uniform_index) {
1367   static const char* uniforms[] = {
1368     "y_texture",
1369     "u_texture",
1370     "v_texture",
1371     "alpha",
1372     "yuv_matrix",
1373     "yuv_adj",
1374   };
1375   int locations[arraysize(uniforms)];
1376
1377   GetProgramUniformLocations(context,
1378                              program,
1379                              arraysize(uniforms),
1380                              uniforms,
1381                              locations,
1382                              using_bind_uniform,
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];
1390 }
1391
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;
1404     void main() {
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;
1411     }
1412   );  // NOLINT(whitespace/parens)
1413 }
1414
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) {
1423 }
1424
1425 void FragmentShaderYUVAVideo::Init(WebGraphicsContext3D* context,
1426                                    unsigned program,
1427                                    bool using_bind_uniform,
1428                                    int* base_uniform_index) {
1429   static const char* uniforms[] = {
1430       "y_texture",
1431       "u_texture",
1432       "v_texture",
1433       "a_texture",
1434       "alpha",
1435       "cc_matrix",
1436       "yuv_adj",
1437   };
1438   int locations[arraysize(uniforms)];
1439
1440   GetProgramUniformLocations(context,
1441                              program,
1442                              arraysize(uniforms),
1443                              uniforms,
1444                              locations,
1445                              using_bind_uniform,
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];
1454 }
1455
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;
1469     void main() {
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);
1477     }
1478   );  // NOLINT(whitespace/parens)
1479 }
1480
1481 FragmentShaderColor::FragmentShaderColor()
1482     : color_location_(-1) {}
1483
1484 void FragmentShaderColor::Init(WebGraphicsContext3D* context,
1485                                unsigned program,
1486                                bool using_bind_uniform,
1487                                int* base_uniform_index) {
1488   static const char* uniforms[] = {
1489     "color",
1490   };
1491   int locations[arraysize(uniforms)];
1492
1493   GetProgramUniformLocations(context,
1494                              program,
1495                              arraysize(uniforms),
1496                              uniforms,
1497                              locations,
1498                              using_bind_uniform,
1499                              base_uniform_index);
1500   color_location_ = locations[0];
1501 }
1502
1503 std::string FragmentShaderColor::GetShaderString(
1504     TexCoordPrecision precision) const {
1505   return FRAGMENT_SHADER(
1506     precision mediump float;
1507     uniform vec4 color;
1508     void main() {
1509       gl_FragColor = color;
1510     }
1511   );  // NOLINT(whitespace/parens)
1512 }
1513
1514 FragmentShaderColorAA::FragmentShaderColorAA()
1515     : color_location_(-1) {}
1516
1517 void FragmentShaderColorAA::Init(WebGraphicsContext3D* context,
1518                                  unsigned program,
1519                                  bool using_bind_uniform,
1520                                  int* base_uniform_index) {
1521   static const char* uniforms[] = {
1522     "color",
1523   };
1524   int locations[arraysize(uniforms)];
1525
1526   GetProgramUniformLocations(context,
1527                              program,
1528                              arraysize(uniforms),
1529                              uniforms,
1530                              locations,
1531                              using_bind_uniform,
1532                              base_uniform_index);
1533   color_location_ = locations[0];
1534 }
1535
1536 std::string FragmentShaderColorAA::GetShaderString(
1537     TexCoordPrecision precision) const {
1538   return FRAGMENT_SHADER(
1539     precision mediump float;
1540     uniform vec4 color;
1541     varying vec4 edge_dist[2];  // 8 edge distances.
1542
1543     void main() {
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;
1548     }
1549   );  // NOLINT(whitespace/parens)
1550 }
1551
1552 FragmentShaderCheckerboard::FragmentShaderCheckerboard()
1553     : alpha_location_(-1),
1554       tex_transform_location_(-1),
1555       frequency_location_(-1) {}
1556
1557 void FragmentShaderCheckerboard::Init(WebGraphicsContext3D* context,
1558                                       unsigned program,
1559                                       bool using_bind_uniform,
1560                                       int* base_uniform_index) {
1561   static const char* uniforms[] = {
1562     "alpha",
1563     "texTransform",
1564     "frequency",
1565     "color",
1566   };
1567   int locations[arraysize(uniforms)];
1568
1569   GetProgramUniformLocations(context,
1570                              program,
1571                              arraysize(uniforms),
1572                              uniforms,
1573                              locations,
1574                              using_bind_uniform,
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];
1580 }
1581
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;
1593     uniform vec4 color;
1594     void main() {
1595       vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0);
1596       vec4 color2 = color;
1597       vec2 texCoord =
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;
1602     }
1603   );  // NOLINT(whitespace/parens)
1604 }
1605
1606 }  // namespace cc