OLD | NEW |
(Empty) | |
| 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 template <size_t size> |
| 15 std::string StripLambda(const char(&shader)[size]) { |
| 16 // Must contain at least "[]() {}" and trailing null (included in size). |
| 17 static_assert(size >= 8, |
| 18 "String passed to StripLambda must be at least 8 characters"); |
| 19 DCHECK_EQ(strncmp("[]() {", shader, 6), 0); |
| 20 DCHECK_EQ(shader[size - 2], '}'); |
| 21 return std::string(shader + 6, shader + size - 2); |
| 22 } |
| 23 |
| 24 // Shaders are passed in with lambda syntax, which tricks clang-format into |
| 25 // handling them correctly. StipLambda removes this. |
| 26 #define SHADER0(Src) StripLambda(#Src) |
| 27 #define VERTEX_SHADER(Head, Body) SetVertexTexCoordPrecision(Head + Body) |
| 28 #define FRAGMENT_SHADER(Head, Body) \ |
| 29 SetFragmentTexCoordPrecision( \ |
| 30 precision, \ |
| 31 SetFragmentSamplerType(sampler, SetBlendModeFunctions(Head + Body))) |
| 32 |
| 33 using gpu::gles2::GLES2Interface; |
| 34 |
| 35 namespace cc { |
| 36 |
| 37 namespace { |
| 38 |
| 39 static void GetProgramUniformLocations(GLES2Interface* context, |
| 40 unsigned program, |
| 41 size_t count, |
| 42 const char** uniforms, |
| 43 int* locations, |
| 44 int* base_uniform_index) { |
| 45 for (size_t i = 0; i < count; i++) { |
| 46 locations[i] = (*base_uniform_index)++; |
| 47 context->BindUniformLocationCHROMIUM(program, locations[i], uniforms[i]); |
| 48 } |
| 49 } |
| 50 |
| 51 static std::string SetFragmentTexCoordPrecision( |
| 52 TexCoordPrecision requested_precision, |
| 53 std::string shader_string) { |
| 54 switch (requested_precision) { |
| 55 case TEX_COORD_PRECISION_HIGH: |
| 56 DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos); |
| 57 return "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" |
| 58 " #define TexCoordPrecision highp\n" |
| 59 "#else\n" |
| 60 " #define TexCoordPrecision mediump\n" |
| 61 "#endif\n" + |
| 62 shader_string; |
| 63 case TEX_COORD_PRECISION_MEDIUM: |
| 64 DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos); |
| 65 return "#define TexCoordPrecision mediump\n" + shader_string; |
| 66 case TEX_COORD_PRECISION_NA: |
| 67 DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos); |
| 68 DCHECK_EQ(shader_string.find("texture2D"), std::string::npos); |
| 69 DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos); |
| 70 return shader_string; |
| 71 default: |
| 72 NOTREACHED(); |
| 73 break; |
| 74 } |
| 75 return shader_string; |
| 76 } |
| 77 |
| 78 static std::string SetVertexTexCoordPrecision( |
| 79 const std::string& shader_string) { |
| 80 // We unconditionally use highp in the vertex shader since |
| 81 // we are unlikely to be vertex shader bound when drawing large quads. |
| 82 // Also, some vertex shaders mutate the texture coordinate in such a |
| 83 // way that the effective precision might be lower than expected. |
| 84 return "#define TexCoordPrecision highp\n" + shader_string; |
| 85 } |
| 86 |
| 87 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context, |
| 88 int* highp_threshold_cache, |
| 89 int highp_threshold_min, |
| 90 int x, |
| 91 int y) { |
| 92 if (*highp_threshold_cache == 0) { |
| 93 // Initialize range and precision with minimum spec values for when |
| 94 // GetShaderPrecisionFormat is a test stub. |
| 95 // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat |
| 96 // everywhere. |
| 97 GLint range[2] = {14, 14}; |
| 98 GLint precision = 10; |
| 99 GLC(context, |
| 100 context->GetShaderPrecisionFormat( |
| 101 GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range, &precision)); |
| 102 *highp_threshold_cache = 1 << precision; |
| 103 } |
| 104 |
| 105 int highp_threshold = std::max(*highp_threshold_cache, highp_threshold_min); |
| 106 if (x > highp_threshold || y > highp_threshold) |
| 107 return TEX_COORD_PRECISION_HIGH; |
| 108 return TEX_COORD_PRECISION_MEDIUM; |
| 109 } |
| 110 |
| 111 static std::string SetFragmentSamplerType(SamplerType requested_type, |
| 112 std::string shader_string) { |
| 113 switch (requested_type) { |
| 114 case SAMPLER_TYPE_2D: |
| 115 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos); |
| 116 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos); |
| 117 return "#define SamplerType sampler2D\n" |
| 118 "#define TextureLookup texture2D\n" + |
| 119 shader_string; |
| 120 case SAMPLER_TYPE_2D_RECT: |
| 121 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos); |
| 122 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos); |
| 123 return "#extension GL_ARB_texture_rectangle : require\n" |
| 124 "#define SamplerType sampler2DRect\n" |
| 125 "#define TextureLookup texture2DRect\n" + |
| 126 shader_string; |
| 127 case SAMPLER_TYPE_EXTERNAL_OES: |
| 128 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos); |
| 129 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos); |
| 130 return "#extension GL_OES_EGL_image_external : require\n" |
| 131 "#define SamplerType samplerExternalOES\n" |
| 132 "#define TextureLookup texture2D\n" + |
| 133 shader_string; |
| 134 case SAMPLER_TYPE_NA: |
| 135 DCHECK_EQ(shader_string.find("SamplerType"), std::string::npos); |
| 136 DCHECK_EQ(shader_string.find("TextureLookup"), std::string::npos); |
| 137 return shader_string; |
| 138 default: |
| 139 NOTREACHED(); |
| 140 break; |
| 141 } |
| 142 return shader_string; |
| 143 } |
| 144 |
| 145 } // namespace |
| 146 |
| 147 ShaderLocations::ShaderLocations() { |
| 148 } |
| 149 |
| 150 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context, |
| 151 int* highp_threshold_cache, |
| 152 int highp_threshold_min, |
| 153 const gfx::Point& max_coordinate) { |
| 154 return TexCoordPrecisionRequired(context, |
| 155 highp_threshold_cache, |
| 156 highp_threshold_min, |
| 157 max_coordinate.x(), |
| 158 max_coordinate.y()); |
| 159 } |
| 160 |
| 161 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context, |
| 162 int* highp_threshold_cache, |
| 163 int highp_threshold_min, |
| 164 const gfx::Size& max_size) { |
| 165 return TexCoordPrecisionRequired(context, |
| 166 highp_threshold_cache, |
| 167 highp_threshold_min, |
| 168 max_size.width(), |
| 169 max_size.height()); |
| 170 } |
| 171 |
| 172 VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) { |
| 173 } |
| 174 |
| 175 void VertexShaderPosTex::Init(GLES2Interface* context, |
| 176 unsigned program, |
| 177 int* base_uniform_index) { |
| 178 static const char* uniforms[] = { |
| 179 "matrix", |
| 180 }; |
| 181 int locations[arraysize(uniforms)]; |
| 182 |
| 183 GetProgramUniformLocations(context, |
| 184 program, |
| 185 arraysize(uniforms), |
| 186 uniforms, |
| 187 locations, |
| 188 base_uniform_index); |
| 189 matrix_location_ = locations[0]; |
| 190 } |
| 191 |
| 192 std::string VertexShaderPosTex::GetShaderString() const { |
| 193 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 194 } |
| 195 |
| 196 std::string VertexShaderPosTex::GetShaderHead() { |
| 197 return SHADER0([]() { |
| 198 attribute vec4 a_position; |
| 199 attribute TexCoordPrecision vec2 a_texCoord; |
| 200 uniform mat4 matrix; |
| 201 varying TexCoordPrecision vec2 v_texCoord; |
| 202 }); |
| 203 } |
| 204 |
| 205 std::string VertexShaderPosTex::GetShaderBody() { |
| 206 return SHADER0([]() { |
| 207 void main() { |
| 208 gl_Position = matrix * a_position; |
| 209 v_texCoord = a_texCoord; |
| 210 } |
| 211 }); |
| 212 } |
| 213 |
| 214 VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset() |
| 215 : matrix_location_(-1), tex_scale_location_(-1), tex_offset_location_(-1) { |
| 216 } |
| 217 |
| 218 void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context, |
| 219 unsigned program, |
| 220 int* base_uniform_index) { |
| 221 static const char* uniforms[] = { |
| 222 "matrix", "texScale", "texOffset", |
| 223 }; |
| 224 int locations[arraysize(uniforms)]; |
| 225 |
| 226 GetProgramUniformLocations(context, |
| 227 program, |
| 228 arraysize(uniforms), |
| 229 uniforms, |
| 230 locations, |
| 231 base_uniform_index); |
| 232 matrix_location_ = locations[0]; |
| 233 tex_scale_location_ = locations[1]; |
| 234 tex_offset_location_ = locations[2]; |
| 235 } |
| 236 |
| 237 std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const { |
| 238 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 239 } |
| 240 |
| 241 std::string VertexShaderPosTexYUVStretchOffset::GetShaderHead() { |
| 242 return SHADER0([]() { |
| 243 precision mediump float; |
| 244 attribute vec4 a_position; |
| 245 attribute TexCoordPrecision vec2 a_texCoord; |
| 246 uniform mat4 matrix; |
| 247 varying TexCoordPrecision vec2 v_texCoord; |
| 248 uniform TexCoordPrecision vec2 texScale; |
| 249 uniform TexCoordPrecision vec2 texOffset; |
| 250 }); |
| 251 } |
| 252 |
| 253 std::string VertexShaderPosTexYUVStretchOffset::GetShaderBody() { |
| 254 return SHADER0([]() { |
| 255 void main() { |
| 256 gl_Position = matrix * a_position; |
| 257 v_texCoord = a_texCoord * texScale + texOffset; |
| 258 } |
| 259 }); |
| 260 } |
| 261 |
| 262 VertexShaderPos::VertexShaderPos() : matrix_location_(-1) { |
| 263 } |
| 264 |
| 265 void VertexShaderPos::Init(GLES2Interface* context, |
| 266 unsigned program, |
| 267 int* base_uniform_index) { |
| 268 static const char* uniforms[] = { |
| 269 "matrix", |
| 270 }; |
| 271 int locations[arraysize(uniforms)]; |
| 272 |
| 273 GetProgramUniformLocations(context, |
| 274 program, |
| 275 arraysize(uniforms), |
| 276 uniforms, |
| 277 locations, |
| 278 base_uniform_index); |
| 279 matrix_location_ = locations[0]; |
| 280 } |
| 281 |
| 282 std::string VertexShaderPos::GetShaderString() const { |
| 283 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 284 } |
| 285 |
| 286 std::string VertexShaderPos::GetShaderHead() { |
| 287 return SHADER0([]() { |
| 288 attribute vec4 a_position; |
| 289 uniform mat4 matrix; |
| 290 }); |
| 291 } |
| 292 |
| 293 std::string VertexShaderPos::GetShaderBody() { |
| 294 return SHADER0([]() { |
| 295 void main() { gl_Position = matrix * a_position; } |
| 296 }); |
| 297 } |
| 298 |
| 299 VertexShaderPosTexTransform::VertexShaderPosTexTransform() |
| 300 : matrix_location_(-1), |
| 301 tex_transform_location_(-1), |
| 302 vertex_opacity_location_(-1) { |
| 303 } |
| 304 |
| 305 void VertexShaderPosTexTransform::Init(GLES2Interface* context, |
| 306 unsigned program, |
| 307 int* base_uniform_index) { |
| 308 static const char* uniforms[] = { |
| 309 "matrix", "texTransform", "opacity", |
| 310 }; |
| 311 int locations[arraysize(uniforms)]; |
| 312 |
| 313 GetProgramUniformLocations(context, |
| 314 program, |
| 315 arraysize(uniforms), |
| 316 uniforms, |
| 317 locations, |
| 318 base_uniform_index); |
| 319 matrix_location_ = locations[0]; |
| 320 tex_transform_location_ = locations[1]; |
| 321 vertex_opacity_location_ = locations[2]; |
| 322 } |
| 323 |
| 324 std::string VertexShaderPosTexTransform::GetShaderString() const { |
| 325 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 326 } |
| 327 |
| 328 std::string VertexShaderPosTexTransform::GetShaderHead() { |
| 329 return SHADER0([]() { |
| 330 attribute vec4 a_position; |
| 331 attribute TexCoordPrecision vec2 a_texCoord; |
| 332 attribute float a_index; |
| 333 uniform mat4 matrix[8]; |
| 334 uniform TexCoordPrecision vec4 texTransform[8]; |
| 335 uniform float opacity[32]; |
| 336 varying TexCoordPrecision vec2 v_texCoord; |
| 337 varying float v_alpha; |
| 338 }); |
| 339 } |
| 340 |
| 341 std::string VertexShaderPosTexTransform::GetShaderBody() { |
| 342 return SHADER0([]() { |
| 343 void main() { |
| 344 int quad_index = int(a_index * 0.25); // NOLINT |
| 345 gl_Position = matrix[quad_index] * a_position; |
| 346 TexCoordPrecision vec4 texTrans = texTransform[quad_index]; |
| 347 v_texCoord = a_texCoord * texTrans.zw + texTrans.xy; |
| 348 v_alpha = opacity[int(a_index)]; // NOLINT |
| 349 } |
| 350 }); |
| 351 } |
| 352 |
| 353 void VertexShaderPosTexTransform::FillLocations( |
| 354 ShaderLocations* locations) const { |
| 355 locations->matrix = matrix_location(); |
| 356 locations->tex_transform = tex_transform_location(); |
| 357 } |
| 358 |
| 359 std::string VertexShaderPosTexIdentity::GetShaderString() const { |
| 360 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 361 } |
| 362 |
| 363 std::string VertexShaderPosTexIdentity::GetShaderHead() { |
| 364 return SHADER0([]() { |
| 365 attribute vec4 a_position; |
| 366 varying TexCoordPrecision vec2 v_texCoord; |
| 367 }); |
| 368 } |
| 369 |
| 370 std::string VertexShaderPosTexIdentity::GetShaderBody() { |
| 371 return SHADER0([]() { |
| 372 void main() { |
| 373 gl_Position = a_position; |
| 374 v_texCoord = (a_position.xy + vec2(1.0)) * 0.5; |
| 375 } |
| 376 }); |
| 377 } |
| 378 |
| 379 VertexShaderQuad::VertexShaderQuad() |
| 380 : matrix_location_(-1), quad_location_(-1) { |
| 381 } |
| 382 |
| 383 void VertexShaderQuad::Init(GLES2Interface* context, |
| 384 unsigned program, |
| 385 int* base_uniform_index) { |
| 386 static const char* uniforms[] = { |
| 387 "matrix", "quad", |
| 388 }; |
| 389 int locations[arraysize(uniforms)]; |
| 390 |
| 391 GetProgramUniformLocations(context, |
| 392 program, |
| 393 arraysize(uniforms), |
| 394 uniforms, |
| 395 locations, |
| 396 base_uniform_index); |
| 397 matrix_location_ = locations[0]; |
| 398 quad_location_ = locations[1]; |
| 399 } |
| 400 |
| 401 std::string VertexShaderQuad::GetShaderString() const { |
| 402 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 403 } |
| 404 |
| 405 std::string VertexShaderQuad::GetShaderHead() { |
| 406 #if defined(OS_ANDROID) |
| 407 // TODO(epenner): Find the cause of this 'quad' uniform |
| 408 // being missing if we don't add dummy variables. |
| 409 // http://crbug.com/240602 |
| 410 return SHADER0([]() { |
| 411 attribute TexCoordPrecision vec4 a_position; |
| 412 attribute float a_index; |
| 413 uniform mat4 matrix; |
| 414 uniform TexCoordPrecision vec2 quad[4]; |
| 415 uniform TexCoordPrecision vec2 dummy_uniform; |
| 416 varying TexCoordPrecision vec2 dummy_varying; |
| 417 }); |
| 418 #else |
| 419 return SHADER0([]() { |
| 420 attribute TexCoordPrecision vec4 a_position; |
| 421 attribute float a_index; |
| 422 uniform mat4 matrix; |
| 423 uniform TexCoordPrecision vec2 quad[4]; |
| 424 }); |
| 425 #endif |
| 426 } |
| 427 |
| 428 std::string VertexShaderQuad::GetShaderBody() { |
| 429 #if defined(OS_ANDROID) |
| 430 return SHADER0([]() { |
| 431 void main() { |
| 432 vec2 pos = quad[int(a_index)]; // NOLINT |
| 433 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 434 dummy_varying = dummy_uniform; |
| 435 } |
| 436 }); |
| 437 #else |
| 438 return SHADER0([]() { |
| 439 void main() { |
| 440 vec2 pos = quad[int(a_index)]; // NOLINT |
| 441 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 442 } |
| 443 }); |
| 444 #endif |
| 445 } |
| 446 |
| 447 VertexShaderQuadAA::VertexShaderQuadAA() |
| 448 : matrix_location_(-1), |
| 449 viewport_location_(-1), |
| 450 quad_location_(-1), |
| 451 edge_location_(-1) { |
| 452 } |
| 453 |
| 454 void VertexShaderQuadAA::Init(GLES2Interface* context, |
| 455 unsigned program, |
| 456 int* base_uniform_index) { |
| 457 static const char* uniforms[] = { |
| 458 "matrix", "viewport", "quad", "edge", |
| 459 }; |
| 460 int locations[arraysize(uniforms)]; |
| 461 |
| 462 GetProgramUniformLocations(context, |
| 463 program, |
| 464 arraysize(uniforms), |
| 465 uniforms, |
| 466 locations, |
| 467 base_uniform_index); |
| 468 matrix_location_ = locations[0]; |
| 469 viewport_location_ = locations[1]; |
| 470 quad_location_ = locations[2]; |
| 471 edge_location_ = locations[3]; |
| 472 } |
| 473 |
| 474 std::string VertexShaderQuadAA::GetShaderString() const { |
| 475 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 476 } |
| 477 |
| 478 std::string VertexShaderQuadAA::GetShaderHead() { |
| 479 return SHADER0([]() { |
| 480 attribute TexCoordPrecision vec4 a_position; |
| 481 attribute float a_index; |
| 482 uniform mat4 matrix; |
| 483 uniform vec4 viewport; |
| 484 uniform TexCoordPrecision vec2 quad[4]; |
| 485 uniform TexCoordPrecision vec3 edge[8]; |
| 486 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 487 }); |
| 488 } |
| 489 |
| 490 std::string VertexShaderQuadAA::GetShaderBody() { |
| 491 return SHADER0([]() { |
| 492 void main() { |
| 493 vec2 pos = quad[int(a_index)]; // NOLINT |
| 494 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 495 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
| 496 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
| 497 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
| 498 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
| 499 gl_Position.w; |
| 500 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
| 501 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
| 502 gl_Position.w; |
| 503 } |
| 504 }); |
| 505 } |
| 506 |
| 507 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA() |
| 508 : matrix_location_(-1), |
| 509 viewport_location_(-1), |
| 510 quad_location_(-1), |
| 511 edge_location_(-1), |
| 512 tex_transform_location_(-1) { |
| 513 } |
| 514 |
| 515 void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context, |
| 516 unsigned program, |
| 517 int* base_uniform_index) { |
| 518 static const char* uniforms[] = { |
| 519 "matrix", "viewport", "quad", "edge", "texTrans", |
| 520 }; |
| 521 int locations[arraysize(uniforms)]; |
| 522 |
| 523 GetProgramUniformLocations(context, |
| 524 program, |
| 525 arraysize(uniforms), |
| 526 uniforms, |
| 527 locations, |
| 528 base_uniform_index); |
| 529 matrix_location_ = locations[0]; |
| 530 viewport_location_ = locations[1]; |
| 531 quad_location_ = locations[2]; |
| 532 edge_location_ = locations[3]; |
| 533 tex_transform_location_ = locations[4]; |
| 534 } |
| 535 |
| 536 std::string VertexShaderQuadTexTransformAA::GetShaderString() const { |
| 537 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 538 } |
| 539 |
| 540 std::string VertexShaderQuadTexTransformAA::GetShaderHead() { |
| 541 return SHADER0([]() { |
| 542 attribute TexCoordPrecision vec4 a_position; |
| 543 attribute float a_index; |
| 544 uniform mat4 matrix; |
| 545 uniform vec4 viewport; |
| 546 uniform TexCoordPrecision vec2 quad[4]; |
| 547 uniform TexCoordPrecision vec3 edge[8]; |
| 548 uniform TexCoordPrecision vec4 texTrans; |
| 549 varying TexCoordPrecision vec2 v_texCoord; |
| 550 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 551 }); |
| 552 } |
| 553 |
| 554 std::string VertexShaderQuadTexTransformAA::GetShaderBody() { |
| 555 return SHADER0([]() { |
| 556 void main() { |
| 557 vec2 pos = quad[int(a_index)]; // NOLINT |
| 558 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 559 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
| 560 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
| 561 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
| 562 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
| 563 gl_Position.w; |
| 564 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
| 565 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
| 566 gl_Position.w; |
| 567 v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy; |
| 568 } |
| 569 }); |
| 570 } |
| 571 |
| 572 void VertexShaderQuadTexTransformAA::FillLocations( |
| 573 ShaderLocations* locations) const { |
| 574 locations->quad = quad_location(); |
| 575 locations->edge = edge_location(); |
| 576 locations->viewport = viewport_location(); |
| 577 locations->matrix = matrix_location(); |
| 578 locations->tex_transform = tex_transform_location(); |
| 579 } |
| 580 |
| 581 |
| 582 VertexShaderTile::VertexShaderTile() |
| 583 : matrix_location_(-1), |
| 584 quad_location_(-1), |
| 585 vertex_tex_transform_location_(-1) { |
| 586 } |
| 587 |
| 588 void VertexShaderTile::Init(GLES2Interface* context, |
| 589 unsigned program, |
| 590 int* base_uniform_index) { |
| 591 static const char* uniforms[] = { |
| 592 "matrix", "quad", "vertexTexTransform", |
| 593 }; |
| 594 int locations[arraysize(uniforms)]; |
| 595 |
| 596 GetProgramUniformLocations(context, |
| 597 program, |
| 598 arraysize(uniforms), |
| 599 uniforms, |
| 600 locations, |
| 601 base_uniform_index); |
| 602 matrix_location_ = locations[0]; |
| 603 quad_location_ = locations[1]; |
| 604 vertex_tex_transform_location_ = locations[2]; |
| 605 } |
| 606 |
| 607 std::string VertexShaderTile::GetShaderString() const { |
| 608 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 609 } |
| 610 |
| 611 std::string VertexShaderTile::GetShaderHead() { |
| 612 return SHADER0([]() { |
| 613 attribute TexCoordPrecision vec4 a_position; |
| 614 attribute TexCoordPrecision vec2 a_texCoord; |
| 615 attribute float a_index; |
| 616 uniform mat4 matrix; |
| 617 uniform TexCoordPrecision vec2 quad[4]; |
| 618 uniform TexCoordPrecision vec4 vertexTexTransform; |
| 619 varying TexCoordPrecision vec2 v_texCoord; |
| 620 }); |
| 621 } |
| 622 |
| 623 std::string VertexShaderTile::GetShaderBody() { |
| 624 return SHADER0([]() { |
| 625 void main() { |
| 626 vec2 pos = quad[int(a_index)]; // NOLINT |
| 627 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 628 v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy; |
| 629 } |
| 630 }); |
| 631 } |
| 632 |
| 633 VertexShaderTileAA::VertexShaderTileAA() |
| 634 : matrix_location_(-1), |
| 635 viewport_location_(-1), |
| 636 quad_location_(-1), |
| 637 edge_location_(-1), |
| 638 vertex_tex_transform_location_(-1) { |
| 639 } |
| 640 |
| 641 void VertexShaderTileAA::Init(GLES2Interface* context, |
| 642 unsigned program, |
| 643 int* base_uniform_index) { |
| 644 static const char* uniforms[] = { |
| 645 "matrix", "viewport", "quad", "edge", "vertexTexTransform", |
| 646 }; |
| 647 int locations[arraysize(uniforms)]; |
| 648 |
| 649 GetProgramUniformLocations(context, |
| 650 program, |
| 651 arraysize(uniforms), |
| 652 uniforms, |
| 653 locations, |
| 654 base_uniform_index); |
| 655 matrix_location_ = locations[0]; |
| 656 viewport_location_ = locations[1]; |
| 657 quad_location_ = locations[2]; |
| 658 edge_location_ = locations[3]; |
| 659 vertex_tex_transform_location_ = locations[4]; |
| 660 } |
| 661 |
| 662 std::string VertexShaderTileAA::GetShaderString() const { |
| 663 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 664 } |
| 665 |
| 666 std::string VertexShaderTileAA::GetShaderHead() { |
| 667 return SHADER0([]() { |
| 668 attribute TexCoordPrecision vec4 a_position; |
| 669 attribute float a_index; |
| 670 uniform mat4 matrix; |
| 671 uniform vec4 viewport; |
| 672 uniform TexCoordPrecision vec2 quad[4]; |
| 673 uniform TexCoordPrecision vec3 edge[8]; |
| 674 uniform TexCoordPrecision vec4 vertexTexTransform; |
| 675 varying TexCoordPrecision vec2 v_texCoord; |
| 676 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 677 }); |
| 678 } |
| 679 |
| 680 std::string VertexShaderTileAA::GetShaderBody() { |
| 681 return SHADER0([]() { |
| 682 void main() { |
| 683 vec2 pos = quad[int(a_index)]; // NOLINT |
| 684 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 685 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
| 686 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
| 687 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
| 688 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
| 689 gl_Position.w; |
| 690 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
| 691 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
| 692 gl_Position.w; |
| 693 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy; |
| 694 } |
| 695 }); |
| 696 } |
| 697 |
| 698 VertexShaderVideoTransform::VertexShaderVideoTransform() |
| 699 : matrix_location_(-1), tex_matrix_location_(-1) { |
| 700 } |
| 701 |
| 702 void VertexShaderVideoTransform::Init(GLES2Interface* context, |
| 703 unsigned program, |
| 704 int* base_uniform_index) { |
| 705 static const char* uniforms[] = { |
| 706 "matrix", "texMatrix", |
| 707 }; |
| 708 int locations[arraysize(uniforms)]; |
| 709 |
| 710 GetProgramUniformLocations(context, |
| 711 program, |
| 712 arraysize(uniforms), |
| 713 uniforms, |
| 714 locations, |
| 715 base_uniform_index); |
| 716 matrix_location_ = locations[0]; |
| 717 tex_matrix_location_ = locations[1]; |
| 718 } |
| 719 |
| 720 std::string VertexShaderVideoTransform::GetShaderString() const { |
| 721 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); |
| 722 } |
| 723 |
| 724 std::string VertexShaderVideoTransform::GetShaderHead() { |
| 725 return SHADER0([]() { |
| 726 attribute vec4 a_position; |
| 727 attribute TexCoordPrecision vec2 a_texCoord; |
| 728 uniform mat4 matrix; |
| 729 uniform TexCoordPrecision mat4 texMatrix; |
| 730 varying TexCoordPrecision vec2 v_texCoord; |
| 731 }); |
| 732 } |
| 733 |
| 734 std::string VertexShaderVideoTransform::GetShaderBody() { |
| 735 return SHADER0([]() { |
| 736 void main() { |
| 737 gl_Position = matrix * a_position; |
| 738 v_texCoord = |
| 739 vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0)); |
| 740 } |
| 741 }); |
| 742 } |
| 743 |
| 744 #define BLEND_MODE_UNIFORMS "s_backdropTexture", \ |
| 745 "s_originalBackdropTexture", \ |
| 746 "backdropRect" |
| 747 #define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 3 : 0) |
| 748 #define BLEND_MODE_SET_LOCATIONS(X, POS) \ |
| 749 if (has_blend_mode()) { \ |
| 750 DCHECK_LT(static_cast<size_t>(POS) + 2, arraysize(X)); \ |
| 751 backdrop_location_ = locations[POS]; \ |
| 752 original_backdrop_location_ = locations[POS + 1]; \ |
| 753 backdrop_rect_location_ = locations[POS + 2]; \ |
| 754 } |
| 755 |
| 756 FragmentTexBlendMode::FragmentTexBlendMode() |
| 757 : backdrop_location_(-1), |
| 758 original_backdrop_location_(-1), |
| 759 backdrop_rect_location_(-1), |
| 760 blend_mode_(BLEND_MODE_NONE), |
| 761 mask_for_background_(false) { |
| 762 } |
| 763 |
| 764 std::string FragmentTexBlendMode::SetBlendModeFunctions( |
| 765 std::string shader_string) const { |
| 766 if (shader_string.find("ApplyBlendMode") == std::string::npos) |
| 767 return shader_string; |
| 768 |
| 769 if (!has_blend_mode()) { |
| 770 return "#define ApplyBlendMode(X, Y) (X)\n" + shader_string; |
| 771 } |
| 772 |
| 773 static const std::string kUniforms = SHADER0([]() { |
| 774 uniform sampler2D s_backdropTexture; |
| 775 uniform sampler2D s_originalBackdropTexture; |
| 776 uniform TexCoordPrecision vec4 backdropRect; |
| 777 }); |
| 778 |
| 779 std::string mixFunction; |
| 780 if (mask_for_background()) { |
| 781 mixFunction = SHADER0([]() { |
| 782 vec4 MixBackdrop(TexCoordPrecision vec2 bgTexCoord, float mask) { |
| 783 vec4 backdrop = texture2D(s_backdropTexture, bgTexCoord); |
| 784 vec4 original_backdrop = |
| 785 texture2D(s_originalBackdropTexture, bgTexCoord); |
| 786 return mix(original_backdrop, backdrop, mask); |
| 787 } |
| 788 }); |
| 789 } else { |
| 790 mixFunction = SHADER0([]() { |
| 791 vec4 MixBackdrop(TexCoordPrecision vec2 bgTexCoord, float mask) { |
| 792 return texture2D(s_backdropTexture, bgTexCoord); |
| 793 } |
| 794 }); |
| 795 } |
| 796 |
| 797 static const std::string kFunctionApplyBlendMode = SHADER0([]() { |
| 798 vec4 GetBackdropColor(float mask) { |
| 799 TexCoordPrecision vec2 bgTexCoord = gl_FragCoord.xy - backdropRect.xy; |
| 800 bgTexCoord.x /= backdropRect.z; |
| 801 bgTexCoord.y /= backdropRect.w; |
| 802 return MixBackdrop(bgTexCoord, mask); |
| 803 } |
| 804 |
| 805 vec4 ApplyBlendMode(vec4 src, float mask) { |
| 806 vec4 dst = GetBackdropColor(mask); |
| 807 return Blend(src, dst); |
| 808 } |
| 809 }); |
| 810 |
| 811 return "precision mediump float;" + GetHelperFunctions() + |
| 812 GetBlendFunction() + kUniforms + mixFunction + |
| 813 kFunctionApplyBlendMode + shader_string; |
| 814 } |
| 815 |
| 816 std::string FragmentTexBlendMode::GetHelperFunctions() const { |
| 817 static const std::string kFunctionHardLight = SHADER0([]() { |
| 818 vec3 hardLight(vec4 src, vec4 dst) { |
| 819 vec3 result; |
| 820 result.r = |
| 821 (2.0 * src.r <= src.a) |
| 822 ? (2.0 * src.r * dst.r) |
| 823 : (src.a * dst.a - 2.0 * (dst.a - dst.r) * (src.a - src.r)); |
| 824 result.g = |
| 825 (2.0 * src.g <= src.a) |
| 826 ? (2.0 * src.g * dst.g) |
| 827 : (src.a * dst.a - 2.0 * (dst.a - dst.g) * (src.a - src.g)); |
| 828 result.b = |
| 829 (2.0 * src.b <= src.a) |
| 830 ? (2.0 * src.b * dst.b) |
| 831 : (src.a * dst.a - 2.0 * (dst.a - dst.b) * (src.a - src.b)); |
| 832 result.rgb += src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a); |
| 833 return result; |
| 834 } |
| 835 }); |
| 836 |
| 837 static const std::string kFunctionColorDodgeComponent = SHADER0([]() { |
| 838 float getColorDodgeComponent(float srcc, float srca, float dstc, |
| 839 float dsta) { |
| 840 if (0.0 == dstc) |
| 841 return srcc * (1.0 - dsta); |
| 842 float d = srca - srcc; |
| 843 if (0.0 == d) |
| 844 return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca); |
| 845 d = min(dsta, dstc * srca / d); |
| 846 return d * srca + srcc * (1.0 - dsta) + dstc * (1.0 - srca); |
| 847 } |
| 848 }); |
| 849 |
| 850 static const std::string kFunctionColorBurnComponent = SHADER0([]() { |
| 851 float getColorBurnComponent(float srcc, float srca, float dstc, |
| 852 float dsta) { |
| 853 if (dsta == dstc) |
| 854 return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca); |
| 855 if (0.0 == srcc) |
| 856 return dstc * (1.0 - srca); |
| 857 float d = max(0.0, dsta - (dsta - dstc) * srca / srcc); |
| 858 return srca * d + srcc * (1.0 - dsta) + dstc * (1.0 - srca); |
| 859 } |
| 860 }); |
| 861 |
| 862 static const std::string kFunctionSoftLightComponentPosDstAlpha = |
| 863 SHADER0([]() { |
| 864 float getSoftLightComponent(float srcc, float srca, float dstc, |
| 865 float dsta) { |
| 866 if (2.0 * srcc <= srca) { |
| 867 return (dstc * dstc * (srca - 2.0 * srcc)) / dsta + |
| 868 (1.0 - dsta) * srcc + dstc * (-srca + 2.0 * srcc + 1.0); |
| 869 } else if (4.0 * dstc <= dsta) { |
| 870 float DSqd = dstc * dstc; |
| 871 float DCub = DSqd * dstc; |
| 872 float DaSqd = dsta * dsta; |
| 873 float DaCub = DaSqd * dsta; |
| 874 return (-DaCub * srcc + |
| 875 DaSqd * (srcc - dstc * (3.0 * srca - 6.0 * srcc - 1.0)) + |
| 876 12.0 * dsta * DSqd * (srca - 2.0 * srcc) - |
| 877 16.0 * DCub * (srca - 2.0 * srcc)) / |
| 878 DaSqd; |
| 879 } else { |
| 880 return -sqrt(dsta * dstc) * (srca - 2.0 * srcc) - dsta * srcc + |
| 881 dstc * (srca - 2.0 * srcc + 1.0) + srcc; |
| 882 } |
| 883 } |
| 884 }); |
| 885 |
| 886 static const std::string kFunctionLum = SHADER0([]() { |
| 887 float luminance(vec3 color) { return dot(vec3(0.3, 0.59, 0.11), color); } |
| 888 |
| 889 vec3 set_luminance(vec3 hueSat, float alpha, vec3 lumColor) { |
| 890 float diff = luminance(lumColor - hueSat); |
| 891 vec3 outColor = hueSat + diff; |
| 892 float outLum = luminance(outColor); |
| 893 float minComp = min(min(outColor.r, outColor.g), outColor.b); |
| 894 float maxComp = max(max(outColor.r, outColor.g), outColor.b); |
| 895 if (minComp < 0.0 && outLum != minComp) { |
| 896 outColor = outLum + |
| 897 ((outColor - vec3(outLum, outLum, outLum)) * outLum) / |
| 898 (outLum - minComp); |
| 899 } |
| 900 if (maxComp > alpha && maxComp != outLum) { |
| 901 outColor = |
| 902 outLum + |
| 903 ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / |
| 904 (maxComp - outLum); |
| 905 } |
| 906 return outColor; |
| 907 } |
| 908 }); |
| 909 |
| 910 static const std::string kFunctionSat = SHADER0([]() { |
| 911 float saturation(vec3 color) { |
| 912 return max(max(color.r, color.g), color.b) - |
| 913 min(min(color.r, color.g), color.b); |
| 914 } |
| 915 |
| 916 vec3 set_saturation_helper(float minComp, float midComp, float maxComp, |
| 917 float sat) { |
| 918 if (minComp < maxComp) { |
| 919 vec3 result; |
| 920 result.r = 0.0; |
| 921 result.g = sat * (midComp - minComp) / (maxComp - minComp); |
| 922 result.b = sat; |
| 923 return result; |
| 924 } else { |
| 925 return vec3(0, 0, 0); |
| 926 } |
| 927 } |
| 928 |
| 929 vec3 set_saturation(vec3 hueLumColor, vec3 satColor) { |
| 930 float sat = saturation(satColor); |
| 931 if (hueLumColor.r <= hueLumColor.g) { |
| 932 if (hueLumColor.g <= hueLumColor.b) { |
| 933 hueLumColor.rgb = set_saturation_helper(hueLumColor.r, hueLumColor.g, |
| 934 hueLumColor.b, sat); |
| 935 } else if (hueLumColor.r <= hueLumColor.b) { |
| 936 hueLumColor.rbg = set_saturation_helper(hueLumColor.r, hueLumColor.b, |
| 937 hueLumColor.g, sat); |
| 938 } else { |
| 939 hueLumColor.brg = set_saturation_helper(hueLumColor.b, hueLumColor.r, |
| 940 hueLumColor.g, sat); |
| 941 } |
| 942 } else if (hueLumColor.r <= hueLumColor.b) { |
| 943 hueLumColor.grb = set_saturation_helper(hueLumColor.g, hueLumColor.r, |
| 944 hueLumColor.b, sat); |
| 945 } else if (hueLumColor.g <= hueLumColor.b) { |
| 946 hueLumColor.gbr = set_saturation_helper(hueLumColor.g, hueLumColor.b, |
| 947 hueLumColor.r, sat); |
| 948 } else { |
| 949 hueLumColor.bgr = set_saturation_helper(hueLumColor.b, hueLumColor.g, |
| 950 hueLumColor.r, sat); |
| 951 } |
| 952 return hueLumColor; |
| 953 } |
| 954 }); |
| 955 |
| 956 switch (blend_mode_) { |
| 957 case BLEND_MODE_OVERLAY: |
| 958 case BLEND_MODE_HARD_LIGHT: |
| 959 return kFunctionHardLight; |
| 960 case BLEND_MODE_COLOR_DODGE: |
| 961 return kFunctionColorDodgeComponent; |
| 962 case BLEND_MODE_COLOR_BURN: |
| 963 return kFunctionColorBurnComponent; |
| 964 case BLEND_MODE_SOFT_LIGHT: |
| 965 return kFunctionSoftLightComponentPosDstAlpha; |
| 966 case BLEND_MODE_HUE: |
| 967 case BLEND_MODE_SATURATION: |
| 968 return kFunctionLum + kFunctionSat; |
| 969 case BLEND_MODE_COLOR: |
| 970 case BLEND_MODE_LUMINOSITY: |
| 971 return kFunctionLum; |
| 972 default: |
| 973 return std::string(); |
| 974 } |
| 975 } |
| 976 |
| 977 std::string FragmentTexBlendMode::GetBlendFunction() const { |
| 978 return "vec4 Blend(vec4 src, vec4 dst) {" |
| 979 " vec4 result;" |
| 980 " result.a = src.a + (1.0 - src.a) * dst.a;" + |
| 981 GetBlendFunctionBodyForRGB() + |
| 982 " return result;" |
| 983 "}"; |
| 984 } |
| 985 |
| 986 std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const { |
| 987 switch (blend_mode_) { |
| 988 case BLEND_MODE_NORMAL: |
| 989 return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);"; |
| 990 case BLEND_MODE_SCREEN: |
| 991 return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;"; |
| 992 case BLEND_MODE_LIGHTEN: |
| 993 return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb," |
| 994 " (1.0 - dst.a) * src.rgb + dst.rgb);"; |
| 995 case BLEND_MODE_OVERLAY: |
| 996 return "result.rgb = hardLight(dst, src);"; |
| 997 case BLEND_MODE_DARKEN: |
| 998 return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb," |
| 999 " (1.0 - dst.a) * src.rgb + dst.rgb);"; |
| 1000 case BLEND_MODE_COLOR_DODGE: |
| 1001 return "result.r = getColorDodgeComponent(src.r, src.a, dst.r, dst.a);" |
| 1002 "result.g = getColorDodgeComponent(src.g, src.a, dst.g, dst.a);" |
| 1003 "result.b = getColorDodgeComponent(src.b, src.a, dst.b, dst.a);"; |
| 1004 case BLEND_MODE_COLOR_BURN: |
| 1005 return "result.r = getColorBurnComponent(src.r, src.a, dst.r, dst.a);" |
| 1006 "result.g = getColorBurnComponent(src.g, src.a, dst.g, dst.a);" |
| 1007 "result.b = getColorBurnComponent(src.b, src.a, dst.b, dst.a);"; |
| 1008 case BLEND_MODE_HARD_LIGHT: |
| 1009 return "result.rgb = hardLight(src, dst);"; |
| 1010 case BLEND_MODE_SOFT_LIGHT: |
| 1011 return "if (0.0 == dst.a) {" |
| 1012 " result.rgb = src.rgb;" |
| 1013 "} else {" |
| 1014 " result.r = getSoftLightComponent(src.r, src.a, dst.r, dst.a);" |
| 1015 " result.g = getSoftLightComponent(src.g, src.a, dst.g, dst.a);" |
| 1016 " result.b = getSoftLightComponent(src.b, src.a, dst.b, dst.a);" |
| 1017 "}"; |
| 1018 case BLEND_MODE_DIFFERENCE: |
| 1019 return "result.rgb = src.rgb + dst.rgb -" |
| 1020 " 2.0 * min(src.rgb * dst.a, dst.rgb * src.a);"; |
| 1021 case BLEND_MODE_EXCLUSION: |
| 1022 return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;"; |
| 1023 case BLEND_MODE_MULTIPLY: |
| 1024 return "result.rgb = (1.0 - src.a) * dst.rgb +" |
| 1025 " (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;"; |
| 1026 case BLEND_MODE_HUE: |
| 1027 return "vec4 dstSrcAlpha = dst * src.a;" |
| 1028 "result.rgb =" |
| 1029 " set_luminance(set_saturation(src.rgb * dst.a," |
| 1030 " dstSrcAlpha.rgb)," |
| 1031 " dstSrcAlpha.a," |
| 1032 " dstSrcAlpha.rgb);" |
| 1033 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;"; |
| 1034 case BLEND_MODE_SATURATION: |
| 1035 return "vec4 dstSrcAlpha = dst * src.a;" |
| 1036 "result.rgb = set_luminance(set_saturation(dstSrcAlpha.rgb," |
| 1037 " src.rgb * dst.a)," |
| 1038 " dstSrcAlpha.a," |
| 1039 " dstSrcAlpha.rgb);" |
| 1040 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;"; |
| 1041 case BLEND_MODE_COLOR: |
| 1042 return "vec4 srcDstAlpha = src * dst.a;" |
| 1043 "result.rgb = set_luminance(srcDstAlpha.rgb," |
| 1044 " srcDstAlpha.a," |
| 1045 " dst.rgb * src.a);" |
| 1046 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;"; |
| 1047 case BLEND_MODE_LUMINOSITY: |
| 1048 return "vec4 srcDstAlpha = src * dst.a;" |
| 1049 "result.rgb = set_luminance(dst.rgb * src.a," |
| 1050 " srcDstAlpha.a," |
| 1051 " srcDstAlpha.rgb);" |
| 1052 "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;"; |
| 1053 case BLEND_MODE_NONE: |
| 1054 NOTREACHED(); |
| 1055 } |
| 1056 return "result = vec4(1.0, 0.0, 0.0, 1.0);"; |
| 1057 } |
| 1058 |
| 1059 FragmentTexAlphaBinding::FragmentTexAlphaBinding() |
| 1060 : sampler_location_(-1), alpha_location_(-1) { |
| 1061 } |
| 1062 |
| 1063 void FragmentTexAlphaBinding::Init(GLES2Interface* context, |
| 1064 unsigned program, |
| 1065 int* base_uniform_index) { |
| 1066 static const char* uniforms[] = { |
| 1067 "s_texture", "alpha", BLEND_MODE_UNIFORMS, |
| 1068 }; |
| 1069 int locations[arraysize(uniforms)]; |
| 1070 |
| 1071 GetProgramUniformLocations(context, |
| 1072 program, |
| 1073 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1074 uniforms, |
| 1075 locations, |
| 1076 base_uniform_index); |
| 1077 sampler_location_ = locations[0]; |
| 1078 alpha_location_ = locations[1]; |
| 1079 BLEND_MODE_SET_LOCATIONS(locations, 2); |
| 1080 } |
| 1081 |
| 1082 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding() |
| 1083 : sampler_location_(-1), |
| 1084 alpha_location_(-1), |
| 1085 color_matrix_location_(-1), |
| 1086 color_offset_location_(-1) { |
| 1087 } |
| 1088 |
| 1089 void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface* context, |
| 1090 unsigned program, |
| 1091 int* base_uniform_index) { |
| 1092 static const char* uniforms[] = { |
| 1093 "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS, |
| 1094 }; |
| 1095 int locations[arraysize(uniforms)]; |
| 1096 |
| 1097 GetProgramUniformLocations(context, |
| 1098 program, |
| 1099 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1100 uniforms, |
| 1101 locations, |
| 1102 base_uniform_index); |
| 1103 sampler_location_ = locations[0]; |
| 1104 alpha_location_ = locations[1]; |
| 1105 color_matrix_location_ = locations[2]; |
| 1106 color_offset_location_ = locations[3]; |
| 1107 BLEND_MODE_SET_LOCATIONS(locations, 4); |
| 1108 } |
| 1109 |
| 1110 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding() : sampler_location_(-1) { |
| 1111 } |
| 1112 |
| 1113 void FragmentTexOpaqueBinding::Init(GLES2Interface* context, |
| 1114 unsigned program, |
| 1115 int* base_uniform_index) { |
| 1116 static const char* uniforms[] = { |
| 1117 "s_texture", |
| 1118 }; |
| 1119 int locations[arraysize(uniforms)]; |
| 1120 |
| 1121 GetProgramUniformLocations(context, |
| 1122 program, |
| 1123 arraysize(uniforms), |
| 1124 uniforms, |
| 1125 locations, |
| 1126 base_uniform_index); |
| 1127 sampler_location_ = locations[0]; |
| 1128 } |
| 1129 |
| 1130 std::string FragmentShaderRGBATexAlpha::GetShaderString( |
| 1131 TexCoordPrecision precision, |
| 1132 SamplerType sampler) const { |
| 1133 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1134 } |
| 1135 |
| 1136 std::string FragmentShaderRGBATexAlpha::GetShaderHead() { |
| 1137 return SHADER0([]() { |
| 1138 precision mediump float; |
| 1139 varying TexCoordPrecision vec2 v_texCoord; |
| 1140 uniform SamplerType s_texture; |
| 1141 uniform float alpha; |
| 1142 }); |
| 1143 } |
| 1144 |
| 1145 std::string FragmentShaderRGBATexAlpha::GetShaderBody() { |
| 1146 return SHADER0([]() { |
| 1147 void main() { |
| 1148 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1149 gl_FragColor = ApplyBlendMode(texColor * alpha, 0.0); |
| 1150 } |
| 1151 }); |
| 1152 } |
| 1153 |
| 1154 void FragmentShaderRGBATexAlpha::FillLocations( |
| 1155 ShaderLocations* locations) const { |
| 1156 locations->sampler = sampler_location(); |
| 1157 locations->alpha = alpha_location(); |
| 1158 locations->backdrop = backdrop_location(); |
| 1159 locations->backdrop_rect = backdrop_rect_location(); |
| 1160 } |
| 1161 |
| 1162 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString( |
| 1163 TexCoordPrecision precision, |
| 1164 SamplerType sampler) const { |
| 1165 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1166 } |
| 1167 |
| 1168 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderHead() { |
| 1169 return SHADER0([]() { |
| 1170 precision mediump float; |
| 1171 varying TexCoordPrecision vec2 v_texCoord; |
| 1172 uniform SamplerType s_texture; |
| 1173 uniform float alpha; |
| 1174 uniform mat4 colorMatrix; |
| 1175 uniform vec4 colorOffset; |
| 1176 }); |
| 1177 } |
| 1178 |
| 1179 std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderBody() { |
| 1180 return SHADER0([]() { |
| 1181 void main() { |
| 1182 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1183 float nonZeroAlpha = max(texColor.a, 0.00001); |
| 1184 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha); |
| 1185 texColor = colorMatrix * texColor + colorOffset; |
| 1186 texColor.rgb *= texColor.a; |
| 1187 texColor = clamp(texColor, 0.0, 1.0); |
| 1188 gl_FragColor = ApplyBlendMode(texColor * alpha, 0.0); |
| 1189 } |
| 1190 }); |
| 1191 } |
| 1192 |
| 1193 void FragmentShaderRGBATexColorMatrixAlpha::FillLocations( |
| 1194 ShaderLocations* locations) const { |
| 1195 locations->sampler = sampler_location(); |
| 1196 locations->alpha = alpha_location(); |
| 1197 locations->color_matrix = color_matrix_location(); |
| 1198 locations->color_offset = color_offset_location(); |
| 1199 locations->backdrop = backdrop_location(); |
| 1200 locations->backdrop_rect = backdrop_rect_location(); |
| 1201 } |
| 1202 |
| 1203 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString( |
| 1204 TexCoordPrecision precision, |
| 1205 SamplerType sampler) const { |
| 1206 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1207 } |
| 1208 |
| 1209 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderHead() { |
| 1210 return SHADER0([]() { |
| 1211 precision mediump float; |
| 1212 varying TexCoordPrecision vec2 v_texCoord; |
| 1213 varying float v_alpha; |
| 1214 uniform SamplerType s_texture; |
| 1215 }); |
| 1216 } |
| 1217 |
| 1218 std::string FragmentShaderRGBATexVaryingAlpha::GetShaderBody() { |
| 1219 return SHADER0([]() { |
| 1220 void main() { |
| 1221 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1222 gl_FragColor = texColor * v_alpha; |
| 1223 } |
| 1224 }); |
| 1225 } |
| 1226 |
| 1227 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString( |
| 1228 TexCoordPrecision precision, |
| 1229 SamplerType sampler) const { |
| 1230 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1231 } |
| 1232 |
| 1233 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderHead() { |
| 1234 return SHADER0([]() { |
| 1235 precision mediump float; |
| 1236 varying TexCoordPrecision vec2 v_texCoord; |
| 1237 varying float v_alpha; |
| 1238 uniform SamplerType s_texture; |
| 1239 }); |
| 1240 } |
| 1241 |
| 1242 std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderBody() { |
| 1243 return SHADER0([]() { |
| 1244 void main() { |
| 1245 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1246 texColor.rgb *= texColor.a; |
| 1247 gl_FragColor = texColor * v_alpha; |
| 1248 } |
| 1249 }); |
| 1250 } |
| 1251 |
| 1252 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding() |
| 1253 : background_color_location_(-1), sampler_location_(-1) { |
| 1254 } |
| 1255 |
| 1256 void FragmentTexBackgroundBinding::Init(GLES2Interface* context, |
| 1257 unsigned program, |
| 1258 int* base_uniform_index) { |
| 1259 static const char* uniforms[] = { |
| 1260 "s_texture", "background_color", |
| 1261 }; |
| 1262 int locations[arraysize(uniforms)]; |
| 1263 |
| 1264 GetProgramUniformLocations(context, |
| 1265 program, |
| 1266 arraysize(uniforms), |
| 1267 uniforms, |
| 1268 locations, |
| 1269 base_uniform_index); |
| 1270 |
| 1271 sampler_location_ = locations[0]; |
| 1272 DCHECK_NE(sampler_location_, -1); |
| 1273 |
| 1274 background_color_location_ = locations[1]; |
| 1275 DCHECK_NE(background_color_location_, -1); |
| 1276 } |
| 1277 |
| 1278 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString( |
| 1279 TexCoordPrecision precision, |
| 1280 SamplerType sampler) const { |
| 1281 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1282 } |
| 1283 |
| 1284 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderHead() { |
| 1285 return SHADER0([]() { |
| 1286 precision mediump float; |
| 1287 varying TexCoordPrecision vec2 v_texCoord; |
| 1288 varying float v_alpha; |
| 1289 uniform vec4 background_color; |
| 1290 uniform SamplerType s_texture; |
| 1291 }); |
| 1292 } |
| 1293 |
| 1294 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderBody() { |
| 1295 return SHADER0([]() { |
| 1296 void main() { |
| 1297 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1298 texColor += background_color * (1.0 - texColor.a); |
| 1299 gl_FragColor = texColor * v_alpha; |
| 1300 } |
| 1301 }); |
| 1302 } |
| 1303 |
| 1304 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString( |
| 1305 TexCoordPrecision precision, |
| 1306 SamplerType sampler) const { |
| 1307 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1308 } |
| 1309 |
| 1310 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderHead() { |
| 1311 return SHADER0([]() { |
| 1312 precision mediump float; |
| 1313 varying TexCoordPrecision vec2 v_texCoord; |
| 1314 varying float v_alpha; |
| 1315 uniform vec4 background_color; |
| 1316 uniform SamplerType s_texture; |
| 1317 }); |
| 1318 } |
| 1319 |
| 1320 std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderBody() { |
| 1321 return SHADER0([]() { |
| 1322 void main() { |
| 1323 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1324 texColor.rgb *= texColor.a; |
| 1325 texColor += background_color * (1.0 - texColor.a); |
| 1326 gl_FragColor = texColor * v_alpha; |
| 1327 } |
| 1328 }); |
| 1329 } |
| 1330 |
| 1331 std::string FragmentShaderRGBATexOpaque::GetShaderString( |
| 1332 TexCoordPrecision precision, |
| 1333 SamplerType sampler) const { |
| 1334 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1335 } |
| 1336 |
| 1337 std::string FragmentShaderRGBATexOpaque::GetShaderHead() { |
| 1338 return SHADER0([]() { |
| 1339 precision mediump float; |
| 1340 varying TexCoordPrecision vec2 v_texCoord; |
| 1341 uniform SamplerType s_texture; |
| 1342 }); |
| 1343 } |
| 1344 |
| 1345 std::string FragmentShaderRGBATexOpaque::GetShaderBody() { |
| 1346 return SHADER0([]() { |
| 1347 void main() { |
| 1348 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1349 gl_FragColor = vec4(texColor.rgb, 1.0); |
| 1350 } |
| 1351 }); |
| 1352 } |
| 1353 |
| 1354 std::string FragmentShaderRGBATex::GetShaderString(TexCoordPrecision precision, |
| 1355 SamplerType sampler) const { |
| 1356 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1357 } |
| 1358 |
| 1359 std::string FragmentShaderRGBATex::GetShaderHead() { |
| 1360 return SHADER0([]() { |
| 1361 precision mediump float; |
| 1362 varying TexCoordPrecision vec2 v_texCoord; |
| 1363 uniform SamplerType s_texture; |
| 1364 }); |
| 1365 } |
| 1366 |
| 1367 std::string FragmentShaderRGBATex::GetShaderBody() { |
| 1368 return SHADER0([]() { |
| 1369 void main() { gl_FragColor = TextureLookup(s_texture, v_texCoord); } |
| 1370 }); |
| 1371 } |
| 1372 |
| 1373 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString( |
| 1374 TexCoordPrecision precision, |
| 1375 SamplerType sampler) const { |
| 1376 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1377 } |
| 1378 |
| 1379 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderHead() { |
| 1380 return SHADER0([]() { |
| 1381 precision mediump float; |
| 1382 varying TexCoordPrecision vec2 v_texCoord; |
| 1383 uniform SamplerType s_texture; |
| 1384 uniform float alpha; |
| 1385 }); |
| 1386 } |
| 1387 |
| 1388 std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderBody() { |
| 1389 return SHADER0([]() { |
| 1390 void main() { |
| 1391 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1392 gl_FragColor = |
| 1393 vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; |
| 1394 } |
| 1395 }); |
| 1396 } |
| 1397 |
| 1398 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString( |
| 1399 TexCoordPrecision precision, |
| 1400 SamplerType sampler) const { |
| 1401 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1402 } |
| 1403 |
| 1404 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderHead() { |
| 1405 return SHADER0([]() { |
| 1406 precision mediump float; |
| 1407 varying TexCoordPrecision vec2 v_texCoord; |
| 1408 uniform SamplerType s_texture; |
| 1409 }); |
| 1410 } |
| 1411 |
| 1412 std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderBody() { |
| 1413 return SHADER0([]() { |
| 1414 void main() { |
| 1415 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1416 gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0); |
| 1417 } |
| 1418 }); |
| 1419 } |
| 1420 |
| 1421 FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA() |
| 1422 : sampler_location_(-1), alpha_location_(-1) { |
| 1423 } |
| 1424 |
| 1425 void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface* context, |
| 1426 unsigned program, |
| 1427 int* base_uniform_index) { |
| 1428 static const char* uniforms[] = { |
| 1429 "s_texture", "alpha", BLEND_MODE_UNIFORMS, |
| 1430 }; |
| 1431 int locations[arraysize(uniforms)]; |
| 1432 |
| 1433 GetProgramUniformLocations(context, |
| 1434 program, |
| 1435 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1436 uniforms, |
| 1437 locations, |
| 1438 base_uniform_index); |
| 1439 sampler_location_ = locations[0]; |
| 1440 alpha_location_ = locations[1]; |
| 1441 BLEND_MODE_SET_LOCATIONS(locations, 2); |
| 1442 } |
| 1443 |
| 1444 std::string FragmentShaderRGBATexAlphaAA::GetShaderString( |
| 1445 TexCoordPrecision precision, |
| 1446 SamplerType sampler) const { |
| 1447 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1448 } |
| 1449 |
| 1450 std::string FragmentShaderRGBATexAlphaAA::GetShaderHead() { |
| 1451 return SHADER0([]() { |
| 1452 precision mediump float; |
| 1453 uniform SamplerType s_texture; |
| 1454 uniform float alpha; |
| 1455 varying TexCoordPrecision vec2 v_texCoord; |
| 1456 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 1457 }); |
| 1458 } |
| 1459 |
| 1460 std::string FragmentShaderRGBATexAlphaAA::GetShaderBody() { |
| 1461 return SHADER0([]() { |
| 1462 void main() { |
| 1463 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1464 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 1465 vec2 d2 = min(d4.xz, d4.yw); |
| 1466 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 1467 gl_FragColor = ApplyBlendMode(texColor * alpha * aa, 0.0); |
| 1468 } |
| 1469 }); |
| 1470 } |
| 1471 |
| 1472 void FragmentShaderRGBATexAlphaAA::FillLocations( |
| 1473 ShaderLocations* locations) const { |
| 1474 locations->sampler = sampler_location(); |
| 1475 locations->alpha = alpha_location(); |
| 1476 locations->backdrop = backdrop_location(); |
| 1477 locations->backdrop_rect = backdrop_rect_location(); |
| 1478 } |
| 1479 |
| 1480 FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding() |
| 1481 : sampler_location_(-1), |
| 1482 alpha_location_(-1), |
| 1483 fragment_tex_transform_location_(-1) { |
| 1484 } |
| 1485 |
| 1486 void FragmentTexClampAlphaAABinding::Init(GLES2Interface* context, |
| 1487 unsigned program, |
| 1488 int* base_uniform_index) { |
| 1489 static const char* uniforms[] = { |
| 1490 "s_texture", "alpha", "fragmentTexTransform", |
| 1491 }; |
| 1492 int locations[arraysize(uniforms)]; |
| 1493 |
| 1494 GetProgramUniformLocations(context, |
| 1495 program, |
| 1496 arraysize(uniforms), |
| 1497 uniforms, |
| 1498 locations, |
| 1499 base_uniform_index); |
| 1500 sampler_location_ = locations[0]; |
| 1501 alpha_location_ = locations[1]; |
| 1502 fragment_tex_transform_location_ = locations[2]; |
| 1503 } |
| 1504 |
| 1505 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString( |
| 1506 TexCoordPrecision precision, |
| 1507 SamplerType sampler) const { |
| 1508 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1509 } |
| 1510 |
| 1511 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderHead() { |
| 1512 return SHADER0([]() { |
| 1513 precision mediump float; |
| 1514 uniform SamplerType s_texture; |
| 1515 uniform float alpha; |
| 1516 uniform TexCoordPrecision vec4 fragmentTexTransform; |
| 1517 varying TexCoordPrecision vec2 v_texCoord; |
| 1518 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 1519 }); |
| 1520 } |
| 1521 |
| 1522 std::string FragmentShaderRGBATexClampAlphaAA::GetShaderBody() { |
| 1523 return SHADER0([]() { |
| 1524 void main() { |
| 1525 TexCoordPrecision vec2 texCoord = |
| 1526 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + |
| 1527 fragmentTexTransform.xy; |
| 1528 vec4 texColor = TextureLookup(s_texture, texCoord); |
| 1529 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 1530 vec2 d2 = min(d4.xz, d4.yw); |
| 1531 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 1532 gl_FragColor = texColor * alpha * aa; |
| 1533 } |
| 1534 }); |
| 1535 } |
| 1536 |
| 1537 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString( |
| 1538 TexCoordPrecision precision, |
| 1539 SamplerType sampler) const { |
| 1540 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1541 } |
| 1542 |
| 1543 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderHead() { |
| 1544 return SHADER0([]() { |
| 1545 precision mediump float; |
| 1546 uniform SamplerType s_texture; |
| 1547 uniform float alpha; |
| 1548 uniform TexCoordPrecision vec4 fragmentTexTransform; |
| 1549 varying TexCoordPrecision vec2 v_texCoord; |
| 1550 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 1551 }); |
| 1552 } |
| 1553 |
| 1554 std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderBody() { |
| 1555 return SHADER0([]() { |
| 1556 void main() { |
| 1557 TexCoordPrecision vec2 texCoord = |
| 1558 clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + |
| 1559 fragmentTexTransform.xy; |
| 1560 vec4 texColor = TextureLookup(s_texture, texCoord); |
| 1561 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 1562 vec2 d2 = min(d4.xz, d4.yw); |
| 1563 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 1564 gl_FragColor = |
| 1565 vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha * aa; |
| 1566 } |
| 1567 }); |
| 1568 } |
| 1569 |
| 1570 FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask() |
| 1571 : sampler_location_(-1), |
| 1572 mask_sampler_location_(-1), |
| 1573 alpha_location_(-1), |
| 1574 mask_tex_coord_scale_location_(-1) { |
| 1575 } |
| 1576 |
| 1577 void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface* context, |
| 1578 unsigned program, |
| 1579 int* base_uniform_index) { |
| 1580 static const char* uniforms[] = { |
| 1581 "s_texture", |
| 1582 "s_mask", |
| 1583 "alpha", |
| 1584 "maskTexCoordScale", |
| 1585 "maskTexCoordOffset", |
| 1586 BLEND_MODE_UNIFORMS, |
| 1587 }; |
| 1588 int locations[arraysize(uniforms)]; |
| 1589 |
| 1590 GetProgramUniformLocations(context, |
| 1591 program, |
| 1592 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1593 uniforms, |
| 1594 locations, |
| 1595 base_uniform_index); |
| 1596 sampler_location_ = locations[0]; |
| 1597 mask_sampler_location_ = locations[1]; |
| 1598 alpha_location_ = locations[2]; |
| 1599 mask_tex_coord_scale_location_ = locations[3]; |
| 1600 mask_tex_coord_offset_location_ = locations[4]; |
| 1601 BLEND_MODE_SET_LOCATIONS(locations, 5); |
| 1602 } |
| 1603 |
| 1604 std::string FragmentShaderRGBATexAlphaMask::GetShaderString( |
| 1605 TexCoordPrecision precision, |
| 1606 SamplerType sampler) const { |
| 1607 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1608 } |
| 1609 |
| 1610 std::string FragmentShaderRGBATexAlphaMask::GetShaderHead() { |
| 1611 return SHADER0([]() { |
| 1612 precision mediump float; |
| 1613 varying TexCoordPrecision vec2 v_texCoord; |
| 1614 uniform sampler2D s_texture; |
| 1615 uniform SamplerType s_mask; |
| 1616 uniform TexCoordPrecision vec2 maskTexCoordScale; |
| 1617 uniform TexCoordPrecision vec2 maskTexCoordOffset; |
| 1618 uniform float alpha; |
| 1619 }); |
| 1620 } |
| 1621 |
| 1622 std::string FragmentShaderRGBATexAlphaMask::GetShaderBody() { |
| 1623 return SHADER0([]() { |
| 1624 void main() { |
| 1625 vec4 texColor = texture2D(s_texture, v_texCoord); |
| 1626 TexCoordPrecision vec2 maskTexCoord = |
| 1627 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, |
| 1628 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); |
| 1629 vec4 maskColor = TextureLookup(s_mask, maskTexCoord); |
| 1630 gl_FragColor = ApplyBlendMode( |
| 1631 texColor * alpha * maskColor.w, maskColor.w); |
| 1632 } |
| 1633 }); |
| 1634 } |
| 1635 |
| 1636 void FragmentShaderRGBATexAlphaMask::FillLocations( |
| 1637 ShaderLocations* locations) const { |
| 1638 locations->sampler = sampler_location(); |
| 1639 locations->mask_sampler = mask_sampler_location(); |
| 1640 locations->mask_tex_coord_scale = mask_tex_coord_scale_location(); |
| 1641 locations->mask_tex_coord_offset = mask_tex_coord_offset_location(); |
| 1642 locations->alpha = alpha_location(); |
| 1643 locations->backdrop = backdrop_location(); |
| 1644 locations->backdrop_rect = backdrop_rect_location(); |
| 1645 if (mask_for_background()) |
| 1646 locations->original_backdrop = original_backdrop_location(); |
| 1647 } |
| 1648 |
| 1649 FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA() |
| 1650 : sampler_location_(-1), |
| 1651 mask_sampler_location_(-1), |
| 1652 alpha_location_(-1), |
| 1653 mask_tex_coord_scale_location_(-1), |
| 1654 mask_tex_coord_offset_location_(-1) { |
| 1655 } |
| 1656 |
| 1657 void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface* context, |
| 1658 unsigned program, |
| 1659 int* base_uniform_index) { |
| 1660 static const char* uniforms[] = { |
| 1661 "s_texture", |
| 1662 "s_mask", |
| 1663 "alpha", |
| 1664 "maskTexCoordScale", |
| 1665 "maskTexCoordOffset", |
| 1666 BLEND_MODE_UNIFORMS, |
| 1667 }; |
| 1668 int locations[arraysize(uniforms)]; |
| 1669 |
| 1670 GetProgramUniformLocations(context, |
| 1671 program, |
| 1672 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1673 uniforms, |
| 1674 locations, |
| 1675 base_uniform_index); |
| 1676 sampler_location_ = locations[0]; |
| 1677 mask_sampler_location_ = locations[1]; |
| 1678 alpha_location_ = locations[2]; |
| 1679 mask_tex_coord_scale_location_ = locations[3]; |
| 1680 mask_tex_coord_offset_location_ = locations[4]; |
| 1681 BLEND_MODE_SET_LOCATIONS(locations, 5); |
| 1682 } |
| 1683 |
| 1684 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString( |
| 1685 TexCoordPrecision precision, |
| 1686 SamplerType sampler) const { |
| 1687 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1688 } |
| 1689 |
| 1690 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderHead() { |
| 1691 return SHADER0([]() { |
| 1692 precision mediump float; |
| 1693 uniform sampler2D s_texture; |
| 1694 uniform SamplerType s_mask; |
| 1695 uniform TexCoordPrecision vec2 maskTexCoordScale; |
| 1696 uniform TexCoordPrecision vec2 maskTexCoordOffset; |
| 1697 uniform float alpha; |
| 1698 varying TexCoordPrecision vec2 v_texCoord; |
| 1699 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 1700 }); |
| 1701 } |
| 1702 |
| 1703 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderBody() { |
| 1704 return SHADER0([]() { |
| 1705 void main() { |
| 1706 vec4 texColor = texture2D(s_texture, v_texCoord); |
| 1707 TexCoordPrecision vec2 maskTexCoord = |
| 1708 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, |
| 1709 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); |
| 1710 vec4 maskColor = TextureLookup(s_mask, maskTexCoord); |
| 1711 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 1712 vec2 d2 = min(d4.xz, d4.yw); |
| 1713 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 1714 gl_FragColor = ApplyBlendMode( |
| 1715 texColor * alpha * maskColor.w * aa, maskColor.w); |
| 1716 } |
| 1717 }); |
| 1718 } |
| 1719 |
| 1720 void FragmentShaderRGBATexAlphaMaskAA::FillLocations( |
| 1721 ShaderLocations* locations) const { |
| 1722 locations->sampler = sampler_location(); |
| 1723 locations->mask_sampler = mask_sampler_location(); |
| 1724 locations->mask_tex_coord_scale = mask_tex_coord_scale_location(); |
| 1725 locations->mask_tex_coord_offset = mask_tex_coord_offset_location(); |
| 1726 locations->alpha = alpha_location(); |
| 1727 locations->backdrop = backdrop_location(); |
| 1728 locations->backdrop_rect = backdrop_rect_location(); |
| 1729 if (mask_for_background()) |
| 1730 locations->original_backdrop = original_backdrop_location(); |
| 1731 } |
| 1732 |
| 1733 FragmentShaderRGBATexAlphaMaskColorMatrixAA:: |
| 1734 FragmentShaderRGBATexAlphaMaskColorMatrixAA() |
| 1735 : sampler_location_(-1), |
| 1736 mask_sampler_location_(-1), |
| 1737 alpha_location_(-1), |
| 1738 mask_tex_coord_scale_location_(-1), |
| 1739 color_matrix_location_(-1), |
| 1740 color_offset_location_(-1) { |
| 1741 } |
| 1742 |
| 1743 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init( |
| 1744 GLES2Interface* context, |
| 1745 unsigned program, |
| 1746 int* base_uniform_index) { |
| 1747 static const char* uniforms[] = { |
| 1748 "s_texture", |
| 1749 "s_mask", |
| 1750 "alpha", |
| 1751 "maskTexCoordScale", |
| 1752 "maskTexCoordOffset", |
| 1753 "colorMatrix", |
| 1754 "colorOffset", |
| 1755 BLEND_MODE_UNIFORMS, |
| 1756 }; |
| 1757 int locations[arraysize(uniforms)]; |
| 1758 |
| 1759 GetProgramUniformLocations(context, |
| 1760 program, |
| 1761 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1762 uniforms, |
| 1763 locations, |
| 1764 base_uniform_index); |
| 1765 sampler_location_ = locations[0]; |
| 1766 mask_sampler_location_ = locations[1]; |
| 1767 alpha_location_ = locations[2]; |
| 1768 mask_tex_coord_scale_location_ = locations[3]; |
| 1769 mask_tex_coord_offset_location_ = locations[4]; |
| 1770 color_matrix_location_ = locations[5]; |
| 1771 color_offset_location_ = locations[6]; |
| 1772 BLEND_MODE_SET_LOCATIONS(locations, 7); |
| 1773 } |
| 1774 |
| 1775 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString( |
| 1776 TexCoordPrecision precision, |
| 1777 SamplerType sampler) const { |
| 1778 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1779 } |
| 1780 |
| 1781 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderHead() { |
| 1782 return SHADER0([]() { |
| 1783 precision mediump float; |
| 1784 uniform sampler2D s_texture; |
| 1785 uniform SamplerType s_mask; |
| 1786 uniform vec2 maskTexCoordScale; |
| 1787 uniform vec2 maskTexCoordOffset; |
| 1788 uniform mat4 colorMatrix; |
| 1789 uniform vec4 colorOffset; |
| 1790 uniform float alpha; |
| 1791 varying TexCoordPrecision vec2 v_texCoord; |
| 1792 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 1793 }); |
| 1794 } |
| 1795 |
| 1796 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderBody() { |
| 1797 return SHADER0([]() { |
| 1798 void main() { |
| 1799 vec4 texColor = texture2D(s_texture, v_texCoord); |
| 1800 float nonZeroAlpha = max(texColor.a, 0.00001); |
| 1801 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha); |
| 1802 texColor = colorMatrix * texColor + colorOffset; |
| 1803 texColor.rgb *= texColor.a; |
| 1804 texColor = clamp(texColor, 0.0, 1.0); |
| 1805 TexCoordPrecision vec2 maskTexCoord = |
| 1806 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, |
| 1807 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); |
| 1808 vec4 maskColor = TextureLookup(s_mask, maskTexCoord); |
| 1809 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 1810 vec2 d2 = min(d4.xz, d4.yw); |
| 1811 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 1812 gl_FragColor = ApplyBlendMode( |
| 1813 texColor * alpha * maskColor.w * aa, maskColor.w); |
| 1814 } |
| 1815 }); |
| 1816 } |
| 1817 |
| 1818 void FragmentShaderRGBATexAlphaMaskColorMatrixAA::FillLocations( |
| 1819 ShaderLocations* locations) const { |
| 1820 locations->sampler = sampler_location(); |
| 1821 locations->alpha = alpha_location(); |
| 1822 locations->mask_sampler = mask_sampler_location(); |
| 1823 locations->mask_tex_coord_scale = mask_tex_coord_scale_location(); |
| 1824 locations->mask_tex_coord_offset = mask_tex_coord_offset_location(); |
| 1825 locations->color_matrix = color_matrix_location(); |
| 1826 locations->color_offset = color_offset_location(); |
| 1827 locations->backdrop = backdrop_location(); |
| 1828 locations->backdrop_rect = backdrop_rect_location(); |
| 1829 if (mask_for_background()) |
| 1830 locations->original_backdrop = original_backdrop_location(); |
| 1831 } |
| 1832 |
| 1833 FragmentShaderRGBATexAlphaColorMatrixAA:: |
| 1834 FragmentShaderRGBATexAlphaColorMatrixAA() |
| 1835 : sampler_location_(-1), |
| 1836 alpha_location_(-1), |
| 1837 color_matrix_location_(-1), |
| 1838 color_offset_location_(-1) { |
| 1839 } |
| 1840 |
| 1841 void FragmentShaderRGBATexAlphaColorMatrixAA::Init(GLES2Interface* context, |
| 1842 unsigned program, |
| 1843 int* base_uniform_index) { |
| 1844 static const char* uniforms[] = { |
| 1845 "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS, |
| 1846 }; |
| 1847 int locations[arraysize(uniforms)]; |
| 1848 |
| 1849 GetProgramUniformLocations(context, |
| 1850 program, |
| 1851 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1852 uniforms, |
| 1853 locations, |
| 1854 base_uniform_index); |
| 1855 sampler_location_ = locations[0]; |
| 1856 alpha_location_ = locations[1]; |
| 1857 color_matrix_location_ = locations[2]; |
| 1858 color_offset_location_ = locations[3]; |
| 1859 BLEND_MODE_SET_LOCATIONS(locations, 4); |
| 1860 } |
| 1861 |
| 1862 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString( |
| 1863 TexCoordPrecision precision, |
| 1864 SamplerType sampler) const { |
| 1865 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1866 } |
| 1867 |
| 1868 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderHead() { |
| 1869 return SHADER0([]() { |
| 1870 precision mediump float; |
| 1871 uniform SamplerType s_texture; |
| 1872 uniform float alpha; |
| 1873 uniform mat4 colorMatrix; |
| 1874 uniform vec4 colorOffset; |
| 1875 varying TexCoordPrecision vec2 v_texCoord; |
| 1876 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 1877 }); |
| 1878 } |
| 1879 |
| 1880 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderBody() { |
| 1881 return SHADER0([]() { |
| 1882 void main() { |
| 1883 vec4 texColor = TextureLookup(s_texture, v_texCoord); |
| 1884 float nonZeroAlpha = max(texColor.a, 0.00001); |
| 1885 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha); |
| 1886 texColor = colorMatrix * texColor + colorOffset; |
| 1887 texColor.rgb *= texColor.a; |
| 1888 texColor = clamp(texColor, 0.0, 1.0); |
| 1889 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 1890 vec2 d2 = min(d4.xz, d4.yw); |
| 1891 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 1892 gl_FragColor = ApplyBlendMode(texColor * alpha * aa, 0.0); |
| 1893 } |
| 1894 }); |
| 1895 } |
| 1896 |
| 1897 void FragmentShaderRGBATexAlphaColorMatrixAA::FillLocations( |
| 1898 ShaderLocations* locations) const { |
| 1899 locations->sampler = sampler_location(); |
| 1900 locations->alpha = alpha_location(); |
| 1901 locations->color_matrix = color_matrix_location(); |
| 1902 locations->color_offset = color_offset_location(); |
| 1903 locations->backdrop = backdrop_location(); |
| 1904 locations->backdrop_rect = backdrop_rect_location(); |
| 1905 } |
| 1906 |
| 1907 FragmentShaderRGBATexAlphaMaskColorMatrix:: |
| 1908 FragmentShaderRGBATexAlphaMaskColorMatrix() |
| 1909 : sampler_location_(-1), |
| 1910 mask_sampler_location_(-1), |
| 1911 alpha_location_(-1), |
| 1912 mask_tex_coord_scale_location_(-1) { |
| 1913 } |
| 1914 |
| 1915 void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(GLES2Interface* context, |
| 1916 unsigned program, |
| 1917 int* base_uniform_index) { |
| 1918 static const char* uniforms[] = { |
| 1919 "s_texture", |
| 1920 "s_mask", |
| 1921 "alpha", |
| 1922 "maskTexCoordScale", |
| 1923 "maskTexCoordOffset", |
| 1924 "colorMatrix", |
| 1925 "colorOffset", |
| 1926 BLEND_MODE_UNIFORMS, |
| 1927 }; |
| 1928 int locations[arraysize(uniforms)]; |
| 1929 |
| 1930 GetProgramUniformLocations(context, |
| 1931 program, |
| 1932 arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS, |
| 1933 uniforms, |
| 1934 locations, |
| 1935 base_uniform_index); |
| 1936 sampler_location_ = locations[0]; |
| 1937 mask_sampler_location_ = locations[1]; |
| 1938 alpha_location_ = locations[2]; |
| 1939 mask_tex_coord_scale_location_ = locations[3]; |
| 1940 mask_tex_coord_offset_location_ = locations[4]; |
| 1941 color_matrix_location_ = locations[5]; |
| 1942 color_offset_location_ = locations[6]; |
| 1943 BLEND_MODE_SET_LOCATIONS(locations, 7); |
| 1944 } |
| 1945 |
| 1946 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString( |
| 1947 TexCoordPrecision precision, |
| 1948 SamplerType sampler) const { |
| 1949 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 1950 } |
| 1951 |
| 1952 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderHead() { |
| 1953 return SHADER0([]() { |
| 1954 precision mediump float; |
| 1955 varying TexCoordPrecision vec2 v_texCoord; |
| 1956 uniform sampler2D s_texture; |
| 1957 uniform SamplerType s_mask; |
| 1958 uniform vec2 maskTexCoordScale; |
| 1959 uniform vec2 maskTexCoordOffset; |
| 1960 uniform mat4 colorMatrix; |
| 1961 uniform vec4 colorOffset; |
| 1962 uniform float alpha; |
| 1963 }); |
| 1964 } |
| 1965 |
| 1966 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderBody() { |
| 1967 return SHADER0([]() { |
| 1968 void main() { |
| 1969 vec4 texColor = texture2D(s_texture, v_texCoord); |
| 1970 float nonZeroAlpha = max(texColor.a, 0.00001); |
| 1971 texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha); |
| 1972 texColor = colorMatrix * texColor + colorOffset; |
| 1973 texColor.rgb *= texColor.a; |
| 1974 texColor = clamp(texColor, 0.0, 1.0); |
| 1975 TexCoordPrecision vec2 maskTexCoord = |
| 1976 vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, |
| 1977 maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); |
| 1978 vec4 maskColor = TextureLookup(s_mask, maskTexCoord); |
| 1979 gl_FragColor = ApplyBlendMode( |
| 1980 texColor * alpha * maskColor.w, maskColor.w); |
| 1981 } |
| 1982 }); |
| 1983 } |
| 1984 |
| 1985 void FragmentShaderRGBATexAlphaMaskColorMatrix::FillLocations( |
| 1986 ShaderLocations* locations) const { |
| 1987 locations->sampler = sampler_location(); |
| 1988 locations->mask_sampler = mask_sampler_location(); |
| 1989 locations->mask_tex_coord_scale = mask_tex_coord_scale_location(); |
| 1990 locations->mask_tex_coord_offset = mask_tex_coord_offset_location(); |
| 1991 locations->alpha = alpha_location(); |
| 1992 locations->color_matrix = color_matrix_location(); |
| 1993 locations->color_offset = color_offset_location(); |
| 1994 locations->backdrop = backdrop_location(); |
| 1995 locations->backdrop_rect = backdrop_rect_location(); |
| 1996 if (mask_for_background()) |
| 1997 locations->original_backdrop = original_backdrop_location(); |
| 1998 } |
| 1999 |
| 2000 FragmentShaderYUVVideo::FragmentShaderYUVVideo() |
| 2001 : y_texture_location_(-1), |
| 2002 u_texture_location_(-1), |
| 2003 v_texture_location_(-1), |
| 2004 alpha_location_(-1), |
| 2005 yuv_matrix_location_(-1), |
| 2006 yuv_adj_location_(-1), |
| 2007 clamp_rect_location_(-1) { |
| 2008 } |
| 2009 |
| 2010 void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
| 2011 unsigned program, |
| 2012 int* base_uniform_index) { |
| 2013 static const char* uniforms[] = {"y_texture", |
| 2014 "u_texture", |
| 2015 "v_texture", |
| 2016 "alpha", |
| 2017 "yuv_matrix", |
| 2018 "yuv_adj", |
| 2019 "clamp_rect"}; |
| 2020 int locations[arraysize(uniforms)]; |
| 2021 |
| 2022 GetProgramUniformLocations(context, |
| 2023 program, |
| 2024 arraysize(uniforms), |
| 2025 uniforms, |
| 2026 locations, |
| 2027 base_uniform_index); |
| 2028 y_texture_location_ = locations[0]; |
| 2029 u_texture_location_ = locations[1]; |
| 2030 v_texture_location_ = locations[2]; |
| 2031 alpha_location_ = locations[3]; |
| 2032 yuv_matrix_location_ = locations[4]; |
| 2033 yuv_adj_location_ = locations[5]; |
| 2034 clamp_rect_location_ = locations[6]; |
| 2035 } |
| 2036 |
| 2037 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
| 2038 SamplerType sampler) const { |
| 2039 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 2040 } |
| 2041 |
| 2042 std::string FragmentShaderYUVVideo::GetShaderHead() { |
| 2043 return SHADER0([]() { |
| 2044 precision mediump float; |
| 2045 precision mediump int; |
| 2046 varying TexCoordPrecision vec2 v_texCoord; |
| 2047 uniform SamplerType y_texture; |
| 2048 uniform SamplerType u_texture; |
| 2049 uniform SamplerType v_texture; |
| 2050 uniform float alpha; |
| 2051 uniform vec3 yuv_adj; |
| 2052 uniform mat3 yuv_matrix; |
| 2053 uniform vec4 clamp_rect; |
| 2054 }); |
| 2055 } |
| 2056 |
| 2057 std::string FragmentShaderYUVVideo::GetShaderBody() { |
| 2058 return SHADER0([]() { |
| 2059 void main() { |
| 2060 vec2 clamped = max(clamp_rect.xy, min(clamp_rect.zw, v_texCoord)); |
| 2061 float y_raw = TextureLookup(y_texture, clamped).x; |
| 2062 float u_unsigned = TextureLookup(u_texture, clamped).x; |
| 2063 float v_unsigned = TextureLookup(v_texture, clamped).x; |
| 2064 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj; |
| 2065 vec3 rgb = yuv_matrix * yuv; |
| 2066 gl_FragColor = vec4(rgb, 1.0) * alpha; |
| 2067 } |
| 2068 }); |
| 2069 } |
| 2070 |
| 2071 FragmentShaderYUVAVideo::FragmentShaderYUVAVideo() |
| 2072 : y_texture_location_(-1), |
| 2073 u_texture_location_(-1), |
| 2074 v_texture_location_(-1), |
| 2075 a_texture_location_(-1), |
| 2076 alpha_location_(-1), |
| 2077 yuv_matrix_location_(-1), |
| 2078 yuv_adj_location_(-1) { |
| 2079 } |
| 2080 |
| 2081 void FragmentShaderYUVAVideo::Init(GLES2Interface* context, |
| 2082 unsigned program, |
| 2083 int* base_uniform_index) { |
| 2084 static const char* uniforms[] = { |
| 2085 "y_texture", |
| 2086 "u_texture", |
| 2087 "v_texture", |
| 2088 "a_texture", |
| 2089 "alpha", |
| 2090 "cc_matrix", |
| 2091 "yuv_adj", |
| 2092 "clamp_rect", |
| 2093 }; |
| 2094 int locations[arraysize(uniforms)]; |
| 2095 |
| 2096 GetProgramUniformLocations(context, |
| 2097 program, |
| 2098 arraysize(uniforms), |
| 2099 uniforms, |
| 2100 locations, |
| 2101 base_uniform_index); |
| 2102 y_texture_location_ = locations[0]; |
| 2103 u_texture_location_ = locations[1]; |
| 2104 v_texture_location_ = locations[2]; |
| 2105 a_texture_location_ = locations[3]; |
| 2106 alpha_location_ = locations[4]; |
| 2107 yuv_matrix_location_ = locations[5]; |
| 2108 yuv_adj_location_ = locations[6]; |
| 2109 clamp_rect_location_ = locations[7]; |
| 2110 } |
| 2111 |
| 2112 std::string FragmentShaderYUVAVideo::GetShaderString( |
| 2113 TexCoordPrecision precision, |
| 2114 SamplerType sampler) const { |
| 2115 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 2116 } |
| 2117 |
| 2118 std::string FragmentShaderYUVAVideo::GetShaderHead() { |
| 2119 return SHADER0([]() { |
| 2120 precision mediump float; |
| 2121 precision mediump int; |
| 2122 varying TexCoordPrecision vec2 v_texCoord; |
| 2123 uniform SamplerType y_texture; |
| 2124 uniform SamplerType u_texture; |
| 2125 uniform SamplerType v_texture; |
| 2126 uniform SamplerType a_texture; |
| 2127 uniform float alpha; |
| 2128 uniform vec3 yuv_adj; |
| 2129 uniform mat3 yuv_matrix; |
| 2130 uniform vec4 clamp_rect; |
| 2131 }); |
| 2132 } |
| 2133 |
| 2134 std::string FragmentShaderYUVAVideo::GetShaderBody() { |
| 2135 return SHADER0([]() { |
| 2136 void main() { |
| 2137 vec2 clamped = max(clamp_rect.xy, min(clamp_rect.zw, v_texCoord)); |
| 2138 float y_raw = TextureLookup(y_texture, clamped).x; |
| 2139 float u_unsigned = TextureLookup(u_texture, clamped).x; |
| 2140 float v_unsigned = TextureLookup(v_texture, clamped).x; |
| 2141 float a_raw = TextureLookup(a_texture, clamped).x; |
| 2142 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj; |
| 2143 vec3 rgb = yuv_matrix * yuv; |
| 2144 gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw); |
| 2145 } |
| 2146 }); |
| 2147 } |
| 2148 |
| 2149 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) { |
| 2150 } |
| 2151 |
| 2152 void FragmentShaderColor::Init(GLES2Interface* context, |
| 2153 unsigned program, |
| 2154 int* base_uniform_index) { |
| 2155 static const char* uniforms[] = { |
| 2156 "color", |
| 2157 }; |
| 2158 int locations[arraysize(uniforms)]; |
| 2159 |
| 2160 GetProgramUniformLocations(context, |
| 2161 program, |
| 2162 arraysize(uniforms), |
| 2163 uniforms, |
| 2164 locations, |
| 2165 base_uniform_index); |
| 2166 color_location_ = locations[0]; |
| 2167 } |
| 2168 |
| 2169 std::string FragmentShaderColor::GetShaderString(TexCoordPrecision precision, |
| 2170 SamplerType sampler) const { |
| 2171 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 2172 } |
| 2173 |
| 2174 std::string FragmentShaderColor::GetShaderHead() { |
| 2175 return SHADER0([]() { |
| 2176 precision mediump float; |
| 2177 uniform vec4 color; |
| 2178 }); |
| 2179 } |
| 2180 |
| 2181 std::string FragmentShaderColor::GetShaderBody() { |
| 2182 return SHADER0([]() { |
| 2183 void main() { gl_FragColor = color; } |
| 2184 }); |
| 2185 } |
| 2186 |
| 2187 FragmentShaderColorAA::FragmentShaderColorAA() : color_location_(-1) { |
| 2188 } |
| 2189 |
| 2190 void FragmentShaderColorAA::Init(GLES2Interface* context, |
| 2191 unsigned program, |
| 2192 int* base_uniform_index) { |
| 2193 static const char* uniforms[] = { |
| 2194 "color", |
| 2195 }; |
| 2196 int locations[arraysize(uniforms)]; |
| 2197 |
| 2198 GetProgramUniformLocations(context, |
| 2199 program, |
| 2200 arraysize(uniforms), |
| 2201 uniforms, |
| 2202 locations, |
| 2203 base_uniform_index); |
| 2204 color_location_ = locations[0]; |
| 2205 } |
| 2206 |
| 2207 std::string FragmentShaderColorAA::GetShaderString(TexCoordPrecision precision, |
| 2208 SamplerType sampler) const { |
| 2209 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 2210 } |
| 2211 |
| 2212 std::string FragmentShaderColorAA::GetShaderHead() { |
| 2213 return SHADER0([]() { |
| 2214 precision mediump float; |
| 2215 uniform vec4 color; |
| 2216 varying vec4 edge_dist[2]; // 8 edge distances. |
| 2217 }); |
| 2218 } |
| 2219 |
| 2220 std::string FragmentShaderColorAA::GetShaderBody() { |
| 2221 return SHADER0([]() { |
| 2222 void main() { |
| 2223 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 2224 vec2 d2 = min(d4.xz, d4.yw); |
| 2225 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 2226 gl_FragColor = color * aa; |
| 2227 } |
| 2228 }); |
| 2229 } |
| 2230 |
| 2231 FragmentShaderCheckerboard::FragmentShaderCheckerboard() |
| 2232 : alpha_location_(-1), |
| 2233 tex_transform_location_(-1), |
| 2234 frequency_location_(-1) { |
| 2235 } |
| 2236 |
| 2237 void FragmentShaderCheckerboard::Init(GLES2Interface* context, |
| 2238 unsigned program, |
| 2239 int* base_uniform_index) { |
| 2240 static const char* uniforms[] = { |
| 2241 "alpha", "texTransform", "frequency", "color", |
| 2242 }; |
| 2243 int locations[arraysize(uniforms)]; |
| 2244 |
| 2245 GetProgramUniformLocations(context, |
| 2246 program, |
| 2247 arraysize(uniforms), |
| 2248 uniforms, |
| 2249 locations, |
| 2250 base_uniform_index); |
| 2251 alpha_location_ = locations[0]; |
| 2252 tex_transform_location_ = locations[1]; |
| 2253 frequency_location_ = locations[2]; |
| 2254 color_location_ = locations[3]; |
| 2255 } |
| 2256 |
| 2257 std::string FragmentShaderCheckerboard::GetShaderString( |
| 2258 TexCoordPrecision precision, |
| 2259 SamplerType sampler) const { |
| 2260 return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); |
| 2261 } |
| 2262 |
| 2263 std::string FragmentShaderCheckerboard::GetShaderHead() { |
| 2264 return SHADER0([]() { |
| 2265 precision mediump float; |
| 2266 precision mediump int; |
| 2267 varying vec2 v_texCoord; |
| 2268 uniform float alpha; |
| 2269 uniform float frequency; |
| 2270 uniform vec4 texTransform; |
| 2271 uniform vec4 color; |
| 2272 }); |
| 2273 } |
| 2274 |
| 2275 std::string FragmentShaderCheckerboard::GetShaderBody() { |
| 2276 // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide" |
| 2277 // by Munshi, Ginsburg, Shreiner. |
| 2278 return SHADER0([]() { |
| 2279 void main() { |
| 2280 vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0); |
| 2281 vec4 color2 = color; |
| 2282 vec2 texCoord = |
| 2283 clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy; |
| 2284 vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0); |
| 2285 float picker = abs(coord.x - coord.y); // NOLINT |
| 2286 gl_FragColor = mix(color1, color2, picker) * alpha; |
| 2287 } |
| 2288 }); |
| 2289 } |
| 2290 |
| 2291 } // namespace cc |
OLD | NEW |