Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/output/shader.h" | 5 #include "cc/output/shader.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 static_assert(size >= 8, | 22 static_assert(size >= 8, |
| 23 "String passed to StripLambda must be at least 8 characters"); | 23 "String passed to StripLambda must be at least 8 characters"); |
| 24 DCHECK_EQ(strncmp("[]() {", shader, 6), 0); | 24 DCHECK_EQ(strncmp("[]() {", shader, 6), 0); |
| 25 DCHECK_EQ(shader[size - 2], '}'); | 25 DCHECK_EQ(shader[size - 2], '}'); |
| 26 return std::string(shader + 6, shader + size - 2); | 26 return std::string(shader + 6, shader + size - 2); |
| 27 } | 27 } |
| 28 | 28 |
| 29 // Shaders are passed in with lambda syntax, which tricks clang-format into | 29 // Shaders are passed in with lambda syntax, which tricks clang-format into |
| 30 // handling them correctly. StipLambda removes this. | 30 // handling them correctly. StipLambda removes this. |
| 31 #define SHADER0(Src) StripLambda(#Src) | 31 #define SHADER0(Src) StripLambda(#Src) |
| 32 #define VERTEX_SHADER(Head, Body) SetVertexShaderDefines(Head + Body) | |
| 33 | 32 |
| 34 using gpu::gles2::GLES2Interface; | 33 using gpu::gles2::GLES2Interface; |
| 35 | 34 |
| 36 namespace cc { | 35 namespace cc { |
| 37 | 36 |
| 38 namespace { | 37 namespace { |
| 39 | 38 |
| 40 static void GetProgramUniformLocations(GLES2Interface* context, | 39 static void GetProgramUniformLocations(GLES2Interface* context, |
| 41 unsigned program, | 40 unsigned program, |
| 42 size_t count, | 41 size_t count, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 69 DCHECK_EQ(shader_string.find("texture2D"), std::string::npos); | 68 DCHECK_EQ(shader_string.find("texture2D"), std::string::npos); |
| 70 DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos); | 69 DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos); |
| 71 return shader_string; | 70 return shader_string; |
| 72 default: | 71 default: |
| 73 NOTREACHED(); | 72 NOTREACHED(); |
| 74 break; | 73 break; |
| 75 } | 74 } |
| 76 return shader_string; | 75 return shader_string; |
| 77 } | 76 } |
| 78 | 77 |
| 79 static std::string SetVertexShaderDefines(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 base::StringPrintf( | |
| 85 "#define TexCoordPrecision highp\n" | |
| 86 "#define NUM_STATIC_QUADS %d\n", | |
| 87 StaticGeometryBinding::NUM_QUADS) + | |
| 88 shader_string; | |
| 89 } | |
| 90 | |
| 91 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context, | 78 TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context, |
| 92 int* highp_threshold_cache, | 79 int* highp_threshold_cache, |
| 93 int highp_threshold_min, | 80 int highp_threshold_min, |
| 94 int x, | 81 int x, |
| 95 int y) { | 82 int y) { |
| 96 if (*highp_threshold_cache == 0) { | 83 if (*highp_threshold_cache == 0) { |
| 97 // Initialize range and precision with minimum spec values for when | 84 // Initialize range and precision with minimum spec values for when |
| 98 // GetShaderPrecisionFormat is a test stub. | 85 // GetShaderPrecisionFormat is a test stub. |
| 99 // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat | 86 // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat |
| 100 // everywhere. | 87 // everywhere. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 int* highp_threshold_cache, | 153 int* highp_threshold_cache, |
| 167 int highp_threshold_min, | 154 int highp_threshold_min, |
| 168 const gfx::Size& max_size) { | 155 const gfx::Size& max_size) { |
| 169 return TexCoordPrecisionRequired(context, | 156 return TexCoordPrecisionRequired(context, |
| 170 highp_threshold_cache, | 157 highp_threshold_cache, |
| 171 highp_threshold_min, | 158 highp_threshold_min, |
| 172 max_size.width(), | 159 max_size.width(), |
| 173 max_size.height()); | 160 max_size.height()); |
| 174 } | 161 } |
| 175 | 162 |
| 176 VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) { | 163 VertexShaderBase::VertexShaderBase() {} |
| 164 | |
| 165 void VertexShaderBase::Init(GLES2Interface* context, | |
| 166 unsigned program, | |
| 167 int* base_uniform_index) { | |
| 168 std::vector<const char*> uniforms; | |
| 169 std::vector<int> locations; | |
| 170 | |
| 171 if (has_tex_transform_) | |
| 172 uniforms.push_back("texTransform"); | |
| 173 if (has_vertex_tex_transform_) | |
| 174 uniforms.push_back("vertexTexTransform"); | |
| 175 if (has_tex_matrix_) | |
| 176 uniforms.push_back("texMatrix"); | |
| 177 if (has_ya_uv_tex_scale_offset_) { | |
| 178 uniforms.push_back("yaTexScale"); | |
| 179 uniforms.push_back("yaTexOffset"); | |
| 180 uniforms.push_back("uvTexScale"); | |
| 181 uniforms.push_back("uvTexOffset"); | |
| 182 } | |
| 183 if (has_matrix_) | |
| 184 uniforms.push_back("matrix"); | |
| 185 if (has_vertex_opacity_) | |
| 186 uniforms.push_back("opacity"); | |
| 187 if (has_aa_) { | |
| 188 uniforms.push_back("viewport"); | |
| 189 uniforms.push_back("edge"); | |
| 190 } | |
| 191 if (has_quad_) | |
| 192 uniforms.push_back("quad"); | |
| 193 | |
| 194 locations.resize(uniforms.size()); | |
| 195 | |
| 196 GetProgramUniformLocations(context, program, uniforms.size(), uniforms.data(), | |
| 197 locations.data(), base_uniform_index); | |
| 198 | |
| 199 size_t index = 0; | |
| 200 if (has_tex_transform_) | |
| 201 tex_transform_location_ = locations[index++]; | |
| 202 if (has_vertex_tex_transform_) | |
| 203 vertex_tex_transform_location_ = locations[index++]; | |
| 204 if (has_tex_matrix_) | |
| 205 tex_matrix_location_ = locations[index++]; | |
| 206 if (has_ya_uv_tex_scale_offset_) { | |
| 207 ya_tex_scale_location_ = locations[index++]; | |
| 208 ya_tex_offset_location_ = locations[index++]; | |
| 209 uv_tex_scale_location_ = locations[index++]; | |
| 210 uv_tex_offset_location_ = locations[index++]; | |
| 211 } | |
| 212 if (has_matrix_) | |
| 213 matrix_location_ = locations[index++]; | |
| 214 if (has_vertex_opacity_) | |
| 215 vertex_opacity_location_ = locations[index++]; | |
| 216 if (has_aa_) { | |
| 217 viewport_location_ = locations[index++]; | |
| 218 edge_location_ = locations[index++]; | |
| 219 } | |
| 220 if (has_quad_) | |
| 221 quad_location_ = locations[index++]; | |
| 177 } | 222 } |
| 178 | 223 |
| 179 void VertexShaderPosTex::Init(GLES2Interface* context, | 224 void VertexShaderBase::FillLocations(ShaderLocations* locations) const { |
| 180 unsigned program, | 225 locations->quad = quad_location(); |
| 181 int* base_uniform_index) { | 226 locations->edge = edge_location(); |
| 182 static const char* uniforms[] = { | 227 locations->viewport = viewport_location(); |
| 183 "matrix", | 228 locations->matrix = matrix_location(); |
| 184 }; | 229 locations->tex_transform = tex_transform_location(); |
| 185 int locations[arraysize(uniforms)]; | |
| 186 | |
| 187 GetProgramUniformLocations(context, | |
| 188 program, | |
| 189 arraysize(uniforms), | |
| 190 uniforms, | |
| 191 locations, | |
| 192 base_uniform_index); | |
| 193 matrix_location_ = locations[0]; | |
| 194 } | 230 } |
| 195 | 231 |
| 196 std::string VertexShaderPosTex::GetShaderString() const { | 232 std::string VertexShaderBase::GetShaderString() const { |
| 197 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | 233 // We unconditionally use highp in the vertex shader since |
| 234 // we are unlikely to be vertex shader bound when drawing large quads. | |
| 235 // Also, some vertex shaders mutate the texture coordinate in such a | |
| 236 // way that the effective precision might be lower than expected. | |
| 237 return base::StringPrintf( | |
| 238 "#define TexCoordPrecision highp\n" | |
| 239 "#define NUM_STATIC_QUADS %d\n", | |
| 240 StaticGeometryBinding::NUM_QUADS) + | |
| 241 GetShaderSource(); | |
| 198 } | 242 } |
| 199 | 243 |
| 200 std::string VertexShaderPosTex::GetShaderHead() { | 244 std::string VertexShaderPosTex::GetShaderSource() const { |
| 201 return SHADER0([]() { | 245 return SHADER0([]() { |
| 202 attribute vec4 a_position; | 246 attribute vec4 a_position; |
| 203 attribute TexCoordPrecision vec2 a_texCoord; | 247 attribute TexCoordPrecision vec2 a_texCoord; |
| 204 uniform mat4 matrix; | 248 uniform mat4 matrix; |
| 205 varying TexCoordPrecision vec2 v_texCoord; | 249 varying TexCoordPrecision vec2 v_texCoord; |
| 206 }); | |
| 207 } | |
| 208 | |
| 209 std::string VertexShaderPosTex::GetShaderBody() { | |
| 210 return SHADER0([]() { | |
| 211 void main() { | 250 void main() { |
| 212 gl_Position = matrix * a_position; | 251 gl_Position = matrix * a_position; |
| 213 v_texCoord = a_texCoord; | 252 v_texCoord = a_texCoord; |
| 214 } | 253 } |
| 215 }); | 254 }); |
| 216 } | 255 } |
| 217 | 256 |
| 218 VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset() | 257 std::string VertexShaderPosTexYUVStretchOffset::GetShaderSource() const { |
| 219 : matrix_location_(-1), | |
| 220 ya_tex_scale_location_(-1), | |
| 221 ya_tex_offset_location_(-1), | |
| 222 uv_tex_scale_location_(-1), | |
| 223 uv_tex_offset_location_(-1) { | |
| 224 } | |
| 225 | |
| 226 void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context, | |
| 227 unsigned program, | |
| 228 int* base_uniform_index) { | |
| 229 static const char* uniforms[] = { | |
| 230 "matrix", "yaTexScale", "yaTexOffset", "uvTexScale", "uvTexOffset", | |
| 231 }; | |
| 232 int locations[arraysize(uniforms)]; | |
| 233 | |
| 234 GetProgramUniformLocations(context, | |
| 235 program, | |
| 236 arraysize(uniforms), | |
| 237 uniforms, | |
| 238 locations, | |
| 239 base_uniform_index); | |
| 240 matrix_location_ = locations[0]; | |
| 241 ya_tex_scale_location_ = locations[1]; | |
| 242 ya_tex_offset_location_ = locations[2]; | |
| 243 uv_tex_scale_location_ = locations[3]; | |
| 244 uv_tex_offset_location_ = locations[4]; | |
| 245 } | |
| 246 | |
| 247 std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const { | |
| 248 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 249 } | |
| 250 | |
| 251 std::string VertexShaderPosTexYUVStretchOffset::GetShaderHead() { | |
| 252 return SHADER0([]() { | 258 return SHADER0([]() { |
| 253 precision mediump float; | 259 precision mediump float; |
| 254 attribute vec4 a_position; | 260 attribute vec4 a_position; |
| 255 attribute TexCoordPrecision vec2 a_texCoord; | 261 attribute TexCoordPrecision vec2 a_texCoord; |
| 256 uniform mat4 matrix; | 262 uniform mat4 matrix; |
| 257 varying TexCoordPrecision vec2 v_yaTexCoord; | 263 varying TexCoordPrecision vec2 v_yaTexCoord; |
| 258 varying TexCoordPrecision vec2 v_uvTexCoord; | 264 varying TexCoordPrecision vec2 v_uvTexCoord; |
| 259 uniform TexCoordPrecision vec2 yaTexScale; | 265 uniform TexCoordPrecision vec2 yaTexScale; |
| 260 uniform TexCoordPrecision vec2 yaTexOffset; | 266 uniform TexCoordPrecision vec2 yaTexOffset; |
| 261 uniform TexCoordPrecision vec2 uvTexScale; | 267 uniform TexCoordPrecision vec2 uvTexScale; |
| 262 uniform TexCoordPrecision vec2 uvTexOffset; | 268 uniform TexCoordPrecision vec2 uvTexOffset; |
| 263 }); | |
| 264 } | |
| 265 | |
| 266 std::string VertexShaderPosTexYUVStretchOffset::GetShaderBody() { | |
| 267 return SHADER0([]() { | |
| 268 void main() { | 269 void main() { |
| 269 gl_Position = matrix * a_position; | 270 gl_Position = matrix * a_position; |
| 270 v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset; | 271 v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset; |
| 271 v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset; | 272 v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset; |
| 272 } | 273 } |
| 273 }); | 274 }); |
| 274 } | 275 } |
| 275 | 276 |
| 276 VertexShaderPos::VertexShaderPos() : matrix_location_(-1) { | 277 std::string VertexShaderPos::GetShaderSource() const { |
| 277 } | |
| 278 | |
| 279 void VertexShaderPos::Init(GLES2Interface* context, | |
| 280 unsigned program, | |
| 281 int* base_uniform_index) { | |
| 282 static const char* uniforms[] = { | |
| 283 "matrix", | |
| 284 }; | |
| 285 int locations[arraysize(uniforms)]; | |
| 286 | |
| 287 GetProgramUniformLocations(context, | |
| 288 program, | |
| 289 arraysize(uniforms), | |
| 290 uniforms, | |
| 291 locations, | |
| 292 base_uniform_index); | |
| 293 matrix_location_ = locations[0]; | |
| 294 } | |
| 295 | |
| 296 std::string VertexShaderPos::GetShaderString() const { | |
| 297 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 298 } | |
| 299 | |
| 300 std::string VertexShaderPos::GetShaderHead() { | |
| 301 return SHADER0([]() { | 278 return SHADER0([]() { |
| 302 attribute vec4 a_position; | 279 attribute vec4 a_position; |
| 303 uniform mat4 matrix; | 280 uniform mat4 matrix; |
| 304 }); | |
| 305 } | |
| 306 | |
| 307 std::string VertexShaderPos::GetShaderBody() { | |
| 308 return SHADER0([]() { | |
| 309 void main() { gl_Position = matrix * a_position; } | 281 void main() { gl_Position = matrix * a_position; } |
| 310 }); | 282 }); |
| 311 } | 283 } |
| 312 | 284 |
| 313 VertexShaderPosTexTransform::VertexShaderPosTexTransform() | 285 std::string VertexShaderPosTexTransform::GetShaderSource() const { |
| 314 : matrix_location_(-1), | |
| 315 tex_transform_location_(-1), | |
| 316 vertex_opacity_location_(-1) { | |
| 317 } | |
| 318 | |
| 319 void VertexShaderPosTexTransform::Init(GLES2Interface* context, | |
| 320 unsigned program, | |
| 321 int* base_uniform_index) { | |
| 322 static const char* uniforms[] = { | |
| 323 "matrix", "texTransform", "opacity", | |
| 324 }; | |
| 325 int locations[arraysize(uniforms)]; | |
| 326 | |
| 327 GetProgramUniformLocations(context, | |
| 328 program, | |
| 329 arraysize(uniforms), | |
| 330 uniforms, | |
| 331 locations, | |
| 332 base_uniform_index); | |
| 333 matrix_location_ = locations[0]; | |
| 334 tex_transform_location_ = locations[1]; | |
| 335 vertex_opacity_location_ = locations[2]; | |
| 336 } | |
| 337 | |
| 338 std::string VertexShaderPosTexTransform::GetShaderString() const { | |
| 339 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 340 } | |
| 341 | |
| 342 std::string VertexShaderPosTexTransform::GetShaderHead() { | |
| 343 return SHADER0([]() { | 286 return SHADER0([]() { |
| 344 attribute vec4 a_position; | 287 attribute vec4 a_position; |
| 345 attribute TexCoordPrecision vec2 a_texCoord; | 288 attribute TexCoordPrecision vec2 a_texCoord; |
| 346 attribute float a_index; | 289 attribute float a_index; |
| 347 uniform mat4 matrix[NUM_STATIC_QUADS]; | 290 uniform mat4 matrix[NUM_STATIC_QUADS]; |
| 348 uniform TexCoordPrecision vec4 texTransform[NUM_STATIC_QUADS]; | 291 uniform TexCoordPrecision vec4 texTransform[NUM_STATIC_QUADS]; |
| 349 uniform float opacity[NUM_STATIC_QUADS * 4]; | 292 uniform float opacity[NUM_STATIC_QUADS * 4]; |
| 350 varying TexCoordPrecision vec2 v_texCoord; | 293 varying TexCoordPrecision vec2 v_texCoord; |
| 351 varying float v_alpha; | 294 varying float v_alpha; |
| 352 }); | |
| 353 } | |
| 354 | |
| 355 std::string VertexShaderPosTexTransform::GetShaderBody() { | |
| 356 return SHADER0([]() { | |
| 357 void main() { | 295 void main() { |
| 358 int quad_index = int(a_index * 0.25); // NOLINT | 296 int quad_index = int(a_index * 0.25); // NOLINT |
| 359 gl_Position = matrix[quad_index] * a_position; | 297 gl_Position = matrix[quad_index] * a_position; |
| 360 TexCoordPrecision vec4 texTrans = texTransform[quad_index]; | 298 TexCoordPrecision vec4 texTrans = texTransform[quad_index]; |
| 361 v_texCoord = a_texCoord * texTrans.zw + texTrans.xy; | 299 v_texCoord = a_texCoord * texTrans.zw + texTrans.xy; |
| 362 v_alpha = opacity[int(a_index)]; // NOLINT | 300 v_alpha = opacity[int(a_index)]; // NOLINT |
| 363 } | 301 } |
| 364 }); | 302 }); |
| 365 } | 303 } |
| 366 | 304 |
| 367 void VertexShaderPosTexTransform::FillLocations( | 305 std::string VertexShaderPosTexIdentity::GetShaderSource() const { |
| 368 ShaderLocations* locations) const { | |
| 369 locations->matrix = matrix_location(); | |
| 370 locations->tex_transform = tex_transform_location(); | |
| 371 } | |
| 372 | |
| 373 std::string VertexShaderPosTexIdentity::GetShaderString() const { | |
| 374 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 375 } | |
| 376 | |
| 377 std::string VertexShaderPosTexIdentity::GetShaderHead() { | |
| 378 return SHADER0([]() { | 306 return SHADER0([]() { |
| 379 attribute vec4 a_position; | 307 attribute vec4 a_position; |
| 380 varying TexCoordPrecision vec2 v_texCoord; | 308 varying TexCoordPrecision vec2 v_texCoord; |
| 381 }); | |
| 382 } | |
| 383 | |
| 384 std::string VertexShaderPosTexIdentity::GetShaderBody() { | |
| 385 return SHADER0([]() { | |
| 386 void main() { | 309 void main() { |
| 387 gl_Position = a_position; | 310 gl_Position = a_position; |
| 388 v_texCoord = (a_position.xy + vec2(1.0)) * 0.5; | 311 v_texCoord = (a_position.xy + vec2(1.0)) * 0.5; |
| 389 } | 312 } |
| 390 }); | 313 }); |
| 391 } | 314 } |
| 392 | 315 |
| 393 VertexShaderQuad::VertexShaderQuad() | 316 std::string VertexShaderQuad::GetShaderSource() const { |
| 394 : matrix_location_(-1), quad_location_(-1) { | |
| 395 } | |
| 396 | |
| 397 void VertexShaderQuad::Init(GLES2Interface* context, | |
| 398 unsigned program, | |
| 399 int* base_uniform_index) { | |
| 400 static const char* uniforms[] = { | |
| 401 "matrix", "quad", | |
| 402 }; | |
| 403 int locations[arraysize(uniforms)]; | |
| 404 | |
| 405 GetProgramUniformLocations(context, | |
| 406 program, | |
| 407 arraysize(uniforms), | |
| 408 uniforms, | |
| 409 locations, | |
| 410 base_uniform_index); | |
| 411 matrix_location_ = locations[0]; | |
| 412 quad_location_ = locations[1]; | |
| 413 } | |
| 414 | |
| 415 std::string VertexShaderQuad::GetShaderString() const { | |
| 416 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 417 } | |
| 418 | |
| 419 std::string VertexShaderQuad::GetShaderHead() { | |
| 420 #if defined(OS_ANDROID) | 317 #if defined(OS_ANDROID) |
| 421 // TODO(epenner): Find the cause of this 'quad' uniform | 318 // TODO(epenner): Find the cause of this 'quad' uniform |
| 422 // being missing if we don't add dummy variables. | 319 // being missing if we don't add dummy variables. |
| 423 // http://crbug.com/240602 | 320 // http://crbug.com/240602 |
| 424 return SHADER0([]() { | 321 return SHADER0([]() { |
| 425 attribute TexCoordPrecision vec4 a_position; | 322 attribute TexCoordPrecision vec4 a_position; |
| 426 attribute float a_index; | 323 attribute float a_index; |
| 427 uniform mat4 matrix; | 324 uniform mat4 matrix; |
| 428 uniform TexCoordPrecision vec2 quad[4]; | 325 uniform TexCoordPrecision vec2 quad[4]; |
| 429 uniform TexCoordPrecision vec2 dummy_uniform; | 326 uniform TexCoordPrecision vec2 dummy_uniform; |
| 430 varying TexCoordPrecision vec2 dummy_varying; | 327 varying TexCoordPrecision vec2 dummy_varying; |
| 431 }); | |
| 432 #else | |
| 433 return SHADER0([]() { | |
| 434 attribute TexCoordPrecision vec4 a_position; | |
| 435 attribute float a_index; | |
| 436 uniform mat4 matrix; | |
| 437 uniform TexCoordPrecision vec2 quad[4]; | |
| 438 }); | |
| 439 #endif | |
| 440 } | |
| 441 | |
| 442 std::string VertexShaderQuad::GetShaderBody() { | |
| 443 #if defined(OS_ANDROID) | |
| 444 return SHADER0([]() { | |
| 445 void main() { | 328 void main() { |
| 446 vec2 pos = quad[int(a_index)]; // NOLINT | 329 vec2 pos = quad[int(a_index)]; // NOLINT |
| 447 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); | 330 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 448 dummy_varying = dummy_uniform; | 331 dummy_varying = dummy_uniform; |
| 449 } | 332 } |
| 450 }); | 333 }); |
| 451 #else | 334 #else |
| 452 return SHADER0([]() { | 335 return SHADER0([]() { |
| 336 attribute TexCoordPrecision vec4 a_position; | |
| 337 attribute float a_index; | |
| 338 uniform mat4 matrix; | |
| 339 uniform TexCoordPrecision vec2 quad[4]; | |
| 453 void main() { | 340 void main() { |
| 454 vec2 pos = quad[int(a_index)]; // NOLINT | 341 vec2 pos = quad[int(a_index)]; // NOLINT |
| 455 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); | 342 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 456 } | 343 } |
| 457 }); | 344 }); |
| 458 #endif | 345 #endif |
| 459 } | 346 } |
| 460 | 347 |
| 461 VertexShaderQuadAA::VertexShaderQuadAA() | 348 std::string VertexShaderQuadAA::GetShaderSource() const { |
| 462 : matrix_location_(-1), | |
| 463 viewport_location_(-1), | |
| 464 quad_location_(-1), | |
| 465 edge_location_(-1) { | |
| 466 } | |
| 467 | |
| 468 void VertexShaderQuadAA::Init(GLES2Interface* context, | |
| 469 unsigned program, | |
| 470 int* base_uniform_index) { | |
| 471 static const char* uniforms[] = { | |
| 472 "matrix", "viewport", "quad", "edge", | |
| 473 }; | |
| 474 int locations[arraysize(uniforms)]; | |
| 475 | |
| 476 GetProgramUniformLocations(context, | |
| 477 program, | |
| 478 arraysize(uniforms), | |
| 479 uniforms, | |
| 480 locations, | |
| 481 base_uniform_index); | |
| 482 matrix_location_ = locations[0]; | |
| 483 viewport_location_ = locations[1]; | |
| 484 quad_location_ = locations[2]; | |
| 485 edge_location_ = locations[3]; | |
| 486 } | |
| 487 | |
| 488 std::string VertexShaderQuadAA::GetShaderString() const { | |
| 489 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 490 } | |
| 491 | |
| 492 std::string VertexShaderQuadAA::GetShaderHead() { | |
| 493 return SHADER0([]() { | 349 return SHADER0([]() { |
| 494 attribute TexCoordPrecision vec4 a_position; | 350 attribute TexCoordPrecision vec4 a_position; |
| 495 attribute float a_index; | 351 attribute float a_index; |
| 496 uniform mat4 matrix; | 352 uniform mat4 matrix; |
| 497 uniform vec4 viewport; | 353 uniform vec4 viewport; |
| 498 uniform TexCoordPrecision vec2 quad[4]; | 354 uniform TexCoordPrecision vec2 quad[4]; |
| 499 uniform TexCoordPrecision vec3 edge[8]; | 355 uniform TexCoordPrecision vec3 edge[8]; |
| 500 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. | 356 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 501 }); | |
| 502 } | |
| 503 | |
| 504 std::string VertexShaderQuadAA::GetShaderBody() { | |
| 505 return SHADER0([]() { | |
| 506 void main() { | 357 void main() { |
| 507 vec2 pos = quad[int(a_index)]; // NOLINT | 358 vec2 pos = quad[int(a_index)]; // NOLINT |
| 508 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); | 359 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 509 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); | 360 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
| 510 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); | 361 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
| 511 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), | 362 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
| 512 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * | 363 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
| 513 gl_Position.w; | 364 gl_Position.w; |
| 514 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), | 365 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
| 515 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * | 366 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
| 516 gl_Position.w; | 367 gl_Position.w; |
| 517 } | 368 } |
| 518 }); | 369 }); |
| 519 } | 370 } |
| 520 | 371 |
| 521 VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA() | 372 std::string VertexShaderQuadTexTransformAA::GetShaderSource() const { |
| 522 : matrix_location_(-1), | |
| 523 viewport_location_(-1), | |
| 524 quad_location_(-1), | |
| 525 edge_location_(-1), | |
| 526 tex_transform_location_(-1) { | |
| 527 } | |
| 528 | |
| 529 void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context, | |
| 530 unsigned program, | |
| 531 int* base_uniform_index) { | |
| 532 static const char* uniforms[] = { | |
| 533 "matrix", "viewport", "quad", "edge", "texTrans", | |
| 534 }; | |
| 535 int locations[arraysize(uniforms)]; | |
| 536 | |
| 537 GetProgramUniformLocations(context, | |
| 538 program, | |
| 539 arraysize(uniforms), | |
| 540 uniforms, | |
| 541 locations, | |
| 542 base_uniform_index); | |
| 543 matrix_location_ = locations[0]; | |
| 544 viewport_location_ = locations[1]; | |
| 545 quad_location_ = locations[2]; | |
| 546 edge_location_ = locations[3]; | |
| 547 tex_transform_location_ = locations[4]; | |
| 548 } | |
| 549 | |
| 550 std::string VertexShaderQuadTexTransformAA::GetShaderString() const { | |
| 551 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 552 } | |
| 553 | |
| 554 std::string VertexShaderQuadTexTransformAA::GetShaderHead() { | |
| 555 return SHADER0([]() { | 373 return SHADER0([]() { |
| 556 attribute TexCoordPrecision vec4 a_position; | 374 attribute TexCoordPrecision vec4 a_position; |
| 557 attribute float a_index; | 375 attribute float a_index; |
| 558 uniform mat4 matrix; | 376 uniform mat4 matrix; |
| 559 uniform vec4 viewport; | 377 uniform vec4 viewport; |
| 560 uniform TexCoordPrecision vec2 quad[4]; | 378 uniform TexCoordPrecision vec2 quad[4]; |
| 561 uniform TexCoordPrecision vec3 edge[8]; | 379 uniform TexCoordPrecision vec3 edge[8]; |
| 562 uniform TexCoordPrecision vec4 texTrans; | 380 uniform TexCoordPrecision vec4 texTransform; |
|
ccameron
2017/01/04 09:06:12
This is the one instance where I had to edit a sha
| |
| 563 varying TexCoordPrecision vec2 v_texCoord; | 381 varying TexCoordPrecision vec2 v_texCoord; |
| 564 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. | 382 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 565 }); | |
| 566 } | |
| 567 | |
| 568 std::string VertexShaderQuadTexTransformAA::GetShaderBody() { | |
| 569 return SHADER0([]() { | |
| 570 void main() { | 383 void main() { |
| 571 vec2 pos = quad[int(a_index)]; // NOLINT | 384 vec2 pos = quad[int(a_index)]; // NOLINT |
| 572 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); | 385 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 573 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); | 386 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
| 574 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); | 387 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
| 575 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), | 388 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
| 576 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * | 389 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
| 577 gl_Position.w; | 390 gl_Position.w; |
| 578 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), | 391 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
| 579 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * | 392 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
| 580 gl_Position.w; | 393 gl_Position.w; |
| 581 v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy; | 394 v_texCoord = (pos.xy + vec2(0.5)) * texTransform.zw + texTransform.xy; |
| 582 } | 395 } |
| 583 }); | 396 }); |
| 584 } | 397 } |
| 585 | 398 |
| 586 void VertexShaderQuadTexTransformAA::FillLocations( | 399 std::string VertexShaderTile::GetShaderSource() const { |
| 587 ShaderLocations* locations) const { | |
| 588 locations->quad = quad_location(); | |
| 589 locations->edge = edge_location(); | |
| 590 locations->viewport = viewport_location(); | |
| 591 locations->matrix = matrix_location(); | |
| 592 locations->tex_transform = tex_transform_location(); | |
| 593 } | |
| 594 | |
| 595 | |
| 596 VertexShaderTile::VertexShaderTile() | |
| 597 : matrix_location_(-1), | |
| 598 quad_location_(-1), | |
| 599 vertex_tex_transform_location_(-1) { | |
| 600 } | |
| 601 | |
| 602 void VertexShaderTile::Init(GLES2Interface* context, | |
| 603 unsigned program, | |
| 604 int* base_uniform_index) { | |
| 605 static const char* uniforms[] = { | |
| 606 "matrix", "quad", "vertexTexTransform", | |
| 607 }; | |
| 608 int locations[arraysize(uniforms)]; | |
| 609 | |
| 610 GetProgramUniformLocations(context, | |
| 611 program, | |
| 612 arraysize(uniforms), | |
| 613 uniforms, | |
| 614 locations, | |
| 615 base_uniform_index); | |
| 616 matrix_location_ = locations[0]; | |
| 617 quad_location_ = locations[1]; | |
| 618 vertex_tex_transform_location_ = locations[2]; | |
| 619 } | |
| 620 | |
| 621 std::string VertexShaderTile::GetShaderString() const { | |
| 622 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 623 } | |
| 624 | |
| 625 std::string VertexShaderTile::GetShaderHead() { | |
| 626 return SHADER0([]() { | 400 return SHADER0([]() { |
| 627 attribute TexCoordPrecision vec4 a_position; | 401 attribute TexCoordPrecision vec4 a_position; |
| 628 attribute TexCoordPrecision vec2 a_texCoord; | 402 attribute TexCoordPrecision vec2 a_texCoord; |
| 629 attribute float a_index; | 403 attribute float a_index; |
| 630 uniform mat4 matrix; | 404 uniform mat4 matrix; |
| 631 uniform TexCoordPrecision vec2 quad[4]; | 405 uniform TexCoordPrecision vec2 quad[4]; |
| 632 uniform TexCoordPrecision vec4 vertexTexTransform; | 406 uniform TexCoordPrecision vec4 vertexTexTransform; |
| 633 varying TexCoordPrecision vec2 v_texCoord; | 407 varying TexCoordPrecision vec2 v_texCoord; |
| 634 }); | |
| 635 } | |
| 636 | |
| 637 std::string VertexShaderTile::GetShaderBody() { | |
| 638 return SHADER0([]() { | |
| 639 void main() { | 408 void main() { |
| 640 vec2 pos = quad[int(a_index)]; // NOLINT | 409 vec2 pos = quad[int(a_index)]; // NOLINT |
| 641 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); | 410 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 642 v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy; | 411 v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy; |
| 643 } | 412 } |
| 644 }); | 413 }); |
| 645 } | 414 } |
| 646 | 415 |
| 647 VertexShaderTileAA::VertexShaderTileAA() | 416 std::string VertexShaderTileAA::GetShaderSource() const { |
| 648 : matrix_location_(-1), | |
| 649 viewport_location_(-1), | |
| 650 quad_location_(-1), | |
| 651 edge_location_(-1), | |
| 652 vertex_tex_transform_location_(-1) { | |
| 653 } | |
| 654 | |
| 655 void VertexShaderTileAA::Init(GLES2Interface* context, | |
| 656 unsigned program, | |
| 657 int* base_uniform_index) { | |
| 658 static const char* uniforms[] = { | |
| 659 "matrix", "viewport", "quad", "edge", "vertexTexTransform", | |
| 660 }; | |
| 661 int locations[arraysize(uniforms)]; | |
| 662 | |
| 663 GetProgramUniformLocations(context, | |
| 664 program, | |
| 665 arraysize(uniforms), | |
| 666 uniforms, | |
| 667 locations, | |
| 668 base_uniform_index); | |
| 669 matrix_location_ = locations[0]; | |
| 670 viewport_location_ = locations[1]; | |
| 671 quad_location_ = locations[2]; | |
| 672 edge_location_ = locations[3]; | |
| 673 vertex_tex_transform_location_ = locations[4]; | |
| 674 } | |
| 675 | |
| 676 std::string VertexShaderTileAA::GetShaderString() const { | |
| 677 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 678 } | |
| 679 | |
| 680 std::string VertexShaderTileAA::GetShaderHead() { | |
| 681 return SHADER0([]() { | 417 return SHADER0([]() { |
| 682 attribute TexCoordPrecision vec4 a_position; | 418 attribute TexCoordPrecision vec4 a_position; |
| 683 attribute float a_index; | 419 attribute float a_index; |
| 684 uniform mat4 matrix; | 420 uniform mat4 matrix; |
| 685 uniform vec4 viewport; | 421 uniform vec4 viewport; |
| 686 uniform TexCoordPrecision vec2 quad[4]; | 422 uniform TexCoordPrecision vec2 quad[4]; |
| 687 uniform TexCoordPrecision vec3 edge[8]; | 423 uniform TexCoordPrecision vec3 edge[8]; |
| 688 uniform TexCoordPrecision vec4 vertexTexTransform; | 424 uniform TexCoordPrecision vec4 vertexTexTransform; |
| 689 varying TexCoordPrecision vec2 v_texCoord; | 425 varying TexCoordPrecision vec2 v_texCoord; |
| 690 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. | 426 varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. |
| 691 }); | |
| 692 } | |
| 693 | |
| 694 std::string VertexShaderTileAA::GetShaderBody() { | |
| 695 return SHADER0([]() { | |
| 696 void main() { | 427 void main() { |
| 697 vec2 pos = quad[int(a_index)]; // NOLINT | 428 vec2 pos = quad[int(a_index)]; // NOLINT |
| 698 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); | 429 gl_Position = matrix * vec4(pos, a_position.z, a_position.w); |
| 699 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); | 430 vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w); |
| 700 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); | 431 vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0); |
| 701 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), | 432 edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos), |
| 702 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * | 433 dot(edge[2], screen_pos), dot(edge[3], screen_pos)) * |
| 703 gl_Position.w; | 434 gl_Position.w; |
| 704 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), | 435 edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), |
| 705 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * | 436 dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * |
| 706 gl_Position.w; | 437 gl_Position.w; |
| 707 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy; | 438 v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy; |
| 708 } | 439 } |
| 709 }); | 440 }); |
| 710 } | 441 } |
| 711 | 442 |
| 712 VertexShaderVideoTransform::VertexShaderVideoTransform() | 443 std::string VertexShaderVideoTransform::GetShaderSource() const { |
| 713 : matrix_location_(-1), tex_matrix_location_(-1) { | |
| 714 } | |
| 715 | |
| 716 void VertexShaderVideoTransform::Init(GLES2Interface* context, | |
| 717 unsigned program, | |
| 718 int* base_uniform_index) { | |
| 719 static const char* uniforms[] = { | |
| 720 "matrix", "texMatrix", | |
| 721 }; | |
| 722 int locations[arraysize(uniforms)]; | |
| 723 | |
| 724 GetProgramUniformLocations(context, | |
| 725 program, | |
| 726 arraysize(uniforms), | |
| 727 uniforms, | |
| 728 locations, | |
| 729 base_uniform_index); | |
| 730 matrix_location_ = locations[0]; | |
| 731 tex_matrix_location_ = locations[1]; | |
| 732 } | |
| 733 | |
| 734 std::string VertexShaderVideoTransform::GetShaderString() const { | |
| 735 return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); | |
| 736 } | |
| 737 | |
| 738 std::string VertexShaderVideoTransform::GetShaderHead() { | |
| 739 return SHADER0([]() { | 444 return SHADER0([]() { |
| 740 attribute vec4 a_position; | 445 attribute vec4 a_position; |
| 741 attribute TexCoordPrecision vec2 a_texCoord; | 446 attribute TexCoordPrecision vec2 a_texCoord; |
| 742 uniform mat4 matrix; | 447 uniform mat4 matrix; |
| 743 uniform TexCoordPrecision mat4 texMatrix; | 448 uniform TexCoordPrecision mat4 texMatrix; |
| 744 varying TexCoordPrecision vec2 v_texCoord; | 449 varying TexCoordPrecision vec2 v_texCoord; |
| 745 }); | |
| 746 } | |
| 747 | |
| 748 std::string VertexShaderVideoTransform::GetShaderBody() { | |
| 749 return SHADER0([]() { | |
| 750 void main() { | 450 void main() { |
| 751 gl_Position = matrix * a_position; | 451 gl_Position = matrix * a_position; |
| 752 v_texCoord = (texMatrix * vec4(a_texCoord.xy, 0.0, 1.0)).xy; | 452 v_texCoord = (texMatrix * vec4(a_texCoord.xy, 0.0, 1.0)).xy; |
| 753 } | 453 } |
| 754 }); | 454 }); |
| 755 } | 455 } |
| 756 | 456 |
| 757 #define BLEND_MODE_UNIFORMS "s_backdropTexture", \ | 457 #define BLEND_MODE_UNIFORMS "s_backdropTexture", \ |
| 758 "s_originalBackdropTexture", \ | 458 "s_originalBackdropTexture", \ |
| 759 "backdropRect" | 459 "backdropRect" |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1312 break; | 1012 break; |
| 1313 } | 1013 } |
| 1314 source += "}\n"; | 1014 source += "}\n"; |
| 1315 | 1015 |
| 1316 #undef HDR | 1016 #undef HDR |
| 1317 #undef SRC | 1017 #undef SRC |
| 1318 | 1018 |
| 1319 return header + source; | 1019 return header + source; |
| 1320 } | 1020 } |
| 1321 | 1021 |
| 1322 FragmentShaderYUVVideo::FragmentShaderYUVVideo() | 1022 FragmentShaderYUVVideo::FragmentShaderYUVVideo() {} |
| 1323 : y_texture_location_(-1), | |
| 1324 u_texture_location_(-1), | |
| 1325 v_texture_location_(-1), | |
| 1326 uv_texture_location_(-1), | |
| 1327 a_texture_location_(-1), | |
| 1328 lut_texture_location_(-1), | |
| 1329 alpha_location_(-1), | |
| 1330 yuv_matrix_location_(-1), | |
| 1331 yuv_adj_location_(-1), | |
| 1332 ya_clamp_rect_location_(-1), | |
| 1333 uv_clamp_rect_location_(-1), | |
| 1334 resource_multiplier_location_(-1), | |
| 1335 resource_offset_location_(-1) {} | |
| 1336 | 1023 |
| 1337 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, | 1024 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, |
| 1338 bool use_nv12, | 1025 bool use_nv12, |
| 1339 bool use_color_lut) { | 1026 bool use_color_lut) { |
| 1340 use_alpha_texture_ = use_alpha_texture; | 1027 use_alpha_texture_ = use_alpha_texture; |
| 1341 use_nv12_ = use_nv12; | 1028 use_nv12_ = use_nv12; |
| 1342 use_color_lut_ = use_color_lut; | 1029 use_color_lut_ = use_color_lut; |
| 1343 } | 1030 } |
| 1344 | 1031 |
| 1345 void FragmentShaderYUVVideo::Init(GLES2Interface* context, | 1032 void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1475 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); | 1162 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); |
| 1476 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); | 1163 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); |
| 1477 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); | 1164 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); |
| 1478 } | 1165 } |
| 1479 }); | 1166 }); |
| 1480 | 1167 |
| 1481 return head + functions; | 1168 return head + functions; |
| 1482 } | 1169 } |
| 1483 | 1170 |
| 1484 } // namespace cc | 1171 } // namespace cc |
| OLD | NEW |