• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gpu/command_buffer/client/gles2_interface.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) SetFragmentTexCoordPrecision( \
18     precision, SetFragmentSamplerType(sampler, SHADER0(Src)))
19 
20 using gpu::gles2::GLES2Interface;
21 
22 namespace cc {
23 
24 namespace {
25 
GetProgramUniformLocations(GLES2Interface * context,unsigned program,size_t count,const char ** uniforms,int * locations,int * base_uniform_index)26 static void GetProgramUniformLocations(GLES2Interface* context,
27                                        unsigned program,
28                                        size_t count,
29                                        const char** uniforms,
30                                        int* locations,
31                                        int* base_uniform_index) {
32   for (size_t i = 0; i < count; i++) {
33     locations[i] = (*base_uniform_index)++;
34     context->BindUniformLocationCHROMIUM(program, locations[i], uniforms[i]);
35   }
36 }
37 
SetFragmentTexCoordPrecision(TexCoordPrecision requested_precision,std::string shader_string)38 static std::string SetFragmentTexCoordPrecision(
39     TexCoordPrecision requested_precision, std::string shader_string) {
40   switch (requested_precision) {
41     case TexCoordPrecisionHigh:
42       DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
43       return
44           "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
45           "  #define TexCoordPrecision highp\n"
46           "#else\n"
47           "  #define TexCoordPrecision mediump\n"
48           "#endif\n" +
49           shader_string;
50     case TexCoordPrecisionMedium:
51       DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
52       return "#define TexCoordPrecision mediump\n" +
53           shader_string;
54     case TexCoordPrecisionNA:
55       DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos);
56       DCHECK_EQ(shader_string.find("texture2D"), std::string::npos);
57       DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos);
58       return shader_string;
59     default:
60       NOTREACHED();
61       break;
62   }
63   return shader_string;
64 }
65 
SetVertexTexCoordPrecision(const char * shader_string)66 static std::string SetVertexTexCoordPrecision(const char* shader_string) {
67   // We unconditionally use highp in the vertex shader since
68   // we are unlikely to be vertex shader bound when drawing large quads.
69   // Also, some vertex shaders mutate the texture coordinate in such a
70   // way that the effective precision might be lower than expected.
71   return "#define TexCoordPrecision highp\n" +
72       std::string(shader_string);
73 }
74 
TexCoordPrecisionRequired(GLES2Interface * context,int * highp_threshold_cache,int highp_threshold_min,int x,int y)75 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
76                                             int *highp_threshold_cache,
77                                             int highp_threshold_min,
78                                             int x, int y) {
79   if (*highp_threshold_cache == 0) {
80     // Initialize range and precision with minimum spec values for when
81     // GetShaderPrecisionFormat is a test stub.
82     // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat
83     // everywhere.
84     GLint range[2] = { 14, 14 };
85     GLint precision = 10;
86     GLC(context, context->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER,
87                                                    GL_MEDIUM_FLOAT,
88                                                    range, &precision));
89     *highp_threshold_cache = 1 << precision;
90   }
91 
92   int highp_threshold = std::max(*highp_threshold_cache, highp_threshold_min);
93   if (x > highp_threshold || y > highp_threshold)
94     return TexCoordPrecisionHigh;
95   return TexCoordPrecisionMedium;
96 }
97 
SetFragmentSamplerType(SamplerType requested_type,std::string shader_string)98 static std::string SetFragmentSamplerType(
99     SamplerType requested_type, std::string shader_string) {
100   switch (requested_type) {
101     case SamplerType2D:
102       DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
103       DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
104       return
105           "#define SamplerType sampler2D\n"
106           "#define TextureLookup texture2D\n" +
107           shader_string;
108     case SamplerType2DRect:
109       DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
110       DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
111       return
112           "#extension GL_ARB_texture_rectangle : require\n"
113           "#define SamplerType sampler2DRect\n"
114           "#define TextureLookup texture2DRect\n" +
115           shader_string;
116     case SamplerTypeExternalOES:
117       DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
118       DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
119       return
120           "#extension GL_OES_EGL_image_external : require\n"
121           "#define SamplerType samplerExternalOES\n"
122           "#define TextureLookup texture2D\n" +
123           shader_string;
124     case SamplerTypeNA:
125       DCHECK_EQ(shader_string.find("SamplerType"), std::string::npos);
126       DCHECK_EQ(shader_string.find("TextureLookup"), std::string::npos);
127       return shader_string;
128     default:
129       NOTREACHED();
130       break;
131   }
132   return shader_string;
133 }
134 
135 }  // namespace
136 
TexCoordPrecisionRequired(GLES2Interface * context,int * highp_threshold_cache,int highp_threshold_min,const gfx::Point & max_coordinate)137 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
138                                             int* highp_threshold_cache,
139                                             int highp_threshold_min,
140                                             const gfx::Point& max_coordinate) {
141   return TexCoordPrecisionRequired(context,
142                                    highp_threshold_cache, highp_threshold_min,
143                                    max_coordinate.x(), max_coordinate.y());
144 }
145 
TexCoordPrecisionRequired(GLES2Interface * context,int * highp_threshold_cache,int highp_threshold_min,const gfx::Size & max_size)146 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
147                                             int *highp_threshold_cache,
148                                             int highp_threshold_min,
149                                             const gfx::Size& max_size) {
150   return TexCoordPrecisionRequired(context,
151                                    highp_threshold_cache, highp_threshold_min,
152                                    max_size.width(), max_size.height());
153 }
154 
VertexShaderPosTex()155 VertexShaderPosTex::VertexShaderPosTex()
156       : matrix_location_(-1) {}
157 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)158 void VertexShaderPosTex::Init(GLES2Interface* context,
159                               unsigned program,
160                               int* base_uniform_index) {
161   static const char* uniforms[] = {
162       "matrix",
163   };
164   int locations[arraysize(uniforms)];
165 
166   GetProgramUniformLocations(context,
167                              program,
168                              arraysize(uniforms),
169                              uniforms,
170                              locations,
171                              base_uniform_index);
172   matrix_location_ = locations[0];
173 }
174 
GetShaderString() const175 std::string VertexShaderPosTex::GetShaderString() const {
176   return VERTEX_SHADER(
177     attribute vec4 a_position;
178     attribute TexCoordPrecision vec2 a_texCoord;
179     uniform mat4 matrix;
180     varying TexCoordPrecision vec2 v_texCoord;
181     void main() {
182       gl_Position = matrix * a_position;
183       v_texCoord = a_texCoord;
184     }
185   );  // NOLINT(whitespace/parens)
186 }
187 
VertexShaderPosTexYUVStretchOffset()188 VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset()
189     : matrix_location_(-1), tex_scale_location_(-1), tex_offset_location_(-1) {}
190 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)191 void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context,
192                                               unsigned program,
193                                               int* base_uniform_index) {
194   static const char* uniforms[] = {
195     "matrix",
196     "texScale",
197     "texOffset",
198   };
199   int locations[arraysize(uniforms)];
200 
201   GetProgramUniformLocations(context,
202                              program,
203                              arraysize(uniforms),
204                              uniforms,
205                              locations,
206                              base_uniform_index);
207   matrix_location_ = locations[0];
208   tex_scale_location_ = locations[1];
209   tex_offset_location_ = locations[2];
210 }
211 
GetShaderString() const212 std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const {
213   return VERTEX_SHADER(
214     precision mediump float;
215     attribute vec4 a_position;
216     attribute TexCoordPrecision vec2 a_texCoord;
217     uniform mat4 matrix;
218     varying TexCoordPrecision vec2 v_texCoord;
219     uniform TexCoordPrecision vec2 texScale;
220     uniform TexCoordPrecision vec2 texOffset;
221     void main() {
222         gl_Position = matrix * a_position;
223         v_texCoord = a_texCoord * texScale + texOffset;
224     }
225   );  // NOLINT(whitespace/parens)
226 }
227 
VertexShaderPos()228 VertexShaderPos::VertexShaderPos()
229     : matrix_location_(-1) {}
230 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)231 void VertexShaderPos::Init(GLES2Interface* context,
232                            unsigned program,
233                            int* base_uniform_index) {
234   static const char* uniforms[] = {
235       "matrix",
236   };
237   int locations[arraysize(uniforms)];
238 
239   GetProgramUniformLocations(context,
240                              program,
241                              arraysize(uniforms),
242                              uniforms,
243                              locations,
244                              base_uniform_index);
245   matrix_location_ = locations[0];
246 }
247 
GetShaderString() const248 std::string VertexShaderPos::GetShaderString() const {
249   return VERTEX_SHADER(
250     attribute vec4 a_position;
251     uniform mat4 matrix;
252     void main() {
253         gl_Position = matrix * a_position;
254     }
255   );  // NOLINT(whitespace/parens)
256 }
257 
VertexShaderPosTexTransform()258 VertexShaderPosTexTransform::VertexShaderPosTexTransform()
259     : matrix_location_(-1),
260       tex_transform_location_(-1),
261       vertex_opacity_location_(-1) {}
262 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)263 void VertexShaderPosTexTransform::Init(GLES2Interface* context,
264                                        unsigned program,
265                                        int* base_uniform_index) {
266   static const char* uniforms[] = {
267     "matrix",
268     "texTransform",
269     "opacity",
270   };
271   int locations[arraysize(uniforms)];
272 
273   GetProgramUniformLocations(context,
274                              program,
275                              arraysize(uniforms),
276                              uniforms,
277                              locations,
278                              base_uniform_index);
279   matrix_location_ = locations[0];
280   tex_transform_location_ = locations[1];
281   vertex_opacity_location_ = locations[2];
282 }
283 
GetShaderString() const284 std::string VertexShaderPosTexTransform::GetShaderString() const {
285   return VERTEX_SHADER(
286     attribute vec4 a_position;
287     attribute TexCoordPrecision vec2 a_texCoord;
288     attribute float a_index;
289     uniform mat4 matrix[8];
290     uniform TexCoordPrecision vec4 texTransform[8];
291     uniform float opacity[32];
292     varying TexCoordPrecision vec2 v_texCoord;
293     varying float v_alpha;
294     void main() {
295       int quad_index = int(a_index * 0.25);  // NOLINT
296       gl_Position = matrix[quad_index] * a_position;
297       TexCoordPrecision vec4 texTrans = texTransform[quad_index];
298       v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
299       v_alpha = opacity[int(a_index)]; // NOLINT
300     }
301   );  // NOLINT(whitespace/parens)
302 }
303 
GetShaderString() const304 std::string VertexShaderPosTexIdentity::GetShaderString() const {
305   return VERTEX_SHADER(
306     attribute vec4 a_position;
307     varying TexCoordPrecision vec2 v_texCoord;
308     void main() {
309       gl_Position = a_position;
310       v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
311     }
312   );  // NOLINT(whitespace/parens)
313 }
314 
VertexShaderQuad()315 VertexShaderQuad::VertexShaderQuad()
316     : matrix_location_(-1),
317       quad_location_(-1) {}
318 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)319 void VertexShaderQuad::Init(GLES2Interface* context,
320                             unsigned program,
321                             int* base_uniform_index) {
322   static const char* uniforms[] = {
323     "matrix",
324     "quad",
325   };
326   int locations[arraysize(uniforms)];
327 
328   GetProgramUniformLocations(context,
329                              program,
330                              arraysize(uniforms),
331                              uniforms,
332                              locations,
333                              base_uniform_index);
334   matrix_location_ = locations[0];
335   quad_location_ = locations[1];
336 }
337 
GetShaderString() const338 std::string VertexShaderQuad::GetShaderString() const {
339 #if defined(OS_ANDROID)
340 // TODO(epenner): Find the cause of this 'quad' uniform
341 // being missing if we don't add dummy variables.
342 // http://crbug.com/240602
343   return VERTEX_SHADER(
344     attribute TexCoordPrecision vec4 a_position;
345     attribute float a_index;
346     uniform mat4 matrix;
347     uniform TexCoordPrecision vec2 quad[4];
348     uniform TexCoordPrecision vec2 dummy_uniform;
349     varying TexCoordPrecision vec2 dummy_varying;
350     void main() {
351       vec2 pos = quad[int(a_index)];  // NOLINT
352       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
353       dummy_varying = dummy_uniform;
354     }
355   );  // NOLINT(whitespace/parens)
356 #else
357   return VERTEX_SHADER(
358     attribute TexCoordPrecision vec4 a_position;
359     attribute float a_index;
360     uniform mat4 matrix;
361     uniform TexCoordPrecision vec2 quad[4];
362     void main() {
363       vec2 pos = quad[int(a_index)];  // NOLINT
364       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
365     }
366   );  // NOLINT(whitespace/parens)
367 #endif
368 }
369 
VertexShaderQuadAA()370 VertexShaderQuadAA::VertexShaderQuadAA()
371     : matrix_location_(-1),
372       viewport_location_(-1),
373       quad_location_(-1),
374       edge_location_(-1) {}
375 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)376 void VertexShaderQuadAA::Init(GLES2Interface* context,
377                             unsigned program,
378                             int* base_uniform_index) {
379   static const char* uniforms[] = {
380     "matrix",
381     "viewport",
382     "quad",
383     "edge",
384   };
385   int locations[arraysize(uniforms)];
386 
387   GetProgramUniformLocations(context,
388                              program,
389                              arraysize(uniforms),
390                              uniforms,
391                              locations,
392                              base_uniform_index);
393   matrix_location_ = locations[0];
394   viewport_location_ = locations[1];
395   quad_location_ = locations[2];
396   edge_location_ = locations[3];
397 }
398 
GetShaderString() const399 std::string VertexShaderQuadAA::GetShaderString() const {
400   return VERTEX_SHADER(
401     attribute TexCoordPrecision vec4 a_position;
402     attribute float a_index;
403     uniform mat4 matrix;
404     uniform vec4 viewport;
405     uniform TexCoordPrecision vec2 quad[4];
406     uniform TexCoordPrecision vec3 edge[8];
407     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
408 
409     void main() {
410       vec2 pos = quad[int(a_index)];  // NOLINT
411       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
412       vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
413       vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
414       edge_dist[0] = vec4(dot(edge[0], screen_pos),
415                           dot(edge[1], screen_pos),
416                           dot(edge[2], screen_pos),
417                           dot(edge[3], screen_pos)) * gl_Position.w;
418       edge_dist[1] = vec4(dot(edge[4], screen_pos),
419                           dot(edge[5], screen_pos),
420                           dot(edge[6], screen_pos),
421                           dot(edge[7], screen_pos)) * gl_Position.w;
422     }
423   );  // NOLINT(whitespace/parens)
424 }
425 
VertexShaderQuadTexTransformAA()426 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
427     : matrix_location_(-1),
428       viewport_location_(-1),
429       quad_location_(-1),
430       edge_location_(-1),
431       tex_transform_location_(-1) {}
432 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)433 void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context,
434                                         unsigned program,
435                                         int* base_uniform_index) {
436   static const char* uniforms[] = {
437     "matrix",
438     "viewport",
439     "quad",
440     "edge",
441     "texTrans",
442   };
443   int locations[arraysize(uniforms)];
444 
445   GetProgramUniformLocations(context,
446                              program,
447                              arraysize(uniforms),
448                              uniforms,
449                              locations,
450                              base_uniform_index);
451   matrix_location_ = locations[0];
452   viewport_location_ = locations[1];
453   quad_location_ = locations[2];
454   edge_location_ = locations[3];
455   tex_transform_location_ = locations[4];
456 }
457 
GetShaderString() const458 std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
459   return VERTEX_SHADER(
460     attribute TexCoordPrecision vec4 a_position;
461     attribute float a_index;
462     uniform mat4 matrix;
463     uniform vec4 viewport;
464     uniform TexCoordPrecision vec2 quad[4];
465     uniform TexCoordPrecision vec3 edge[8];
466     uniform TexCoordPrecision vec4 texTrans;
467     varying TexCoordPrecision vec2 v_texCoord;
468     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
469 
470     void main() {
471       vec2 pos = quad[int(a_index)];  // NOLINT
472       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
473       vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
474       vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
475       edge_dist[0] = vec4(dot(edge[0], screen_pos),
476                           dot(edge[1], screen_pos),
477                           dot(edge[2], screen_pos),
478                           dot(edge[3], screen_pos)) * gl_Position.w;
479       edge_dist[1] = vec4(dot(edge[4], screen_pos),
480                           dot(edge[5], screen_pos),
481                           dot(edge[6], screen_pos),
482                           dot(edge[7], screen_pos)) * gl_Position.w;
483       v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy;
484     }
485   );  // NOLINT(whitespace/parens)
486 }
487 
VertexShaderTile()488 VertexShaderTile::VertexShaderTile()
489     : matrix_location_(-1),
490       quad_location_(-1),
491       vertex_tex_transform_location_(-1) {}
492 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)493 void VertexShaderTile::Init(GLES2Interface* context,
494                             unsigned program,
495                             int* base_uniform_index) {
496   static const char* uniforms[] = {
497     "matrix",
498     "quad",
499     "vertexTexTransform",
500   };
501   int locations[arraysize(uniforms)];
502 
503   GetProgramUniformLocations(context,
504                              program,
505                              arraysize(uniforms),
506                              uniforms,
507                              locations,
508                              base_uniform_index);
509   matrix_location_ = locations[0];
510   quad_location_ = locations[1];
511   vertex_tex_transform_location_ = locations[2];
512 }
513 
GetShaderString() const514 std::string VertexShaderTile::GetShaderString() const {
515   return VERTEX_SHADER(
516     attribute TexCoordPrecision vec4 a_position;
517     attribute float a_index;
518     uniform mat4 matrix;
519     uniform TexCoordPrecision vec2 quad[4];
520     uniform TexCoordPrecision vec4 vertexTexTransform;
521     varying TexCoordPrecision vec2 v_texCoord;
522     void main() {
523       vec2 pos = quad[int(a_index)];  // NOLINT
524       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
525       v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
526     }
527   );  // NOLINT(whitespace/parens)
528 }
529 
VertexShaderTileAA()530 VertexShaderTileAA::VertexShaderTileAA()
531     : matrix_location_(-1),
532       viewport_location_(-1),
533       quad_location_(-1),
534       edge_location_(-1),
535       vertex_tex_transform_location_(-1) {}
536 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)537 void VertexShaderTileAA::Init(GLES2Interface* context,
538                               unsigned program,
539                               int* base_uniform_index) {
540   static const char* uniforms[] = {
541     "matrix",
542     "viewport",
543     "quad",
544     "edge",
545     "vertexTexTransform",
546   };
547   int locations[arraysize(uniforms)];
548 
549   GetProgramUniformLocations(context,
550                              program,
551                              arraysize(uniforms),
552                              uniforms,
553                              locations,
554                              base_uniform_index);
555   matrix_location_ = locations[0];
556   viewport_location_ = locations[1];
557   quad_location_ = locations[2];
558   edge_location_ = locations[3];
559   vertex_tex_transform_location_ = locations[4];
560 }
561 
GetShaderString() const562 std::string VertexShaderTileAA::GetShaderString() const {
563   return VERTEX_SHADER(
564     attribute TexCoordPrecision vec4 a_position;
565     attribute float a_index;
566     uniform mat4 matrix;
567     uniform vec4 viewport;
568     uniform TexCoordPrecision vec2 quad[4];
569     uniform TexCoordPrecision vec3 edge[8];
570     uniform TexCoordPrecision vec4 vertexTexTransform;
571     varying TexCoordPrecision vec2 v_texCoord;
572     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
573 
574     void main() {
575       vec2 pos = quad[int(a_index)];  // NOLINT
576       gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
577       vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
578       vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
579       edge_dist[0] = vec4(dot(edge[0], screen_pos),
580                           dot(edge[1], screen_pos),
581                           dot(edge[2], screen_pos),
582                           dot(edge[3], screen_pos)) * gl_Position.w;
583       edge_dist[1] = vec4(dot(edge[4], screen_pos),
584                           dot(edge[5], screen_pos),
585                           dot(edge[6], screen_pos),
586                           dot(edge[7], screen_pos)) * gl_Position.w;
587       v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
588     }
589   );  // NOLINT(whitespace/parens)
590 }
591 
VertexShaderVideoTransform()592 VertexShaderVideoTransform::VertexShaderVideoTransform()
593     : matrix_location_(-1),
594       tex_matrix_location_(-1) {}
595 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)596 void VertexShaderVideoTransform::Init(GLES2Interface* context,
597                                       unsigned program,
598                                       int* base_uniform_index) {
599   static const char* uniforms[] = {
600     "matrix",
601     "texMatrix",
602   };
603   int locations[arraysize(uniforms)];
604 
605   GetProgramUniformLocations(context,
606                              program,
607                              arraysize(uniforms),
608                              uniforms,
609                              locations,
610                              base_uniform_index);
611   matrix_location_ = locations[0];
612   tex_matrix_location_ = locations[1];
613 }
614 
GetShaderString() const615 std::string VertexShaderVideoTransform::GetShaderString() const {
616   return VERTEX_SHADER(
617     attribute vec4 a_position;
618     attribute TexCoordPrecision vec2 a_texCoord;
619     uniform mat4 matrix;
620     uniform TexCoordPrecision mat4 texMatrix;
621     varying TexCoordPrecision vec2 v_texCoord;
622     void main() {
623         gl_Position = matrix * a_position;
624         v_texCoord =
625             vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
626     }
627   );  // NOLINT(whitespace/parens)
628 }
629 
FragmentTexAlphaBinding()630 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
631     : sampler_location_(-1),
632       alpha_location_(-1) {}
633 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)634 void FragmentTexAlphaBinding::Init(GLES2Interface* context,
635                                    unsigned program,
636                                    int* base_uniform_index) {
637   static const char* uniforms[] = {
638     "s_texture",
639     "alpha",
640   };
641   int locations[arraysize(uniforms)];
642 
643   GetProgramUniformLocations(context,
644                              program,
645                              arraysize(uniforms),
646                              uniforms,
647                              locations,
648                              base_uniform_index);
649   sampler_location_ = locations[0];
650   alpha_location_ = locations[1];
651 }
652 
FragmentTexColorMatrixAlphaBinding()653 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
654     : sampler_location_(-1),
655       alpha_location_(-1),
656       color_matrix_location_(-1),
657       color_offset_location_(-1) {}
658 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)659 void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface* context,
660                                               unsigned program,
661                                               int* base_uniform_index) {
662   static const char* uniforms[] = {
663     "s_texture",
664     "alpha",
665     "colorMatrix",
666     "colorOffset",
667   };
668   int locations[arraysize(uniforms)];
669 
670   GetProgramUniformLocations(context,
671                              program,
672                              arraysize(uniforms),
673                              uniforms,
674                              locations,
675                              base_uniform_index);
676   sampler_location_ = locations[0];
677   alpha_location_ = locations[1];
678   color_matrix_location_ = locations[2];
679   color_offset_location_ = locations[3];
680 }
681 
FragmentTexOpaqueBinding()682 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
683     : sampler_location_(-1) {}
684 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)685 void FragmentTexOpaqueBinding::Init(GLES2Interface* context,
686                                     unsigned program,
687                                     int* base_uniform_index) {
688   static const char* uniforms[] = {
689     "s_texture",
690   };
691   int locations[arraysize(uniforms)];
692 
693   GetProgramUniformLocations(context,
694                              program,
695                              arraysize(uniforms),
696                              uniforms,
697                              locations,
698                              base_uniform_index);
699   sampler_location_ = locations[0];
700 }
701 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const702 std::string FragmentShaderRGBATexAlpha::GetShaderString(
703     TexCoordPrecision precision, SamplerType sampler) const {
704   return FRAGMENT_SHADER(
705     precision mediump float;
706     varying TexCoordPrecision vec2 v_texCoord;
707     uniform SamplerType s_texture;
708     uniform float alpha;
709     void main() {
710       vec4 texColor = TextureLookup(s_texture, v_texCoord);
711       gl_FragColor = texColor * alpha;
712     }
713   );  // NOLINT(whitespace/parens)
714 }
715 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const716 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
717     TexCoordPrecision precision, SamplerType sampler) const {
718   return FRAGMENT_SHADER(
719     precision mediump float;
720     varying TexCoordPrecision vec2 v_texCoord;
721     uniform SamplerType s_texture;
722     uniform float alpha;
723     uniform mat4 colorMatrix;
724     uniform vec4 colorOffset;
725     void main() {
726       vec4 texColor = TextureLookup(s_texture, v_texCoord);
727       float nonZeroAlpha = max(texColor.a, 0.00001);
728       texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
729       texColor = colorMatrix * texColor + colorOffset;
730       texColor.rgb *= texColor.a;
731       texColor = clamp(texColor, 0.0, 1.0);
732       gl_FragColor = texColor * alpha;
733     }
734   );  // NOLINT(whitespace/parens)
735 }
736 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const737 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
738     TexCoordPrecision precision, SamplerType sampler) const {
739   return FRAGMENT_SHADER(
740     precision mediump float;
741     varying TexCoordPrecision vec2 v_texCoord;
742     varying float v_alpha;
743     uniform SamplerType s_texture;
744     void main() {
745       vec4 texColor = TextureLookup(s_texture, v_texCoord);
746       gl_FragColor = texColor * v_alpha;
747     }
748   );  // NOLINT(whitespace/parens)
749 }
750 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const751 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
752     TexCoordPrecision precision, SamplerType sampler) const {
753   return FRAGMENT_SHADER(
754     precision mediump float;
755     varying TexCoordPrecision vec2 v_texCoord;
756     varying float v_alpha;
757     uniform SamplerType s_texture;
758     void main() {
759       vec4 texColor = TextureLookup(s_texture, v_texCoord);
760       texColor.rgb *= texColor.a;
761       gl_FragColor = texColor * v_alpha;
762     }
763   );  // NOLINT(whitespace/parens)
764 }
765 
FragmentTexBackgroundBinding()766 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
767     : background_color_location_(-1),
768       sampler_location_(-1) {
769 }
770 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)771 void FragmentTexBackgroundBinding::Init(GLES2Interface* context,
772                                         unsigned program,
773                                         int* base_uniform_index) {
774   static const char* uniforms[] = {
775     "s_texture",
776     "background_color",
777   };
778   int locations[arraysize(uniforms)];
779 
780   GetProgramUniformLocations(context,
781                              program,
782                              arraysize(uniforms),
783                              uniforms,
784                              locations,
785                              base_uniform_index);
786 
787   sampler_location_ = locations[0];
788   DCHECK_NE(sampler_location_, -1);
789 
790   background_color_location_ = locations[1];
791   DCHECK_NE(background_color_location_, -1);
792 }
793 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const794 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
795     TexCoordPrecision precision, SamplerType sampler) const {
796   return FRAGMENT_SHADER(
797     precision mediump float;
798     varying TexCoordPrecision vec2 v_texCoord;
799     varying float v_alpha;
800     uniform vec4 background_color;
801     uniform SamplerType s_texture;
802     void main() {
803       vec4 texColor = TextureLookup(s_texture, v_texCoord);
804       texColor += background_color * (1.0 - texColor.a);
805       gl_FragColor = texColor * v_alpha;
806     }
807   );  // NOLINT(whitespace/parens)
808 }
809 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const810 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
811     TexCoordPrecision precision, SamplerType sampler) const {
812   return FRAGMENT_SHADER(
813     precision mediump float;
814     varying TexCoordPrecision vec2 v_texCoord;
815     varying float v_alpha;
816     uniform vec4 background_color;
817     uniform SamplerType s_texture;
818     void main() {
819       vec4 texColor = TextureLookup(s_texture, v_texCoord);
820       texColor.rgb *= texColor.a;
821       texColor += background_color * (1.0 - texColor.a);
822       gl_FragColor = texColor * v_alpha;
823     }
824   );  // NOLINT(whitespace/parens)
825 }
826 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const827 std::string FragmentShaderRGBATexOpaque::GetShaderString(
828     TexCoordPrecision precision, SamplerType sampler) const {
829   return FRAGMENT_SHADER(
830     precision mediump float;
831     varying TexCoordPrecision vec2 v_texCoord;
832     uniform SamplerType s_texture;
833     void main() {
834       vec4 texColor = TextureLookup(s_texture, v_texCoord);
835       gl_FragColor = vec4(texColor.rgb, 1.0);
836     }
837   );  // NOLINT(whitespace/parens)
838 }
839 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const840 std::string FragmentShaderRGBATex::GetShaderString(
841     TexCoordPrecision precision, SamplerType sampler) const {
842   return FRAGMENT_SHADER(
843     precision mediump float;
844     varying TexCoordPrecision vec2 v_texCoord;
845     uniform SamplerType s_texture;
846     void main() {
847       gl_FragColor = TextureLookup(s_texture, v_texCoord);
848     }
849   );  // NOLINT(whitespace/parens)
850 }
851 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const852 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
853     TexCoordPrecision precision, SamplerType sampler) const {
854   return FRAGMENT_SHADER(
855     precision mediump float;
856     varying TexCoordPrecision vec2 v_texCoord;
857     uniform SamplerType s_texture;
858     uniform float alpha;
859     void main() {
860         vec4 texColor = TextureLookup(s_texture, v_texCoord);
861         gl_FragColor =
862             vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
863     }
864   );  // NOLINT(whitespace/parens)
865 }
866 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const867 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
868     TexCoordPrecision precision, SamplerType sampler) const {
869   return FRAGMENT_SHADER(
870     precision mediump float;
871     varying TexCoordPrecision vec2 v_texCoord;
872     uniform SamplerType s_texture;
873     void main() {
874       vec4 texColor = TextureLookup(s_texture, v_texCoord);
875       gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
876     }
877   );  // NOLINT(whitespace/parens)
878 }
879 
FragmentShaderRGBATexAlphaAA()880 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
881     : sampler_location_(-1),
882       alpha_location_(-1) {}
883 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)884 void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface* context,
885                                         unsigned program,
886                                         int* base_uniform_index) {
887   static const char* uniforms[] = {
888     "s_texture",
889     "alpha",
890   };
891   int locations[arraysize(uniforms)];
892 
893   GetProgramUniformLocations(context,
894                              program,
895                              arraysize(uniforms),
896                              uniforms,
897                              locations,
898                              base_uniform_index);
899   sampler_location_ = locations[0];
900   alpha_location_ = locations[1];
901 }
902 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const903 std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
904     TexCoordPrecision precision, SamplerType sampler) const {
905   return FRAGMENT_SHADER(
906     precision mediump float;
907     uniform SamplerType s_texture;
908     uniform float alpha;
909     varying TexCoordPrecision vec2 v_texCoord;
910     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
911 
912     void main() {
913       vec4 texColor = TextureLookup(s_texture, v_texCoord);
914       vec4 d4 = min(edge_dist[0], edge_dist[1]);
915       vec2 d2 = min(d4.xz, d4.yw);
916       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
917       gl_FragColor = texColor * alpha * aa;
918     }
919   );  // NOLINT(whitespace/parens)
920 }
921 
FragmentTexClampAlphaAABinding()922 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
923     : sampler_location_(-1),
924       alpha_location_(-1),
925       fragment_tex_transform_location_(-1) {}
926 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)927 void FragmentTexClampAlphaAABinding::Init(GLES2Interface* context,
928                                           unsigned program,
929                                           int* base_uniform_index) {
930   static const char* uniforms[] = {
931     "s_texture",
932     "alpha",
933     "fragmentTexTransform",
934   };
935   int locations[arraysize(uniforms)];
936 
937   GetProgramUniformLocations(context,
938                              program,
939                              arraysize(uniforms),
940                              uniforms,
941                              locations,
942                              base_uniform_index);
943   sampler_location_ = locations[0];
944   alpha_location_ = locations[1];
945   fragment_tex_transform_location_ = locations[2];
946 }
947 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const948 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
949     TexCoordPrecision precision, SamplerType sampler) const {
950   return FRAGMENT_SHADER(
951     precision mediump float;
952     uniform SamplerType s_texture;
953     uniform float alpha;
954     uniform TexCoordPrecision vec4 fragmentTexTransform;
955     varying TexCoordPrecision vec2 v_texCoord;
956     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
957 
958     void main() {
959       TexCoordPrecision vec2 texCoord =
960           clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
961           fragmentTexTransform.xy;
962       vec4 texColor = TextureLookup(s_texture, texCoord);
963       vec4 d4 = min(edge_dist[0], edge_dist[1]);
964       vec2 d2 = min(d4.xz, d4.yw);
965       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
966       gl_FragColor = texColor * alpha * aa;
967     }
968   );  // NOLINT(whitespace/parens)
969 }
970 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const971 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
972     TexCoordPrecision precision, SamplerType sampler) const {
973   return FRAGMENT_SHADER(
974     precision mediump float;
975     uniform SamplerType s_texture;
976     uniform float alpha;
977     uniform TexCoordPrecision vec4 fragmentTexTransform;
978     varying TexCoordPrecision vec2 v_texCoord;
979     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
980 
981     void main() {
982       TexCoordPrecision vec2 texCoord =
983           clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
984           fragmentTexTransform.xy;
985       vec4 texColor = TextureLookup(s_texture, texCoord);
986       vec4 d4 = min(edge_dist[0], edge_dist[1]);
987       vec2 d2 = min(d4.xz, d4.yw);
988       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
989       gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) *
990           alpha * aa;
991     }
992   );  // NOLINT(whitespace/parens)
993 }
994 
FragmentShaderRGBATexAlphaMask()995 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
996     : sampler_location_(-1),
997       mask_sampler_location_(-1),
998       alpha_location_(-1),
999       mask_tex_coord_scale_location_(-1) {}
1000 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1001 void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface* context,
1002                                           unsigned program,
1003                                           int* base_uniform_index) {
1004   static const char* uniforms[] = {
1005     "s_texture",
1006     "s_mask",
1007     "alpha",
1008     "maskTexCoordScale",
1009     "maskTexCoordOffset",
1010   };
1011   int locations[arraysize(uniforms)];
1012 
1013   GetProgramUniformLocations(context,
1014                              program,
1015                              arraysize(uniforms),
1016                              uniforms,
1017                              locations,
1018                              base_uniform_index);
1019   sampler_location_ = locations[0];
1020   mask_sampler_location_ = locations[1];
1021   alpha_location_ = locations[2];
1022   mask_tex_coord_scale_location_ = locations[3];
1023   mask_tex_coord_offset_location_ = locations[4];
1024 }
1025 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1026 std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
1027     TexCoordPrecision precision, SamplerType sampler) const {
1028   return FRAGMENT_SHADER(
1029     precision mediump float;
1030     varying TexCoordPrecision vec2 v_texCoord;
1031     uniform SamplerType s_texture;
1032     uniform SamplerType s_mask;
1033     uniform TexCoordPrecision vec2 maskTexCoordScale;
1034     uniform TexCoordPrecision vec2 maskTexCoordOffset;
1035     uniform float alpha;
1036     void main() {
1037       vec4 texColor = TextureLookup(s_texture, v_texCoord);
1038       TexCoordPrecision vec2 maskTexCoord =
1039           vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1040                maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1041       vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1042       gl_FragColor = texColor * alpha * maskColor.w;
1043     }
1044   );  // NOLINT(whitespace/parens)
1045 }
1046 
FragmentShaderRGBATexAlphaMaskAA()1047 FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
1048     : sampler_location_(-1),
1049       mask_sampler_location_(-1),
1050       alpha_location_(-1),
1051       mask_tex_coord_scale_location_(-1),
1052       mask_tex_coord_offset_location_(-1) {}
1053 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1054 void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface* context,
1055                                             unsigned program,
1056                                             int* base_uniform_index) {
1057   static const char* uniforms[] = {
1058     "s_texture",
1059     "s_mask",
1060     "alpha",
1061     "maskTexCoordScale",
1062     "maskTexCoordOffset",
1063   };
1064   int locations[arraysize(uniforms)];
1065 
1066   GetProgramUniformLocations(context,
1067                              program,
1068                              arraysize(uniforms),
1069                              uniforms,
1070                              locations,
1071                              base_uniform_index);
1072   sampler_location_ = locations[0];
1073   mask_sampler_location_ = locations[1];
1074   alpha_location_ = locations[2];
1075   mask_tex_coord_scale_location_ = locations[3];
1076   mask_tex_coord_offset_location_ = locations[4];
1077 }
1078 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1079 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
1080     TexCoordPrecision precision, SamplerType sampler) const {
1081   return FRAGMENT_SHADER(
1082     precision mediump float;
1083     uniform SamplerType s_texture;
1084     uniform SamplerType s_mask;
1085     uniform TexCoordPrecision vec2 maskTexCoordScale;
1086     uniform TexCoordPrecision vec2 maskTexCoordOffset;
1087     uniform float alpha;
1088     varying TexCoordPrecision vec2 v_texCoord;
1089     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
1090 
1091     void main() {
1092       vec4 texColor = TextureLookup(s_texture, v_texCoord);
1093       TexCoordPrecision vec2 maskTexCoord =
1094           vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1095                maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1096       vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1097       vec4 d4 = min(edge_dist[0], edge_dist[1]);
1098       vec2 d2 = min(d4.xz, d4.yw);
1099       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1100       gl_FragColor = texColor * alpha * maskColor.w * aa;
1101     }
1102   );  // NOLINT(whitespace/parens)
1103 }
1104 
1105 FragmentShaderRGBATexAlphaMaskColorMatrixAA::
FragmentShaderRGBATexAlphaMaskColorMatrixAA()1106     FragmentShaderRGBATexAlphaMaskColorMatrixAA()
1107         : sampler_location_(-1),
1108           mask_sampler_location_(-1),
1109           alpha_location_(-1),
1110           mask_tex_coord_scale_location_(-1),
1111           color_matrix_location_(-1),
1112           color_offset_location_(-1) {}
1113 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1114 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
1115     GLES2Interface* context,
1116     unsigned program,
1117     int* base_uniform_index) {
1118   static const char* uniforms[] = {
1119     "s_texture",
1120     "s_mask",
1121     "alpha",
1122     "maskTexCoordScale",
1123     "maskTexCoordOffset",
1124     "colorMatrix",
1125     "colorOffset",
1126   };
1127   int locations[arraysize(uniforms)];
1128 
1129   GetProgramUniformLocations(context,
1130                              program,
1131                              arraysize(uniforms),
1132                              uniforms,
1133                              locations,
1134                              base_uniform_index);
1135   sampler_location_ = locations[0];
1136   mask_sampler_location_ = locations[1];
1137   alpha_location_ = locations[2];
1138   mask_tex_coord_scale_location_ = locations[3];
1139   mask_tex_coord_offset_location_ = locations[4];
1140   color_matrix_location_ = locations[5];
1141   color_offset_location_ = locations[6];
1142 }
1143 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1144 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
1145     TexCoordPrecision precision, SamplerType sampler) const {
1146   return FRAGMENT_SHADER(
1147     precision mediump float;
1148     uniform SamplerType s_texture;
1149     uniform SamplerType s_mask;
1150     uniform vec2 maskTexCoordScale;
1151     uniform vec2 maskTexCoordOffset;
1152     uniform mat4 colorMatrix;
1153     uniform vec4 colorOffset;
1154     uniform float alpha;
1155     varying TexCoordPrecision vec2 v_texCoord;
1156     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
1157 
1158     void main() {
1159       vec4 texColor = TextureLookup(s_texture, v_texCoord);
1160       float nonZeroAlpha = max(texColor.a, 0.00001);
1161       texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1162       texColor = colorMatrix * texColor + colorOffset;
1163       texColor.rgb *= texColor.a;
1164       texColor = clamp(texColor, 0.0, 1.0);
1165       TexCoordPrecision vec2 maskTexCoord =
1166           vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1167                maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1168       vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1169       vec4 d4 = min(edge_dist[0], edge_dist[1]);
1170       vec2 d2 = min(d4.xz, d4.yw);
1171       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1172       gl_FragColor = texColor * alpha * maskColor.w * aa;
1173     }
1174   );  // NOLINT(whitespace/parens)
1175 }
1176 
1177 FragmentShaderRGBATexAlphaColorMatrixAA::
FragmentShaderRGBATexAlphaColorMatrixAA()1178     FragmentShaderRGBATexAlphaColorMatrixAA()
1179         : sampler_location_(-1),
1180           alpha_location_(-1),
1181           color_matrix_location_(-1),
1182           color_offset_location_(-1) {}
1183 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1184 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(
1185       GLES2Interface* context,
1186       unsigned program,
1187       int* base_uniform_index) {
1188   static const char* uniforms[] = {
1189     "s_texture",
1190     "alpha",
1191     "colorMatrix",
1192     "colorOffset",
1193   };
1194   int locations[arraysize(uniforms)];
1195 
1196   GetProgramUniformLocations(context,
1197                              program,
1198                              arraysize(uniforms),
1199                              uniforms,
1200                              locations,
1201                              base_uniform_index);
1202   sampler_location_ = locations[0];
1203   alpha_location_ = locations[1];
1204   color_matrix_location_ = locations[2];
1205   color_offset_location_ = locations[3];
1206 }
1207 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1208 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
1209     TexCoordPrecision precision, SamplerType sampler) const {
1210   return FRAGMENT_SHADER(
1211     precision mediump float;
1212     uniform SamplerType s_texture;
1213     uniform float alpha;
1214     uniform mat4 colorMatrix;
1215     uniform vec4 colorOffset;
1216     varying TexCoordPrecision vec2 v_texCoord;
1217     varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
1218 
1219     void main() {
1220       vec4 texColor = TextureLookup(s_texture, v_texCoord);
1221       float nonZeroAlpha = max(texColor.a, 0.00001);
1222       texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1223       texColor = colorMatrix * texColor + colorOffset;
1224       texColor.rgb *= texColor.a;
1225       texColor = clamp(texColor, 0.0, 1.0);
1226       vec4 d4 = min(edge_dist[0], edge_dist[1]);
1227       vec2 d2 = min(d4.xz, d4.yw);
1228       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1229       gl_FragColor = texColor * alpha * aa;
1230     }
1231   );  // NOLINT(whitespace/parens)
1232 }
1233 
1234 FragmentShaderRGBATexAlphaMaskColorMatrix::
FragmentShaderRGBATexAlphaMaskColorMatrix()1235     FragmentShaderRGBATexAlphaMaskColorMatrix()
1236         : sampler_location_(-1),
1237           mask_sampler_location_(-1),
1238           alpha_location_(-1),
1239           mask_tex_coord_scale_location_(-1) {}
1240 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1241 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(
1242     GLES2Interface* context,
1243     unsigned program,
1244     int* base_uniform_index) {
1245   static const char* uniforms[] = {
1246     "s_texture",
1247     "s_mask",
1248     "alpha",
1249     "maskTexCoordScale",
1250     "maskTexCoordOffset",
1251     "colorMatrix",
1252     "colorOffset",
1253   };
1254   int locations[arraysize(uniforms)];
1255 
1256   GetProgramUniformLocations(context,
1257                              program,
1258                              arraysize(uniforms),
1259                              uniforms,
1260                              locations,
1261                              base_uniform_index);
1262   sampler_location_ = locations[0];
1263   mask_sampler_location_ = locations[1];
1264   alpha_location_ = locations[2];
1265   mask_tex_coord_scale_location_ = locations[3];
1266   mask_tex_coord_offset_location_ = locations[4];
1267   color_matrix_location_ = locations[5];
1268   color_offset_location_ = locations[6];
1269 }
1270 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1271 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
1272     TexCoordPrecision precision, SamplerType sampler) const {
1273   return FRAGMENT_SHADER(
1274     precision mediump float;
1275     varying TexCoordPrecision vec2 v_texCoord;
1276     uniform SamplerType s_texture;
1277     uniform SamplerType s_mask;
1278     uniform vec2 maskTexCoordScale;
1279     uniform vec2 maskTexCoordOffset;
1280     uniform mat4 colorMatrix;
1281     uniform vec4 colorOffset;
1282     uniform float alpha;
1283     void main() {
1284       vec4 texColor = TextureLookup(s_texture, v_texCoord);
1285       float nonZeroAlpha = max(texColor.a, 0.00001);
1286       texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1287       texColor = colorMatrix * texColor + colorOffset;
1288       texColor.rgb *= texColor.a;
1289       texColor = clamp(texColor, 0.0, 1.0);
1290       TexCoordPrecision vec2 maskTexCoord =
1291           vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1292                maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1293       vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1294       gl_FragColor = texColor * alpha * maskColor.w;
1295     }
1296   );  // NOLINT(whitespace/parens)
1297 }
1298 
FragmentShaderYUVVideo()1299 FragmentShaderYUVVideo::FragmentShaderYUVVideo()
1300     : y_texture_location_(-1),
1301       u_texture_location_(-1),
1302       v_texture_location_(-1),
1303       alpha_location_(-1),
1304       yuv_matrix_location_(-1),
1305       yuv_adj_location_(-1) {}
1306 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1307 void FragmentShaderYUVVideo::Init(GLES2Interface* context,
1308                                   unsigned program,
1309                                   int* base_uniform_index) {
1310   static const char* uniforms[] = {
1311     "y_texture",
1312     "u_texture",
1313     "v_texture",
1314     "alpha",
1315     "yuv_matrix",
1316     "yuv_adj",
1317   };
1318   int locations[arraysize(uniforms)];
1319 
1320   GetProgramUniformLocations(context,
1321                              program,
1322                              arraysize(uniforms),
1323                              uniforms,
1324                              locations,
1325                              base_uniform_index);
1326   y_texture_location_ = locations[0];
1327   u_texture_location_ = locations[1];
1328   v_texture_location_ = locations[2];
1329   alpha_location_ = locations[3];
1330   yuv_matrix_location_ = locations[4];
1331   yuv_adj_location_ = locations[5];
1332 }
1333 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1334 std::string FragmentShaderYUVVideo::GetShaderString(
1335     TexCoordPrecision precision, SamplerType sampler) const {
1336   return FRAGMENT_SHADER(
1337     precision mediump float;
1338     precision mediump int;
1339     varying TexCoordPrecision vec2 v_texCoord;
1340     uniform SamplerType y_texture;
1341     uniform SamplerType u_texture;
1342     uniform SamplerType v_texture;
1343     uniform float alpha;
1344     uniform vec3 yuv_adj;
1345     uniform mat3 yuv_matrix;
1346     void main() {
1347       float y_raw = TextureLookup(y_texture, v_texCoord).x;
1348       float u_unsigned = TextureLookup(u_texture, v_texCoord).x;
1349       float v_unsigned = TextureLookup(v_texture, v_texCoord).x;
1350       vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
1351       vec3 rgb = yuv_matrix * yuv;
1352       gl_FragColor = vec4(rgb, 1.0) * alpha;
1353     }
1354   );  // NOLINT(whitespace/parens)
1355 }
1356 
FragmentShaderYUVAVideo()1357 FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
1358     : y_texture_location_(-1),
1359       u_texture_location_(-1),
1360       v_texture_location_(-1),
1361       a_texture_location_(-1),
1362       alpha_location_(-1),
1363       yuv_matrix_location_(-1),
1364       yuv_adj_location_(-1) {
1365 }
1366 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1367 void FragmentShaderYUVAVideo::Init(GLES2Interface* context,
1368                                    unsigned program,
1369                                    int* base_uniform_index) {
1370   static const char* uniforms[] = {
1371       "y_texture",
1372       "u_texture",
1373       "v_texture",
1374       "a_texture",
1375       "alpha",
1376       "cc_matrix",
1377       "yuv_adj",
1378   };
1379   int locations[arraysize(uniforms)];
1380 
1381   GetProgramUniformLocations(context,
1382                              program,
1383                              arraysize(uniforms),
1384                              uniforms,
1385                              locations,
1386                              base_uniform_index);
1387   y_texture_location_ = locations[0];
1388   u_texture_location_ = locations[1];
1389   v_texture_location_ = locations[2];
1390   a_texture_location_ = locations[3];
1391   alpha_location_ = locations[4];
1392   yuv_matrix_location_ = locations[5];
1393   yuv_adj_location_ = locations[6];
1394 }
1395 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1396 std::string FragmentShaderYUVAVideo::GetShaderString(
1397     TexCoordPrecision precision, SamplerType sampler) const {
1398   return FRAGMENT_SHADER(
1399     precision mediump float;
1400     precision mediump int;
1401     varying TexCoordPrecision vec2 v_texCoord;
1402     uniform SamplerType y_texture;
1403     uniform SamplerType u_texture;
1404     uniform SamplerType v_texture;
1405     uniform SamplerType a_texture;
1406     uniform float alpha;
1407     uniform vec3 yuv_adj;
1408     uniform mat3 yuv_matrix;
1409     void main() {
1410       float y_raw = TextureLookup(y_texture, v_texCoord).x;
1411       float u_unsigned = TextureLookup(u_texture, v_texCoord).x;
1412       float v_unsigned = TextureLookup(v_texture, v_texCoord).x;
1413       float a_raw = TextureLookup(a_texture, v_texCoord).x;
1414       vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
1415       vec3 rgb = yuv_matrix * yuv;
1416       gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);
1417     }
1418   );  // NOLINT(whitespace/parens)
1419 }
1420 
FragmentShaderColor()1421 FragmentShaderColor::FragmentShaderColor()
1422     : color_location_(-1) {}
1423 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1424 void FragmentShaderColor::Init(GLES2Interface* context,
1425                                unsigned program,
1426                                int* base_uniform_index) {
1427   static const char* uniforms[] = {
1428     "color",
1429   };
1430   int locations[arraysize(uniforms)];
1431 
1432   GetProgramUniformLocations(context,
1433                              program,
1434                              arraysize(uniforms),
1435                              uniforms,
1436                              locations,
1437                              base_uniform_index);
1438   color_location_ = locations[0];
1439 }
1440 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1441 std::string FragmentShaderColor::GetShaderString(
1442     TexCoordPrecision precision, SamplerType sampler) const {
1443   return FRAGMENT_SHADER(
1444     precision mediump float;
1445     uniform vec4 color;
1446     void main() {
1447       gl_FragColor = color;
1448     }
1449   );  // NOLINT(whitespace/parens)
1450 }
1451 
FragmentShaderColorAA()1452 FragmentShaderColorAA::FragmentShaderColorAA()
1453     : color_location_(-1) {}
1454 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1455 void FragmentShaderColorAA::Init(GLES2Interface* context,
1456                                  unsigned program,
1457                                  int* base_uniform_index) {
1458   static const char* uniforms[] = {
1459     "color",
1460   };
1461   int locations[arraysize(uniforms)];
1462 
1463   GetProgramUniformLocations(context,
1464                              program,
1465                              arraysize(uniforms),
1466                              uniforms,
1467                              locations,
1468                              base_uniform_index);
1469   color_location_ = locations[0];
1470 }
1471 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1472 std::string FragmentShaderColorAA::GetShaderString(
1473     TexCoordPrecision precision, SamplerType sampler) const {
1474   return FRAGMENT_SHADER(
1475     precision mediump float;
1476     uniform vec4 color;
1477     varying vec4 edge_dist[2];  // 8 edge distances.
1478 
1479     void main() {
1480       vec4 d4 = min(edge_dist[0], edge_dist[1]);
1481       vec2 d2 = min(d4.xz, d4.yw);
1482       float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1483       gl_FragColor = color * aa;
1484     }
1485   );  // NOLINT(whitespace/parens)
1486 }
1487 
FragmentShaderCheckerboard()1488 FragmentShaderCheckerboard::FragmentShaderCheckerboard()
1489     : alpha_location_(-1),
1490       tex_transform_location_(-1),
1491       frequency_location_(-1) {}
1492 
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1493 void FragmentShaderCheckerboard::Init(GLES2Interface* context,
1494                                       unsigned program,
1495                                       int* base_uniform_index) {
1496   static const char* uniforms[] = {
1497     "alpha",
1498     "texTransform",
1499     "frequency",
1500     "color",
1501   };
1502   int locations[arraysize(uniforms)];
1503 
1504   GetProgramUniformLocations(context,
1505                              program,
1506                              arraysize(uniforms),
1507                              uniforms,
1508                              locations,
1509                              base_uniform_index);
1510   alpha_location_ = locations[0];
1511   tex_transform_location_ = locations[1];
1512   frequency_location_ = locations[2];
1513   color_location_ = locations[3];
1514 }
1515 
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1516 std::string FragmentShaderCheckerboard::GetShaderString(
1517     TexCoordPrecision precision, SamplerType sampler) const {
1518   // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
1519   // by Munshi, Ginsburg, Shreiner.
1520   return FRAGMENT_SHADER(
1521     precision mediump float;
1522     precision mediump int;
1523     varying vec2 v_texCoord;
1524     uniform float alpha;
1525     uniform float frequency;
1526     uniform vec4 texTransform;
1527     uniform vec4 color;
1528     void main() {
1529       vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0);
1530       vec4 color2 = color;
1531       vec2 texCoord =
1532           clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy;
1533       vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0);
1534       float picker = abs(coord.x - coord.y);  // NOLINT
1535       gl_FragColor = mix(color1, color2, picker) * alpha;
1536     }
1537   );  // NOLINT(whitespace/parens)
1538 }
1539 
1540 }  // namespace cc
1541