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