• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
swizzle_requires_alpha_remapping(const GrGLCaps & caps,uint32_t configComponentMask,uint32_t swizzleComponentMask)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  */
get_matrix_type(EffectKey transformKey,int transformIdx)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  */
get_source_coords(EffectKey transformKey,int transformIdx)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  */
get_transform_translation(const GrDrawEffect & drawEffect,int transformIdx,GrGLfloat * tx,GrGLfloat * ty)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  */
get_transform_matrix(const GrDrawEffect & drawEffect,int transformIdx)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 
GenAttribKey(const GrDrawEffect & drawEffect)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 
GenTransformKey(const GrDrawEffect & drawEffect)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 
GenTextureKey(const GrDrawEffect & drawEffect,const GrGLCaps & caps)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 
~GrGLProgramEffects()209 GrGLProgramEffects::~GrGLProgramEffects() {
210     int numEffects = fGLEffects.count();
211     for (int e = 0; e < numEffects; ++e) {
212         SkDELETE(fGLEffects[e]);
213     }
214 }
215 
emitSamplers(GrGLShaderBuilder * builder,const GrEffectRef & effect,TextureSamplerArray * outSamplers)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 
initSamplers(const GrGLUniformManager & uniformManager,int * texUnitIdx)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 
bindTextures(GrGpuGL * gpu,const GrEffectRef & effect,int effectIdx)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 
emitEffect(GrGLFullShaderBuilder * builder,const GrEffectStage & stage,EffectKey key,const char * outColor,const char * inColor,int stageIndex)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 
emitAttributes(GrGLFullShaderBuilder * builder,const GrEffectStage & stage)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 
emitTransforms(GrGLFullShaderBuilder * builder,const GrEffectRef & effect,EffectKey effectKey,TransformedCoordsArray * outCoords)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                 SkFAIL("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                 SkFAIL("Unexpected uniform type.");
397         }
398         SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
399                                (SkString(fsVaryingName), varyingType));
400     }
401 }
402 
setData(GrGpuGL * gpu,const GrGLUniformManager & uniformManager,const GrEffectStage * effectStages[])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 
setTransformData(const GrGLUniformManager & uniformManager,const GrDrawEffect & drawEffect,int effectIdx)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                 break;
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                 SkFAIL("Unexpected uniform type.");
450         }
451     }
452 }
453 
GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder * builder,int reserveCount)454 GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder,
455                                                                  int reserveCount)
456     : fBuilder(builder)
457     , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
458                                  (reserveCount, fBuilder->hasExplicitLocalCoords()))) {
459 }
460 
emitEffect(const GrEffectStage & stage,GrGLProgramEffects::EffectKey key,const char * outColor,const char * inColor,int stageIndex)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 
emitEffect(GrGLFragmentOnlyShaderBuilder * builder,const GrEffectStage & stage,EffectKey key,const char * outColor,const char * inColor,int stageIndex)472 void GrGLPathTexGenProgramEffects::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->setupPathTexGen(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 
setupPathTexGen(GrGLFragmentOnlyShaderBuilder * builder,const GrEffectRef & effect,EffectKey effectKey,TransformedCoordsArray * outCoords)501 void GrGLPathTexGenProgramEffects::setupPathTexGen(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 
setData(GrGpuGL * gpu,const GrGLUniformManager & uniformManager,const GrEffectStage * effectStages[])519 void GrGLPathTexGenProgramEffects::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->setPathTexGenState(gpu, drawEffect, e);
529         this->bindTextures(gpu, *drawEffect.effect(), e);
530     }
531 }
532 
setPathTexGenState(GrGpuGL * gpu,const GrDrawEffect & drawEffect,int effectIdx)533 void GrGLPathTexGenProgramEffects::setPathTexGenState(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->enablePathTexGen(texCoordIndex++,
546                                       GrGpuGL::kST_PathTexGenComponents,
547                                       identity);
548                 break;
549             }
550             case kTrans_MatrixType: {
551                 GrGLfloat tx, ty;
552                 get_transform_translation(drawEffect, t, &tx, &ty);
553                 GrGLfloat translate[] = {1, 0, tx,
554                                          0, 1, ty};
555                 gpu->enablePathTexGen(texCoordIndex++,
556                                       GrGpuGL::kST_PathTexGenComponents,
557                                       translate);
558                 break;
559             }
560             case kNoPersp_MatrixType: {
561                 const SkMatrix& transform = get_transform_matrix(drawEffect, t);
562                 gpu->enablePathTexGen(texCoordIndex++,
563                                       GrGpuGL::kST_PathTexGenComponents,
564                                       transform);
565                 break;
566             }
567             case kGeneral_MatrixType: {
568                 const SkMatrix& transform = get_transform_matrix(drawEffect, t);
569                 gpu->enablePathTexGen(texCoordIndex++,
570                                       GrGpuGL::kSTR_PathTexGenComponents,
571                                       transform);
572                 break;
573             }
574             default:
575                 SkFAIL("Unexpected matrixs type.");
576         }
577     }
578 }
579 
GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder * builder,int reserveCount)580 GrGLPathTexGenProgramEffectsBuilder::GrGLPathTexGenProgramEffectsBuilder(
581         GrGLFragmentOnlyShaderBuilder* builder,
582         int reserveCount)
583     : fBuilder(builder)
584     , fProgramEffects(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (reserveCount))) {
585 }
586 
emitEffect(const GrEffectStage & stage,GrGLProgramEffects::EffectKey key,const char * outColor,const char * inColor,int stageIndex)587 void GrGLPathTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
588                                                      GrGLProgramEffects::EffectKey key,
589                                                      const char* outColor,
590                                                      const char* inColor,
591                                                      int stageIndex) {
592     SkASSERT(NULL != fProgramEffects.get());
593     fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
594 }
595