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,gfx::Point max_coordinate)137 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
138 int *highp_threshold_cache,
139 int highp_threshold_min,
140 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,gfx::Size max_size)146 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
147 int *highp_threshold_cache,
148 int highp_threshold_min,
149 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
VertexShaderPosTexYUVStretch()188 VertexShaderPosTexYUVStretch::VertexShaderPosTexYUVStretch()
189 : matrix_location_(-1),
190 tex_scale_location_(-1) {}
191
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)192 void VertexShaderPosTexYUVStretch::Init(GLES2Interface* context,
193 unsigned program,
194 int* base_uniform_index) {
195 static const char* uniforms[] = {
196 "matrix",
197 "texScale",
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 }
210
GetShaderString() const211 std::string VertexShaderPosTexYUVStretch::GetShaderString() const {
212 return VERTEX_SHADER(
213 precision mediump float;
214 attribute vec4 a_position;
215 attribute TexCoordPrecision vec2 a_texCoord;
216 uniform mat4 matrix;
217 varying TexCoordPrecision vec2 v_texCoord;
218 uniform TexCoordPrecision vec2 texScale;
219 void main() {
220 gl_Position = matrix * a_position;
221 v_texCoord = a_texCoord * texScale;
222 }
223 ); // NOLINT(whitespace/parens)
224 }
225
VertexShaderPos()226 VertexShaderPos::VertexShaderPos()
227 : matrix_location_(-1) {}
228
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)229 void VertexShaderPos::Init(GLES2Interface* context,
230 unsigned program,
231 int* base_uniform_index) {
232 static const char* uniforms[] = {
233 "matrix",
234 };
235 int locations[arraysize(uniforms)];
236
237 GetProgramUniformLocations(context,
238 program,
239 arraysize(uniforms),
240 uniforms,
241 locations,
242 base_uniform_index);
243 matrix_location_ = locations[0];
244 }
245
GetShaderString() const246 std::string VertexShaderPos::GetShaderString() const {
247 return VERTEX_SHADER(
248 attribute vec4 a_position;
249 uniform mat4 matrix;
250 void main() {
251 gl_Position = matrix * a_position;
252 }
253 ); // NOLINT(whitespace/parens)
254 }
255
VertexShaderPosTexTransform()256 VertexShaderPosTexTransform::VertexShaderPosTexTransform()
257 : matrix_location_(-1),
258 tex_transform_location_(-1),
259 vertex_opacity_location_(-1) {}
260
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)261 void VertexShaderPosTexTransform::Init(GLES2Interface* context,
262 unsigned program,
263 int* base_uniform_index) {
264 static const char* uniforms[] = {
265 "matrix",
266 "texTransform",
267 "opacity",
268 };
269 int locations[arraysize(uniforms)];
270
271 GetProgramUniformLocations(context,
272 program,
273 arraysize(uniforms),
274 uniforms,
275 locations,
276 base_uniform_index);
277 matrix_location_ = locations[0];
278 tex_transform_location_ = locations[1];
279 vertex_opacity_location_ = locations[2];
280 }
281
GetShaderString() const282 std::string VertexShaderPosTexTransform::GetShaderString() const {
283 return VERTEX_SHADER(
284 attribute vec4 a_position;
285 attribute TexCoordPrecision vec2 a_texCoord;
286 attribute float a_index;
287 uniform mat4 matrix[8];
288 uniform TexCoordPrecision vec4 texTransform[8];
289 uniform float opacity[32];
290 varying TexCoordPrecision vec2 v_texCoord;
291 varying float v_alpha;
292 void main() {
293 int quad_index = int(a_index * 0.25); // NOLINT
294 gl_Position = matrix[quad_index] * a_position;
295 TexCoordPrecision vec4 texTrans = texTransform[quad_index];
296 v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
297 v_alpha = opacity[int(a_index)]; // NOLINT
298 }
299 ); // NOLINT(whitespace/parens)
300 }
301
GetShaderString() const302 std::string VertexShaderPosTexIdentity::GetShaderString() const {
303 return VERTEX_SHADER(
304 attribute vec4 a_position;
305 varying TexCoordPrecision vec2 v_texCoord;
306 void main() {
307 gl_Position = a_position;
308 v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
309 }
310 ); // NOLINT(whitespace/parens)
311 }
312
VertexShaderQuad()313 VertexShaderQuad::VertexShaderQuad()
314 : matrix_location_(-1),
315 quad_location_(-1) {}
316
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)317 void VertexShaderQuad::Init(GLES2Interface* context,
318 unsigned program,
319 int* base_uniform_index) {
320 static const char* uniforms[] = {
321 "matrix",
322 "quad",
323 };
324 int locations[arraysize(uniforms)];
325
326 GetProgramUniformLocations(context,
327 program,
328 arraysize(uniforms),
329 uniforms,
330 locations,
331 base_uniform_index);
332 matrix_location_ = locations[0];
333 quad_location_ = locations[1];
334 }
335
GetShaderString() const336 std::string VertexShaderQuad::GetShaderString() const {
337 #if defined(OS_ANDROID)
338 // TODO(epenner): Find the cause of this 'quad' uniform
339 // being missing if we don't add dummy variables.
340 // http://crbug.com/240602
341 return VERTEX_SHADER(
342 attribute TexCoordPrecision vec4 a_position;
343 attribute float a_index;
344 uniform mat4 matrix;
345 uniform TexCoordPrecision vec2 quad[4];
346 uniform TexCoordPrecision vec2 dummy_uniform;
347 varying TexCoordPrecision vec2 dummy_varying;
348 void main() {
349 vec2 pos = quad[int(a_index)]; // NOLINT
350 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
351 dummy_varying = dummy_uniform;
352 }
353 ); // NOLINT(whitespace/parens)
354 #else
355 return VERTEX_SHADER(
356 attribute TexCoordPrecision vec4 a_position;
357 attribute float a_index;
358 uniform mat4 matrix;
359 uniform TexCoordPrecision vec2 quad[4];
360 void main() {
361 vec2 pos = quad[int(a_index)]; // NOLINT
362 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
363 }
364 ); // NOLINT(whitespace/parens)
365 #endif
366 }
367
VertexShaderQuadAA()368 VertexShaderQuadAA::VertexShaderQuadAA()
369 : matrix_location_(-1),
370 viewport_location_(-1),
371 quad_location_(-1),
372 edge_location_(-1) {}
373
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)374 void VertexShaderQuadAA::Init(GLES2Interface* context,
375 unsigned program,
376 int* base_uniform_index) {
377 static const char* uniforms[] = {
378 "matrix",
379 "viewport",
380 "quad",
381 "edge",
382 };
383 int locations[arraysize(uniforms)];
384
385 GetProgramUniformLocations(context,
386 program,
387 arraysize(uniforms),
388 uniforms,
389 locations,
390 base_uniform_index);
391 matrix_location_ = locations[0];
392 viewport_location_ = locations[1];
393 quad_location_ = locations[2];
394 edge_location_ = locations[3];
395 }
396
GetShaderString() const397 std::string VertexShaderQuadAA::GetShaderString() const {
398 return VERTEX_SHADER(
399 attribute TexCoordPrecision vec4 a_position;
400 attribute float a_index;
401 uniform mat4 matrix;
402 uniform vec4 viewport;
403 uniform TexCoordPrecision vec2 quad[4];
404 uniform TexCoordPrecision vec3 edge[8];
405 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
406
407 void main() {
408 vec2 pos = quad[int(a_index)]; // NOLINT
409 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
410 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
411 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
412 edge_dist[0] = vec4(dot(edge[0], screen_pos),
413 dot(edge[1], screen_pos),
414 dot(edge[2], screen_pos),
415 dot(edge[3], screen_pos)) * gl_Position.w;
416 edge_dist[1] = vec4(dot(edge[4], screen_pos),
417 dot(edge[5], screen_pos),
418 dot(edge[6], screen_pos),
419 dot(edge[7], screen_pos)) * gl_Position.w;
420 }
421 ); // NOLINT(whitespace/parens)
422 }
423
VertexShaderQuadTexTransformAA()424 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
425 : matrix_location_(-1),
426 viewport_location_(-1),
427 quad_location_(-1),
428 edge_location_(-1),
429 tex_transform_location_(-1) {}
430
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)431 void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context,
432 unsigned program,
433 int* base_uniform_index) {
434 static const char* uniforms[] = {
435 "matrix",
436 "viewport",
437 "quad",
438 "edge",
439 "texTrans",
440 };
441 int locations[arraysize(uniforms)];
442
443 GetProgramUniformLocations(context,
444 program,
445 arraysize(uniforms),
446 uniforms,
447 locations,
448 base_uniform_index);
449 matrix_location_ = locations[0];
450 viewport_location_ = locations[1];
451 quad_location_ = locations[2];
452 edge_location_ = locations[3];
453 tex_transform_location_ = locations[4];
454 }
455
GetShaderString() const456 std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
457 return VERTEX_SHADER(
458 attribute TexCoordPrecision vec4 a_position;
459 attribute float a_index;
460 uniform mat4 matrix;
461 uniform vec4 viewport;
462 uniform TexCoordPrecision vec2 quad[4];
463 uniform TexCoordPrecision vec3 edge[8];
464 uniform TexCoordPrecision vec4 texTrans;
465 varying TexCoordPrecision vec2 v_texCoord;
466 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
467
468 void main() {
469 vec2 pos = quad[int(a_index)]; // NOLINT
470 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
471 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
472 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
473 edge_dist[0] = vec4(dot(edge[0], screen_pos),
474 dot(edge[1], screen_pos),
475 dot(edge[2], screen_pos),
476 dot(edge[3], screen_pos)) * gl_Position.w;
477 edge_dist[1] = vec4(dot(edge[4], screen_pos),
478 dot(edge[5], screen_pos),
479 dot(edge[6], screen_pos),
480 dot(edge[7], screen_pos)) * gl_Position.w;
481 v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy;
482 }
483 ); // NOLINT(whitespace/parens)
484 }
485
VertexShaderTile()486 VertexShaderTile::VertexShaderTile()
487 : matrix_location_(-1),
488 quad_location_(-1),
489 vertex_tex_transform_location_(-1) {}
490
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)491 void VertexShaderTile::Init(GLES2Interface* context,
492 unsigned program,
493 int* base_uniform_index) {
494 static const char* uniforms[] = {
495 "matrix",
496 "quad",
497 "vertexTexTransform",
498 };
499 int locations[arraysize(uniforms)];
500
501 GetProgramUniformLocations(context,
502 program,
503 arraysize(uniforms),
504 uniforms,
505 locations,
506 base_uniform_index);
507 matrix_location_ = locations[0];
508 quad_location_ = locations[1];
509 vertex_tex_transform_location_ = locations[2];
510 }
511
GetShaderString() const512 std::string VertexShaderTile::GetShaderString() const {
513 return VERTEX_SHADER(
514 attribute TexCoordPrecision vec4 a_position;
515 attribute float a_index;
516 uniform mat4 matrix;
517 uniform TexCoordPrecision vec2 quad[4];
518 uniform TexCoordPrecision vec4 vertexTexTransform;
519 varying TexCoordPrecision vec2 v_texCoord;
520 void main() {
521 vec2 pos = quad[int(a_index)]; // NOLINT
522 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
523 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
524 }
525 ); // NOLINT(whitespace/parens)
526 }
527
VertexShaderTileAA()528 VertexShaderTileAA::VertexShaderTileAA()
529 : matrix_location_(-1),
530 viewport_location_(-1),
531 quad_location_(-1),
532 edge_location_(-1),
533 vertex_tex_transform_location_(-1) {}
534
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)535 void VertexShaderTileAA::Init(GLES2Interface* context,
536 unsigned program,
537 int* base_uniform_index) {
538 static const char* uniforms[] = {
539 "matrix",
540 "viewport",
541 "quad",
542 "edge",
543 "vertexTexTransform",
544 };
545 int locations[arraysize(uniforms)];
546
547 GetProgramUniformLocations(context,
548 program,
549 arraysize(uniforms),
550 uniforms,
551 locations,
552 base_uniform_index);
553 matrix_location_ = locations[0];
554 viewport_location_ = locations[1];
555 quad_location_ = locations[2];
556 edge_location_ = locations[3];
557 vertex_tex_transform_location_ = locations[4];
558 }
559
GetShaderString() const560 std::string VertexShaderTileAA::GetShaderString() const {
561 return VERTEX_SHADER(
562 attribute TexCoordPrecision vec4 a_position;
563 attribute float a_index;
564 uniform mat4 matrix;
565 uniform vec4 viewport;
566 uniform TexCoordPrecision vec2 quad[4];
567 uniform TexCoordPrecision vec3 edge[8];
568 uniform TexCoordPrecision vec4 vertexTexTransform;
569 varying TexCoordPrecision vec2 v_texCoord;
570 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
571
572 void main() {
573 vec2 pos = quad[int(a_index)]; // NOLINT
574 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
575 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
576 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
577 edge_dist[0] = vec4(dot(edge[0], screen_pos),
578 dot(edge[1], screen_pos),
579 dot(edge[2], screen_pos),
580 dot(edge[3], screen_pos)) * gl_Position.w;
581 edge_dist[1] = vec4(dot(edge[4], screen_pos),
582 dot(edge[5], screen_pos),
583 dot(edge[6], screen_pos),
584 dot(edge[7], screen_pos)) * gl_Position.w;
585 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
586 }
587 ); // NOLINT(whitespace/parens)
588 }
589
VertexShaderVideoTransform()590 VertexShaderVideoTransform::VertexShaderVideoTransform()
591 : matrix_location_(-1),
592 tex_matrix_location_(-1) {}
593
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)594 void VertexShaderVideoTransform::Init(GLES2Interface* context,
595 unsigned program,
596 int* base_uniform_index) {
597 static const char* uniforms[] = {
598 "matrix",
599 "texMatrix",
600 };
601 int locations[arraysize(uniforms)];
602
603 GetProgramUniformLocations(context,
604 program,
605 arraysize(uniforms),
606 uniforms,
607 locations,
608 base_uniform_index);
609 matrix_location_ = locations[0];
610 tex_matrix_location_ = locations[1];
611 }
612
GetShaderString() const613 std::string VertexShaderVideoTransform::GetShaderString() const {
614 return VERTEX_SHADER(
615 attribute vec4 a_position;
616 attribute TexCoordPrecision vec2 a_texCoord;
617 uniform mat4 matrix;
618 uniform TexCoordPrecision mat4 texMatrix;
619 varying TexCoordPrecision vec2 v_texCoord;
620 void main() {
621 gl_Position = matrix * a_position;
622 v_texCoord =
623 vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
624 }
625 ); // NOLINT(whitespace/parens)
626 }
627
FragmentTexAlphaBinding()628 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
629 : sampler_location_(-1),
630 alpha_location_(-1) {}
631
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)632 void FragmentTexAlphaBinding::Init(GLES2Interface* context,
633 unsigned program,
634 int* base_uniform_index) {
635 static const char* uniforms[] = {
636 "s_texture",
637 "alpha",
638 };
639 int locations[arraysize(uniforms)];
640
641 GetProgramUniformLocations(context,
642 program,
643 arraysize(uniforms),
644 uniforms,
645 locations,
646 base_uniform_index);
647 sampler_location_ = locations[0];
648 alpha_location_ = locations[1];
649 }
650
FragmentTexColorMatrixAlphaBinding()651 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
652 : sampler_location_(-1),
653 alpha_location_(-1),
654 color_matrix_location_(-1),
655 color_offset_location_(-1) {}
656
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)657 void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface* context,
658 unsigned program,
659 int* base_uniform_index) {
660 static const char* uniforms[] = {
661 "s_texture",
662 "alpha",
663 "colorMatrix",
664 "colorOffset",
665 };
666 int locations[arraysize(uniforms)];
667
668 GetProgramUniformLocations(context,
669 program,
670 arraysize(uniforms),
671 uniforms,
672 locations,
673 base_uniform_index);
674 sampler_location_ = locations[0];
675 alpha_location_ = locations[1];
676 color_matrix_location_ = locations[2];
677 color_offset_location_ = locations[3];
678 }
679
FragmentTexOpaqueBinding()680 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
681 : sampler_location_(-1) {}
682
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)683 void FragmentTexOpaqueBinding::Init(GLES2Interface* context,
684 unsigned program,
685 int* base_uniform_index) {
686 static const char* uniforms[] = {
687 "s_texture",
688 };
689 int locations[arraysize(uniforms)];
690
691 GetProgramUniformLocations(context,
692 program,
693 arraysize(uniforms),
694 uniforms,
695 locations,
696 base_uniform_index);
697 sampler_location_ = locations[0];
698 }
699
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const700 std::string FragmentShaderRGBATexAlpha::GetShaderString(
701 TexCoordPrecision precision, SamplerType sampler) const {
702 return FRAGMENT_SHADER(
703 precision mediump float;
704 varying TexCoordPrecision vec2 v_texCoord;
705 uniform SamplerType s_texture;
706 uniform float alpha;
707 void main() {
708 vec4 texColor = TextureLookup(s_texture, v_texCoord);
709 gl_FragColor = texColor * alpha;
710 }
711 ); // NOLINT(whitespace/parens)
712 }
713
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const714 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
715 TexCoordPrecision precision, SamplerType sampler) const {
716 return FRAGMENT_SHADER(
717 precision mediump float;
718 varying TexCoordPrecision vec2 v_texCoord;
719 uniform SamplerType s_texture;
720 uniform float alpha;
721 uniform mat4 colorMatrix;
722 uniform vec4 colorOffset;
723 void main() {
724 vec4 texColor = TextureLookup(s_texture, v_texCoord);
725 float nonZeroAlpha = max(texColor.a, 0.00001);
726 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
727 texColor = colorMatrix * texColor + colorOffset;
728 texColor.rgb *= texColor.a;
729 texColor = clamp(texColor, 0.0, 1.0);
730 gl_FragColor = texColor * alpha;
731 }
732 ); // NOLINT(whitespace/parens)
733 }
734
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const735 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
736 TexCoordPrecision precision, SamplerType sampler) const {
737 return FRAGMENT_SHADER(
738 precision mediump float;
739 varying TexCoordPrecision vec2 v_texCoord;
740 varying float v_alpha;
741 uniform SamplerType s_texture;
742 void main() {
743 vec4 texColor = TextureLookup(s_texture, v_texCoord);
744 gl_FragColor = texColor * v_alpha;
745 }
746 ); // NOLINT(whitespace/parens)
747 }
748
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const749 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
750 TexCoordPrecision precision, SamplerType sampler) const {
751 return FRAGMENT_SHADER(
752 precision mediump float;
753 varying TexCoordPrecision vec2 v_texCoord;
754 varying float v_alpha;
755 uniform SamplerType s_texture;
756 void main() {
757 vec4 texColor = TextureLookup(s_texture, v_texCoord);
758 texColor.rgb *= texColor.a;
759 gl_FragColor = texColor * v_alpha;
760 }
761 ); // NOLINT(whitespace/parens)
762 }
763
FragmentTexBackgroundBinding()764 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
765 : background_color_location_(-1),
766 sampler_location_(-1) {
767 }
768
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)769 void FragmentTexBackgroundBinding::Init(GLES2Interface* context,
770 unsigned program,
771 int* base_uniform_index) {
772 static const char* uniforms[] = {
773 "s_texture",
774 "background_color",
775 };
776 int locations[arraysize(uniforms)];
777
778 GetProgramUniformLocations(context,
779 program,
780 arraysize(uniforms),
781 uniforms,
782 locations,
783 base_uniform_index);
784
785 sampler_location_ = locations[0];
786 DCHECK_NE(sampler_location_, -1);
787
788 background_color_location_ = locations[1];
789 DCHECK_NE(background_color_location_, -1);
790 }
791
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const792 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
793 TexCoordPrecision precision, SamplerType sampler) const {
794 return FRAGMENT_SHADER(
795 precision mediump float;
796 varying TexCoordPrecision vec2 v_texCoord;
797 varying float v_alpha;
798 uniform vec4 background_color;
799 uniform SamplerType s_texture;
800 void main() {
801 vec4 texColor = TextureLookup(s_texture, v_texCoord);
802 texColor += background_color * (1.0 - texColor.a);
803 gl_FragColor = texColor * v_alpha;
804 }
805 ); // NOLINT(whitespace/parens)
806 }
807
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const808 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
809 TexCoordPrecision precision, SamplerType sampler) const {
810 return FRAGMENT_SHADER(
811 precision mediump float;
812 varying TexCoordPrecision vec2 v_texCoord;
813 varying float v_alpha;
814 uniform vec4 background_color;
815 uniform SamplerType s_texture;
816 void main() {
817 vec4 texColor = TextureLookup(s_texture, v_texCoord);
818 texColor.rgb *= texColor.a;
819 texColor += background_color * (1.0 - texColor.a);
820 gl_FragColor = texColor * v_alpha;
821 }
822 ); // NOLINT(whitespace/parens)
823 }
824
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const825 std::string FragmentShaderRGBATexOpaque::GetShaderString(
826 TexCoordPrecision precision, SamplerType sampler) const {
827 return FRAGMENT_SHADER(
828 precision mediump float;
829 varying TexCoordPrecision vec2 v_texCoord;
830 uniform SamplerType s_texture;
831 void main() {
832 vec4 texColor = TextureLookup(s_texture, v_texCoord);
833 gl_FragColor = vec4(texColor.rgb, 1.0);
834 }
835 ); // NOLINT(whitespace/parens)
836 }
837
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const838 std::string FragmentShaderRGBATex::GetShaderString(
839 TexCoordPrecision precision, SamplerType sampler) const {
840 return FRAGMENT_SHADER(
841 precision mediump float;
842 varying TexCoordPrecision vec2 v_texCoord;
843 uniform SamplerType s_texture;
844 void main() {
845 gl_FragColor = TextureLookup(s_texture, v_texCoord);
846 }
847 ); // NOLINT(whitespace/parens)
848 }
849
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const850 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
851 TexCoordPrecision precision, SamplerType sampler) const {
852 return FRAGMENT_SHADER(
853 precision mediump float;
854 varying TexCoordPrecision vec2 v_texCoord;
855 uniform SamplerType s_texture;
856 uniform float alpha;
857 void main() {
858 vec4 texColor = TextureLookup(s_texture, v_texCoord);
859 gl_FragColor =
860 vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
861 }
862 ); // NOLINT(whitespace/parens)
863 }
864
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const865 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
866 TexCoordPrecision precision, SamplerType sampler) const {
867 return FRAGMENT_SHADER(
868 precision mediump float;
869 varying TexCoordPrecision vec2 v_texCoord;
870 uniform SamplerType s_texture;
871 void main() {
872 vec4 texColor = TextureLookup(s_texture, v_texCoord);
873 gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
874 }
875 ); // NOLINT(whitespace/parens)
876 }
877
FragmentShaderRGBATexAlphaAA()878 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
879 : sampler_location_(-1),
880 alpha_location_(-1) {}
881
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)882 void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface* context,
883 unsigned program,
884 int* base_uniform_index) {
885 static const char* uniforms[] = {
886 "s_texture",
887 "alpha",
888 };
889 int locations[arraysize(uniforms)];
890
891 GetProgramUniformLocations(context,
892 program,
893 arraysize(uniforms),
894 uniforms,
895 locations,
896 base_uniform_index);
897 sampler_location_ = locations[0];
898 alpha_location_ = locations[1];
899 }
900
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const901 std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
902 TexCoordPrecision precision, SamplerType sampler) const {
903 return FRAGMENT_SHADER(
904 precision mediump float;
905 uniform SamplerType s_texture;
906 uniform float alpha;
907 varying TexCoordPrecision vec2 v_texCoord;
908 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
909
910 void main() {
911 vec4 texColor = TextureLookup(s_texture, v_texCoord);
912 vec4 d4 = min(edge_dist[0], edge_dist[1]);
913 vec2 d2 = min(d4.xz, d4.yw);
914 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
915 gl_FragColor = texColor * alpha * aa;
916 }
917 ); // NOLINT(whitespace/parens)
918 }
919
FragmentTexClampAlphaAABinding()920 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
921 : sampler_location_(-1),
922 alpha_location_(-1),
923 fragment_tex_transform_location_(-1) {}
924
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)925 void FragmentTexClampAlphaAABinding::Init(GLES2Interface* context,
926 unsigned program,
927 int* base_uniform_index) {
928 static const char* uniforms[] = {
929 "s_texture",
930 "alpha",
931 "fragmentTexTransform",
932 };
933 int locations[arraysize(uniforms)];
934
935 GetProgramUniformLocations(context,
936 program,
937 arraysize(uniforms),
938 uniforms,
939 locations,
940 base_uniform_index);
941 sampler_location_ = locations[0];
942 alpha_location_ = locations[1];
943 fragment_tex_transform_location_ = locations[2];
944 }
945
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const946 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
947 TexCoordPrecision precision, SamplerType sampler) const {
948 return FRAGMENT_SHADER(
949 precision mediump float;
950 uniform SamplerType s_texture;
951 uniform float alpha;
952 uniform TexCoordPrecision vec4 fragmentTexTransform;
953 varying TexCoordPrecision vec2 v_texCoord;
954 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
955
956 void main() {
957 TexCoordPrecision vec2 texCoord =
958 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
959 fragmentTexTransform.xy;
960 vec4 texColor = TextureLookup(s_texture, texCoord);
961 vec4 d4 = min(edge_dist[0], edge_dist[1]);
962 vec2 d2 = min(d4.xz, d4.yw);
963 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
964 gl_FragColor = texColor * alpha * aa;
965 }
966 ); // NOLINT(whitespace/parens)
967 }
968
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const969 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
970 TexCoordPrecision precision, SamplerType sampler) const {
971 return FRAGMENT_SHADER(
972 precision mediump float;
973 uniform SamplerType s_texture;
974 uniform float alpha;
975 uniform TexCoordPrecision vec4 fragmentTexTransform;
976 varying TexCoordPrecision vec2 v_texCoord;
977 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
978
979 void main() {
980 TexCoordPrecision vec2 texCoord =
981 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
982 fragmentTexTransform.xy;
983 vec4 texColor = TextureLookup(s_texture, texCoord);
984 vec4 d4 = min(edge_dist[0], edge_dist[1]);
985 vec2 d2 = min(d4.xz, d4.yw);
986 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
987 gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) *
988 alpha * aa;
989 }
990 ); // NOLINT(whitespace/parens)
991 }
992
FragmentShaderRGBATexAlphaMask()993 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
994 : sampler_location_(-1),
995 mask_sampler_location_(-1),
996 alpha_location_(-1),
997 mask_tex_coord_scale_location_(-1) {}
998
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)999 void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface* context,
1000 unsigned program,
1001 int* base_uniform_index) {
1002 static const char* uniforms[] = {
1003 "s_texture",
1004 "s_mask",
1005 "alpha",
1006 "maskTexCoordScale",
1007 "maskTexCoordOffset",
1008 };
1009 int locations[arraysize(uniforms)];
1010
1011 GetProgramUniformLocations(context,
1012 program,
1013 arraysize(uniforms),
1014 uniforms,
1015 locations,
1016 base_uniform_index);
1017 sampler_location_ = locations[0];
1018 mask_sampler_location_ = locations[1];
1019 alpha_location_ = locations[2];
1020 mask_tex_coord_scale_location_ = locations[3];
1021 mask_tex_coord_offset_location_ = locations[4];
1022 }
1023
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1024 std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
1025 TexCoordPrecision precision, SamplerType sampler) const {
1026 return FRAGMENT_SHADER(
1027 precision mediump float;
1028 varying TexCoordPrecision vec2 v_texCoord;
1029 uniform SamplerType s_texture;
1030 uniform SamplerType s_mask;
1031 uniform TexCoordPrecision vec2 maskTexCoordScale;
1032 uniform TexCoordPrecision vec2 maskTexCoordOffset;
1033 uniform float alpha;
1034 void main() {
1035 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1036 TexCoordPrecision vec2 maskTexCoord =
1037 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1038 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1039 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1040 gl_FragColor = texColor * alpha * maskColor.w;
1041 }
1042 ); // NOLINT(whitespace/parens)
1043 }
1044
FragmentShaderRGBATexAlphaMaskAA()1045 FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
1046 : sampler_location_(-1),
1047 mask_sampler_location_(-1),
1048 alpha_location_(-1),
1049 mask_tex_coord_scale_location_(-1),
1050 mask_tex_coord_offset_location_(-1) {}
1051
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1052 void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface* context,
1053 unsigned program,
1054 int* base_uniform_index) {
1055 static const char* uniforms[] = {
1056 "s_texture",
1057 "s_mask",
1058 "alpha",
1059 "maskTexCoordScale",
1060 "maskTexCoordOffset",
1061 };
1062 int locations[arraysize(uniforms)];
1063
1064 GetProgramUniformLocations(context,
1065 program,
1066 arraysize(uniforms),
1067 uniforms,
1068 locations,
1069 base_uniform_index);
1070 sampler_location_ = locations[0];
1071 mask_sampler_location_ = locations[1];
1072 alpha_location_ = locations[2];
1073 mask_tex_coord_scale_location_ = locations[3];
1074 mask_tex_coord_offset_location_ = locations[4];
1075 }
1076
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1077 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
1078 TexCoordPrecision precision, SamplerType sampler) const {
1079 return FRAGMENT_SHADER(
1080 precision mediump float;
1081 uniform SamplerType s_texture;
1082 uniform SamplerType s_mask;
1083 uniform TexCoordPrecision vec2 maskTexCoordScale;
1084 uniform TexCoordPrecision vec2 maskTexCoordOffset;
1085 uniform float alpha;
1086 varying TexCoordPrecision vec2 v_texCoord;
1087 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1088
1089 void main() {
1090 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1091 TexCoordPrecision vec2 maskTexCoord =
1092 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1093 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1094 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1095 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1096 vec2 d2 = min(d4.xz, d4.yw);
1097 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1098 gl_FragColor = texColor * alpha * maskColor.w * aa;
1099 }
1100 ); // NOLINT(whitespace/parens)
1101 }
1102
1103 FragmentShaderRGBATexAlphaMaskColorMatrixAA::
FragmentShaderRGBATexAlphaMaskColorMatrixAA()1104 FragmentShaderRGBATexAlphaMaskColorMatrixAA()
1105 : sampler_location_(-1),
1106 mask_sampler_location_(-1),
1107 alpha_location_(-1),
1108 mask_tex_coord_scale_location_(-1),
1109 color_matrix_location_(-1),
1110 color_offset_location_(-1) {}
1111
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1112 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
1113 GLES2Interface* context,
1114 unsigned program,
1115 int* base_uniform_index) {
1116 static const char* uniforms[] = {
1117 "s_texture",
1118 "s_mask",
1119 "alpha",
1120 "maskTexCoordScale",
1121 "maskTexCoordOffset",
1122 "colorMatrix",
1123 "colorOffset",
1124 };
1125 int locations[arraysize(uniforms)];
1126
1127 GetProgramUniformLocations(context,
1128 program,
1129 arraysize(uniforms),
1130 uniforms,
1131 locations,
1132 base_uniform_index);
1133 sampler_location_ = locations[0];
1134 mask_sampler_location_ = locations[1];
1135 alpha_location_ = locations[2];
1136 mask_tex_coord_scale_location_ = locations[3];
1137 mask_tex_coord_offset_location_ = locations[4];
1138 color_matrix_location_ = locations[5];
1139 color_offset_location_ = locations[6];
1140 }
1141
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1142 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
1143 TexCoordPrecision precision, SamplerType sampler) const {
1144 return FRAGMENT_SHADER(
1145 precision mediump float;
1146 uniform SamplerType s_texture;
1147 uniform SamplerType s_mask;
1148 uniform vec2 maskTexCoordScale;
1149 uniform vec2 maskTexCoordOffset;
1150 uniform mat4 colorMatrix;
1151 uniform vec4 colorOffset;
1152 uniform float alpha;
1153 varying TexCoordPrecision vec2 v_texCoord;
1154 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1155
1156 void main() {
1157 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1158 float nonZeroAlpha = max(texColor.a, 0.00001);
1159 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1160 texColor = colorMatrix * texColor + colorOffset;
1161 texColor.rgb *= texColor.a;
1162 texColor = clamp(texColor, 0.0, 1.0);
1163 TexCoordPrecision vec2 maskTexCoord =
1164 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1165 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1166 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1167 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1168 vec2 d2 = min(d4.xz, d4.yw);
1169 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1170 gl_FragColor = texColor * alpha * maskColor.w * aa;
1171 }
1172 ); // NOLINT(whitespace/parens)
1173 }
1174
1175 FragmentShaderRGBATexAlphaColorMatrixAA::
FragmentShaderRGBATexAlphaColorMatrixAA()1176 FragmentShaderRGBATexAlphaColorMatrixAA()
1177 : sampler_location_(-1),
1178 alpha_location_(-1),
1179 color_matrix_location_(-1),
1180 color_offset_location_(-1) {}
1181
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1182 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(
1183 GLES2Interface* context,
1184 unsigned program,
1185 int* base_uniform_index) {
1186 static const char* uniforms[] = {
1187 "s_texture",
1188 "alpha",
1189 "colorMatrix",
1190 "colorOffset",
1191 };
1192 int locations[arraysize(uniforms)];
1193
1194 GetProgramUniformLocations(context,
1195 program,
1196 arraysize(uniforms),
1197 uniforms,
1198 locations,
1199 base_uniform_index);
1200 sampler_location_ = locations[0];
1201 alpha_location_ = locations[1];
1202 color_matrix_location_ = locations[2];
1203 color_offset_location_ = locations[3];
1204 }
1205
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1206 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
1207 TexCoordPrecision precision, SamplerType sampler) const {
1208 return FRAGMENT_SHADER(
1209 precision mediump float;
1210 uniform SamplerType s_texture;
1211 uniform float alpha;
1212 uniform mat4 colorMatrix;
1213 uniform vec4 colorOffset;
1214 varying TexCoordPrecision vec2 v_texCoord;
1215 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1216
1217 void main() {
1218 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1219 float nonZeroAlpha = max(texColor.a, 0.00001);
1220 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1221 texColor = colorMatrix * texColor + colorOffset;
1222 texColor.rgb *= texColor.a;
1223 texColor = clamp(texColor, 0.0, 1.0);
1224 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1225 vec2 d2 = min(d4.xz, d4.yw);
1226 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1227 gl_FragColor = texColor * alpha * aa;
1228 }
1229 ); // NOLINT(whitespace/parens)
1230 }
1231
1232 FragmentShaderRGBATexAlphaMaskColorMatrix::
FragmentShaderRGBATexAlphaMaskColorMatrix()1233 FragmentShaderRGBATexAlphaMaskColorMatrix()
1234 : sampler_location_(-1),
1235 mask_sampler_location_(-1),
1236 alpha_location_(-1),
1237 mask_tex_coord_scale_location_(-1) {}
1238
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1239 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(
1240 GLES2Interface* context,
1241 unsigned program,
1242 int* base_uniform_index) {
1243 static const char* uniforms[] = {
1244 "s_texture",
1245 "s_mask",
1246 "alpha",
1247 "maskTexCoordScale",
1248 "maskTexCoordOffset",
1249 "colorMatrix",
1250 "colorOffset",
1251 };
1252 int locations[arraysize(uniforms)];
1253
1254 GetProgramUniformLocations(context,
1255 program,
1256 arraysize(uniforms),
1257 uniforms,
1258 locations,
1259 base_uniform_index);
1260 sampler_location_ = locations[0];
1261 mask_sampler_location_ = locations[1];
1262 alpha_location_ = locations[2];
1263 mask_tex_coord_scale_location_ = locations[3];
1264 mask_tex_coord_offset_location_ = locations[4];
1265 color_matrix_location_ = locations[5];
1266 color_offset_location_ = locations[6];
1267 }
1268
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1269 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
1270 TexCoordPrecision precision, SamplerType sampler) const {
1271 return FRAGMENT_SHADER(
1272 precision mediump float;
1273 varying TexCoordPrecision vec2 v_texCoord;
1274 uniform SamplerType s_texture;
1275 uniform SamplerType s_mask;
1276 uniform vec2 maskTexCoordScale;
1277 uniform vec2 maskTexCoordOffset;
1278 uniform mat4 colorMatrix;
1279 uniform vec4 colorOffset;
1280 uniform float alpha;
1281 void main() {
1282 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1283 float nonZeroAlpha = max(texColor.a, 0.00001);
1284 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1285 texColor = colorMatrix * texColor + colorOffset;
1286 texColor.rgb *= texColor.a;
1287 texColor = clamp(texColor, 0.0, 1.0);
1288 TexCoordPrecision vec2 maskTexCoord =
1289 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1290 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1291 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1292 gl_FragColor = texColor * alpha * maskColor.w;
1293 }
1294 ); // NOLINT(whitespace/parens)
1295 }
1296
FragmentShaderYUVVideo()1297 FragmentShaderYUVVideo::FragmentShaderYUVVideo()
1298 : y_texture_location_(-1),
1299 u_texture_location_(-1),
1300 v_texture_location_(-1),
1301 alpha_location_(-1),
1302 yuv_matrix_location_(-1),
1303 yuv_adj_location_(-1) {}
1304
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1305 void FragmentShaderYUVVideo::Init(GLES2Interface* context,
1306 unsigned program,
1307 int* base_uniform_index) {
1308 static const char* uniforms[] = {
1309 "y_texture",
1310 "u_texture",
1311 "v_texture",
1312 "alpha",
1313 "yuv_matrix",
1314 "yuv_adj",
1315 };
1316 int locations[arraysize(uniforms)];
1317
1318 GetProgramUniformLocations(context,
1319 program,
1320 arraysize(uniforms),
1321 uniforms,
1322 locations,
1323 base_uniform_index);
1324 y_texture_location_ = locations[0];
1325 u_texture_location_ = locations[1];
1326 v_texture_location_ = locations[2];
1327 alpha_location_ = locations[3];
1328 yuv_matrix_location_ = locations[4];
1329 yuv_adj_location_ = locations[5];
1330 }
1331
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1332 std::string FragmentShaderYUVVideo::GetShaderString(
1333 TexCoordPrecision precision, SamplerType sampler) const {
1334 return FRAGMENT_SHADER(
1335 precision mediump float;
1336 precision mediump int;
1337 varying TexCoordPrecision vec2 v_texCoord;
1338 uniform SamplerType y_texture;
1339 uniform SamplerType u_texture;
1340 uniform SamplerType v_texture;
1341 uniform float alpha;
1342 uniform vec3 yuv_adj;
1343 uniform mat3 yuv_matrix;
1344 void main() {
1345 float y_raw = TextureLookup(y_texture, v_texCoord).x;
1346 float u_unsigned = TextureLookup(u_texture, v_texCoord).x;
1347 float v_unsigned = TextureLookup(v_texture, v_texCoord).x;
1348 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
1349 vec3 rgb = yuv_matrix * yuv;
1350 gl_FragColor = vec4(rgb, 1.0) * alpha;
1351 }
1352 ); // NOLINT(whitespace/parens)
1353 }
1354
FragmentShaderYUVAVideo()1355 FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
1356 : y_texture_location_(-1),
1357 u_texture_location_(-1),
1358 v_texture_location_(-1),
1359 a_texture_location_(-1),
1360 alpha_location_(-1),
1361 yuv_matrix_location_(-1),
1362 yuv_adj_location_(-1) {
1363 }
1364
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1365 void FragmentShaderYUVAVideo::Init(GLES2Interface* context,
1366 unsigned program,
1367 int* base_uniform_index) {
1368 static const char* uniforms[] = {
1369 "y_texture",
1370 "u_texture",
1371 "v_texture",
1372 "a_texture",
1373 "alpha",
1374 "cc_matrix",
1375 "yuv_adj",
1376 };
1377 int locations[arraysize(uniforms)];
1378
1379 GetProgramUniformLocations(context,
1380 program,
1381 arraysize(uniforms),
1382 uniforms,
1383 locations,
1384 base_uniform_index);
1385 y_texture_location_ = locations[0];
1386 u_texture_location_ = locations[1];
1387 v_texture_location_ = locations[2];
1388 a_texture_location_ = locations[3];
1389 alpha_location_ = locations[4];
1390 yuv_matrix_location_ = locations[5];
1391 yuv_adj_location_ = locations[6];
1392 }
1393
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1394 std::string FragmentShaderYUVAVideo::GetShaderString(
1395 TexCoordPrecision precision, SamplerType sampler) const {
1396 return FRAGMENT_SHADER(
1397 precision mediump float;
1398 precision mediump int;
1399 varying TexCoordPrecision vec2 v_texCoord;
1400 uniform SamplerType y_texture;
1401 uniform SamplerType u_texture;
1402 uniform SamplerType v_texture;
1403 uniform SamplerType a_texture;
1404 uniform float alpha;
1405 uniform vec3 yuv_adj;
1406 uniform mat3 yuv_matrix;
1407 void main() {
1408 float y_raw = TextureLookup(y_texture, v_texCoord).x;
1409 float u_unsigned = TextureLookup(u_texture, v_texCoord).x;
1410 float v_unsigned = TextureLookup(v_texture, v_texCoord).x;
1411 float a_raw = TextureLookup(a_texture, v_texCoord).x;
1412 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
1413 vec3 rgb = yuv_matrix * yuv;
1414 gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);
1415 }
1416 ); // NOLINT(whitespace/parens)
1417 }
1418
FragmentShaderColor()1419 FragmentShaderColor::FragmentShaderColor()
1420 : color_location_(-1) {}
1421
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1422 void FragmentShaderColor::Init(GLES2Interface* context,
1423 unsigned program,
1424 int* base_uniform_index) {
1425 static const char* uniforms[] = {
1426 "color",
1427 };
1428 int locations[arraysize(uniforms)];
1429
1430 GetProgramUniformLocations(context,
1431 program,
1432 arraysize(uniforms),
1433 uniforms,
1434 locations,
1435 base_uniform_index);
1436 color_location_ = locations[0];
1437 }
1438
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1439 std::string FragmentShaderColor::GetShaderString(
1440 TexCoordPrecision precision, SamplerType sampler) const {
1441 return FRAGMENT_SHADER(
1442 precision mediump float;
1443 uniform vec4 color;
1444 void main() {
1445 gl_FragColor = color;
1446 }
1447 ); // NOLINT(whitespace/parens)
1448 }
1449
FragmentShaderColorAA()1450 FragmentShaderColorAA::FragmentShaderColorAA()
1451 : color_location_(-1) {}
1452
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1453 void FragmentShaderColorAA::Init(GLES2Interface* context,
1454 unsigned program,
1455 int* base_uniform_index) {
1456 static const char* uniforms[] = {
1457 "color",
1458 };
1459 int locations[arraysize(uniforms)];
1460
1461 GetProgramUniformLocations(context,
1462 program,
1463 arraysize(uniforms),
1464 uniforms,
1465 locations,
1466 base_uniform_index);
1467 color_location_ = locations[0];
1468 }
1469
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1470 std::string FragmentShaderColorAA::GetShaderString(
1471 TexCoordPrecision precision, SamplerType sampler) const {
1472 return FRAGMENT_SHADER(
1473 precision mediump float;
1474 uniform vec4 color;
1475 varying vec4 edge_dist[2]; // 8 edge distances.
1476
1477 void main() {
1478 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1479 vec2 d2 = min(d4.xz, d4.yw);
1480 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1481 gl_FragColor = color * aa;
1482 }
1483 ); // NOLINT(whitespace/parens)
1484 }
1485
FragmentShaderCheckerboard()1486 FragmentShaderCheckerboard::FragmentShaderCheckerboard()
1487 : alpha_location_(-1),
1488 tex_transform_location_(-1),
1489 frequency_location_(-1) {}
1490
Init(GLES2Interface * context,unsigned program,int * base_uniform_index)1491 void FragmentShaderCheckerboard::Init(GLES2Interface* context,
1492 unsigned program,
1493 int* base_uniform_index) {
1494 static const char* uniforms[] = {
1495 "alpha",
1496 "texTransform",
1497 "frequency",
1498 "color",
1499 };
1500 int locations[arraysize(uniforms)];
1501
1502 GetProgramUniformLocations(context,
1503 program,
1504 arraysize(uniforms),
1505 uniforms,
1506 locations,
1507 base_uniform_index);
1508 alpha_location_ = locations[0];
1509 tex_transform_location_ = locations[1];
1510 frequency_location_ = locations[2];
1511 color_location_ = locations[3];
1512 }
1513
GetShaderString(TexCoordPrecision precision,SamplerType sampler) const1514 std::string FragmentShaderCheckerboard::GetShaderString(
1515 TexCoordPrecision precision, SamplerType sampler) const {
1516 // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
1517 // by Munshi, Ginsburg, Shreiner.
1518 return FRAGMENT_SHADER(
1519 precision mediump float;
1520 precision mediump int;
1521 varying vec2 v_texCoord;
1522 uniform float alpha;
1523 uniform float frequency;
1524 uniform vec4 texTransform;
1525 uniform vec4 color;
1526 void main() {
1527 vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0);
1528 vec4 color2 = color;
1529 vec2 texCoord =
1530 clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy;
1531 vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0);
1532 float picker = abs(coord.x - coord.y); // NOLINT
1533 gl_FragColor = mix(color1, color2, picker) * alpha;
1534 }
1535 ); // NOLINT(whitespace/parens)
1536 }
1537
1538 } // namespace cc
1539