gfx/skia/trunk/src/gpu/gl/GrGLProgramEffects.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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  */
     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"
    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;
    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 };
    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 };
    42 namespace {
    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 }
    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 }
    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 }
    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 }
   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 }
   139 }
   141 ////////////////////////////////////////////////////////////////////////////////
   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 }
   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         }
   176         int combinedTypes = type0 | type1;
   178         bool reverseY = coordTransform.reverseY();
   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 }
   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 }
   209 GrGLProgramEffects::~GrGLProgramEffects() {
   210     int numEffects = fGLEffects.count();
   211     for (int e = 0; e < numEffects; ++e) {
   212         SkDELETE(fGLEffects[e]);
   213     }
   214 }
   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 }
   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 }
   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 }
   260 ////////////////////////////////////////////////////////////////////////////////
   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());
   273     this->emitAttributes(builder, stage);
   274     this->emitTransforms(builder, effect, key, &coords);
   275     this->emitSamplers(builder, effect, &samplers);
   277     GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
   278     fGLEffects.push_back(glEffect);
   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());
   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     }
   293     builder->vsCodeAppend("\t}\n");
   294     builder->fsCodeAppend("\t}\n");
   295 }
   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 }
   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         }
   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);
   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 }
   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 }
   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 }
   454 GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder,
   455                                                                  int reserveCount)
   456     : fBuilder(builder)
   457     , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
   458                                  (reserveCount, fBuilder->hasExplicitLocalCoords()))) {
   459 }
   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 }
   470 ////////////////////////////////////////////////////////////////////////////////
   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());
   483     SkASSERT(0 == stage.getVertexAttribIndexCount());
   484     this->setupTexGen(builder, effect, key, &coords);
   485     this->emitSamplers(builder, effect, &samplers);
   487     GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
   488     fGLEffects.push_back(glEffect);
   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());
   495     SkASSERT(!glEffect->isVertexEffect());
   496     glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
   498     builder->fsCodeAppend("\t}\n");
   499 }
   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 }
   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 }
   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 }
   572 GrGLTexGenProgramEffectsBuilder::GrGLTexGenProgramEffectsBuilder(
   573         GrGLFragmentOnlyShaderBuilder* builder,
   574         int reserveCount)
   575     : fBuilder(builder)
   576     , fProgramEffects(SkNEW_ARGS(GrGLTexGenProgramEffects, (reserveCount))) {
   577 }
   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 }

mercurial