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