1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrGLProgramEffects.h" 9 #include "GrDrawEffect.h" 10 #include "gl/GrGLEffect.h" 11 #include "gl/GrGLShaderBuilder.h" 12 #include "gl/GrGLVertexEffect.h" 13 #include "gl/GrGpuGL.h" 14 15 typedef GrGLProgramEffects::EffectKey EffectKey; 16 typedef GrGLProgramEffects::TransformedCoords TransformedCoords; 17 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; 18 typedef GrGLProgramEffects::TextureSampler TextureSampler; 19 typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray; 20 21 /** 22 * We specialize the vertex code for each of these matrix types. 23 */ 24 enum MatrixType { 25 kIdentity_MatrixType = 0, 26 kTrans_MatrixType = 1, 27 kNoPersp_MatrixType = 2, 28 kGeneral_MatrixType = 3, 29 }; 30 31 /** 32 * The key for an individual coord transform is made up of a matrix type and a bit that 33 * indicates the source of the input coords. 34 */ 35 enum { 36 kMatrixTypeKeyBits = 2, 37 kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, 38 kPositionCoords_Flag = (1 << kMatrixTypeKeyBits), 39 kTransformKeyBits = kMatrixTypeKeyBits + 1, 40 }; 41 42 namespace { 43 44 /** 45 * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are 46 * present in the texture's config. swizzleComponentMask indicates the channels present in the 47 * shader swizzle. 48 */ 49 inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, 50 uint32_t configComponentMask, 51 uint32_t swizzleComponentMask) { 52 if (caps.textureSwizzleSupport()) { 53 // Any remapping is handled using texture swizzling not shader modifications. 54 return false; 55 } 56 // check if the texture is alpha-only 57 if (kA_GrColorComponentFlag == configComponentMask) { 58 if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) { 59 // we must map the swizzle 'a's to 'r'. 60 return true; 61 } 62 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { 63 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that 64 // alpha-only textures smear alpha across all four channels when read. 65 return true; 66 } 67 } 68 return false; 69 } 70 71 /** 72 * Retrieves the matrix type from transformKey for the transform at transformIdx. 73 */ 74 MatrixType get_matrix_type(EffectKey transformKey, int transformIdx) { 75 return static_cast<MatrixType>( 76 (transformKey >> (kTransformKeyBits * transformIdx)) & kMatrixTypeKeyMask); 77 } 78 79 /** 80 * Retrieves the source coords from transformKey for the transform at transformIdx. It may not be 81 * the same coordinate set as the original GrCoordTransform if the position and local coords are 82 * identical for this program. 83 */ 84 GrCoordSet get_source_coords(EffectKey transformKey, int transformIdx) { 85 return (transformKey >> (kTransformKeyBits * transformIdx)) & kPositionCoords_Flag ? 86 kPosition_GrCoordSet : 87 kLocal_GrCoordSet; 88 } 89 90 /** 91 * Retrieves the final translation that a transform needs to apply to its source coords (and 92 * verifies that a translation is all it needs). 93 */ 94 void get_transform_translation(const GrDrawEffect& drawEffect, 95 int transformIdx, 96 GrGLfloat* tx, 97 GrGLfloat* ty) { 98 const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx); 99 SkASSERT(!coordTransform.reverseY()); 100 const SkMatrix& matrix = coordTransform.getMatrix(); 101 if (kLocal_GrCoordSet == coordTransform.sourceCoords() && 102 !drawEffect.programHasExplicitLocalCoords()) { 103 const SkMatrix& coordChangeMatrix = drawEffect.getCoordChangeMatrix(); 104 SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType())); 105 *tx = SkScalarToFloat(matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX]); 106 *ty = SkScalarToFloat(matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY]); 107 } else { 108 SkASSERT(SkMatrix::kTranslate_Mask == matrix.getType()); 109 *tx = SkScalarToFloat(matrix[SkMatrix::kMTransX]); 110 *ty = SkScalarToFloat(matrix[SkMatrix::kMTransY]); 111 } 112 } 113 114 /** 115 * Retrieves the final matrix that a transform needs to apply to its source coords. 116 */ 117 SkMatrix get_transform_matrix(const GrDrawEffect& drawEffect, int transformIdx) { 118 const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx); 119 SkMatrix combined; 120 if (kLocal_GrCoordSet == coordTransform.sourceCoords() && 121 !drawEffect.programHasExplicitLocalCoords()) { 122 combined.setConcat(coordTransform.getMatrix(), drawEffect.getCoordChangeMatrix()); 123 } else { 124 combined = coordTransform.getMatrix(); 125 } 126 if (coordTransform.reverseY()) { 127 // combined.postScale(1,-1); 128 // combined.postTranslate(0,1); 129 combined.set(SkMatrix::kMSkewY, 130 combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); 131 combined.set(SkMatrix::kMScaleY, 132 combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); 133 combined.set(SkMatrix::kMTransY, 134 combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); 135 } 136 return combined; 137 } 138 139 } 140 141 //////////////////////////////////////////////////////////////////////////////// 142 143 EffectKey GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) { 144 EffectKey key = 0; 145 int numAttributes = drawEffect.getVertexAttribIndexCount(); 146 SkASSERT(numAttributes <= 2); 147 const int* attributeIndices = drawEffect.getVertexAttribIndices(); 148 for (int a = 0; a < numAttributes; ++a) { 149 EffectKey value = attributeIndices[a] << 3 * a; 150 SkASSERT(0 == (value & key)); // keys for each attribute ought not to overlap 151 key |= value; 152 } 153 return key; 154 } 155 156 EffectKey GrGLProgramEffects::GenTransformKey(const GrDrawEffect& drawEffect) { 157 EffectKey totalKey = 0; 158 int numTransforms = (*drawEffect.effect())->numTransforms(); 159 for (int t = 0; t < numTransforms; ++t) { 160 EffectKey key = 0; 161 const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(t); 162 SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType(); 163 SkMatrix::TypeMask type1; 164 if (kLocal_GrCoordSet == coordTransform.sourceCoords()) { 165 type1 = drawEffect.getCoordChangeMatrix().getType(); 166 } else { 167 if (drawEffect.programHasExplicitLocalCoords()) { 168 // We only make the key indicate that device coords are referenced when the local coords 169 // are not actually determined by positions. Otherwise the local coords var and position 170 // var are identical. 171 key |= kPositionCoords_Flag; 172 } 173 type1 = SkMatrix::kIdentity_Mask; 174 } 175 176 int combinedTypes = type0 | type1; 177 178 bool reverseY = coordTransform.reverseY(); 179 180 if (SkMatrix::kPerspective_Mask & combinedTypes) { 181 key |= kGeneral_MatrixType; 182 } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) { 183 key |= kNoPersp_MatrixType; 184 } else if (SkMatrix::kTranslate_Mask & combinedTypes) { 185 key |= kTrans_MatrixType; 186 } else { 187 key |= kIdentity_MatrixType; 188 } 189 key <<= kTransformKeyBits * t; 190 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap 191 totalKey |= key; 192 } 193 return totalKey; 194 } 195 196 EffectKey GrGLProgramEffects::GenTextureKey(const GrDrawEffect& drawEffect, const GrGLCaps& caps) { 197 EffectKey key = 0; 198 int numTextures = (*drawEffect.effect())->numTextures(); 199 for (int t = 0; t < numTextures; ++t) { 200 const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(t); 201 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config()); 202 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) { 203 key |= 1 << t; 204 } 205 } 206 return key; 207 } 208 209 GrGLProgramEffects::~GrGLProgramEffects() { 210 int numEffects = fGLEffects.count(); 211 for (int e = 0; e < numEffects; ++e) { 212 SkDELETE(fGLEffects[e]); 213 } 214 } 215 216 void GrGLProgramEffects::emitSamplers(GrGLShaderBuilder* builder, 217 const GrEffectRef& effect, 218 TextureSamplerArray* outSamplers) { 219 SkTArray<Sampler, true>& samplers = fSamplers.push_back(); 220 int numTextures = effect->numTextures(); 221 samplers.push_back_n(numTextures); 222 SkString name; 223 for (int t = 0; t < numTextures; ++t) { 224 name.printf("Sampler%d", t); 225 samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 226 kSampler2D_GrSLType, 227 name.c_str()); 228 SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler, 229 (samplers[t].fUniform, effect->textureAccess(t))); 230 } 231 } 232 233 void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, int* texUnitIdx) { 234 int numEffects = fGLEffects.count(); 235 SkASSERT(numEffects == fSamplers.count()); 236 for (int e = 0; e < numEffects; ++e) { 237 SkTArray<Sampler, true>& samplers = fSamplers[e]; 238 int numSamplers = samplers.count(); 239 for (int s = 0; s < numSamplers; ++s) { 240 SkASSERT(samplers[s].fUniform.isValid()); 241 uniformManager.setSampler(samplers[s].fUniform, *texUnitIdx); 242 samplers[s].fTextureUnit = (*texUnitIdx)++; 243 } 244 } 245 } 246 247 void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) { 248 const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx]; 249 int numSamplers = samplers.count(); 250 SkASSERT(numSamplers == effect->numTextures()); 251 for (int s = 0; s < numSamplers; ++s) { 252 SkASSERT(samplers[s].fTextureUnit >= 0); 253 const GrTextureAccess& textureAccess = effect->textureAccess(s); 254 gpu->bindTexture(samplers[s].fTextureUnit, 255 textureAccess.getParams(), 256 static_cast<GrGLTexture*>(textureAccess.getTexture())); 257 } 258 } 259 260 //////////////////////////////////////////////////////////////////////////////// 261 262 void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder, 263 const GrEffectStage& stage, 264 EffectKey key, 265 const char* outColor, 266 const char* inColor, 267 int stageIndex) { 268 GrDrawEffect drawEffect(stage, fHasExplicitLocalCoords); 269 const GrEffectRef& effect = *stage.getEffect(); 270 SkSTArray<2, TransformedCoords> coords(effect->numTransforms()); 271 SkSTArray<4, TextureSampler> samplers(effect->numTextures()); 272 273 this->emitAttributes(builder, stage); 274 this->emitTransforms(builder, effect, key, &coords); 275 this->emitSamplers(builder, effect, &samplers); 276 277 GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect); 278 fGLEffects.push_back(glEffect); 279 280 // Enclose custom code in a block to avoid namespace conflicts 281 SkString openBrace; 282 openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name()); 283 builder->vsCodeAppend(openBrace.c_str()); 284 builder->fsCodeAppend(openBrace.c_str()); 285 286 if (glEffect->isVertexEffect()) { 287 GrGLVertexEffect* vertexEffect = static_cast<GrGLVertexEffect*>(glEffect); 288 vertexEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers); 289 } else { 290 glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers); 291 } 292 293 builder->vsCodeAppend("\t}\n"); 294 builder->fsCodeAppend("\t}\n"); 295 } 296 297 void GrGLVertexProgramEffects::emitAttributes(GrGLFullShaderBuilder* builder, 298 const GrEffectStage& stage) { 299 int numAttributes = stage.getVertexAttribIndexCount(); 300 const int* attributeIndices = stage.getVertexAttribIndices(); 301 for (int a = 0; a < numAttributes; ++a) { 302 // TODO: Make addAttribute mangle the name. 303 SkString attributeName("aAttr"); 304 attributeName.appendS32(attributeIndices[a]); 305 builder->addEffectAttribute(attributeIndices[a], 306 (*stage.getEffect())->vertexAttribType(a), 307 attributeName); 308 } 309 } 310 311 void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder, 312 const GrEffectRef& effect, 313 EffectKey effectKey, 314 TransformedCoordsArray* outCoords) { 315 SkTArray<Transform, true>& transforms = fTransforms.push_back(); 316 EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey); 317 int numTransforms = effect->numTransforms(); 318 transforms.push_back_n(numTransforms); 319 for (int t = 0; t < numTransforms; t++) { 320 GrSLType varyingType = kVoid_GrSLType; 321 const char* uniName; 322 switch (get_matrix_type(totalKey, t)) { 323 case kIdentity_MatrixType: 324 transforms[t].fType = kVoid_GrSLType; 325 uniName = NULL; 326 varyingType = kVec2f_GrSLType; 327 break; 328 case kTrans_MatrixType: 329 transforms[t].fType = kVec2f_GrSLType; 330 uniName = "StageTranslate"; 331 varyingType = kVec2f_GrSLType; 332 break; 333 case kNoPersp_MatrixType: 334 transforms[t].fType = kMat33f_GrSLType; 335 uniName = "StageMatrix"; 336 varyingType = kVec2f_GrSLType; 337 break; 338 case kGeneral_MatrixType: 339 transforms[t].fType = kMat33f_GrSLType; 340 uniName = "StageMatrix"; 341 varyingType = kVec3f_GrSLType; 342 break; 343 default: 344 GrCrash("Unexpected key."); 345 } 346 SkString suffixedUniName; 347 if (kVoid_GrSLType != transforms[t].fType) { 348 if (0 != t) { 349 suffixedUniName.append(uniName); 350 suffixedUniName.appendf("_%i", t); 351 uniName = suffixedUniName.c_str(); 352 } 353 transforms[t].fHandle = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility, 354 transforms[t].fType, 355 uniName, 356 &uniName); 357 } 358 359 const char* varyingName = "MatrixCoord"; 360 SkString suffixedVaryingName; 361 if (0 != t) { 362 suffixedVaryingName.append(varyingName); 363 suffixedVaryingName.appendf("_%i", t); 364 varyingName = suffixedVaryingName.c_str(); 365 } 366 const char* vsVaryingName; 367 const char* fsVaryingName; 368 builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); 369 370 const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ? 371 builder->positionAttribute() : 372 builder->localCoordsAttribute(); 373 // varying = matrix * coords (logically) 374 switch (transforms[t].fType) { 375 case kVoid_GrSLType: 376 SkASSERT(kVec2f_GrSLType == varyingType); 377 builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str()); 378 break; 379 case kVec2f_GrSLType: 380 SkASSERT(kVec2f_GrSLType == varyingType); 381 builder->vsCodeAppendf("\t%s = %s + %s;\n", 382 vsVaryingName, uniName, coords.c_str()); 383 break; 384 case kMat33f_GrSLType: { 385 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); 386 if (kVec2f_GrSLType == varyingType) { 387 builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n", 388 vsVaryingName, uniName, coords.c_str()); 389 } else { 390 builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n", 391 vsVaryingName, uniName, coords.c_str()); 392 } 393 break; 394 } 395 default: 396 GrCrash("Unexpected uniform type."); 397 } 398 SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, 399 (SkString(fsVaryingName), varyingType)); 400 } 401 } 402 403 void GrGLVertexProgramEffects::setData(GrGpuGL* gpu, 404 const GrGLUniformManager& uniformManager, 405 const GrEffectStage* effectStages[]) { 406 int numEffects = fGLEffects.count(); 407 SkASSERT(numEffects == fTransforms.count()); 408 SkASSERT(numEffects == fSamplers.count()); 409 for (int e = 0; e < numEffects; ++e) { 410 GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords); 411 fGLEffects[e]->setData(uniformManager, drawEffect); 412 this->setTransformData(uniformManager, drawEffect, e); 413 this->bindTextures(gpu, *drawEffect.effect(), e); 414 } 415 } 416 417 void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager, 418 const GrDrawEffect& drawEffect, 419 int effectIdx) { 420 SkTArray<Transform, true>& transforms = fTransforms[effectIdx]; 421 int numTransforms = transforms.count(); 422 SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms()); 423 for (int t = 0; t < numTransforms; ++t) { 424 SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType)); 425 switch (transforms[t].fType) { 426 case kVoid_GrSLType: 427 SkASSERT(get_transform_matrix(drawEffect, t).isIdentity()); 428 return; 429 case kVec2f_GrSLType: { 430 GrGLfloat tx, ty; 431 get_transform_translation(drawEffect, t, &tx, &ty); 432 if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx || 433 transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) { 434 uniformManager.set2f(transforms[t].fHandle, tx, ty); 435 transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx); 436 transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty); 437 } 438 break; 439 } 440 case kMat33f_GrSLType: { 441 const SkMatrix& matrix = get_transform_matrix(drawEffect, t); 442 if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) { 443 uniformManager.setSkMatrix(transforms[t].fHandle, matrix); 444 transforms[t].fCurrentValue = matrix; 445 } 446 break; 447 } 448 default: 449 GrCrash("Unexpected uniform type."); 450 } 451 } 452 } 453 454 GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder, 455 int reserveCount) 456 : fBuilder(builder) 457 , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects, 458 (reserveCount, fBuilder->hasExplicitLocalCoords()))) { 459 } 460 461 void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, 462 GrGLProgramEffects::EffectKey key, 463 const char* outColor, 464 const char* inColor, 465 int stageIndex) { 466 SkASSERT(NULL != fProgramEffects.get()); 467 fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex); 468 } 469 470 //////////////////////////////////////////////////////////////////////////////// 471 472 void GrGLTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder, 473 const GrEffectStage& stage, 474 EffectKey key, 475 const char* outColor, 476 const char* inColor, 477 int stageIndex) { 478 GrDrawEffect drawEffect(stage, false); 479 const GrEffectRef& effect = *stage.getEffect(); 480 SkSTArray<2, TransformedCoords> coords(effect->numTransforms()); 481 SkSTArray<4, TextureSampler> samplers(effect->numTextures()); 482 483 SkASSERT(0 == stage.getVertexAttribIndexCount()); 484 this->setupTexGen(builder, effect, key, &coords); 485 this->emitSamplers(builder, effect, &samplers); 486 487 GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect); 488 fGLEffects.push_back(glEffect); 489 490 // Enclose custom code in a block to avoid namespace conflicts 491 SkString openBrace; 492 openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name()); 493 builder->fsCodeAppend(openBrace.c_str()); 494 495 SkASSERT(!glEffect->isVertexEffect()); 496 glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers); 497 498 builder->fsCodeAppend("\t}\n"); 499 } 500 501 void GrGLTexGenProgramEffects::setupTexGen(GrGLFragmentOnlyShaderBuilder* builder, 502 const GrEffectRef& effect, 503 EffectKey effectKey, 504 TransformedCoordsArray* outCoords) { 505 int numTransforms = effect->numTransforms(); 506 EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey); 507 int texCoordIndex = builder->addTexCoordSets(numTransforms); 508 SkNEW_APPEND_TO_TARRAY(&fTransforms, Transforms, (totalKey, texCoordIndex)); 509 SkString name; 510 for (int t = 0; t < numTransforms; ++t) { 511 GrSLType type = kGeneral_MatrixType == get_matrix_type(totalKey, t) ? 512 kVec3f_GrSLType : 513 kVec2f_GrSLType; 514 name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++); 515 SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (name, type)); 516 } 517 } 518 519 void GrGLTexGenProgramEffects::setData(GrGpuGL* gpu, 520 const GrGLUniformManager& uniformManager, 521 const GrEffectStage* effectStages[]) { 522 int numEffects = fGLEffects.count(); 523 SkASSERT(numEffects == fTransforms.count()); 524 SkASSERT(numEffects == fSamplers.count()); 525 for (int e = 0; e < numEffects; ++e) { 526 GrDrawEffect drawEffect(*effectStages[e], false); 527 fGLEffects[e]->setData(uniformManager, drawEffect); 528 this->setTexGenState(gpu, drawEffect, e); 529 this->bindTextures(gpu, *drawEffect.effect(), e); 530 } 531 } 532 533 void GrGLTexGenProgramEffects::setTexGenState(GrGpuGL* gpu, 534 const GrDrawEffect& drawEffect, 535 int effectIdx) { 536 EffectKey totalKey = fTransforms[effectIdx].fTransformKey; 537 int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex; 538 int numTransforms = (*drawEffect.effect())->numTransforms(); 539 for (int t = 0; t < numTransforms; ++t) { 540 switch (get_matrix_type(totalKey, t)) { 541 case kIdentity_MatrixType: { 542 SkASSERT(get_transform_matrix(drawEffect, t).isIdentity()); 543 GrGLfloat identity[] = {1, 0, 0, 544 0, 1, 0}; 545 gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, identity); 546 break; 547 } 548 case kTrans_MatrixType: { 549 GrGLfloat tx, ty; 550 get_transform_translation(drawEffect, t, &tx, &ty); 551 GrGLfloat translate[] = {1, 0, tx, 552 0, 1, ty}; 553 gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, translate); 554 break; 555 } 556 case kNoPersp_MatrixType: { 557 const SkMatrix& transform = get_transform_matrix(drawEffect, t); 558 gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, transform); 559 break; 560 } 561 case kGeneral_MatrixType: { 562 const SkMatrix& transform = get_transform_matrix(drawEffect, t); 563 gpu->enableTexGen(texCoordIndex++, GrGpuGL::kSTR_TexGenComponents, transform); 564 break; 565 } 566 default: 567 GrCrash("Unexpected matrixs type."); 568 } 569 } 570 } 571 572 GrGLTexGenProgramEffectsBuilder::GrGLTexGenProgramEffectsBuilder( 573 GrGLFragmentOnlyShaderBuilder* builder, 574 int reserveCount) 575 : fBuilder(builder) 576 , fProgramEffects(SkNEW_ARGS(GrGLTexGenProgramEffects, (reserveCount))) { 577 } 578 579 void GrGLTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage, 580 GrGLProgramEffects::EffectKey key, 581 const char* outColor, 582 const char* inColor, 583 int stageIndex) { 584 SkASSERT(NULL != fProgramEffects.get()); 585 fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex); 586 } 587