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"
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"
14 #define SHADER0(Src) #Src
15 #define VERTEX_SHADER(Src) SetVertexTexCoordPrecision(SHADER0(Src))
16 #define FRAGMENT_SHADER(Src) \
17 SetFragmentTexCoordPrecision( \
19 SetFragmentSamplerType(sampler, SetBlendModeFunctions(SHADER0(Src))))
21 using gpu::gles2::GLES2Interface
;
27 static void GetProgramUniformLocations(GLES2Interface
* context
,
30 const char** uniforms
,
32 int* base_uniform_index
) {
33 for (size_t i
= 0; i
< count
; i
++) {
34 locations
[i
] = (*base_uniform_index
)++;
35 context
->BindUniformLocationCHROMIUM(program
, locations
[i
], uniforms
[i
]);
39 static std::string
SetFragmentTexCoordPrecision(
40 TexCoordPrecision requested_precision
,
41 std::string shader_string
) {
42 switch (requested_precision
) {
43 case TexCoordPrecisionHigh
:
44 DCHECK_NE(shader_string
.find("TexCoordPrecision"), std::string::npos
);
45 return "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
46 " #define TexCoordPrecision highp\n"
48 " #define TexCoordPrecision mediump\n"
51 case TexCoordPrecisionMedium
:
52 DCHECK_NE(shader_string
.find("TexCoordPrecision"), std::string::npos
);
53 return "#define TexCoordPrecision mediump\n" + 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
);
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" + std::string(shader_string
);
74 TexCoordPrecision
TexCoordPrecisionRequired(GLES2Interface
* context
,
75 int* highp_threshold_cache
,
76 int highp_threshold_min
,
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
84 GLint range
[2] = {14, 14};
87 context
->GetShaderPrecisionFormat(
88 GL_FRAGMENT_SHADER
, GL_MEDIUM_FLOAT
, range
, &precision
));
89 *highp_threshold_cache
= 1 << precision
;
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
;
98 static std::string
SetFragmentSamplerType(SamplerType requested_type
,
99 std::string shader_string
) {
100 switch (requested_type
) {
102 DCHECK_NE(shader_string
.find("SamplerType"), std::string::npos
);
103 DCHECK_NE(shader_string
.find("TextureLookup"), std::string::npos
);
104 return "#define SamplerType sampler2D\n"
105 "#define TextureLookup texture2D\n" +
107 case SamplerType2DRect
:
108 DCHECK_NE(shader_string
.find("SamplerType"), std::string::npos
);
109 DCHECK_NE(shader_string
.find("TextureLookup"), std::string::npos
);
110 return "#extension GL_ARB_texture_rectangle : require\n"
111 "#define SamplerType sampler2DRect\n"
112 "#define TextureLookup texture2DRect\n" +
114 case SamplerTypeExternalOES
:
115 DCHECK_NE(shader_string
.find("SamplerType"), std::string::npos
);
116 DCHECK_NE(shader_string
.find("TextureLookup"), std::string::npos
);
117 return "#extension GL_OES_EGL_image_external : require\n"
118 "#define SamplerType samplerExternalOES\n"
119 "#define TextureLookup texture2D\n" +
122 DCHECK_EQ(shader_string
.find("SamplerType"), std::string::npos
);
123 DCHECK_EQ(shader_string
.find("TextureLookup"), std::string::npos
);
124 return shader_string
;
129 return shader_string
;
134 TexCoordPrecision
TexCoordPrecisionRequired(GLES2Interface
* context
,
135 int* highp_threshold_cache
,
136 int highp_threshold_min
,
137 const gfx::Point
& max_coordinate
) {
138 return TexCoordPrecisionRequired(context
,
139 highp_threshold_cache
,
145 TexCoordPrecision
TexCoordPrecisionRequired(GLES2Interface
* context
,
146 int* highp_threshold_cache
,
147 int highp_threshold_min
,
148 const gfx::Size
& max_size
) {
149 return TexCoordPrecisionRequired(context
,
150 highp_threshold_cache
,
156 VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) {
159 void VertexShaderPosTex::Init(GLES2Interface
* context
,
161 int* base_uniform_index
) {
162 static const char* uniforms
[] = {
165 int locations
[arraysize(uniforms
)];
167 GetProgramUniformLocations(context
,
173 matrix_location_
= locations
[0];
176 std::string
VertexShaderPosTex::GetShaderString() const {
178 return VERTEX_SHADER(
180 attribute vec4 a_position
;
181 attribute TexCoordPrecision vec2 a_texCoord
;
183 varying TexCoordPrecision vec2 v_texCoord
;
185 gl_Position
= matrix
* a_position
;
186 v_texCoord
= a_texCoord
;
189 ); // NOLINT(whitespace/parens)
193 VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset()
194 : matrix_location_(-1), tex_scale_location_(-1), tex_offset_location_(-1) {
197 void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface
* context
,
199 int* base_uniform_index
) {
200 static const char* uniforms
[] = {
201 "matrix", "texScale", "texOffset",
203 int locations
[arraysize(uniforms
)];
205 GetProgramUniformLocations(context
,
211 matrix_location_
= locations
[0];
212 tex_scale_location_
= locations
[1];
213 tex_offset_location_
= locations
[2];
216 std::string
VertexShaderPosTexYUVStretchOffset::GetShaderString() const {
218 return VERTEX_SHADER(
220 precision mediump
float;
221 attribute vec4 a_position
;
222 attribute TexCoordPrecision vec2 a_texCoord
;
224 varying TexCoordPrecision vec2 v_texCoord
;
225 uniform TexCoordPrecision vec2 texScale
;
226 uniform TexCoordPrecision vec2 texOffset
;
228 gl_Position
= matrix
* a_position
;
229 v_texCoord
= a_texCoord
* texScale
+ texOffset
;
232 ); // NOLINT(whitespace/parens)
236 VertexShaderPos::VertexShaderPos() : matrix_location_(-1) {
239 void VertexShaderPos::Init(GLES2Interface
* context
,
241 int* base_uniform_index
) {
242 static const char* uniforms
[] = {
245 int locations
[arraysize(uniforms
)];
247 GetProgramUniformLocations(context
,
253 matrix_location_
= locations
[0];
256 std::string
VertexShaderPos::GetShaderString() const {
258 return VERTEX_SHADER(
260 attribute vec4 a_position
;
262 void main() { gl_Position
= matrix
* a_position
; }
264 ); // NOLINT(whitespace/parens)
268 VertexShaderPosTexTransform::VertexShaderPosTexTransform()
269 : matrix_location_(-1),
270 tex_transform_location_(-1),
271 vertex_opacity_location_(-1) {
274 void VertexShaderPosTexTransform::Init(GLES2Interface
* context
,
276 int* base_uniform_index
) {
277 static const char* uniforms
[] = {
278 "matrix", "texTransform", "opacity",
280 int locations
[arraysize(uniforms
)];
282 GetProgramUniformLocations(context
,
288 matrix_location_
= locations
[0];
289 tex_transform_location_
= locations
[1];
290 vertex_opacity_location_
= locations
[2];
293 std::string
VertexShaderPosTexTransform::GetShaderString() const {
295 return VERTEX_SHADER(
297 attribute vec4 a_position
;
298 attribute TexCoordPrecision vec2 a_texCoord
;
299 attribute
float a_index
;
300 uniform mat4 matrix
[8];
301 uniform TexCoordPrecision vec4 texTransform
[8];
302 uniform
float opacity
[32];
303 varying TexCoordPrecision vec2 v_texCoord
;
304 varying
float v_alpha
;
306 int quad_index
= int(a_index
* 0.25); // NOLINT
307 gl_Position
= matrix
[quad_index
] * a_position
;
308 TexCoordPrecision vec4 texTrans
= texTransform
[quad_index
];
309 v_texCoord
= a_texCoord
* texTrans
.zw
+ texTrans
.xy
;
310 v_alpha
= opacity
[int(a_index
)]; // NOLINT
313 ); // NOLINT(whitespace/parens)
317 std::string
VertexShaderPosTexIdentity::GetShaderString() const {
319 return VERTEX_SHADER(
321 attribute vec4 a_position
;
322 varying TexCoordPrecision vec2 v_texCoord
;
324 gl_Position
= a_position
;
325 v_texCoord
= (a_position
.xy
+ vec2(1.0)) * 0.5;
328 ); // NOLINT(whitespace/parens)
332 VertexShaderQuad::VertexShaderQuad()
333 : matrix_location_(-1), quad_location_(-1) {
336 void VertexShaderQuad::Init(GLES2Interface
* context
,
338 int* base_uniform_index
) {
339 static const char* uniforms
[] = {
342 int locations
[arraysize(uniforms
)];
344 GetProgramUniformLocations(context
,
350 matrix_location_
= locations
[0];
351 quad_location_
= locations
[1];
354 std::string
VertexShaderQuad::GetShaderString() const {
355 #if defined(OS_ANDROID)
356 // TODO(epenner): Find the cause of this 'quad' uniform
357 // being missing if we don't add dummy variables.
358 // http://crbug.com/240602
360 return VERTEX_SHADER(
362 attribute TexCoordPrecision vec4 a_position
;
363 attribute
float a_index
;
365 uniform TexCoordPrecision vec2 quad
[4];
366 uniform TexCoordPrecision vec2 dummy_uniform
;
367 varying TexCoordPrecision vec2 dummy_varying
;
369 vec2 pos
= quad
[int(a_index
)]; // NOLINT
370 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
371 dummy_varying
= dummy_uniform
;
374 ); // NOLINT(whitespace/parens)
378 return VERTEX_SHADER(
380 attribute TexCoordPrecision vec4 a_position
;
381 attribute
float a_index
;
383 uniform TexCoordPrecision vec2 quad
[4];
385 vec2 pos
= quad
[int(a_index
)]; // NOLINT
386 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
389 ); // NOLINT(whitespace/parens)
394 VertexShaderQuadAA::VertexShaderQuadAA()
395 : matrix_location_(-1),
396 viewport_location_(-1),
401 void VertexShaderQuadAA::Init(GLES2Interface
* context
,
403 int* base_uniform_index
) {
404 static const char* uniforms
[] = {
405 "matrix", "viewport", "quad", "edge",
407 int locations
[arraysize(uniforms
)];
409 GetProgramUniformLocations(context
,
415 matrix_location_
= locations
[0];
416 viewport_location_
= locations
[1];
417 quad_location_
= locations
[2];
418 edge_location_
= locations
[3];
421 std::string
VertexShaderQuadAA::GetShaderString() const {
423 return VERTEX_SHADER(
425 attribute TexCoordPrecision vec4 a_position
;
426 attribute
float a_index
;
428 uniform vec4 viewport
;
429 uniform TexCoordPrecision vec2 quad
[4];
430 uniform TexCoordPrecision vec3 edge
[8];
431 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
434 vec2 pos
= quad
[int(a_index
)]; // NOLINT
435 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
436 vec2 ndc_pos
= 0.5 * (1.0 + gl_Position
.xy
/ gl_Position
.w
);
437 vec3 screen_pos
= vec3(viewport
.xy
+ viewport
.zw
* ndc_pos
, 1.0);
438 edge_dist
[0] = vec4(dot(edge
[0], screen_pos
),
439 dot(edge
[1], screen_pos
),
440 dot(edge
[2], screen_pos
),
441 dot(edge
[3], screen_pos
)) *
443 edge_dist
[1] = vec4(dot(edge
[4], screen_pos
),
444 dot(edge
[5], screen_pos
),
445 dot(edge
[6], screen_pos
),
446 dot(edge
[7], screen_pos
)) *
450 ); // NOLINT(whitespace/parens)
454 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
455 : matrix_location_(-1),
456 viewport_location_(-1),
459 tex_transform_location_(-1) {
462 void VertexShaderQuadTexTransformAA::Init(GLES2Interface
* context
,
464 int* base_uniform_index
) {
465 static const char* uniforms
[] = {
466 "matrix", "viewport", "quad", "edge", "texTrans",
468 int locations
[arraysize(uniforms
)];
470 GetProgramUniformLocations(context
,
476 matrix_location_
= locations
[0];
477 viewport_location_
= locations
[1];
478 quad_location_
= locations
[2];
479 edge_location_
= locations
[3];
480 tex_transform_location_
= locations
[4];
483 std::string
VertexShaderQuadTexTransformAA::GetShaderString() const {
485 return VERTEX_SHADER(
487 attribute TexCoordPrecision vec4 a_position
;
488 attribute
float a_index
;
490 uniform vec4 viewport
;
491 uniform TexCoordPrecision vec2 quad
[4];
492 uniform TexCoordPrecision vec3 edge
[8];
493 uniform TexCoordPrecision vec4 texTrans
;
494 varying TexCoordPrecision vec2 v_texCoord
;
495 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
498 vec2 pos
= quad
[int(a_index
)]; // NOLINT
499 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
500 vec2 ndc_pos
= 0.5 * (1.0 + gl_Position
.xy
/ gl_Position
.w
);
501 vec3 screen_pos
= vec3(viewport
.xy
+ viewport
.zw
* ndc_pos
, 1.0);
502 edge_dist
[0] = vec4(dot(edge
[0], screen_pos
),
503 dot(edge
[1], screen_pos
),
504 dot(edge
[2], screen_pos
),
505 dot(edge
[3], screen_pos
)) *
507 edge_dist
[1] = vec4(dot(edge
[4], screen_pos
),
508 dot(edge
[5], screen_pos
),
509 dot(edge
[6], screen_pos
),
510 dot(edge
[7], screen_pos
)) *
512 v_texCoord
= (pos
.xy
+ vec2(0.5)) * texTrans
.zw
+ texTrans
.xy
;
515 ); // NOLINT(whitespace/parens)
519 VertexShaderTile::VertexShaderTile()
520 : matrix_location_(-1),
522 vertex_tex_transform_location_(-1) {
525 void VertexShaderTile::Init(GLES2Interface
* context
,
527 int* base_uniform_index
) {
528 static const char* uniforms
[] = {
529 "matrix", "quad", "vertexTexTransform",
531 int locations
[arraysize(uniforms
)];
533 GetProgramUniformLocations(context
,
539 matrix_location_
= locations
[0];
540 quad_location_
= locations
[1];
541 vertex_tex_transform_location_
= locations
[2];
544 std::string
VertexShaderTile::GetShaderString() const {
546 return VERTEX_SHADER(
548 attribute TexCoordPrecision vec4 a_position
;
549 attribute TexCoordPrecision vec2 a_texCoord
;
550 attribute
float a_index
;
552 uniform TexCoordPrecision vec2 quad
[4];
553 uniform TexCoordPrecision vec4 vertexTexTransform
;
554 varying TexCoordPrecision vec2 v_texCoord
;
556 vec2 pos
= quad
[int(a_index
)]; // NOLINT
557 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
558 v_texCoord
= a_texCoord
* vertexTexTransform
.zw
+ vertexTexTransform
.xy
;
561 ); // NOLINT(whitespace/parens)
565 VertexShaderTileAA::VertexShaderTileAA()
566 : matrix_location_(-1),
567 viewport_location_(-1),
570 vertex_tex_transform_location_(-1) {
573 void VertexShaderTileAA::Init(GLES2Interface
* context
,
575 int* base_uniform_index
) {
576 static const char* uniforms
[] = {
577 "matrix", "viewport", "quad", "edge", "vertexTexTransform",
579 int locations
[arraysize(uniforms
)];
581 GetProgramUniformLocations(context
,
587 matrix_location_
= locations
[0];
588 viewport_location_
= locations
[1];
589 quad_location_
= locations
[2];
590 edge_location_
= locations
[3];
591 vertex_tex_transform_location_
= locations
[4];
594 std::string
VertexShaderTileAA::GetShaderString() const {
596 return VERTEX_SHADER(
598 attribute TexCoordPrecision vec4 a_position
;
599 attribute
float a_index
;
601 uniform vec4 viewport
;
602 uniform TexCoordPrecision vec2 quad
[4];
603 uniform TexCoordPrecision vec3 edge
[8];
604 uniform TexCoordPrecision vec4 vertexTexTransform
;
605 varying TexCoordPrecision vec2 v_texCoord
;
606 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
609 vec2 pos
= quad
[int(a_index
)]; // NOLINT
610 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
611 vec2 ndc_pos
= 0.5 * (1.0 + gl_Position
.xy
/ gl_Position
.w
);
612 vec3 screen_pos
= vec3(viewport
.xy
+ viewport
.zw
* ndc_pos
, 1.0);
613 edge_dist
[0] = vec4(dot(edge
[0], screen_pos
),
614 dot(edge
[1], screen_pos
),
615 dot(edge
[2], screen_pos
),
616 dot(edge
[3], screen_pos
)) *
618 edge_dist
[1] = vec4(dot(edge
[4], screen_pos
),
619 dot(edge
[5], screen_pos
),
620 dot(edge
[6], screen_pos
),
621 dot(edge
[7], screen_pos
)) *
623 v_texCoord
= pos
.xy
* vertexTexTransform
.zw
+ vertexTexTransform
.xy
;
626 ); // NOLINT(whitespace/parens)
630 VertexShaderVideoTransform::VertexShaderVideoTransform()
631 : matrix_location_(-1), tex_matrix_location_(-1) {
634 void VertexShaderVideoTransform::Init(GLES2Interface
* context
,
636 int* base_uniform_index
) {
637 static const char* uniforms
[] = {
638 "matrix", "texMatrix",
640 int locations
[arraysize(uniforms
)];
642 GetProgramUniformLocations(context
,
648 matrix_location_
= locations
[0];
649 tex_matrix_location_
= locations
[1];
652 std::string
VertexShaderVideoTransform::GetShaderString() const {
654 return VERTEX_SHADER(
656 attribute vec4 a_position
;
657 attribute TexCoordPrecision vec2 a_texCoord
;
659 uniform TexCoordPrecision mat4 texMatrix
;
660 varying TexCoordPrecision vec2 v_texCoord
;
662 gl_Position
= matrix
* a_position
;
664 vec2(texMatrix
* vec4(a_texCoord
.x
, 1.0 - a_texCoord
.y
, 0.0, 1.0));
667 ); // NOLINT(whitespace/parens)
671 #define BLEND_MODE_UNIFORMS "s_backdropTexture", "backdropRect"
672 #define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 2 : 0)
673 #define BLEND_MODE_SET_LOCATIONS(X, POS) \
674 if (has_blend_mode()) { \
675 DCHECK_LT(static_cast<size_t>(POS) + 1, arraysize(X)); \
676 backdrop_location_ = locations[POS]; \
677 backdrop_rect_location_ = locations[POS + 1]; \
680 FragmentTexBlendMode::FragmentTexBlendMode()
681 : backdrop_location_(-1),
682 backdrop_rect_location_(-1),
683 blend_mode_(BlendModeNone
) {
686 std::string
FragmentTexBlendMode::SetBlendModeFunctions(
687 std::string shader_string
) const {
688 if (shader_string
.find("ApplyBlendMode") == std::string::npos
)
689 return shader_string
;
691 if (!has_blend_mode()) {
692 return "#define ApplyBlendMode(X) (X)\n" + shader_string
;
696 static const std::string kFunctionApplyBlendMode
= SHADER0(
698 uniform SamplerType s_backdropTexture
;
699 uniform TexCoordPrecision vec4 backdropRect
;
701 vec4
GetBackdropColor() {
702 TexCoordPrecision vec2 bgTexCoord
= gl_FragCoord
.xy
- backdropRect
.xy
;
703 bgTexCoord
.x
/= backdropRect
.z
;
704 bgTexCoord
.y
/= backdropRect
.w
;
705 return TextureLookup(s_backdropTexture
, bgTexCoord
);
708 vec4
ApplyBlendMode(vec4 src
) {
709 vec4 dst
= GetBackdropColor();
710 return Blend(src
, dst
);
713 ); // NOLINT(whitespace/parens)
716 return "precision mediump float;" + GetHelperFunctions() +
717 GetBlendFunction() + kFunctionApplyBlendMode
+ shader_string
;
720 std::string
FragmentTexBlendMode::GetHelperFunctions() const {
722 static const std::string kFunctionHardLight
= SHADER0(
724 vec3
hardLight(vec4 src
, vec4 dst
) {
727 (2.0 * src
.r
<= src
.a
)
728 ? (2.0 * src
.r
* dst
.r
)
729 : (src
.a
* dst
.a
- 2.0 * (dst
.a
- dst
.r
) * (src
.a
- src
.r
));
731 (2.0 * src
.g
<= src
.a
)
732 ? (2.0 * src
.g
* dst
.g
)
733 : (src
.a
* dst
.a
- 2.0 * (dst
.a
- dst
.g
) * (src
.a
- src
.g
));
735 (2.0 * src
.b
<= src
.a
)
736 ? (2.0 * src
.b
* dst
.b
)
737 : (src
.a
* dst
.a
- 2.0 * (dst
.a
- dst
.b
) * (src
.a
- src
.b
));
738 result
.rgb
+= src
.rgb
* (1.0 - dst
.a
) + dst
.rgb
* (1.0 - src
.a
);
742 ); // NOLINT(whitespace/parens)
744 static const std::string kFunctionColorDodgeComponent
= SHADER0(
746 float getColorDodgeComponent(
747 float srcc
, float srca
, float dstc
, float dsta
) {
749 return srcc
* (1.0 - dsta
);
750 float d
= srca
- srcc
;
752 return srca
* dsta
+ srcc
* (1.0 - dsta
) + dstc
* (1.0 - srca
);
753 d
= min(dsta
, dstc
* srca
/ d
);
754 return d
* srca
+ srcc
* (1.0 - dsta
) + dstc
* (1.0 - srca
);
757 ); // NOLINT(whitespace/parens)
759 static const std::string kFunctionColorBurnComponent
= SHADER0(
761 float getColorBurnComponent(
762 float srcc
, float srca
, float dstc
, float dsta
) {
764 return srca
* dsta
+ srcc
* (1.0 - dsta
) + dstc
* (1.0 - srca
);
766 return dstc
* (1.0 - srca
);
767 float d
= max(0.0, dsta
- (dsta
- dstc
) * srca
/ srcc
);
768 return srca
* d
+ srcc
* (1.0 - dsta
) + dstc
* (1.0 - srca
);
771 ); // NOLINT(whitespace/parens)
773 static const std::string kFunctionSoftLightComponentPosDstAlpha
= SHADER0(
775 float getSoftLightComponent(
776 float srcc
, float srca
, float dstc
, float dsta
) {
777 if (2.0 * srcc
<= srca
) {
778 return (dstc
* dstc
* (srca
- 2.0 * srcc
)) / dsta
+
779 (1.0 - dsta
) * srcc
+ dstc
* (-srca
+ 2.0 * srcc
+ 1.0);
780 } else if (4.0 * dstc
<= dsta
) {
781 float DSqd
= dstc
* dstc
;
782 float DCub
= DSqd
* dstc
;
783 float DaSqd
= dsta
* dsta
;
784 float DaCub
= DaSqd
* dsta
;
785 return (-DaCub
* srcc
+
786 DaSqd
* (srcc
- dstc
* (3.0 * srca
- 6.0 * srcc
- 1.0)) +
787 12.0 * dsta
* DSqd
* (srca
- 2.0 * srcc
) -
788 16.0 * DCub
* (srca
- 2.0 * srcc
)) /
791 return -sqrt(dsta
* dstc
) * (srca
- 2.0 * srcc
) - dsta
* srcc
+
792 dstc
* (srca
- 2.0 * srcc
+ 1.0) + srcc
;
796 ); // NOLINT(whitespace/parens)
798 static const std::string kFunctionLum
= SHADER0(
800 float luminance(vec3 color
) { return dot(vec3(0.3, 0.59, 0.11), color
); }
802 vec3
set_luminance(vec3 hueSat
, float alpha
, vec3 lumColor
) {
803 float diff
= luminance(lumColor
- hueSat
);
804 vec3 outColor
= hueSat
+ diff
;
805 float outLum
= luminance(outColor
);
806 float minComp
= min(min(outColor
.r
, outColor
.g
), outColor
.b
);
807 float maxComp
= max(max(outColor
.r
, outColor
.g
), outColor
.b
);
808 if (minComp
< 0.0 && outLum
!= minComp
) {
810 ((outColor
- vec3(outLum
, outLum
, outLum
)) * outLum
) /
813 if (maxComp
> alpha
&& maxComp
!= outLum
) {
816 ((outColor
- vec3(outLum
, outLum
, outLum
)) * (alpha
- outLum
)) /
822 ); // NOLINT(whitespace/parens)
824 static const std::string kFunctionSat
= SHADER0(
826 float saturation(vec3 color
) {
827 return max(max(color
.r
, color
.g
), color
.b
) -
828 min(min(color
.r
, color
.g
), color
.b
);
831 vec3
set_saturation_helper(
832 float minComp
, float midComp
, float maxComp
, float sat
) {
833 if (minComp
< maxComp
) {
836 result
.g
= sat
* (midComp
- minComp
) / (maxComp
- minComp
);
840 return vec3(0, 0, 0);
844 vec3
set_saturation(vec3 hueLumColor
, vec3 satColor
) {
845 float sat
= saturation(satColor
);
846 if (hueLumColor
.r
<= hueLumColor
.g
) {
847 if (hueLumColor
.g
<= hueLumColor
.b
) {
848 hueLumColor
.rgb
= set_saturation_helper(
849 hueLumColor
.r
, hueLumColor
.g
, hueLumColor
.b
, sat
);
850 } else if (hueLumColor
.r
<= hueLumColor
.b
) {
851 hueLumColor
.rbg
= set_saturation_helper(
852 hueLumColor
.r
, hueLumColor
.b
, hueLumColor
.g
, sat
);
854 hueLumColor
.brg
= set_saturation_helper(
855 hueLumColor
.b
, hueLumColor
.r
, hueLumColor
.g
, sat
);
857 } else if (hueLumColor
.r
<= hueLumColor
.b
) {
858 hueLumColor
.grb
= set_saturation_helper(
859 hueLumColor
.g
, hueLumColor
.r
, hueLumColor
.b
, sat
);
860 } else if (hueLumColor
.g
<= hueLumColor
.b
) {
861 hueLumColor
.gbr
= set_saturation_helper(
862 hueLumColor
.g
, hueLumColor
.b
, hueLumColor
.r
, sat
);
864 hueLumColor
.bgr
= set_saturation_helper(
865 hueLumColor
.b
, hueLumColor
.g
, hueLumColor
.r
, sat
);
870 ); // NOLINT(whitespace/parens)
873 switch (blend_mode_
) {
874 case BlendModeOverlay
:
875 case BlendModeHardLight
:
876 return kFunctionHardLight
;
877 case BlendModeColorDodge
:
878 return kFunctionColorDodgeComponent
;
879 case BlendModeColorBurn
:
880 return kFunctionColorBurnComponent
;
881 case BlendModeSoftLight
:
882 return kFunctionSoftLightComponentPosDstAlpha
;
884 case BlendModeSaturation
:
885 return kFunctionLum
+ kFunctionSat
;
887 case BlendModeLuminosity
:
890 return std::string();
894 std::string
FragmentTexBlendMode::GetBlendFunction() const {
895 return "vec4 Blend(vec4 src, vec4 dst) {"
897 " result.a = src.a + (1.0 - src.a) * dst.a;" +
898 GetBlendFunctionBodyForRGB() +
903 std::string
FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
904 switch (blend_mode_
) {
905 case BlendModeNormal
:
906 return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
907 case BlendModeScreen
:
908 return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
909 case BlendModeLighten
:
910 return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
911 " (1.0 - dst.a) * src.rgb + dst.rgb);";
912 case BlendModeOverlay
:
913 return "result.rgb = hardLight(dst, src);";
914 case BlendModeDarken
:
915 return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb,"
916 " (1.0 - dst.a) * src.rgb + dst.rgb);";
917 case BlendModeColorDodge
:
918 return "result.r = getColorDodgeComponent(src.r, src.a, dst.r, dst.a);"
919 "result.g = getColorDodgeComponent(src.g, src.a, dst.g, dst.a);"
920 "result.b = getColorDodgeComponent(src.b, src.a, dst.b, dst.a);";
921 case BlendModeColorBurn
:
922 return "result.r = getColorBurnComponent(src.r, src.a, dst.r, dst.a);"
923 "result.g = getColorBurnComponent(src.g, src.a, dst.g, dst.a);"
924 "result.b = getColorBurnComponent(src.b, src.a, dst.b, dst.a);";
925 case BlendModeHardLight
:
926 return "result.rgb = hardLight(src, dst);";
927 case BlendModeSoftLight
:
928 return "if (0.0 == dst.a) {"
929 " result.rgb = src.rgb;"
931 " result.r = getSoftLightComponent(src.r, src.a, dst.r, dst.a);"
932 " result.g = getSoftLightComponent(src.g, src.a, dst.g, dst.a);"
933 " result.b = getSoftLightComponent(src.b, src.a, dst.b, dst.a);"
935 case BlendModeDifference
:
936 return "result.rgb = src.rgb + dst.rgb -"
937 " 2.0 * min(src.rgb * dst.a, dst.rgb * src.a);";
938 case BlendModeExclusion
:
939 return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;";
940 case BlendModeMultiply
:
941 return "result.rgb = (1.0 - src.a) * dst.rgb +"
942 " (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;";
944 return "vec4 dstSrcAlpha = dst * src.a;"
946 " set_luminance(set_saturation(src.rgb * dst.a,"
950 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
951 case BlendModeSaturation
:
952 return "vec4 dstSrcAlpha = dst * src.a;"
953 "result.rgb = set_luminance(set_saturation(dstSrcAlpha.rgb,"
957 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
959 return "vec4 srcDstAlpha = src * dst.a;"
960 "result.rgb = set_luminance(srcDstAlpha.rgb,"
963 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
964 case BlendModeLuminosity
:
965 return "vec4 srcDstAlpha = src * dst.a;"
966 "result.rgb = set_luminance(dst.rgb * src.a,"
969 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
974 return "result = vec4(1.0, 0.0, 0.0, 1.0);";
977 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
978 : sampler_location_(-1), alpha_location_(-1) {
981 void FragmentTexAlphaBinding::Init(GLES2Interface
* context
,
983 int* base_uniform_index
) {
984 static const char* uniforms
[] = {
985 "s_texture", "alpha", BLEND_MODE_UNIFORMS
,
987 int locations
[arraysize(uniforms
)];
989 GetProgramUniformLocations(context
,
991 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
995 sampler_location_
= locations
[0];
996 alpha_location_
= locations
[1];
997 BLEND_MODE_SET_LOCATIONS(locations
, 2);
1000 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
1001 : sampler_location_(-1),
1002 alpha_location_(-1),
1003 color_matrix_location_(-1),
1004 color_offset_location_(-1) {
1007 void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface
* context
,
1009 int* base_uniform_index
) {
1010 static const char* uniforms
[] = {
1011 "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS
,
1013 int locations
[arraysize(uniforms
)];
1015 GetProgramUniformLocations(context
,
1017 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1020 base_uniform_index
);
1021 sampler_location_
= locations
[0];
1022 alpha_location_
= locations
[1];
1023 color_matrix_location_
= locations
[2];
1024 color_offset_location_
= locations
[3];
1025 BLEND_MODE_SET_LOCATIONS(locations
, 4);
1028 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding() : sampler_location_(-1) {
1031 void FragmentTexOpaqueBinding::Init(GLES2Interface
* context
,
1033 int* base_uniform_index
) {
1034 static const char* uniforms
[] = {
1037 int locations
[arraysize(uniforms
)];
1039 GetProgramUniformLocations(context
,
1041 arraysize(uniforms
),
1044 base_uniform_index
);
1045 sampler_location_
= locations
[0];
1048 std::string
FragmentShaderRGBATexAlpha::GetShaderString(
1049 TexCoordPrecision precision
,
1050 SamplerType sampler
) const {
1052 return FRAGMENT_SHADER(
1054 precision mediump
float;
1055 varying TexCoordPrecision vec2 v_texCoord
;
1056 uniform SamplerType s_texture
;
1057 uniform
float alpha
;
1059 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1060 gl_FragColor
= ApplyBlendMode(texColor
* alpha
);
1063 ); // NOLINT(whitespace/parens)
1067 std::string
FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
1068 TexCoordPrecision precision
,
1069 SamplerType sampler
) const {
1071 return FRAGMENT_SHADER(
1073 precision mediump
float;
1074 varying TexCoordPrecision vec2 v_texCoord
;
1075 uniform SamplerType s_texture
;
1076 uniform
float alpha
;
1077 uniform mat4 colorMatrix
;
1078 uniform vec4 colorOffset
;
1080 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1081 float nonZeroAlpha
= max(texColor
.a
, 0.00001);
1082 texColor
= vec4(texColor
.rgb
/ nonZeroAlpha
, nonZeroAlpha
);
1083 texColor
= colorMatrix
* texColor
+ colorOffset
;
1084 texColor
.rgb
*= texColor
.a
;
1085 texColor
= clamp(texColor
, 0.0, 1.0);
1086 gl_FragColor
= ApplyBlendMode(texColor
* alpha
);
1089 ); // NOLINT(whitespace/parens)
1093 std::string
FragmentShaderRGBATexVaryingAlpha::GetShaderString(
1094 TexCoordPrecision precision
,
1095 SamplerType sampler
) const {
1097 return FRAGMENT_SHADER(
1099 precision mediump
float;
1100 varying TexCoordPrecision vec2 v_texCoord
;
1101 varying
float v_alpha
;
1102 uniform SamplerType s_texture
;
1104 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1105 gl_FragColor
= texColor
* v_alpha
;
1108 ); // NOLINT(whitespace/parens)
1112 std::string
FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
1113 TexCoordPrecision precision
,
1114 SamplerType sampler
) const {
1116 return FRAGMENT_SHADER(
1118 precision mediump
float;
1119 varying TexCoordPrecision vec2 v_texCoord
;
1120 varying
float v_alpha
;
1121 uniform SamplerType s_texture
;
1123 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1124 texColor
.rgb
*= texColor
.a
;
1125 gl_FragColor
= texColor
* v_alpha
;
1128 ); // NOLINT(whitespace/parens)
1132 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
1133 : background_color_location_(-1), sampler_location_(-1) {
1136 void FragmentTexBackgroundBinding::Init(GLES2Interface
* context
,
1138 int* base_uniform_index
) {
1139 static const char* uniforms
[] = {
1140 "s_texture", "background_color",
1142 int locations
[arraysize(uniforms
)];
1144 GetProgramUniformLocations(context
,
1146 arraysize(uniforms
),
1149 base_uniform_index
);
1151 sampler_location_
= locations
[0];
1152 DCHECK_NE(sampler_location_
, -1);
1154 background_color_location_
= locations
[1];
1155 DCHECK_NE(background_color_location_
, -1);
1158 std::string
FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
1159 TexCoordPrecision precision
,
1160 SamplerType sampler
) const {
1162 return FRAGMENT_SHADER(
1164 precision mediump
float;
1165 varying TexCoordPrecision vec2 v_texCoord
;
1166 varying
float v_alpha
;
1167 uniform vec4 background_color
;
1168 uniform SamplerType s_texture
;
1170 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1171 texColor
+= background_color
* (1.0 - texColor
.a
);
1172 gl_FragColor
= texColor
* v_alpha
;
1175 ); // NOLINT(whitespace/parens)
1179 std::string
FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
1180 TexCoordPrecision precision
,
1181 SamplerType sampler
) const {
1183 return FRAGMENT_SHADER(
1185 precision mediump
float;
1186 varying TexCoordPrecision vec2 v_texCoord
;
1187 varying
float v_alpha
;
1188 uniform vec4 background_color
;
1189 uniform SamplerType s_texture
;
1191 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1192 texColor
.rgb
*= texColor
.a
;
1193 texColor
+= background_color
* (1.0 - texColor
.a
);
1194 gl_FragColor
= texColor
* v_alpha
;
1197 ); // NOLINT(whitespace/parens)
1201 std::string
FragmentShaderRGBATexOpaque::GetShaderString(
1202 TexCoordPrecision precision
,
1203 SamplerType sampler
) const {
1205 return FRAGMENT_SHADER(
1207 precision mediump
float;
1208 varying TexCoordPrecision vec2 v_texCoord
;
1209 uniform SamplerType s_texture
;
1211 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1212 gl_FragColor
= vec4(texColor
.rgb
, 1.0);
1215 ); // NOLINT(whitespace/parens)
1219 std::string
FragmentShaderRGBATex::GetShaderString(TexCoordPrecision precision
,
1220 SamplerType sampler
) const {
1222 return FRAGMENT_SHADER(
1224 precision mediump
float;
1225 varying TexCoordPrecision vec2 v_texCoord
;
1226 uniform SamplerType s_texture
;
1227 void main() { gl_FragColor
= TextureLookup(s_texture
, v_texCoord
); }
1229 ); // NOLINT(whitespace/parens)
1233 std::string
FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
1234 TexCoordPrecision precision
,
1235 SamplerType sampler
) const {
1237 return FRAGMENT_SHADER(
1239 precision mediump
float;
1240 varying TexCoordPrecision vec2 v_texCoord
;
1241 uniform SamplerType s_texture
;
1242 uniform
float alpha
;
1244 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1246 vec4(texColor
.z
, texColor
.y
, texColor
.x
, texColor
.w
) * alpha
;
1249 ); // NOLINT(whitespace/parens)
1253 std::string
FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
1254 TexCoordPrecision precision
,
1255 SamplerType sampler
) const {
1257 return FRAGMENT_SHADER(
1259 precision mediump
float;
1260 varying TexCoordPrecision vec2 v_texCoord
;
1261 uniform SamplerType s_texture
;
1263 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1264 gl_FragColor
= vec4(texColor
.z
, texColor
.y
, texColor
.x
, 1.0);
1267 ); // NOLINT(whitespace/parens)
1271 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
1272 : sampler_location_(-1), alpha_location_(-1) {
1275 void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface
* context
,
1277 int* base_uniform_index
) {
1278 static const char* uniforms
[] = {
1279 "s_texture", "alpha", BLEND_MODE_UNIFORMS
,
1281 int locations
[arraysize(uniforms
)];
1283 GetProgramUniformLocations(context
,
1285 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1288 base_uniform_index
);
1289 sampler_location_
= locations
[0];
1290 alpha_location_
= locations
[1];
1291 BLEND_MODE_SET_LOCATIONS(locations
, 2);
1294 std::string
FragmentShaderRGBATexAlphaAA::GetShaderString(
1295 TexCoordPrecision precision
,
1296 SamplerType sampler
) const {
1298 return FRAGMENT_SHADER(
1300 precision mediump
float;
1301 uniform SamplerType s_texture
;
1302 uniform
float alpha
;
1303 varying TexCoordPrecision vec2 v_texCoord
;
1304 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
1307 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1308 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1309 vec2 d2
= min(d4
.xz
, d4
.yw
);
1310 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1311 gl_FragColor
= ApplyBlendMode(texColor
* alpha
* aa
);
1314 ); // NOLINT(whitespace/parens)
1318 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
1319 : sampler_location_(-1),
1320 alpha_location_(-1),
1321 fragment_tex_transform_location_(-1) {
1324 void FragmentTexClampAlphaAABinding::Init(GLES2Interface
* context
,
1326 int* base_uniform_index
) {
1327 static const char* uniforms
[] = {
1328 "s_texture", "alpha", "fragmentTexTransform",
1330 int locations
[arraysize(uniforms
)];
1332 GetProgramUniformLocations(context
,
1334 arraysize(uniforms
),
1337 base_uniform_index
);
1338 sampler_location_
= locations
[0];
1339 alpha_location_
= locations
[1];
1340 fragment_tex_transform_location_
= locations
[2];
1343 std::string
FragmentShaderRGBATexClampAlphaAA::GetShaderString(
1344 TexCoordPrecision precision
,
1345 SamplerType sampler
) const {
1347 return FRAGMENT_SHADER(
1349 precision mediump
float;
1350 uniform SamplerType s_texture
;
1351 uniform
float alpha
;
1352 uniform TexCoordPrecision vec4 fragmentTexTransform
;
1353 varying TexCoordPrecision vec2 v_texCoord
;
1354 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
1357 TexCoordPrecision vec2 texCoord
=
1358 clamp(v_texCoord
, 0.0, 1.0) * fragmentTexTransform
.zw
+
1359 fragmentTexTransform
.xy
;
1360 vec4 texColor
= TextureLookup(s_texture
, texCoord
);
1361 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1362 vec2 d2
= min(d4
.xz
, d4
.yw
);
1363 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1364 gl_FragColor
= texColor
* alpha
* aa
;
1367 ); // NOLINT(whitespace/parens)
1371 std::string
FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
1372 TexCoordPrecision precision
,
1373 SamplerType sampler
) const {
1375 return FRAGMENT_SHADER(
1377 precision mediump
float;
1378 uniform SamplerType s_texture
;
1379 uniform
float alpha
;
1380 uniform TexCoordPrecision vec4 fragmentTexTransform
;
1381 varying TexCoordPrecision vec2 v_texCoord
;
1382 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
1385 TexCoordPrecision vec2 texCoord
=
1386 clamp(v_texCoord
, 0.0, 1.0) * fragmentTexTransform
.zw
+
1387 fragmentTexTransform
.xy
;
1388 vec4 texColor
= TextureLookup(s_texture
, texCoord
);
1389 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1390 vec2 d2
= min(d4
.xz
, d4
.yw
);
1391 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1393 vec4(texColor
.z
, texColor
.y
, texColor
.x
, texColor
.w
) * alpha
* aa
;
1396 ); // NOLINT(whitespace/parens)
1400 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
1401 : sampler_location_(-1),
1402 mask_sampler_location_(-1),
1403 alpha_location_(-1),
1404 mask_tex_coord_scale_location_(-1) {
1407 void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface
* context
,
1409 int* base_uniform_index
) {
1410 static const char* uniforms
[] = {
1414 "maskTexCoordScale",
1415 "maskTexCoordOffset",
1416 BLEND_MODE_UNIFORMS
,
1418 int locations
[arraysize(uniforms
)];
1420 GetProgramUniformLocations(context
,
1422 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1425 base_uniform_index
);
1426 sampler_location_
= locations
[0];
1427 mask_sampler_location_
= locations
[1];
1428 alpha_location_
= locations
[2];
1429 mask_tex_coord_scale_location_
= locations
[3];
1430 mask_tex_coord_offset_location_
= locations
[4];
1431 BLEND_MODE_SET_LOCATIONS(locations
, 5);
1434 std::string
FragmentShaderRGBATexAlphaMask::GetShaderString(
1435 TexCoordPrecision precision
,
1436 SamplerType sampler
) const {
1438 return FRAGMENT_SHADER(
1440 precision mediump
float;
1441 varying TexCoordPrecision vec2 v_texCoord
;
1442 uniform sampler2D s_texture
;
1443 uniform SamplerType s_mask
;
1444 uniform TexCoordPrecision vec2 maskTexCoordScale
;
1445 uniform TexCoordPrecision vec2 maskTexCoordOffset
;
1446 uniform
float alpha
;
1448 vec4 texColor
= texture2D(s_texture
, v_texCoord
);
1449 TexCoordPrecision vec2 maskTexCoord
=
1450 vec2(maskTexCoordOffset
.x
+ v_texCoord
.x
* maskTexCoordScale
.x
,
1451 maskTexCoordOffset
.y
+ v_texCoord
.y
* maskTexCoordScale
.y
);
1452 vec4 maskColor
= TextureLookup(s_mask
, maskTexCoord
);
1453 gl_FragColor
= ApplyBlendMode(texColor
* alpha
* maskColor
.w
);
1456 ); // NOLINT(whitespace/parens)
1460 FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
1461 : sampler_location_(-1),
1462 mask_sampler_location_(-1),
1463 alpha_location_(-1),
1464 mask_tex_coord_scale_location_(-1),
1465 mask_tex_coord_offset_location_(-1) {
1468 void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface
* context
,
1470 int* base_uniform_index
) {
1471 static const char* uniforms
[] = {
1475 "maskTexCoordScale",
1476 "maskTexCoordOffset",
1477 BLEND_MODE_UNIFORMS
,
1479 int locations
[arraysize(uniforms
)];
1481 GetProgramUniformLocations(context
,
1483 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1486 base_uniform_index
);
1487 sampler_location_
= locations
[0];
1488 mask_sampler_location_
= locations
[1];
1489 alpha_location_
= locations
[2];
1490 mask_tex_coord_scale_location_
= locations
[3];
1491 mask_tex_coord_offset_location_
= locations
[4];
1492 BLEND_MODE_SET_LOCATIONS(locations
, 5);
1495 std::string
FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
1496 TexCoordPrecision precision
,
1497 SamplerType sampler
) const {
1499 return FRAGMENT_SHADER(
1501 precision mediump
float;
1502 uniform sampler2D s_texture
;
1503 uniform SamplerType s_mask
;
1504 uniform TexCoordPrecision vec2 maskTexCoordScale
;
1505 uniform TexCoordPrecision vec2 maskTexCoordOffset
;
1506 uniform
float alpha
;
1507 varying TexCoordPrecision vec2 v_texCoord
;
1508 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
1511 vec4 texColor
= texture2D(s_texture
, v_texCoord
);
1512 TexCoordPrecision vec2 maskTexCoord
=
1513 vec2(maskTexCoordOffset
.x
+ v_texCoord
.x
* maskTexCoordScale
.x
,
1514 maskTexCoordOffset
.y
+ v_texCoord
.y
* maskTexCoordScale
.y
);
1515 vec4 maskColor
= TextureLookup(s_mask
, maskTexCoord
);
1516 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1517 vec2 d2
= min(d4
.xz
, d4
.yw
);
1518 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1519 gl_FragColor
= ApplyBlendMode(texColor
* alpha
* maskColor
.w
* aa
);
1522 ); // NOLINT(whitespace/parens)
1526 FragmentShaderRGBATexAlphaMaskColorMatrixAA::
1527 FragmentShaderRGBATexAlphaMaskColorMatrixAA()
1528 : sampler_location_(-1),
1529 mask_sampler_location_(-1),
1530 alpha_location_(-1),
1531 mask_tex_coord_scale_location_(-1),
1532 color_matrix_location_(-1),
1533 color_offset_location_(-1) {
1536 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
1537 GLES2Interface
* context
,
1539 int* base_uniform_index
) {
1540 static const char* uniforms
[] = {
1544 "maskTexCoordScale",
1545 "maskTexCoordOffset",
1548 BLEND_MODE_UNIFORMS
,
1550 int locations
[arraysize(uniforms
)];
1552 GetProgramUniformLocations(context
,
1554 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1557 base_uniform_index
);
1558 sampler_location_
= locations
[0];
1559 mask_sampler_location_
= locations
[1];
1560 alpha_location_
= locations
[2];
1561 mask_tex_coord_scale_location_
= locations
[3];
1562 mask_tex_coord_offset_location_
= locations
[4];
1563 color_matrix_location_
= locations
[5];
1564 color_offset_location_
= locations
[6];
1565 BLEND_MODE_SET_LOCATIONS(locations
, 7);
1568 std::string
FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
1569 TexCoordPrecision precision
,
1570 SamplerType sampler
) const {
1572 return FRAGMENT_SHADER(
1574 precision mediump
float;
1575 uniform sampler2D s_texture
;
1576 uniform SamplerType s_mask
;
1577 uniform vec2 maskTexCoordScale
;
1578 uniform vec2 maskTexCoordOffset
;
1579 uniform mat4 colorMatrix
;
1580 uniform vec4 colorOffset
;
1581 uniform
float alpha
;
1582 varying TexCoordPrecision vec2 v_texCoord
;
1583 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
1586 vec4 texColor
= texture2D(s_texture
, v_texCoord
);
1587 float nonZeroAlpha
= max(texColor
.a
, 0.00001);
1588 texColor
= vec4(texColor
.rgb
/ nonZeroAlpha
, nonZeroAlpha
);
1589 texColor
= colorMatrix
* texColor
+ colorOffset
;
1590 texColor
.rgb
*= texColor
.a
;
1591 texColor
= clamp(texColor
, 0.0, 1.0);
1592 TexCoordPrecision vec2 maskTexCoord
=
1593 vec2(maskTexCoordOffset
.x
+ v_texCoord
.x
* maskTexCoordScale
.x
,
1594 maskTexCoordOffset
.y
+ v_texCoord
.y
* maskTexCoordScale
.y
);
1595 vec4 maskColor
= TextureLookup(s_mask
, maskTexCoord
);
1596 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1597 vec2 d2
= min(d4
.xz
, d4
.yw
);
1598 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1599 gl_FragColor
= ApplyBlendMode(texColor
* alpha
* maskColor
.w
* aa
);
1602 ); // NOLINT(whitespace/parens)
1606 FragmentShaderRGBATexAlphaColorMatrixAA::
1607 FragmentShaderRGBATexAlphaColorMatrixAA()
1608 : sampler_location_(-1),
1609 alpha_location_(-1),
1610 color_matrix_location_(-1),
1611 color_offset_location_(-1) {
1614 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(GLES2Interface
* context
,
1616 int* base_uniform_index
) {
1617 static const char* uniforms
[] = {
1618 "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS
,
1620 int locations
[arraysize(uniforms
)];
1622 GetProgramUniformLocations(context
,
1624 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1627 base_uniform_index
);
1628 sampler_location_
= locations
[0];
1629 alpha_location_
= locations
[1];
1630 color_matrix_location_
= locations
[2];
1631 color_offset_location_
= locations
[3];
1632 BLEND_MODE_SET_LOCATIONS(locations
, 4);
1635 std::string
FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
1636 TexCoordPrecision precision
,
1637 SamplerType sampler
) const {
1639 return FRAGMENT_SHADER(
1641 precision mediump
float;
1642 uniform SamplerType s_texture
;
1643 uniform
float alpha
;
1644 uniform mat4 colorMatrix
;
1645 uniform vec4 colorOffset
;
1646 varying TexCoordPrecision vec2 v_texCoord
;
1647 varying TexCoordPrecision vec4 edge_dist
[2]; // 8 edge distances.
1650 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
1651 float nonZeroAlpha
= max(texColor
.a
, 0.00001);
1652 texColor
= vec4(texColor
.rgb
/ nonZeroAlpha
, nonZeroAlpha
);
1653 texColor
= colorMatrix
* texColor
+ colorOffset
;
1654 texColor
.rgb
*= texColor
.a
;
1655 texColor
= clamp(texColor
, 0.0, 1.0);
1656 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1657 vec2 d2
= min(d4
.xz
, d4
.yw
);
1658 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1659 gl_FragColor
= ApplyBlendMode(texColor
* alpha
* aa
);
1662 ); // NOLINT(whitespace/parens)
1666 FragmentShaderRGBATexAlphaMaskColorMatrix::
1667 FragmentShaderRGBATexAlphaMaskColorMatrix()
1668 : sampler_location_(-1),
1669 mask_sampler_location_(-1),
1670 alpha_location_(-1),
1671 mask_tex_coord_scale_location_(-1) {
1674 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(GLES2Interface
* context
,
1676 int* base_uniform_index
) {
1677 static const char* uniforms
[] = {
1681 "maskTexCoordScale",
1682 "maskTexCoordOffset",
1685 BLEND_MODE_UNIFORMS
,
1687 int locations
[arraysize(uniforms
)];
1689 GetProgramUniformLocations(context
,
1691 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
1694 base_uniform_index
);
1695 sampler_location_
= locations
[0];
1696 mask_sampler_location_
= locations
[1];
1697 alpha_location_
= locations
[2];
1698 mask_tex_coord_scale_location_
= locations
[3];
1699 mask_tex_coord_offset_location_
= locations
[4];
1700 color_matrix_location_
= locations
[5];
1701 color_offset_location_
= locations
[6];
1702 BLEND_MODE_SET_LOCATIONS(locations
, 7);
1705 std::string
FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
1706 TexCoordPrecision precision
,
1707 SamplerType sampler
) const {
1709 return FRAGMENT_SHADER(
1711 precision mediump
float;
1712 varying TexCoordPrecision vec2 v_texCoord
;
1713 uniform sampler2D s_texture
;
1714 uniform SamplerType s_mask
;
1715 uniform vec2 maskTexCoordScale
;
1716 uniform vec2 maskTexCoordOffset
;
1717 uniform mat4 colorMatrix
;
1718 uniform vec4 colorOffset
;
1719 uniform
float alpha
;
1721 vec4 texColor
= texture2D(s_texture
, v_texCoord
);
1722 float nonZeroAlpha
= max(texColor
.a
, 0.00001);
1723 texColor
= vec4(texColor
.rgb
/ nonZeroAlpha
, nonZeroAlpha
);
1724 texColor
= colorMatrix
* texColor
+ colorOffset
;
1725 texColor
.rgb
*= texColor
.a
;
1726 texColor
= clamp(texColor
, 0.0, 1.0);
1727 TexCoordPrecision vec2 maskTexCoord
=
1728 vec2(maskTexCoordOffset
.x
+ v_texCoord
.x
* maskTexCoordScale
.x
,
1729 maskTexCoordOffset
.y
+ v_texCoord
.y
* maskTexCoordScale
.y
);
1730 vec4 maskColor
= TextureLookup(s_mask
, maskTexCoord
);
1731 gl_FragColor
= ApplyBlendMode(texColor
* alpha
* maskColor
.w
);
1734 ); // NOLINT(whitespace/parens)
1738 FragmentShaderYUVVideo::FragmentShaderYUVVideo()
1739 : y_texture_location_(-1),
1740 u_texture_location_(-1),
1741 v_texture_location_(-1),
1742 alpha_location_(-1),
1743 yuv_matrix_location_(-1),
1744 yuv_adj_location_(-1) {
1747 void FragmentShaderYUVVideo::Init(GLES2Interface
* context
,
1749 int* base_uniform_index
) {
1750 static const char* uniforms
[] = {
1751 "y_texture", "u_texture", "v_texture", "alpha", "yuv_matrix", "yuv_adj",
1753 int locations
[arraysize(uniforms
)];
1755 GetProgramUniformLocations(context
,
1757 arraysize(uniforms
),
1760 base_uniform_index
);
1761 y_texture_location_
= locations
[0];
1762 u_texture_location_
= locations
[1];
1763 v_texture_location_
= locations
[2];
1764 alpha_location_
= locations
[3];
1765 yuv_matrix_location_
= locations
[4];
1766 yuv_adj_location_
= locations
[5];
1769 std::string
FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision
,
1770 SamplerType sampler
) const {
1772 return FRAGMENT_SHADER(
1774 precision mediump
float;
1775 precision mediump
int;
1776 varying TexCoordPrecision vec2 v_texCoord
;
1777 uniform SamplerType y_texture
;
1778 uniform SamplerType u_texture
;
1779 uniform SamplerType v_texture
;
1780 uniform
float alpha
;
1781 uniform vec3 yuv_adj
;
1782 uniform mat3 yuv_matrix
;
1784 float y_raw
= TextureLookup(y_texture
, v_texCoord
).x
;
1785 float u_unsigned
= TextureLookup(u_texture
, v_texCoord
).x
;
1786 float v_unsigned
= TextureLookup(v_texture
, v_texCoord
).x
;
1787 vec3 yuv
= vec3(y_raw
, u_unsigned
, v_unsigned
) + yuv_adj
;
1788 vec3 rgb
= yuv_matrix
* yuv
;
1789 gl_FragColor
= vec4(rgb
, 1.0) * alpha
;
1792 ); // NOLINT(whitespace/parens)
1796 FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
1797 : y_texture_location_(-1),
1798 u_texture_location_(-1),
1799 v_texture_location_(-1),
1800 a_texture_location_(-1),
1801 alpha_location_(-1),
1802 yuv_matrix_location_(-1),
1803 yuv_adj_location_(-1) {
1806 void FragmentShaderYUVAVideo::Init(GLES2Interface
* context
,
1808 int* base_uniform_index
) {
1809 static const char* uniforms
[] = {
1818 int locations
[arraysize(uniforms
)];
1820 GetProgramUniformLocations(context
,
1822 arraysize(uniforms
),
1825 base_uniform_index
);
1826 y_texture_location_
= locations
[0];
1827 u_texture_location_
= locations
[1];
1828 v_texture_location_
= locations
[2];
1829 a_texture_location_
= locations
[3];
1830 alpha_location_
= locations
[4];
1831 yuv_matrix_location_
= locations
[5];
1832 yuv_adj_location_
= locations
[6];
1835 std::string
FragmentShaderYUVAVideo::GetShaderString(
1836 TexCoordPrecision precision
,
1837 SamplerType sampler
) const {
1839 return FRAGMENT_SHADER(
1841 precision mediump
float;
1842 precision mediump
int;
1843 varying TexCoordPrecision vec2 v_texCoord
;
1844 uniform SamplerType y_texture
;
1845 uniform SamplerType u_texture
;
1846 uniform SamplerType v_texture
;
1847 uniform SamplerType a_texture
;
1848 uniform
float alpha
;
1849 uniform vec3 yuv_adj
;
1850 uniform mat3 yuv_matrix
;
1852 float y_raw
= TextureLookup(y_texture
, v_texCoord
).x
;
1853 float u_unsigned
= TextureLookup(u_texture
, v_texCoord
).x
;
1854 float v_unsigned
= TextureLookup(v_texture
, v_texCoord
).x
;
1855 float a_raw
= TextureLookup(a_texture
, v_texCoord
).x
;
1856 vec3 yuv
= vec3(y_raw
, u_unsigned
, v_unsigned
) + yuv_adj
;
1857 vec3 rgb
= yuv_matrix
* yuv
;
1858 gl_FragColor
= vec4(rgb
, 1.0) * (alpha
* a_raw
);
1861 ); // NOLINT(whitespace/parens)
1865 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) {
1868 void FragmentShaderColor::Init(GLES2Interface
* context
,
1870 int* base_uniform_index
) {
1871 static const char* uniforms
[] = {
1874 int locations
[arraysize(uniforms
)];
1876 GetProgramUniformLocations(context
,
1878 arraysize(uniforms
),
1881 base_uniform_index
);
1882 color_location_
= locations
[0];
1885 std::string
FragmentShaderColor::GetShaderString(TexCoordPrecision precision
,
1886 SamplerType sampler
) const {
1888 return FRAGMENT_SHADER(
1890 precision mediump
float;
1892 void main() { gl_FragColor
= color
; }
1894 ); // NOLINT(whitespace/parens)
1898 FragmentShaderColorAA::FragmentShaderColorAA() : color_location_(-1) {
1901 void FragmentShaderColorAA::Init(GLES2Interface
* context
,
1903 int* base_uniform_index
) {
1904 static const char* uniforms
[] = {
1907 int locations
[arraysize(uniforms
)];
1909 GetProgramUniformLocations(context
,
1911 arraysize(uniforms
),
1914 base_uniform_index
);
1915 color_location_
= locations
[0];
1918 std::string
FragmentShaderColorAA::GetShaderString(TexCoordPrecision precision
,
1919 SamplerType sampler
) const {
1921 return FRAGMENT_SHADER(
1923 precision mediump
float;
1925 varying vec4 edge_dist
[2]; // 8 edge distances.
1928 vec4 d4
= min(edge_dist
[0], edge_dist
[1]);
1929 vec2 d2
= min(d4
.xz
, d4
.yw
);
1930 float aa
= clamp(gl_FragCoord
.w
* min(d2
.x
, d2
.y
), 0.0, 1.0);
1931 gl_FragColor
= color
* aa
;
1934 ); // NOLINT(whitespace/parens)
1938 FragmentShaderCheckerboard::FragmentShaderCheckerboard()
1939 : alpha_location_(-1),
1940 tex_transform_location_(-1),
1941 frequency_location_(-1) {
1944 void FragmentShaderCheckerboard::Init(GLES2Interface
* context
,
1946 int* base_uniform_index
) {
1947 static const char* uniforms
[] = {
1948 "alpha", "texTransform", "frequency", "color",
1950 int locations
[arraysize(uniforms
)];
1952 GetProgramUniformLocations(context
,
1954 arraysize(uniforms
),
1957 base_uniform_index
);
1958 alpha_location_
= locations
[0];
1959 tex_transform_location_
= locations
[1];
1960 frequency_location_
= locations
[2];
1961 color_location_
= locations
[3];
1964 std::string
FragmentShaderCheckerboard::GetShaderString(
1965 TexCoordPrecision precision
,
1966 SamplerType sampler
) const {
1967 // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
1968 // by Munshi, Ginsburg, Shreiner.
1970 return FRAGMENT_SHADER(
1972 precision mediump
float;
1973 precision mediump
int;
1974 varying vec2 v_texCoord
;
1975 uniform
float alpha
;
1976 uniform
float frequency
;
1977 uniform vec4 texTransform
;
1980 vec4 color1
= vec4(1.0, 1.0, 1.0, 1.0);
1981 vec4 color2
= color
;
1983 clamp(v_texCoord
, 0.0, 1.0) * texTransform
.zw
+ texTransform
.xy
;
1984 vec2 coord
= mod(floor(texCoord
* frequency
* 2.0), 2.0);
1985 float picker
= abs(coord
.x
- coord
.y
); // NOLINT
1986 gl_FragColor
= mix(color1
, color2
, picker
) * alpha
;
1989 ); // NOLINT(whitespace/parens)