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 "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( \
32 SetFragmentSamplerType(sampler, SetBlendModeFunctions(Head + Body)))
34 using gpu::gles2::GLES2Interface
;
40 static void GetProgramUniformLocations(GLES2Interface
* context
,
43 const char** uniforms
,
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"
61 " #define TexCoordPrecision mediump\n"
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
);
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
,
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
98 GLint range
[2] = {14, 14};
100 context
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, GL_MEDIUM_FLOAT
,
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" +
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" +
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" +
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
;
142 return shader_string
;
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
,
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
,
172 VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) {
175 void VertexShaderPosTex::Init(GLES2Interface
* context
,
177 int* base_uniform_index
) {
178 static const char* uniforms
[] = {
181 int locations
[arraysize(uniforms
)];
183 GetProgramUniformLocations(context
,
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
;
201 varying TexCoordPrecision vec2 v_texCoord
;
205 std::string
VertexShaderPosTex::GetShaderBody() {
206 return SHADER0([]() {
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
,
224 int* base_uniform_index
) {
225 static const char* uniforms
[] = {
226 "matrix", "yaTexScale", "yaTexOffset", "uvTexScale", "uvTexOffset",
228 int locations
[arraysize(uniforms
)];
230 GetProgramUniformLocations(context
,
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
;
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([]() {
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
,
277 int* base_uniform_index
) {
278 static const char* uniforms
[] = {
281 int locations
[arraysize(uniforms
)];
283 GetProgramUniformLocations(context
,
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
;
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
,
317 int* base_uniform_index
) {
318 static const char* uniforms
[] = {
319 "matrix", "texTransform", "opacity",
321 int locations
[arraysize(uniforms
)];
323 GetProgramUniformLocations(context
,
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([]() {
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([]() {
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
,
395 int* base_uniform_index
) {
396 static const char* uniforms
[] = {
399 int locations
[arraysize(uniforms
)];
401 GetProgramUniformLocations(context
,
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
;
424 uniform TexCoordPrecision vec2 quad
[4];
425 uniform TexCoordPrecision vec2 dummy_uniform
;
426 varying TexCoordPrecision vec2 dummy_varying
;
429 return SHADER0([]() {
430 attribute TexCoordPrecision vec4 a_position
;
431 attribute
float a_index
;
433 uniform TexCoordPrecision vec2 quad
[4];
438 std::string
VertexShaderQuad::GetShaderBody() {
439 #if defined(OS_ANDROID)
440 return SHADER0([]() {
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
;
448 return SHADER0([]() {
450 vec2 pos
= quad
[int(a_index
)]; // NOLINT
451 gl_Position
= matrix
* vec4(pos
, a_position
.z
, a_position
.w
);
457 VertexShaderQuadAA::VertexShaderQuadAA()
458 : matrix_location_(-1),
459 viewport_location_(-1),
464 void VertexShaderQuadAA::Init(GLES2Interface
* context
,
466 int* base_uniform_index
) {
467 static const char* uniforms
[] = {
468 "matrix", "viewport", "quad", "edge",
470 int locations
[arraysize(uniforms
)];
472 GetProgramUniformLocations(context
,
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
;
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([]() {
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
)) *
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
)) *
517 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
518 : matrix_location_(-1),
519 viewport_location_(-1),
522 tex_transform_location_(-1) {
525 void VertexShaderQuadTexTransformAA::Init(GLES2Interface
* context
,
527 int* base_uniform_index
) {
528 static const char* uniforms
[] = {
529 "matrix", "viewport", "quad", "edge", "texTrans",
531 int locations
[arraysize(uniforms
)];
533 GetProgramUniformLocations(context
,
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
;
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([]() {
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
)) *
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
)) *
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),
595 vertex_tex_transform_location_(-1) {
598 void VertexShaderTile::Init(GLES2Interface
* context
,
600 int* base_uniform_index
) {
601 static const char* uniforms
[] = {
602 "matrix", "quad", "vertexTexTransform",
604 int locations
[arraysize(uniforms
)];
606 GetProgramUniformLocations(context
,
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
;
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([]() {
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),
648 vertex_tex_transform_location_(-1) {
651 void VertexShaderTileAA::Init(GLES2Interface
* context
,
653 int* base_uniform_index
) {
654 static const char* uniforms
[] = {
655 "matrix", "viewport", "quad", "edge", "vertexTexTransform",
657 int locations
[arraysize(uniforms
)];
659 GetProgramUniformLocations(context
,
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
;
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([]() {
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
)) *
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
)) *
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
,
714 int* base_uniform_index
) {
715 static const char* uniforms
[] = {
716 "matrix", "texMatrix",
718 int locations
[arraysize(uniforms
)];
720 GetProgramUniformLocations(context
,
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
;
739 uniform TexCoordPrecision mat4 texMatrix
;
740 varying TexCoordPrecision vec2 v_texCoord
;
744 std::string
VertexShaderVideoTransform::GetShaderBody() {
745 return SHADER0([]() {
747 gl_Position
= matrix
* a_position
;
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", \
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 const 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
);
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
) {
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
));
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
));
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
);
847 static const std::string kFunctionColorDodgeComponent
= SHADER0([]() {
848 float getColorDodgeComponent(float srcc
, float srca
, float dstc
,
851 return srcc
* (1.0 - dsta
);
852 float d
= srca
- srcc
;
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
,
864 return srca
* dsta
+ srcc
* (1.0 - dsta
) + dstc
* (1.0 - srca
);
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
=
874 float getSoftLightComponent(float srcc
, float srca
, float dstc
,
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
)) /
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
) {
907 ((outColor
- vec3(outLum
, outLum
, outLum
)) * outLum
) /
910 if (maxComp
> alpha
&& maxComp
!= outLum
) {
913 ((outColor
- vec3(outLum
, outLum
, outLum
)) * (alpha
- outLum
)) /
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
,
928 if (minComp
< maxComp
) {
931 result
.g
= sat
* (midComp
- minComp
) / (maxComp
- minComp
);
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
,
945 } else if (hueLumColor
.r
<= hueLumColor
.b
) {
946 hueLumColor
.rbg
= set_saturation_helper(hueLumColor
.r
, hueLumColor
.b
,
949 hueLumColor
.brg
= set_saturation_helper(hueLumColor
.b
, hueLumColor
.r
,
952 } else if (hueLumColor
.r
<= hueLumColor
.b
) {
953 hueLumColor
.grb
= set_saturation_helper(hueLumColor
.g
, hueLumColor
.r
,
955 } else if (hueLumColor
.g
<= hueLumColor
.b
) {
956 hueLumColor
.gbr
= set_saturation_helper(hueLumColor
.g
, hueLumColor
.b
,
959 hueLumColor
.bgr
= set_saturation_helper(hueLumColor
.b
, hueLumColor
.g
,
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
;
977 case BLEND_MODE_SATURATION
:
978 return kFunctionLum
+ kFunctionSat
;
979 case BLEND_MODE_COLOR
:
980 case BLEND_MODE_LUMINOSITY
:
983 return std::string();
987 std::string
FragmentTexBlendMode::GetBlendFunction() const {
988 return "vec4 Blend(vec4 src, vec4 dst) {"
990 " result.a = src.a + (1.0 - src.a) * dst.a;" +
991 GetBlendFunctionBodyForRGB() +
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;"
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);"
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;"
1039 " set_luminance(set_saturation(src.rgb * dst.a,"
1040 " dstSrcAlpha.rgb),"
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),"
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,"
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,"
1061 " srcDstAlpha.rgb);"
1062 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
1063 case BLEND_MODE_NONE
:
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
,
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
,
1083 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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
,
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
,
1109 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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
,
1125 int* base_uniform_index
) {
1126 static const char* uniforms
[] = {
1129 int locations
[arraysize(uniforms
)];
1131 GetProgramUniformLocations(context
,
1133 arraysize(uniforms
),
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([]() {
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([]() {
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([]() {
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([]() {
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
,
1268 int* base_uniform_index
) {
1269 static const char* uniforms
[] = {
1270 "s_texture", "background_color",
1272 int locations
[arraysize(uniforms
)];
1274 GetProgramUniformLocations(context
,
1276 arraysize(uniforms
),
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([]() {
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([]() {
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([]() {
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([]() {
1401 vec4 texColor
= TextureLookup(s_texture
, v_texCoord
);
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([]() {
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
,
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
,
1445 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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([]() {
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
,
1498 int* base_uniform_index
) {
1499 static const char* uniforms
[] = {
1500 "s_texture", "alpha", "fragmentTexTransform",
1502 int locations
[arraysize(uniforms
)];
1504 GetProgramUniformLocations(context
,
1506 arraysize(uniforms
),
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([]() {
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([]() {
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);
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
,
1589 int* base_uniform_index
) {
1590 static const char* uniforms
[] = {
1594 "maskTexCoordScale",
1595 "maskTexCoordOffset",
1596 BLEND_MODE_UNIFORMS
,
1598 int locations
[arraysize(uniforms
)];
1600 GetProgramUniformLocations(context
,
1602 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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([]() {
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
,
1669 int* base_uniform_index
) {
1670 static const char* uniforms
[] = {
1674 "maskTexCoordScale",
1675 "maskTexCoordOffset",
1676 BLEND_MODE_UNIFORMS
,
1678 int locations
[arraysize(uniforms
)];
1680 GetProgramUniformLocations(context
,
1682 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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([]() {
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
,
1756 int* base_uniform_index
) {
1757 static const char* uniforms
[] = {
1761 "maskTexCoordScale",
1762 "maskTexCoordOffset",
1765 BLEND_MODE_UNIFORMS
,
1767 int locations
[arraysize(uniforms
)];
1769 GetProgramUniformLocations(context
,
1771 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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([]() {
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
,
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
,
1861 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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([]() {
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
,
1927 int* base_uniform_index
) {
1928 static const char* uniforms
[] = {
1932 "maskTexCoordScale",
1933 "maskTexCoordOffset",
1936 BLEND_MODE_UNIFORMS
,
1938 int locations
[arraysize(uniforms
)];
1940 GetProgramUniformLocations(context
,
1942 arraysize(uniforms
) - UNUSED_BLEND_MODE_UNIFORMS
,
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([]() {
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
,
2023 int* base_uniform_index
) {
2024 static const char* uniforms
[] = {"y_texture",
2032 int locations
[arraysize(uniforms
)];
2034 GetProgramUniformLocations(context
,
2036 arraysize(uniforms
),
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([]() {
2076 max(ya_clamp_rect
.xy
, min(ya_clamp_rect
.zw
, v_yaTexCoord
));
2077 float y_raw
= TextureLookup(y_texture
, ya_clamped
).x
;
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
,
2101 int* base_uniform_index
) {
2102 static const char* uniforms
[] = {
2113 int locations
[arraysize(uniforms
)];
2115 GetProgramUniformLocations(context
,
2117 arraysize(uniforms
),
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([]() {
2160 max(ya_clamp_rect
.xy
, min(ya_clamp_rect
.zw
, v_yaTexCoord
));
2161 float y_raw
= TextureLookup(y_texture
, ya_clamped
).x
;
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
,
2179 int* base_uniform_index
) {
2180 static const char* uniforms
[] = {
2183 int locations
[arraysize(uniforms
)];
2185 GetProgramUniformLocations(context
,
2187 arraysize(uniforms
),
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;
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
,
2217 int* base_uniform_index
) {
2218 static const char* uniforms
[] = {
2221 int locations
[arraysize(uniforms
)];
2223 GetProgramUniformLocations(context
,
2225 arraysize(uniforms
),
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;
2241 varying vec4 edge_dist
[2]; // 8 edge distances.
2245 std::string
FragmentShaderColorAA::GetShaderBody() {
2246 return SHADER0([]() {
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
;