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