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