Upgrade ReadPixels to ES3 semantic in command buffer.
[chromium-blink-merge.git] / cc / output / shader.cc
blob4a877ae859f6e6da9bcd4d759881fdfe78e45f00
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/shader.h"
7 #include <algorithm>
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "gpu/command_buffer/client/gles2_interface.h"
12 #include "ui/gfx/geometry/point.h"
13 #include "ui/gfx/geometry/size.h"
15 template <size_t size>
16 std::string StripLambda(const char(&shader)[size]) {
17 // Must contain at least "[]() {}" and trailing null (included in size).
18 static_assert(size >= 8,
19 "String passed to StripLambda must be at least 8 characters");
20 DCHECK_EQ(strncmp("[]() {", shader, 6), 0);
21 DCHECK_EQ(shader[size - 2], '}');
22 return std::string(shader + 6, shader + size - 2);
25 // Shaders are passed in with lambda syntax, which tricks clang-format into
26 // handling them correctly. StipLambda removes this.
27 #define SHADER0(Src) StripLambda(#Src)
28 #define VERTEX_SHADER(Head, Body) SetVertexTexCoordPrecision(Head + Body)
29 #define FRAGMENT_SHADER(Head, Body) \
30 SetFragmentTexCoordPrecision( \
31 precision, \
32 SetFragmentSamplerType(sampler, SetBlendModeFunctions(Head + Body)))
34 using gpu::gles2::GLES2Interface;
36 namespace cc {
38 namespace {
40 static void GetProgramUniformLocations(GLES2Interface* context,
41 unsigned program,
42 size_t count,
43 const char** uniforms,
44 int* locations,
45 int* base_uniform_index) {
46 for (size_t i = 0; i < count; i++) {
47 locations[i] = (*base_uniform_index)++;
48 context->BindUniformLocationCHROMIUM(program, locations[i], uniforms[i]);
52 static std::string SetFragmentTexCoordPrecision(
53 TexCoordPrecision requested_precision,
54 std::string shader_string) {
55 switch (requested_precision) {
56 case TEX_COORD_PRECISION_HIGH:
57 DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
58 return "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
59 " #define TexCoordPrecision highp\n"
60 "#else\n"
61 " #define TexCoordPrecision mediump\n"
62 "#endif\n" +
63 shader_string;
64 case TEX_COORD_PRECISION_MEDIUM:
65 DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
66 return "#define TexCoordPrecision mediump\n" + shader_string;
67 case TEX_COORD_PRECISION_NA:
68 DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos);
69 DCHECK_EQ(shader_string.find("texture2D"), std::string::npos);
70 DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos);
71 return shader_string;
72 default:
73 NOTREACHED();
74 break;
76 return shader_string;
79 static std::string SetVertexTexCoordPrecision(
80 const std::string& shader_string) {
81 // We unconditionally use highp in the vertex shader since
82 // we are unlikely to be vertex shader bound when drawing large quads.
83 // Also, some vertex shaders mutate the texture coordinate in such a
84 // way that the effective precision might be lower than expected.
85 return "#define TexCoordPrecision highp\n" + shader_string;
88 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
89 int* highp_threshold_cache,
90 int highp_threshold_min,
91 int x,
92 int y) {
93 if (*highp_threshold_cache == 0) {
94 // Initialize range and precision with minimum spec values for when
95 // GetShaderPrecisionFormat is a test stub.
96 // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat
97 // everywhere.
98 GLint range[2] = {14, 14};
99 GLint precision = 10;
100 context->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
101 range, &precision);
102 *highp_threshold_cache = 1 << precision;
105 int highp_threshold = std::max(*highp_threshold_cache, highp_threshold_min);
106 if (x > highp_threshold || y > highp_threshold)
107 return TEX_COORD_PRECISION_HIGH;
108 return TEX_COORD_PRECISION_MEDIUM;
111 static std::string SetFragmentSamplerType(SamplerType requested_type,
112 std::string shader_string) {
113 switch (requested_type) {
114 case SAMPLER_TYPE_2D:
115 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
116 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
117 return "#define SamplerType sampler2D\n"
118 "#define TextureLookup texture2D\n" +
119 shader_string;
120 case SAMPLER_TYPE_2D_RECT:
121 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
122 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
123 return "#extension GL_ARB_texture_rectangle : require\n"
124 "#define SamplerType sampler2DRect\n"
125 "#define TextureLookup texture2DRect\n" +
126 shader_string;
127 case SAMPLER_TYPE_EXTERNAL_OES:
128 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
129 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
130 return "#extension GL_OES_EGL_image_external : require\n"
131 "#define SamplerType samplerExternalOES\n"
132 "#define TextureLookup texture2D\n" +
133 shader_string;
134 case SAMPLER_TYPE_NA:
135 DCHECK_EQ(shader_string.find("SamplerType"), std::string::npos);
136 DCHECK_EQ(shader_string.find("TextureLookup"), std::string::npos);
137 return shader_string;
138 default:
139 NOTREACHED();
140 break;
142 return shader_string;
145 } // namespace
147 ShaderLocations::ShaderLocations() {
150 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
151 int* highp_threshold_cache,
152 int highp_threshold_min,
153 const gfx::Point& max_coordinate) {
154 return TexCoordPrecisionRequired(context,
155 highp_threshold_cache,
156 highp_threshold_min,
157 max_coordinate.x(),
158 max_coordinate.y());
161 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
162 int* highp_threshold_cache,
163 int highp_threshold_min,
164 const gfx::Size& max_size) {
165 return TexCoordPrecisionRequired(context,
166 highp_threshold_cache,
167 highp_threshold_min,
168 max_size.width(),
169 max_size.height());
172 VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) {
175 void VertexShaderPosTex::Init(GLES2Interface* context,
176 unsigned program,
177 int* base_uniform_index) {
178 static const char* uniforms[] = {
179 "matrix",
181 int locations[arraysize(uniforms)];
183 GetProgramUniformLocations(context,
184 program,
185 arraysize(uniforms),
186 uniforms,
187 locations,
188 base_uniform_index);
189 matrix_location_ = locations[0];
192 std::string VertexShaderPosTex::GetShaderString() const {
193 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
196 std::string VertexShaderPosTex::GetShaderHead() {
197 return SHADER0([]() {
198 attribute vec4 a_position;
199 attribute TexCoordPrecision vec2 a_texCoord;
200 uniform mat4 matrix;
201 varying TexCoordPrecision vec2 v_texCoord;
205 std::string VertexShaderPosTex::GetShaderBody() {
206 return SHADER0([]() {
207 void main() {
208 gl_Position = matrix * a_position;
209 v_texCoord = a_texCoord;
214 VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset()
215 : matrix_location_(-1),
216 ya_tex_scale_location_(-1),
217 ya_tex_offset_location_(-1),
218 uv_tex_scale_location_(-1),
219 uv_tex_offset_location_(-1) {
222 void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context,
223 unsigned program,
224 int* base_uniform_index) {
225 static const char* uniforms[] = {
226 "matrix", "yaTexScale", "yaTexOffset", "uvTexScale", "uvTexOffset",
228 int locations[arraysize(uniforms)];
230 GetProgramUniformLocations(context,
231 program,
232 arraysize(uniforms),
233 uniforms,
234 locations,
235 base_uniform_index);
236 matrix_location_ = locations[0];
237 ya_tex_scale_location_ = locations[1];
238 ya_tex_offset_location_ = locations[2];
239 uv_tex_scale_location_ = locations[3];
240 uv_tex_offset_location_ = locations[4];
243 std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const {
244 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
247 std::string VertexShaderPosTexYUVStretchOffset::GetShaderHead() {
248 return SHADER0([]() {
249 precision mediump float;
250 attribute vec4 a_position;
251 attribute TexCoordPrecision vec2 a_texCoord;
252 uniform mat4 matrix;
253 varying TexCoordPrecision vec2 v_yaTexCoord;
254 varying TexCoordPrecision vec2 v_uvTexCoord;
255 uniform TexCoordPrecision vec2 yaTexScale;
256 uniform TexCoordPrecision vec2 yaTexOffset;
257 uniform TexCoordPrecision vec2 uvTexScale;
258 uniform TexCoordPrecision vec2 uvTexOffset;
262 std::string VertexShaderPosTexYUVStretchOffset::GetShaderBody() {
263 return SHADER0([]() {
264 void main() {
265 gl_Position = matrix * a_position;
266 v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;
267 v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;
272 VertexShaderPos::VertexShaderPos() : matrix_location_(-1) {
275 void VertexShaderPos::Init(GLES2Interface* context,
276 unsigned program,
277 int* base_uniform_index) {
278 static const char* uniforms[] = {
279 "matrix",
281 int locations[arraysize(uniforms)];
283 GetProgramUniformLocations(context,
284 program,
285 arraysize(uniforms),
286 uniforms,
287 locations,
288 base_uniform_index);
289 matrix_location_ = locations[0];
292 std::string VertexShaderPos::GetShaderString() const {
293 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
296 std::string VertexShaderPos::GetShaderHead() {
297 return SHADER0([]() {
298 attribute vec4 a_position;
299 uniform mat4 matrix;
303 std::string VertexShaderPos::GetShaderBody() {
304 return SHADER0([]() {
305 void main() { gl_Position = matrix * a_position; }
309 VertexShaderPosTexTransform::VertexShaderPosTexTransform()
310 : matrix_location_(-1),
311 tex_transform_location_(-1),
312 vertex_opacity_location_(-1) {
315 void VertexShaderPosTexTransform::Init(GLES2Interface* context,
316 unsigned program,
317 int* base_uniform_index) {
318 static const char* uniforms[] = {
319 "matrix", "texTransform", "opacity",
321 int locations[arraysize(uniforms)];
323 GetProgramUniformLocations(context,
324 program,
325 arraysize(uniforms),
326 uniforms,
327 locations,
328 base_uniform_index);
329 matrix_location_ = locations[0];
330 tex_transform_location_ = locations[1];
331 vertex_opacity_location_ = locations[2];
334 std::string VertexShaderPosTexTransform::GetShaderString() const {
335 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
338 std::string VertexShaderPosTexTransform::GetShaderHead() {
339 return SHADER0([]() {
340 attribute vec4 a_position;
341 attribute TexCoordPrecision vec2 a_texCoord;
342 attribute float a_index;
343 uniform mat4 matrix[8];
344 uniform TexCoordPrecision vec4 texTransform[8];
345 uniform float opacity[32];
346 varying TexCoordPrecision vec2 v_texCoord;
347 varying float v_alpha;
351 std::string VertexShaderPosTexTransform::GetShaderBody() {
352 return SHADER0([]() {
353 void main() {
354 int quad_index = int(a_index * 0.25); // NOLINT
355 gl_Position = matrix[quad_index] * a_position;
356 TexCoordPrecision vec4 texTrans = texTransform[quad_index];
357 v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
358 v_alpha = opacity[int(a_index)]; // NOLINT
363 void VertexShaderPosTexTransform::FillLocations(
364 ShaderLocations* locations) const {
365 locations->matrix = matrix_location();
366 locations->tex_transform = tex_transform_location();
369 std::string VertexShaderPosTexIdentity::GetShaderString() const {
370 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
373 std::string VertexShaderPosTexIdentity::GetShaderHead() {
374 return SHADER0([]() {
375 attribute vec4 a_position;
376 varying TexCoordPrecision vec2 v_texCoord;
380 std::string VertexShaderPosTexIdentity::GetShaderBody() {
381 return SHADER0([]() {
382 void main() {
383 gl_Position = a_position;
384 v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
389 VertexShaderQuad::VertexShaderQuad()
390 : matrix_location_(-1), quad_location_(-1) {
393 void VertexShaderQuad::Init(GLES2Interface* context,
394 unsigned program,
395 int* base_uniform_index) {
396 static const char* uniforms[] = {
397 "matrix", "quad",
399 int locations[arraysize(uniforms)];
401 GetProgramUniformLocations(context,
402 program,
403 arraysize(uniforms),
404 uniforms,
405 locations,
406 base_uniform_index);
407 matrix_location_ = locations[0];
408 quad_location_ = locations[1];
411 std::string VertexShaderQuad::GetShaderString() const {
412 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
415 std::string VertexShaderQuad::GetShaderHead() {
416 #if defined(OS_ANDROID)
417 // TODO(epenner): Find the cause of this 'quad' uniform
418 // being missing if we don't add dummy variables.
419 // http://crbug.com/240602
420 return SHADER0([]() {
421 attribute TexCoordPrecision vec4 a_position;
422 attribute float a_index;
423 uniform mat4 matrix;
424 uniform TexCoordPrecision vec2 quad[4];
425 uniform TexCoordPrecision vec2 dummy_uniform;
426 varying TexCoordPrecision vec2 dummy_varying;
428 #else
429 return SHADER0([]() {
430 attribute TexCoordPrecision vec4 a_position;
431 attribute float a_index;
432 uniform mat4 matrix;
433 uniform TexCoordPrecision vec2 quad[4];
435 #endif
438 std::string VertexShaderQuad::GetShaderBody() {
439 #if defined(OS_ANDROID)
440 return SHADER0([]() {
441 void main() {
442 vec2 pos = quad[int(a_index)]; // NOLINT
443 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
444 dummy_varying = dummy_uniform;
447 #else
448 return SHADER0([]() {
449 void main() {
450 vec2 pos = quad[int(a_index)]; // NOLINT
451 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
454 #endif
457 VertexShaderQuadAA::VertexShaderQuadAA()
458 : matrix_location_(-1),
459 viewport_location_(-1),
460 quad_location_(-1),
461 edge_location_(-1) {
464 void VertexShaderQuadAA::Init(GLES2Interface* context,
465 unsigned program,
466 int* base_uniform_index) {
467 static const char* uniforms[] = {
468 "matrix", "viewport", "quad", "edge",
470 int locations[arraysize(uniforms)];
472 GetProgramUniformLocations(context,
473 program,
474 arraysize(uniforms),
475 uniforms,
476 locations,
477 base_uniform_index);
478 matrix_location_ = locations[0];
479 viewport_location_ = locations[1];
480 quad_location_ = locations[2];
481 edge_location_ = locations[3];
484 std::string VertexShaderQuadAA::GetShaderString() const {
485 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
488 std::string VertexShaderQuadAA::GetShaderHead() {
489 return SHADER0([]() {
490 attribute TexCoordPrecision vec4 a_position;
491 attribute float a_index;
492 uniform mat4 matrix;
493 uniform vec4 viewport;
494 uniform TexCoordPrecision vec2 quad[4];
495 uniform TexCoordPrecision vec3 edge[8];
496 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
500 std::string VertexShaderQuadAA::GetShaderBody() {
501 return SHADER0([]() {
502 void main() {
503 vec2 pos = quad[int(a_index)]; // NOLINT
504 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
505 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
506 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
507 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos),
508 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) *
509 gl_Position.w;
510 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos),
511 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) *
512 gl_Position.w;
517 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
518 : matrix_location_(-1),
519 viewport_location_(-1),
520 quad_location_(-1),
521 edge_location_(-1),
522 tex_transform_location_(-1) {
525 void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context,
526 unsigned program,
527 int* base_uniform_index) {
528 static const char* uniforms[] = {
529 "matrix", "viewport", "quad", "edge", "texTrans",
531 int locations[arraysize(uniforms)];
533 GetProgramUniformLocations(context,
534 program,
535 arraysize(uniforms),
536 uniforms,
537 locations,
538 base_uniform_index);
539 matrix_location_ = locations[0];
540 viewport_location_ = locations[1];
541 quad_location_ = locations[2];
542 edge_location_ = locations[3];
543 tex_transform_location_ = locations[4];
546 std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
547 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
550 std::string VertexShaderQuadTexTransformAA::GetShaderHead() {
551 return SHADER0([]() {
552 attribute TexCoordPrecision vec4 a_position;
553 attribute float a_index;
554 uniform mat4 matrix;
555 uniform vec4 viewport;
556 uniform TexCoordPrecision vec2 quad[4];
557 uniform TexCoordPrecision vec3 edge[8];
558 uniform TexCoordPrecision vec4 texTrans;
559 varying TexCoordPrecision vec2 v_texCoord;
560 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
564 std::string VertexShaderQuadTexTransformAA::GetShaderBody() {
565 return SHADER0([]() {
566 void main() {
567 vec2 pos = quad[int(a_index)]; // NOLINT
568 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
569 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
570 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
571 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos),
572 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) *
573 gl_Position.w;
574 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos),
575 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) *
576 gl_Position.w;
577 v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy;
582 void VertexShaderQuadTexTransformAA::FillLocations(
583 ShaderLocations* locations) const {
584 locations->quad = quad_location();
585 locations->edge = edge_location();
586 locations->viewport = viewport_location();
587 locations->matrix = matrix_location();
588 locations->tex_transform = tex_transform_location();
592 VertexShaderTile::VertexShaderTile()
593 : matrix_location_(-1),
594 quad_location_(-1),
595 vertex_tex_transform_location_(-1) {
598 void VertexShaderTile::Init(GLES2Interface* context,
599 unsigned program,
600 int* base_uniform_index) {
601 static const char* uniforms[] = {
602 "matrix", "quad", "vertexTexTransform",
604 int locations[arraysize(uniforms)];
606 GetProgramUniformLocations(context,
607 program,
608 arraysize(uniforms),
609 uniforms,
610 locations,
611 base_uniform_index);
612 matrix_location_ = locations[0];
613 quad_location_ = locations[1];
614 vertex_tex_transform_location_ = locations[2];
617 std::string VertexShaderTile::GetShaderString() const {
618 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
621 std::string VertexShaderTile::GetShaderHead() {
622 return SHADER0([]() {
623 attribute TexCoordPrecision vec4 a_position;
624 attribute TexCoordPrecision vec2 a_texCoord;
625 attribute float a_index;
626 uniform mat4 matrix;
627 uniform TexCoordPrecision vec2 quad[4];
628 uniform TexCoordPrecision vec4 vertexTexTransform;
629 varying TexCoordPrecision vec2 v_texCoord;
633 std::string VertexShaderTile::GetShaderBody() {
634 return SHADER0([]() {
635 void main() {
636 vec2 pos = quad[int(a_index)]; // NOLINT
637 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
638 v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy;
643 VertexShaderTileAA::VertexShaderTileAA()
644 : matrix_location_(-1),
645 viewport_location_(-1),
646 quad_location_(-1),
647 edge_location_(-1),
648 vertex_tex_transform_location_(-1) {
651 void VertexShaderTileAA::Init(GLES2Interface* context,
652 unsigned program,
653 int* base_uniform_index) {
654 static const char* uniforms[] = {
655 "matrix", "viewport", "quad", "edge", "vertexTexTransform",
657 int locations[arraysize(uniforms)];
659 GetProgramUniformLocations(context,
660 program,
661 arraysize(uniforms),
662 uniforms,
663 locations,
664 base_uniform_index);
665 matrix_location_ = locations[0];
666 viewport_location_ = locations[1];
667 quad_location_ = locations[2];
668 edge_location_ = locations[3];
669 vertex_tex_transform_location_ = locations[4];
672 std::string VertexShaderTileAA::GetShaderString() const {
673 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
676 std::string VertexShaderTileAA::GetShaderHead() {
677 return SHADER0([]() {
678 attribute TexCoordPrecision vec4 a_position;
679 attribute float a_index;
680 uniform mat4 matrix;
681 uniform vec4 viewport;
682 uniform TexCoordPrecision vec2 quad[4];
683 uniform TexCoordPrecision vec3 edge[8];
684 uniform TexCoordPrecision vec4 vertexTexTransform;
685 varying TexCoordPrecision vec2 v_texCoord;
686 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
690 std::string VertexShaderTileAA::GetShaderBody() {
691 return SHADER0([]() {
692 void main() {
693 vec2 pos = quad[int(a_index)]; // NOLINT
694 gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
695 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
696 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
697 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos),
698 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) *
699 gl_Position.w;
700 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos),
701 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) *
702 gl_Position.w;
703 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
708 VertexShaderVideoTransform::VertexShaderVideoTransform()
709 : matrix_location_(-1), tex_matrix_location_(-1) {
712 void VertexShaderVideoTransform::Init(GLES2Interface* context,
713 unsigned program,
714 int* base_uniform_index) {
715 static const char* uniforms[] = {
716 "matrix", "texMatrix",
718 int locations[arraysize(uniforms)];
720 GetProgramUniformLocations(context,
721 program,
722 arraysize(uniforms),
723 uniforms,
724 locations,
725 base_uniform_index);
726 matrix_location_ = locations[0];
727 tex_matrix_location_ = locations[1];
730 std::string VertexShaderVideoTransform::GetShaderString() const {
731 return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
734 std::string VertexShaderVideoTransform::GetShaderHead() {
735 return SHADER0([]() {
736 attribute vec4 a_position;
737 attribute TexCoordPrecision vec2 a_texCoord;
738 uniform mat4 matrix;
739 uniform TexCoordPrecision mat4 texMatrix;
740 varying TexCoordPrecision vec2 v_texCoord;
744 std::string VertexShaderVideoTransform::GetShaderBody() {
745 return SHADER0([]() {
746 void main() {
747 gl_Position = matrix * a_position;
748 v_texCoord =
749 vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
754 #define BLEND_MODE_UNIFORMS "s_backdropTexture", \
755 "s_originalBackdropTexture", \
756 "backdropRect"
757 #define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 3 : 0)
758 #define BLEND_MODE_SET_LOCATIONS(X, POS) \
759 if (has_blend_mode()) { \
760 DCHECK_LT(static_cast<size_t>(POS) + 2, arraysize(X)); \
761 backdrop_location_ = locations[POS]; \
762 original_backdrop_location_ = locations[POS + 1]; \
763 backdrop_rect_location_ = locations[POS + 2]; \
766 FragmentTexBlendMode::FragmentTexBlendMode()
767 : backdrop_location_(-1),
768 original_backdrop_location_(-1),
769 backdrop_rect_location_(-1),
770 blend_mode_(BLEND_MODE_NONE),
771 mask_for_background_(false) {
774 std::string FragmentTexBlendMode::SetBlendModeFunctions(
775 std::string shader_string) const {
776 if (shader_string.find("ApplyBlendMode") == std::string::npos)
777 return shader_string;
779 if (!has_blend_mode()) {
780 return "#define ApplyBlendMode(X, Y) (X)\n" + shader_string;
783 static const std::string kUniforms = SHADER0([]() {
784 uniform sampler2D s_backdropTexture;
785 uniform sampler2D s_originalBackdropTexture;
786 uniform TexCoordPrecision vec4 backdropRect;
789 std::string mixFunction;
790 if (mask_for_background()) {
791 mixFunction = SHADER0([]() {
792 vec4 MixBackdrop(TexCoordPrecision vec2 bgTexCoord, float mask) {
793 vec4 backdrop = texture2D(s_backdropTexture, bgTexCoord);
794 vec4 original_backdrop =
795 texture2D(s_originalBackdropTexture, bgTexCoord);
796 return mix(original_backdrop, backdrop, mask);
799 } else {
800 mixFunction = SHADER0([]() {
801 vec4 MixBackdrop(TexCoordPrecision vec2 bgTexCoord, float mask) {
802 return texture2D(s_backdropTexture, bgTexCoord);
807 static const std::string kFunctionApplyBlendMode = SHADER0([]() {
808 vec4 GetBackdropColor(float mask) {
809 TexCoordPrecision vec2 bgTexCoord = gl_FragCoord.xy - backdropRect.xy;
810 bgTexCoord.x /= backdropRect.z;
811 bgTexCoord.y /= backdropRect.w;
812 return MixBackdrop(bgTexCoord, mask);
815 vec4 ApplyBlendMode(vec4 src, float mask) {
816 vec4 dst = GetBackdropColor(mask);
817 return Blend(src, dst);
821 return "precision mediump float;" + GetHelperFunctions() +
822 GetBlendFunction() + kUniforms + mixFunction +
823 kFunctionApplyBlendMode + shader_string;
826 std::string FragmentTexBlendMode::GetHelperFunctions() const {
827 static const std::string kFunctionHardLight = SHADER0([]() {
828 vec3 hardLight(vec4 src, vec4 dst) {
829 vec3 result;
830 result.r =
831 (2.0 * src.r <= src.a)
832 ? (2.0 * src.r * dst.r)
833 : (src.a * dst.a - 2.0 * (dst.a - dst.r) * (src.a - src.r));
834 result.g =
835 (2.0 * src.g <= src.a)
836 ? (2.0 * src.g * dst.g)
837 : (src.a * dst.a - 2.0 * (dst.a - dst.g) * (src.a - src.g));
838 result.b =
839 (2.0 * src.b <= src.a)
840 ? (2.0 * src.b * dst.b)
841 : (src.a * dst.a - 2.0 * (dst.a - dst.b) * (src.a - src.b));
842 result.rgb += src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
843 return result;
847 static const std::string kFunctionColorDodgeComponent = SHADER0([]() {
848 float getColorDodgeComponent(float srcc, float srca, float dstc,
849 float dsta) {
850 if (0.0 == dstc)
851 return srcc * (1.0 - dsta);
852 float d = srca - srcc;
853 if (0.0 == d)
854 return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
855 d = min(dsta, dstc * srca / d);
856 return d * srca + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
860 static const std::string kFunctionColorBurnComponent = SHADER0([]() {
861 float getColorBurnComponent(float srcc, float srca, float dstc,
862 float dsta) {
863 if (dsta == dstc)
864 return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
865 if (0.0 == srcc)
866 return dstc * (1.0 - srca);
867 float d = max(0.0, dsta - (dsta - dstc) * srca / srcc);
868 return srca * d + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
872 static const std::string kFunctionSoftLightComponentPosDstAlpha =
873 SHADER0([]() {
874 float getSoftLightComponent(float srcc, float srca, float dstc,
875 float dsta) {
876 if (2.0 * srcc <= srca) {
877 return (dstc * dstc * (srca - 2.0 * srcc)) / dsta +
878 (1.0 - dsta) * srcc + dstc * (-srca + 2.0 * srcc + 1.0);
879 } else if (4.0 * dstc <= dsta) {
880 float DSqd = dstc * dstc;
881 float DCub = DSqd * dstc;
882 float DaSqd = dsta * dsta;
883 float DaCub = DaSqd * dsta;
884 return (-DaCub * srcc +
885 DaSqd * (srcc - dstc * (3.0 * srca - 6.0 * srcc - 1.0)) +
886 12.0 * dsta * DSqd * (srca - 2.0 * srcc) -
887 16.0 * DCub * (srca - 2.0 * srcc)) /
888 DaSqd;
889 } else {
890 return -sqrt(dsta * dstc) * (srca - 2.0 * srcc) - dsta * srcc +
891 dstc * (srca - 2.0 * srcc + 1.0) + srcc;
896 static const std::string kFunctionLum = SHADER0([]() {
897 float luminance(vec3 color) { return dot(vec3(0.3, 0.59, 0.11), color); }
899 vec3 set_luminance(vec3 hueSat, float alpha, vec3 lumColor) {
900 float diff = luminance(lumColor - hueSat);
901 vec3 outColor = hueSat + diff;
902 float outLum = luminance(outColor);
903 float minComp = min(min(outColor.r, outColor.g), outColor.b);
904 float maxComp = max(max(outColor.r, outColor.g), outColor.b);
905 if (minComp < 0.0 && outLum != minComp) {
906 outColor = outLum +
907 ((outColor - vec3(outLum, outLum, outLum)) * outLum) /
908 (outLum - minComp);
910 if (maxComp > alpha && maxComp != outLum) {
911 outColor =
912 outLum +
913 ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) /
914 (maxComp - outLum);
916 return outColor;
920 static const std::string kFunctionSat = SHADER0([]() {
921 float saturation(vec3 color) {
922 return max(max(color.r, color.g), color.b) -
923 min(min(color.r, color.g), color.b);
926 vec3 set_saturation_helper(float minComp, float midComp, float maxComp,
927 float sat) {
928 if (minComp < maxComp) {
929 vec3 result;
930 result.r = 0.0;
931 result.g = sat * (midComp - minComp) / (maxComp - minComp);
932 result.b = sat;
933 return result;
934 } else {
935 return vec3(0, 0, 0);
939 vec3 set_saturation(vec3 hueLumColor, vec3 satColor) {
940 float sat = saturation(satColor);
941 if (hueLumColor.r <= hueLumColor.g) {
942 if (hueLumColor.g <= hueLumColor.b) {
943 hueLumColor.rgb = set_saturation_helper(hueLumColor.r, hueLumColor.g,
944 hueLumColor.b, sat);
945 } else if (hueLumColor.r <= hueLumColor.b) {
946 hueLumColor.rbg = set_saturation_helper(hueLumColor.r, hueLumColor.b,
947 hueLumColor.g, sat);
948 } else {
949 hueLumColor.brg = set_saturation_helper(hueLumColor.b, hueLumColor.r,
950 hueLumColor.g, sat);
952 } else if (hueLumColor.r <= hueLumColor.b) {
953 hueLumColor.grb = set_saturation_helper(hueLumColor.g, hueLumColor.r,
954 hueLumColor.b, sat);
955 } else if (hueLumColor.g <= hueLumColor.b) {
956 hueLumColor.gbr = set_saturation_helper(hueLumColor.g, hueLumColor.b,
957 hueLumColor.r, sat);
958 } else {
959 hueLumColor.bgr = set_saturation_helper(hueLumColor.b, hueLumColor.g,
960 hueLumColor.r, sat);
962 return hueLumColor;
966 switch (blend_mode_) {
967 case BLEND_MODE_OVERLAY:
968 case BLEND_MODE_HARD_LIGHT:
969 return kFunctionHardLight;
970 case BLEND_MODE_COLOR_DODGE:
971 return kFunctionColorDodgeComponent;
972 case BLEND_MODE_COLOR_BURN:
973 return kFunctionColorBurnComponent;
974 case BLEND_MODE_SOFT_LIGHT:
975 return kFunctionSoftLightComponentPosDstAlpha;
976 case BLEND_MODE_HUE:
977 case BLEND_MODE_SATURATION:
978 return kFunctionLum + kFunctionSat;
979 case BLEND_MODE_COLOR:
980 case BLEND_MODE_LUMINOSITY:
981 return kFunctionLum;
982 default:
983 return std::string();
987 std::string FragmentTexBlendMode::GetBlendFunction() const {
988 return "vec4 Blend(vec4 src, vec4 dst) {"
989 " vec4 result;"
990 " result.a = src.a + (1.0 - src.a) * dst.a;" +
991 GetBlendFunctionBodyForRGB() +
992 " return result;"
993 "}";
996 std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
997 switch (blend_mode_) {
998 case BLEND_MODE_NORMAL:
999 return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
1000 case BLEND_MODE_SCREEN:
1001 return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
1002 case BLEND_MODE_LIGHTEN:
1003 return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
1004 " (1.0 - dst.a) * src.rgb + dst.rgb);";
1005 case BLEND_MODE_OVERLAY:
1006 return "result.rgb = hardLight(dst, src);";
1007 case BLEND_MODE_DARKEN:
1008 return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb,"
1009 " (1.0 - dst.a) * src.rgb + dst.rgb);";
1010 case BLEND_MODE_COLOR_DODGE:
1011 return "result.r = getColorDodgeComponent(src.r, src.a, dst.r, dst.a);"
1012 "result.g = getColorDodgeComponent(src.g, src.a, dst.g, dst.a);"
1013 "result.b = getColorDodgeComponent(src.b, src.a, dst.b, dst.a);";
1014 case BLEND_MODE_COLOR_BURN:
1015 return "result.r = getColorBurnComponent(src.r, src.a, dst.r, dst.a);"
1016 "result.g = getColorBurnComponent(src.g, src.a, dst.g, dst.a);"
1017 "result.b = getColorBurnComponent(src.b, src.a, dst.b, dst.a);";
1018 case BLEND_MODE_HARD_LIGHT:
1019 return "result.rgb = hardLight(src, dst);";
1020 case BLEND_MODE_SOFT_LIGHT:
1021 return "if (0.0 == dst.a) {"
1022 " result.rgb = src.rgb;"
1023 "} else {"
1024 " result.r = getSoftLightComponent(src.r, src.a, dst.r, dst.a);"
1025 " result.g = getSoftLightComponent(src.g, src.a, dst.g, dst.a);"
1026 " result.b = getSoftLightComponent(src.b, src.a, dst.b, dst.a);"
1027 "}";
1028 case BLEND_MODE_DIFFERENCE:
1029 return "result.rgb = src.rgb + dst.rgb -"
1030 " 2.0 * min(src.rgb * dst.a, dst.rgb * src.a);";
1031 case BLEND_MODE_EXCLUSION:
1032 return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;";
1033 case BLEND_MODE_MULTIPLY:
1034 return "result.rgb = (1.0 - src.a) * dst.rgb +"
1035 " (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;";
1036 case BLEND_MODE_HUE:
1037 return "vec4 dstSrcAlpha = dst * src.a;"
1038 "result.rgb ="
1039 " set_luminance(set_saturation(src.rgb * dst.a,"
1040 " dstSrcAlpha.rgb),"
1041 " dstSrcAlpha.a,"
1042 " dstSrcAlpha.rgb);"
1043 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
1044 case BLEND_MODE_SATURATION:
1045 return "vec4 dstSrcAlpha = dst * src.a;"
1046 "result.rgb = set_luminance(set_saturation(dstSrcAlpha.rgb,"
1047 " src.rgb * dst.a),"
1048 " dstSrcAlpha.a,"
1049 " dstSrcAlpha.rgb);"
1050 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
1051 case BLEND_MODE_COLOR:
1052 return "vec4 srcDstAlpha = src * dst.a;"
1053 "result.rgb = set_luminance(srcDstAlpha.rgb,"
1054 " srcDstAlpha.a,"
1055 " dst.rgb * src.a);"
1056 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
1057 case BLEND_MODE_LUMINOSITY:
1058 return "vec4 srcDstAlpha = src * dst.a;"
1059 "result.rgb = set_luminance(dst.rgb * src.a,"
1060 " srcDstAlpha.a,"
1061 " srcDstAlpha.rgb);"
1062 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
1063 case BLEND_MODE_NONE:
1064 NOTREACHED();
1066 return "result = vec4(1.0, 0.0, 0.0, 1.0);";
1069 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
1070 : sampler_location_(-1), alpha_location_(-1) {
1073 void FragmentTexAlphaBinding::Init(GLES2Interface* context,
1074 unsigned program,
1075 int* base_uniform_index) {
1076 static const char* uniforms[] = {
1077 "s_texture", "alpha", BLEND_MODE_UNIFORMS,
1079 int locations[arraysize(uniforms)];
1081 GetProgramUniformLocations(context,
1082 program,
1083 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1084 uniforms,
1085 locations,
1086 base_uniform_index);
1087 sampler_location_ = locations[0];
1088 alpha_location_ = locations[1];
1089 BLEND_MODE_SET_LOCATIONS(locations, 2);
1092 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
1093 : sampler_location_(-1),
1094 alpha_location_(-1),
1095 color_matrix_location_(-1),
1096 color_offset_location_(-1) {
1099 void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface* context,
1100 unsigned program,
1101 int* base_uniform_index) {
1102 static const char* uniforms[] = {
1103 "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
1105 int locations[arraysize(uniforms)];
1107 GetProgramUniformLocations(context,
1108 program,
1109 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1110 uniforms,
1111 locations,
1112 base_uniform_index);
1113 sampler_location_ = locations[0];
1114 alpha_location_ = locations[1];
1115 color_matrix_location_ = locations[2];
1116 color_offset_location_ = locations[3];
1117 BLEND_MODE_SET_LOCATIONS(locations, 4);
1120 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding() : sampler_location_(-1) {
1123 void FragmentTexOpaqueBinding::Init(GLES2Interface* context,
1124 unsigned program,
1125 int* base_uniform_index) {
1126 static const char* uniforms[] = {
1127 "s_texture",
1129 int locations[arraysize(uniforms)];
1131 GetProgramUniformLocations(context,
1132 program,
1133 arraysize(uniforms),
1134 uniforms,
1135 locations,
1136 base_uniform_index);
1137 sampler_location_ = locations[0];
1140 std::string FragmentShaderRGBATexAlpha::GetShaderString(
1141 TexCoordPrecision precision,
1142 SamplerType sampler) const {
1143 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1146 std::string FragmentShaderRGBATexAlpha::GetShaderHead() {
1147 return SHADER0([]() {
1148 precision mediump float;
1149 varying TexCoordPrecision vec2 v_texCoord;
1150 uniform SamplerType s_texture;
1151 uniform float alpha;
1155 std::string FragmentShaderRGBATexAlpha::GetShaderBody() {
1156 return SHADER0([]() {
1157 void main() {
1158 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1159 gl_FragColor = ApplyBlendMode(texColor * alpha, 0.0);
1164 void FragmentShaderRGBATexAlpha::FillLocations(
1165 ShaderLocations* locations) const {
1166 locations->sampler = sampler_location();
1167 locations->alpha = alpha_location();
1168 locations->backdrop = backdrop_location();
1169 locations->backdrop_rect = backdrop_rect_location();
1172 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
1173 TexCoordPrecision precision,
1174 SamplerType sampler) const {
1175 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1178 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderHead() {
1179 return SHADER0([]() {
1180 precision mediump float;
1181 varying TexCoordPrecision vec2 v_texCoord;
1182 uniform SamplerType s_texture;
1183 uniform float alpha;
1184 uniform mat4 colorMatrix;
1185 uniform vec4 colorOffset;
1189 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderBody() {
1190 return SHADER0([]() {
1191 void main() {
1192 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1193 float nonZeroAlpha = max(texColor.a, 0.00001);
1194 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1195 texColor = colorMatrix * texColor + colorOffset;
1196 texColor.rgb *= texColor.a;
1197 texColor = clamp(texColor, 0.0, 1.0);
1198 gl_FragColor = ApplyBlendMode(texColor * alpha, 0.0);
1203 void FragmentShaderRGBATexColorMatrixAlpha::FillLocations(
1204 ShaderLocations* locations) const {
1205 locations->sampler = sampler_location();
1206 locations->alpha = alpha_location();
1207 locations->color_matrix = color_matrix_location();
1208 locations->color_offset = color_offset_location();
1209 locations->backdrop = backdrop_location();
1210 locations->backdrop_rect = backdrop_rect_location();
1213 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
1214 TexCoordPrecision precision,
1215 SamplerType sampler) const {
1216 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1219 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderHead() {
1220 return SHADER0([]() {
1221 precision mediump float;
1222 varying TexCoordPrecision vec2 v_texCoord;
1223 varying float v_alpha;
1224 uniform SamplerType s_texture;
1228 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderBody() {
1229 return SHADER0([]() {
1230 void main() {
1231 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1232 gl_FragColor = texColor * v_alpha;
1237 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
1238 TexCoordPrecision precision,
1239 SamplerType sampler) const {
1240 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1243 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderHead() {
1244 return SHADER0([]() {
1245 precision mediump float;
1246 varying TexCoordPrecision vec2 v_texCoord;
1247 varying float v_alpha;
1248 uniform SamplerType s_texture;
1252 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderBody() {
1253 return SHADER0([]() {
1254 void main() {
1255 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1256 texColor.rgb *= texColor.a;
1257 gl_FragColor = texColor * v_alpha;
1262 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
1263 : background_color_location_(-1), sampler_location_(-1) {
1266 void FragmentTexBackgroundBinding::Init(GLES2Interface* context,
1267 unsigned program,
1268 int* base_uniform_index) {
1269 static const char* uniforms[] = {
1270 "s_texture", "background_color",
1272 int locations[arraysize(uniforms)];
1274 GetProgramUniformLocations(context,
1275 program,
1276 arraysize(uniforms),
1277 uniforms,
1278 locations,
1279 base_uniform_index);
1281 sampler_location_ = locations[0];
1282 DCHECK_NE(sampler_location_, -1);
1284 background_color_location_ = locations[1];
1285 DCHECK_NE(background_color_location_, -1);
1288 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
1289 TexCoordPrecision precision,
1290 SamplerType sampler) const {
1291 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1294 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderHead() {
1295 return SHADER0([]() {
1296 precision mediump float;
1297 varying TexCoordPrecision vec2 v_texCoord;
1298 varying float v_alpha;
1299 uniform vec4 background_color;
1300 uniform SamplerType s_texture;
1304 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderBody() {
1305 return SHADER0([]() {
1306 void main() {
1307 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1308 texColor += background_color * (1.0 - texColor.a);
1309 gl_FragColor = texColor * v_alpha;
1314 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
1315 TexCoordPrecision precision,
1316 SamplerType sampler) const {
1317 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1320 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderHead() {
1321 return SHADER0([]() {
1322 precision mediump float;
1323 varying TexCoordPrecision vec2 v_texCoord;
1324 varying float v_alpha;
1325 uniform vec4 background_color;
1326 uniform SamplerType s_texture;
1330 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderBody() {
1331 return SHADER0([]() {
1332 void main() {
1333 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1334 texColor.rgb *= texColor.a;
1335 texColor += background_color * (1.0 - texColor.a);
1336 gl_FragColor = texColor * v_alpha;
1341 std::string FragmentShaderRGBATexOpaque::GetShaderString(
1342 TexCoordPrecision precision,
1343 SamplerType sampler) const {
1344 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1347 std::string FragmentShaderRGBATexOpaque::GetShaderHead() {
1348 return SHADER0([]() {
1349 precision mediump float;
1350 varying TexCoordPrecision vec2 v_texCoord;
1351 uniform SamplerType s_texture;
1355 std::string FragmentShaderRGBATexOpaque::GetShaderBody() {
1356 return SHADER0([]() {
1357 void main() {
1358 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1359 gl_FragColor = vec4(texColor.rgb, 1.0);
1364 std::string FragmentShaderRGBATex::GetShaderString(TexCoordPrecision precision,
1365 SamplerType sampler) const {
1366 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1369 std::string FragmentShaderRGBATex::GetShaderHead() {
1370 return SHADER0([]() {
1371 precision mediump float;
1372 varying TexCoordPrecision vec2 v_texCoord;
1373 uniform SamplerType s_texture;
1377 std::string FragmentShaderRGBATex::GetShaderBody() {
1378 return SHADER0([]() {
1379 void main() { gl_FragColor = TextureLookup(s_texture, v_texCoord); }
1383 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
1384 TexCoordPrecision precision,
1385 SamplerType sampler) const {
1386 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1389 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderHead() {
1390 return SHADER0([]() {
1391 precision mediump float;
1392 varying TexCoordPrecision vec2 v_texCoord;
1393 uniform SamplerType s_texture;
1394 uniform float alpha;
1398 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderBody() {
1399 return SHADER0([]() {
1400 void main() {
1401 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1402 gl_FragColor =
1403 vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
1408 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
1409 TexCoordPrecision precision,
1410 SamplerType sampler) const {
1411 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1414 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderHead() {
1415 return SHADER0([]() {
1416 precision mediump float;
1417 varying TexCoordPrecision vec2 v_texCoord;
1418 uniform SamplerType s_texture;
1422 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderBody() {
1423 return SHADER0([]() {
1424 void main() {
1425 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1426 gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
1431 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
1432 : sampler_location_(-1), alpha_location_(-1) {
1435 void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface* context,
1436 unsigned program,
1437 int* base_uniform_index) {
1438 static const char* uniforms[] = {
1439 "s_texture", "alpha", BLEND_MODE_UNIFORMS,
1441 int locations[arraysize(uniforms)];
1443 GetProgramUniformLocations(context,
1444 program,
1445 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1446 uniforms,
1447 locations,
1448 base_uniform_index);
1449 sampler_location_ = locations[0];
1450 alpha_location_ = locations[1];
1451 BLEND_MODE_SET_LOCATIONS(locations, 2);
1454 std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
1455 TexCoordPrecision precision,
1456 SamplerType sampler) const {
1457 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1460 std::string FragmentShaderRGBATexAlphaAA::GetShaderHead() {
1461 return SHADER0([]() {
1462 precision mediump float;
1463 uniform SamplerType s_texture;
1464 uniform float alpha;
1465 varying TexCoordPrecision vec2 v_texCoord;
1466 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1470 std::string FragmentShaderRGBATexAlphaAA::GetShaderBody() {
1471 return SHADER0([]() {
1472 void main() {
1473 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1474 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1475 vec2 d2 = min(d4.xz, d4.yw);
1476 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1477 gl_FragColor = ApplyBlendMode(texColor * alpha * aa, 0.0);
1482 void FragmentShaderRGBATexAlphaAA::FillLocations(
1483 ShaderLocations* locations) const {
1484 locations->sampler = sampler_location();
1485 locations->alpha = alpha_location();
1486 locations->backdrop = backdrop_location();
1487 locations->backdrop_rect = backdrop_rect_location();
1490 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
1491 : sampler_location_(-1),
1492 alpha_location_(-1),
1493 fragment_tex_transform_location_(-1) {
1496 void FragmentTexClampAlphaAABinding::Init(GLES2Interface* context,
1497 unsigned program,
1498 int* base_uniform_index) {
1499 static const char* uniforms[] = {
1500 "s_texture", "alpha", "fragmentTexTransform",
1502 int locations[arraysize(uniforms)];
1504 GetProgramUniformLocations(context,
1505 program,
1506 arraysize(uniforms),
1507 uniforms,
1508 locations,
1509 base_uniform_index);
1510 sampler_location_ = locations[0];
1511 alpha_location_ = locations[1];
1512 fragment_tex_transform_location_ = locations[2];
1515 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
1516 TexCoordPrecision precision,
1517 SamplerType sampler) const {
1518 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1521 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderHead() {
1522 return SHADER0([]() {
1523 precision mediump float;
1524 uniform SamplerType s_texture;
1525 uniform float alpha;
1526 uniform TexCoordPrecision vec4 fragmentTexTransform;
1527 varying TexCoordPrecision vec2 v_texCoord;
1528 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1532 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderBody() {
1533 return SHADER0([]() {
1534 void main() {
1535 TexCoordPrecision vec2 texCoord =
1536 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
1537 fragmentTexTransform.xy;
1538 vec4 texColor = TextureLookup(s_texture, texCoord);
1539 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1540 vec2 d2 = min(d4.xz, d4.yw);
1541 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1542 gl_FragColor = texColor * alpha * aa;
1547 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
1548 TexCoordPrecision precision,
1549 SamplerType sampler) const {
1550 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1553 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderHead() {
1554 return SHADER0([]() {
1555 precision mediump float;
1556 uniform SamplerType s_texture;
1557 uniform float alpha;
1558 uniform TexCoordPrecision vec4 fragmentTexTransform;
1559 varying TexCoordPrecision vec2 v_texCoord;
1560 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1564 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderBody() {
1565 return SHADER0([]() {
1566 void main() {
1567 TexCoordPrecision vec2 texCoord =
1568 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
1569 fragmentTexTransform.xy;
1570 vec4 texColor = TextureLookup(s_texture, texCoord);
1571 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1572 vec2 d2 = min(d4.xz, d4.yw);
1573 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1574 gl_FragColor =
1575 vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha * aa;
1580 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
1581 : sampler_location_(-1),
1582 mask_sampler_location_(-1),
1583 alpha_location_(-1),
1584 mask_tex_coord_scale_location_(-1) {
1587 void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface* context,
1588 unsigned program,
1589 int* base_uniform_index) {
1590 static const char* uniforms[] = {
1591 "s_texture",
1592 "s_mask",
1593 "alpha",
1594 "maskTexCoordScale",
1595 "maskTexCoordOffset",
1596 BLEND_MODE_UNIFORMS,
1598 int locations[arraysize(uniforms)];
1600 GetProgramUniformLocations(context,
1601 program,
1602 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1603 uniforms,
1604 locations,
1605 base_uniform_index);
1606 sampler_location_ = locations[0];
1607 mask_sampler_location_ = locations[1];
1608 alpha_location_ = locations[2];
1609 mask_tex_coord_scale_location_ = locations[3];
1610 mask_tex_coord_offset_location_ = locations[4];
1611 BLEND_MODE_SET_LOCATIONS(locations, 5);
1614 std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
1615 TexCoordPrecision precision,
1616 SamplerType sampler) const {
1617 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1620 std::string FragmentShaderRGBATexAlphaMask::GetShaderHead() {
1621 return SHADER0([]() {
1622 precision mediump float;
1623 varying TexCoordPrecision vec2 v_texCoord;
1624 uniform sampler2D s_texture;
1625 uniform SamplerType s_mask;
1626 uniform TexCoordPrecision vec2 maskTexCoordScale;
1627 uniform TexCoordPrecision vec2 maskTexCoordOffset;
1628 uniform float alpha;
1632 std::string FragmentShaderRGBATexAlphaMask::GetShaderBody() {
1633 return SHADER0([]() {
1634 void main() {
1635 vec4 texColor = texture2D(s_texture, v_texCoord);
1636 TexCoordPrecision vec2 maskTexCoord =
1637 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1638 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1639 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1640 gl_FragColor = ApplyBlendMode(
1641 texColor * alpha * maskColor.w, maskColor.w);
1646 void FragmentShaderRGBATexAlphaMask::FillLocations(
1647 ShaderLocations* locations) const {
1648 locations->sampler = sampler_location();
1649 locations->mask_sampler = mask_sampler_location();
1650 locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
1651 locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
1652 locations->alpha = alpha_location();
1653 locations->backdrop = backdrop_location();
1654 locations->backdrop_rect = backdrop_rect_location();
1655 if (mask_for_background())
1656 locations->original_backdrop = original_backdrop_location();
1659 FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
1660 : sampler_location_(-1),
1661 mask_sampler_location_(-1),
1662 alpha_location_(-1),
1663 mask_tex_coord_scale_location_(-1),
1664 mask_tex_coord_offset_location_(-1) {
1667 void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface* context,
1668 unsigned program,
1669 int* base_uniform_index) {
1670 static const char* uniforms[] = {
1671 "s_texture",
1672 "s_mask",
1673 "alpha",
1674 "maskTexCoordScale",
1675 "maskTexCoordOffset",
1676 BLEND_MODE_UNIFORMS,
1678 int locations[arraysize(uniforms)];
1680 GetProgramUniformLocations(context,
1681 program,
1682 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1683 uniforms,
1684 locations,
1685 base_uniform_index);
1686 sampler_location_ = locations[0];
1687 mask_sampler_location_ = locations[1];
1688 alpha_location_ = locations[2];
1689 mask_tex_coord_scale_location_ = locations[3];
1690 mask_tex_coord_offset_location_ = locations[4];
1691 BLEND_MODE_SET_LOCATIONS(locations, 5);
1694 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
1695 TexCoordPrecision precision,
1696 SamplerType sampler) const {
1697 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1700 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderHead() {
1701 return SHADER0([]() {
1702 precision mediump float;
1703 uniform sampler2D s_texture;
1704 uniform SamplerType s_mask;
1705 uniform TexCoordPrecision vec2 maskTexCoordScale;
1706 uniform TexCoordPrecision vec2 maskTexCoordOffset;
1707 uniform float alpha;
1708 varying TexCoordPrecision vec2 v_texCoord;
1709 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1713 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderBody() {
1714 return SHADER0([]() {
1715 void main() {
1716 vec4 texColor = texture2D(s_texture, v_texCoord);
1717 TexCoordPrecision vec2 maskTexCoord =
1718 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1719 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1720 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1721 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1722 vec2 d2 = min(d4.xz, d4.yw);
1723 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1724 gl_FragColor = ApplyBlendMode(
1725 texColor * alpha * maskColor.w * aa, maskColor.w);
1730 void FragmentShaderRGBATexAlphaMaskAA::FillLocations(
1731 ShaderLocations* locations) const {
1732 locations->sampler = sampler_location();
1733 locations->mask_sampler = mask_sampler_location();
1734 locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
1735 locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
1736 locations->alpha = alpha_location();
1737 locations->backdrop = backdrop_location();
1738 locations->backdrop_rect = backdrop_rect_location();
1739 if (mask_for_background())
1740 locations->original_backdrop = original_backdrop_location();
1743 FragmentShaderRGBATexAlphaMaskColorMatrixAA::
1744 FragmentShaderRGBATexAlphaMaskColorMatrixAA()
1745 : sampler_location_(-1),
1746 mask_sampler_location_(-1),
1747 alpha_location_(-1),
1748 mask_tex_coord_scale_location_(-1),
1749 color_matrix_location_(-1),
1750 color_offset_location_(-1) {
1753 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
1754 GLES2Interface* context,
1755 unsigned program,
1756 int* base_uniform_index) {
1757 static const char* uniforms[] = {
1758 "s_texture",
1759 "s_mask",
1760 "alpha",
1761 "maskTexCoordScale",
1762 "maskTexCoordOffset",
1763 "colorMatrix",
1764 "colorOffset",
1765 BLEND_MODE_UNIFORMS,
1767 int locations[arraysize(uniforms)];
1769 GetProgramUniformLocations(context,
1770 program,
1771 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1772 uniforms,
1773 locations,
1774 base_uniform_index);
1775 sampler_location_ = locations[0];
1776 mask_sampler_location_ = locations[1];
1777 alpha_location_ = locations[2];
1778 mask_tex_coord_scale_location_ = locations[3];
1779 mask_tex_coord_offset_location_ = locations[4];
1780 color_matrix_location_ = locations[5];
1781 color_offset_location_ = locations[6];
1782 BLEND_MODE_SET_LOCATIONS(locations, 7);
1785 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
1786 TexCoordPrecision precision,
1787 SamplerType sampler) const {
1788 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1791 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderHead() {
1792 return SHADER0([]() {
1793 precision mediump float;
1794 uniform sampler2D s_texture;
1795 uniform SamplerType s_mask;
1796 uniform vec2 maskTexCoordScale;
1797 uniform vec2 maskTexCoordOffset;
1798 uniform mat4 colorMatrix;
1799 uniform vec4 colorOffset;
1800 uniform float alpha;
1801 varying TexCoordPrecision vec2 v_texCoord;
1802 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1806 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderBody() {
1807 return SHADER0([]() {
1808 void main() {
1809 vec4 texColor = texture2D(s_texture, v_texCoord);
1810 float nonZeroAlpha = max(texColor.a, 0.00001);
1811 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1812 texColor = colorMatrix * texColor + colorOffset;
1813 texColor.rgb *= texColor.a;
1814 texColor = clamp(texColor, 0.0, 1.0);
1815 TexCoordPrecision vec2 maskTexCoord =
1816 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1817 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1818 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1819 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1820 vec2 d2 = min(d4.xz, d4.yw);
1821 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1822 gl_FragColor = ApplyBlendMode(
1823 texColor * alpha * maskColor.w * aa, maskColor.w);
1828 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::FillLocations(
1829 ShaderLocations* locations) const {
1830 locations->sampler = sampler_location();
1831 locations->alpha = alpha_location();
1832 locations->mask_sampler = mask_sampler_location();
1833 locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
1834 locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
1835 locations->color_matrix = color_matrix_location();
1836 locations->color_offset = color_offset_location();
1837 locations->backdrop = backdrop_location();
1838 locations->backdrop_rect = backdrop_rect_location();
1839 if (mask_for_background())
1840 locations->original_backdrop = original_backdrop_location();
1843 FragmentShaderRGBATexAlphaColorMatrixAA::
1844 FragmentShaderRGBATexAlphaColorMatrixAA()
1845 : sampler_location_(-1),
1846 alpha_location_(-1),
1847 color_matrix_location_(-1),
1848 color_offset_location_(-1) {
1851 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(GLES2Interface* context,
1852 unsigned program,
1853 int* base_uniform_index) {
1854 static const char* uniforms[] = {
1855 "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
1857 int locations[arraysize(uniforms)];
1859 GetProgramUniformLocations(context,
1860 program,
1861 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1862 uniforms,
1863 locations,
1864 base_uniform_index);
1865 sampler_location_ = locations[0];
1866 alpha_location_ = locations[1];
1867 color_matrix_location_ = locations[2];
1868 color_offset_location_ = locations[3];
1869 BLEND_MODE_SET_LOCATIONS(locations, 4);
1872 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
1873 TexCoordPrecision precision,
1874 SamplerType sampler) const {
1875 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1878 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderHead() {
1879 return SHADER0([]() {
1880 precision mediump float;
1881 uniform SamplerType s_texture;
1882 uniform float alpha;
1883 uniform mat4 colorMatrix;
1884 uniform vec4 colorOffset;
1885 varying TexCoordPrecision vec2 v_texCoord;
1886 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances.
1890 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderBody() {
1891 return SHADER0([]() {
1892 void main() {
1893 vec4 texColor = TextureLookup(s_texture, v_texCoord);
1894 float nonZeroAlpha = max(texColor.a, 0.00001);
1895 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1896 texColor = colorMatrix * texColor + colorOffset;
1897 texColor.rgb *= texColor.a;
1898 texColor = clamp(texColor, 0.0, 1.0);
1899 vec4 d4 = min(edge_dist[0], edge_dist[1]);
1900 vec2 d2 = min(d4.xz, d4.yw);
1901 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
1902 gl_FragColor = ApplyBlendMode(texColor * alpha * aa, 0.0);
1907 void FragmentShaderRGBATexAlphaColorMatrixAA::FillLocations(
1908 ShaderLocations* locations) const {
1909 locations->sampler = sampler_location();
1910 locations->alpha = alpha_location();
1911 locations->color_matrix = color_matrix_location();
1912 locations->color_offset = color_offset_location();
1913 locations->backdrop = backdrop_location();
1914 locations->backdrop_rect = backdrop_rect_location();
1917 FragmentShaderRGBATexAlphaMaskColorMatrix::
1918 FragmentShaderRGBATexAlphaMaskColorMatrix()
1919 : sampler_location_(-1),
1920 mask_sampler_location_(-1),
1921 alpha_location_(-1),
1922 mask_tex_coord_scale_location_(-1) {
1925 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(GLES2Interface* context,
1926 unsigned program,
1927 int* base_uniform_index) {
1928 static const char* uniforms[] = {
1929 "s_texture",
1930 "s_mask",
1931 "alpha",
1932 "maskTexCoordScale",
1933 "maskTexCoordOffset",
1934 "colorMatrix",
1935 "colorOffset",
1936 BLEND_MODE_UNIFORMS,
1938 int locations[arraysize(uniforms)];
1940 GetProgramUniformLocations(context,
1941 program,
1942 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
1943 uniforms,
1944 locations,
1945 base_uniform_index);
1946 sampler_location_ = locations[0];
1947 mask_sampler_location_ = locations[1];
1948 alpha_location_ = locations[2];
1949 mask_tex_coord_scale_location_ = locations[3];
1950 mask_tex_coord_offset_location_ = locations[4];
1951 color_matrix_location_ = locations[5];
1952 color_offset_location_ = locations[6];
1953 BLEND_MODE_SET_LOCATIONS(locations, 7);
1956 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
1957 TexCoordPrecision precision,
1958 SamplerType sampler) const {
1959 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
1962 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderHead() {
1963 return SHADER0([]() {
1964 precision mediump float;
1965 varying TexCoordPrecision vec2 v_texCoord;
1966 uniform sampler2D s_texture;
1967 uniform SamplerType s_mask;
1968 uniform vec2 maskTexCoordScale;
1969 uniform vec2 maskTexCoordOffset;
1970 uniform mat4 colorMatrix;
1971 uniform vec4 colorOffset;
1972 uniform float alpha;
1976 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderBody() {
1977 return SHADER0([]() {
1978 void main() {
1979 vec4 texColor = texture2D(s_texture, v_texCoord);
1980 float nonZeroAlpha = max(texColor.a, 0.00001);
1981 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
1982 texColor = colorMatrix * texColor + colorOffset;
1983 texColor.rgb *= texColor.a;
1984 texColor = clamp(texColor, 0.0, 1.0);
1985 TexCoordPrecision vec2 maskTexCoord =
1986 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
1987 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
1988 vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
1989 gl_FragColor = ApplyBlendMode(
1990 texColor * alpha * maskColor.w, maskColor.w);
1995 void FragmentShaderRGBATexAlphaMaskColorMatrix::FillLocations(
1996 ShaderLocations* locations) const {
1997 locations->sampler = sampler_location();
1998 locations->mask_sampler = mask_sampler_location();
1999 locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
2000 locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
2001 locations->alpha = alpha_location();
2002 locations->color_matrix = color_matrix_location();
2003 locations->color_offset = color_offset_location();
2004 locations->backdrop = backdrop_location();
2005 locations->backdrop_rect = backdrop_rect_location();
2006 if (mask_for_background())
2007 locations->original_backdrop = original_backdrop_location();
2010 FragmentShaderYUVVideo::FragmentShaderYUVVideo()
2011 : y_texture_location_(-1),
2012 u_texture_location_(-1),
2013 v_texture_location_(-1),
2014 alpha_location_(-1),
2015 yuv_matrix_location_(-1),
2016 yuv_adj_location_(-1),
2017 ya_clamp_rect_location_(-1),
2018 uv_clamp_rect_location_(-1) {
2021 void FragmentShaderYUVVideo::Init(GLES2Interface* context,
2022 unsigned program,
2023 int* base_uniform_index) {
2024 static const char* uniforms[] = {"y_texture",
2025 "u_texture",
2026 "v_texture",
2027 "alpha",
2028 "yuv_matrix",
2029 "yuv_adj",
2030 "ya_clamp_rect",
2031 "uv_clamp_rect"};
2032 int locations[arraysize(uniforms)];
2034 GetProgramUniformLocations(context,
2035 program,
2036 arraysize(uniforms),
2037 uniforms,
2038 locations,
2039 base_uniform_index);
2040 y_texture_location_ = locations[0];
2041 u_texture_location_ = locations[1];
2042 v_texture_location_ = locations[2];
2043 alpha_location_ = locations[3];
2044 yuv_matrix_location_ = locations[4];
2045 yuv_adj_location_ = locations[5];
2046 ya_clamp_rect_location_ = locations[6];
2047 uv_clamp_rect_location_ = locations[7];
2050 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
2051 SamplerType sampler) const {
2052 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
2055 std::string FragmentShaderYUVVideo::GetShaderHead() {
2056 return SHADER0([]() {
2057 precision mediump float;
2058 precision mediump int;
2059 varying TexCoordPrecision vec2 v_yaTexCoord;
2060 varying TexCoordPrecision vec2 v_uvTexCoord;
2061 uniform SamplerType y_texture;
2062 uniform SamplerType u_texture;
2063 uniform SamplerType v_texture;
2064 uniform float alpha;
2065 uniform vec3 yuv_adj;
2066 uniform mat3 yuv_matrix;
2067 uniform vec4 ya_clamp_rect;
2068 uniform vec4 uv_clamp_rect;
2072 std::string FragmentShaderYUVVideo::GetShaderBody() {
2073 return SHADER0([]() {
2074 void main() {
2075 vec2 ya_clamped =
2076 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));
2077 float y_raw = TextureLookup(y_texture, ya_clamped).x;
2078 vec2 uv_clamped =
2079 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));
2080 float u_unsigned = TextureLookup(u_texture, uv_clamped).x;
2081 float v_unsigned = TextureLookup(v_texture, uv_clamped).x;
2082 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
2083 vec3 rgb = yuv_matrix * yuv;
2084 gl_FragColor = vec4(rgb, 1.0) * alpha;
2089 FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
2090 : y_texture_location_(-1),
2091 u_texture_location_(-1),
2092 v_texture_location_(-1),
2093 a_texture_location_(-1),
2094 alpha_location_(-1),
2095 yuv_matrix_location_(-1),
2096 yuv_adj_location_(-1) {
2099 void FragmentShaderYUVAVideo::Init(GLES2Interface* context,
2100 unsigned program,
2101 int* base_uniform_index) {
2102 static const char* uniforms[] = {
2103 "y_texture",
2104 "u_texture",
2105 "v_texture",
2106 "a_texture",
2107 "alpha",
2108 "cc_matrix",
2109 "yuv_adj",
2110 "ya_clamp_rect",
2111 "uv_clamp_rect",
2113 int locations[arraysize(uniforms)];
2115 GetProgramUniformLocations(context,
2116 program,
2117 arraysize(uniforms),
2118 uniforms,
2119 locations,
2120 base_uniform_index);
2121 y_texture_location_ = locations[0];
2122 u_texture_location_ = locations[1];
2123 v_texture_location_ = locations[2];
2124 a_texture_location_ = locations[3];
2125 alpha_location_ = locations[4];
2126 yuv_matrix_location_ = locations[5];
2127 yuv_adj_location_ = locations[6];
2128 ya_clamp_rect_location_ = locations[7];
2129 uv_clamp_rect_location_ = locations[8];
2132 std::string FragmentShaderYUVAVideo::GetShaderString(
2133 TexCoordPrecision precision,
2134 SamplerType sampler) const {
2135 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
2138 std::string FragmentShaderYUVAVideo::GetShaderHead() {
2139 return SHADER0([]() {
2140 precision mediump float;
2141 precision mediump int;
2142 varying TexCoordPrecision vec2 v_yaTexCoord;
2143 varying TexCoordPrecision vec2 v_uvTexCoord;
2144 uniform SamplerType y_texture;
2145 uniform SamplerType u_texture;
2146 uniform SamplerType v_texture;
2147 uniform SamplerType a_texture;
2148 uniform float alpha;
2149 uniform vec3 yuv_adj;
2150 uniform mat3 yuv_matrix;
2151 uniform vec4 ya_clamp_rect;
2152 uniform vec4 uv_clamp_rect;
2156 std::string FragmentShaderYUVAVideo::GetShaderBody() {
2157 return SHADER0([]() {
2158 void main() {
2159 vec2 ya_clamped =
2160 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));
2161 float y_raw = TextureLookup(y_texture, ya_clamped).x;
2162 vec2 uv_clamped =
2163 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));
2164 float u_unsigned = TextureLookup(u_texture, uv_clamped).x;
2165 float v_unsigned = TextureLookup(v_texture, uv_clamped).x;
2166 float a_raw = TextureLookup(a_texture, ya_clamped).x;
2167 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
2168 vec3 rgb = yuv_matrix * yuv;
2169 gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);
2174 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) {
2177 void FragmentShaderColor::Init(GLES2Interface* context,
2178 unsigned program,
2179 int* base_uniform_index) {
2180 static const char* uniforms[] = {
2181 "color",
2183 int locations[arraysize(uniforms)];
2185 GetProgramUniformLocations(context,
2186 program,
2187 arraysize(uniforms),
2188 uniforms,
2189 locations,
2190 base_uniform_index);
2191 color_location_ = locations[0];
2194 std::string FragmentShaderColor::GetShaderString(TexCoordPrecision precision,
2195 SamplerType sampler) const {
2196 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
2199 std::string FragmentShaderColor::GetShaderHead() {
2200 return SHADER0([]() {
2201 precision mediump float;
2202 uniform vec4 color;
2206 std::string FragmentShaderColor::GetShaderBody() {
2207 return SHADER0([]() {
2208 void main() { gl_FragColor = color; }
2212 FragmentShaderColorAA::FragmentShaderColorAA() : color_location_(-1) {
2215 void FragmentShaderColorAA::Init(GLES2Interface* context,
2216 unsigned program,
2217 int* base_uniform_index) {
2218 static const char* uniforms[] = {
2219 "color",
2221 int locations[arraysize(uniforms)];
2223 GetProgramUniformLocations(context,
2224 program,
2225 arraysize(uniforms),
2226 uniforms,
2227 locations,
2228 base_uniform_index);
2229 color_location_ = locations[0];
2232 std::string FragmentShaderColorAA::GetShaderString(TexCoordPrecision precision,
2233 SamplerType sampler) const {
2234 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
2237 std::string FragmentShaderColorAA::GetShaderHead() {
2238 return SHADER0([]() {
2239 precision mediump float;
2240 uniform vec4 color;
2241 varying vec4 edge_dist[2]; // 8 edge distances.
2245 std::string FragmentShaderColorAA::GetShaderBody() {
2246 return SHADER0([]() {
2247 void main() {
2248 vec4 d4 = min(edge_dist[0], edge_dist[1]);
2249 vec2 d2 = min(d4.xz, d4.yw);
2250 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
2251 gl_FragColor = color * aa;
2256 } // namespace cc