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