Changes to remove program effects builder
authorjoshualitt <joshualitt@chromium.org>
Thu, 18 Sep 2014 19:26:38 +0000 (12:26 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 18 Sep 2014 19:26:38 +0000 (12:26 -0700)
BUG=skia:
R=bsalomon@google.com

Author: joshualitt@chromium.org

Review URL: https://codereview.chromium.org/551253004

25 files changed:
include/gpu/GrEffectStage.h
include/gpu/GrShaderVar.h
src/core/SkXfermode.cpp
src/effects/SkArithmeticMode.cpp
src/effects/SkDisplacementMapEffect.cpp
src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
src/effects/gradients/SkTwoPointRadialGradient.cpp
src/gpu/effects/GrConfigConversionEffect.cpp
src/gpu/effects/GrSimpleTextureEffect.cpp
src/gpu/effects/GrYUVtoRGBEffect.cpp
src/gpu/gl/GrGLEffect.h
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgramDesc.cpp
src/gpu/gl/GrGLProgramEffects.cpp
src/gpu/gl/GrGLProgramEffects.h
src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp
src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLFullProgramBuilder.cpp
src/gpu/gl/builders/GrGLFullProgramBuilder.h
src/gpu/gl/builders/GrGLProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.h
src/gpu/gl/builders/GrGLShaderBuilder.cpp
src/gpu/gl/builders/GrGLShaderBuilder.h
src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp

index 6df7f90..b42d309 100644 (file)
@@ -12,6 +12,7 @@
 #define GrEffectStage_DEFINED
 
 #include "GrBackendEffectFactory.h"
+#include "GrCoordTransform.h"
 #include "GrEffect.h"
 #include "GrProgramElementRef.h"
 #include "SkMatrix.h"
@@ -128,6 +129,23 @@ public:
         }
     }
 
+    bool isPerspectiveCoordTransform(int matrixIndex, bool useExplicitLocalCoords) const {
+        const GrCoordTransform& coordTransform = this->getEffect()->coordTransform(matrixIndex);
+        SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
+        SkMatrix::TypeMask type1 = SkMatrix::kIdentity_Mask;
+        if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
+          type1 = useExplicitLocalCoords ?
+                  SkMatrix::kIdentity_Mask : this->getCoordChangeMatrix().getType();
+        }
+
+        int combinedTypes = type0 | type1;
+        if (SkMatrix::kPerspective_Mask & combinedTypes) {
+          return true;
+        } else {
+          return false;
+        }
+    }
+
     const GrEffect* getEffect() const { return fEffect.get(); }
 
     void convertToPendingExec() { fEffect.convertToPendingExec(); }
index a13cb8c..cbc074d 100644 (file)
@@ -55,6 +55,16 @@ public:
         , fPrecision(kDefault_Precision) {
     }
 
+    GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray,
+                Precision precision = kDefault_Precision)
+        : fType(type)
+        , fTypeModifier(kNone_TypeModifier)
+        , fName(name)
+        , fCount(arrayCount)
+        , fPrecision(precision) {
+        SkASSERT(kVoid_GrSLType != type);
+    }
+
     GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
                   Precision precision = kDefault_Precision)
         : fType(type)
index db9d332..d7f5a7c 100644 (file)
@@ -836,7 +836,7 @@ public:
             if (backgroundTex) {
                 dstColor = "bgColor";
                 fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor);
-                fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+                fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
                 fsBuilder->codeAppendf(";\n");
             } else {
                 dstColor = fsBuilder->dstColor();
index 2160096..7ee2a70 100644 (file)
@@ -372,7 +372,7 @@ void GrGLArithmeticEffect::emitCode(GrGLProgramBuilder* builder,
     const char* dstColor;
     if (backgroundTex) {
         fsBuilder->codeAppend("\t\tvec4 bgColor = ");
-        fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+        fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
         fsBuilder->codeAppendf(";\n");
         dstColor = "bgColor";
     } else {
index 899254f..6f23dae 100644 (file)
@@ -562,7 +562,7 @@ void GrGLDisplacementMapEffect::emitCode(GrGLProgramBuilder* builder,
 
     GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("\t\tvec4 %s = ", dColor);
-    fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+    fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
     fsBuilder->codeAppend(";\n");
 
     // Unpremultiply the displacement
@@ -615,7 +615,7 @@ void GrGLDisplacementMapEffect::emitCode(GrGLProgramBuilder* builder,
         "bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);\t\t",
         outOfBounds, cCoords, cCoords, cCoords, cCoords);
     fsBuilder->codeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
-    fsBuilder->appendTextureLookup(samplers[1], cCoords, coords[1].type());
+    fsBuilder->appendTextureLookup(samplers[1], cCoords, coords[1].getType());
     fsBuilder->codeAppend(";\n");
 }
 
index 4c474b2..720dc63 100644 (file)
@@ -240,11 +240,11 @@ void GLEdge2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
     builder->getUniformVariable(fParamUni).appendArrayAccess(2, &p2);
 
     // We interpolate the linear component in coords[1].
-    SkASSERT(coords[0].type() == coords[1].type());
+    SkASSERT(coords[0].getType() == coords[1].getType());
     const char* coords2D;
     SkString bVar;
     GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
-    if (kVec3f_GrSLType == coords[0].type()) {
+    if (kVec3f_GrSLType == coords[0].getType()) {
         fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
                                coords[0].c_str(), coords[0].c_str(), coords[1].c_str(),
                                coords[1].c_str());
index 70a2cf8..fe56c73 100644 (file)
@@ -598,10 +598,10 @@ void GrGLRadial2Gradient::emitCode(GrGLProgramBuilder* builder,
 
     GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     // We interpolate the linear component in coords[1].
-    SkASSERT(coords[0].type() == coords[1].type());
+    SkASSERT(coords[0].getType() == coords[1].getType());
     const char* coords2D;
     SkString bVar;
-    if (kVec3f_GrSLType == coords[0].type()) {
+    if (kVec3f_GrSLType == coords[0].getType()) {
         fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy, %s.x) / %s.z;\n",
                                coords[0].c_str(), coords[1].c_str(), coords[0].c_str());
         coords2D = "interpolants.xy";
index e00ad53..4000306 100644 (file)
@@ -40,7 +40,7 @@ public:
         fsBuilder->codeAppendf("%s;", tmpDecl.c_str());
 
         fsBuilder->codeAppendf("%s = ", tmpVar.c_str());
-        fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+        fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
         fsBuilder->codeAppend(";");
 
         if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
index 7871920..f2a932b 100644 (file)
@@ -31,7 +31,7 @@ public:
         fsBuilder->appendTextureLookupAndModulate(inputColor,
                                                   samplers[0],
                                                   coords[0].c_str(),
-                                                  coords[0].type());
+                                                  coords[0].getType());
         fsBuilder->codeAppend(";\n");
     }
 
index cba8140..dc67028 100644 (file)
@@ -66,11 +66,11 @@ public:
                                              kMat44f_GrSLType, "YUVMatrix",
                                              &yuvMatrix);
             fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
-            fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
+            fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
             fsBuilder->codeAppend(".r,\n\t\t");
-            fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].type());
+            fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType());
             fsBuilder->codeAppend(".r,\n\t\t");
-            fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].type());
+            fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType());
             fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
         }
 
index 24c20c6..61e3ed8 100644 (file)
@@ -34,11 +34,41 @@ class GrGLTexture;
 class GrGLGeometryProcessor;
 
 class GrGLEffect {
-
 public:
-    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-    typedef GrGLProgramEffects::TextureSampler TextureSampler;
-    typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+
+    /**
+     * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
+     */
+    typedef GrShaderVar TransformedCoords;
+    typedef SkTArray<GrShaderVar> TransformedCoordsArray;
+
+    /**
+     * Passed to GrGLEffects so they can add texture reads to their shader code.
+     */
+    class TextureSampler {
+    public:
+        TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
+            : fSamplerUniform(uniform)
+            , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
+            SkASSERT(0 != fConfigComponentMask);
+            memcpy(fSwizzle, access.getSwizzle(), 5);
+        }
+
+        // bitfield of GrColorComponentFlags present in the texture's config.
+        uint32_t configComponentMask() const { return fConfigComponentMask; }
+        // this is .abcd
+        const char* swizzle() const { return fSwizzle; }
+
+    private:
+        UniformHandle fSamplerUniform;
+        uint32_t      fConfigComponentMask;
+        char          fSwizzle[5];
+
+        friend class GrGLShaderBuilder;
+    };
+
+    typedef SkTArray<TextureSampler> TextureSamplerArray;
 
     GrGLEffect(const GrBackendEffectFactory& factory)
         : fFactory(factory)
index 8c2dd96..dccd4bb 100644 (file)
@@ -4,6 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "GrGLProgram.h"
 
 #include "builders/GrGLFragmentOnlyProgramBuilder.h"
@@ -147,10 +148,10 @@ void GrGLProgram::setData(const GrOptDrawState& optState,
 
     if (fGeometryProcessor.get()) {
         SkASSERT(geometryProcessor);
-        fGeometryProcessor->setData(fGpu, drawType,fProgramDataManager, geometryProcessor);
+        fGeometryProcessor->setData(fGpu, drawType, fProgramDataManager, &geometryProcessor);
     }
-    fColorEffects->setData(fGpu, drawType,fProgramDataManager, colorStages);
-    fCoverageEffects->setData(fGpu, drawType,fProgramDataManager, coverageStages);
+    fColorEffects->setData(fGpu, drawType, fProgramDataManager, colorStages);
+    fCoverageEffects->setData(fGpu, drawType, fProgramDataManager, coverageStages);
 
     // PathTexGen state applies to the the fixed function vertex shader. For
     // custom shaders, it's ignored, so we don't need to change the texgen
index b874091..c6560be 100644 (file)
 
 #include "SkChecksum.h"
 
+/**
+ * The key for an individual coord transform is made up of a matrix type and a bit that
+ * indicates the source of the input coords.
+ */
+enum {
+    kMatrixTypeKeyBits   = 1,
+    kMatrixTypeKeyMask   = (1 << kMatrixTypeKeyBits) - 1,
+    kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
+    kTransformKeyBits    = kMatrixTypeKeyBits + 1,
+};
+
+/**
+ * We specialize the vertex code for each of these matrix types.
+ */
+enum MatrixType {
+    kNoPersp_MatrixType  = 0,
+    kGeneral_MatrixType  = 1,
+};
+
+/**
+ * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
+ * present in the texture's config. swizzleComponentMask indicates the channels present in the
+ * shader swizzle.
+ */
+static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
+                                             uint32_t configComponentMask,
+                                             uint32_t swizzleComponentMask) {
+    if (caps.textureSwizzleSupport()) {
+        // Any remapping is handled using texture swizzling not shader modifications.
+        return false;
+    }
+    // check if the texture is alpha-only
+    if (kA_GrColorComponentFlag == configComponentMask) {
+        if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
+            // we must map the swizzle 'a's to 'r'.
+            return true;
+        }
+        if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
+            // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
+            // alpha-only textures smear alpha across all four channels when read.
+            return true;
+        }
+    }
+    return false;
+}
+
+static uint32_t gen_attrib_key(const GrEffect* effect) {
+    uint32_t key = 0;
+
+    const GrEffect::VertexAttribArray& vars = effect->getVertexAttribs();
+    int numAttributes = vars.count();
+    SkASSERT(numAttributes <= 2);
+    for (int a = 0; a < numAttributes; ++a) {
+        uint32_t value = 1 << a;
+        key |= value;
+    }
+    return key;
+}
+
+static uint32_t gen_transform_key(const GrEffectStage& effectStage,
+                                  bool useExplicitLocalCoords) {
+    uint32_t totalKey = 0;
+    int numTransforms = effectStage.getEffect()->numTransforms();
+    for (int t = 0; t < numTransforms; ++t) {
+        uint32_t key = 0;
+        if (effectStage.isPerspectiveCoordTransform(t, useExplicitLocalCoords)) {
+            key |= kGeneral_MatrixType;
+        } else {
+            key |= kNoPersp_MatrixType;
+        }
+
+        const GrCoordTransform& coordTransform = effectStage.getEffect()->coordTransform(t);
+        if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLocalCoords) {
+            key |= kPositionCoords_Flag;
+        }
+        key <<= kTransformKeyBits * t;
+        SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
+        totalKey |= key;
+    }
+    return totalKey;
+}
+
+static uint32_t gen_texture_key(const GrEffect* effect, const GrGLCaps& caps) {
+    uint32_t key = 0;
+    int numTextures = effect->numTextures();
+    for (int t = 0; t < numTextures; ++t) {
+        const GrTextureAccess& access = effect->textureAccess(t);
+        uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
+        if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
+            key |= 1 << t;
+        }
+    }
+    return key;
+}
+
+/**
+ * A function which emits a meta key into the key builder.  This is required because shader code may
+ * be dependent on properties of the effect that the effect itself doesn't use
+ * in its key (e.g. the pixel format of textures used). So we create a meta-key for
+ * every effect using this function. It is also responsible for inserting the effect's class ID
+ * which must be different for every GrEffect subclass. It can fail if an effect uses too many
+ * textures, attributes, etc for the space allotted in the meta-key.
+ */
+
+static bool gen_effect_meta_key(const GrEffectStage& effectStage,
+                                bool useExplicitLocalCoords,
+                                const GrGLCaps& caps,
+                                GrEffectKeyBuilder* b) {
+
+    uint32_t textureKey = gen_texture_key(effectStage.getEffect(), caps);
+    uint32_t transformKey = gen_transform_key(effectStage,useExplicitLocalCoords);
+    uint32_t attribKey = gen_attrib_key(effectStage.getEffect());
+    uint32_t classID = effectStage.getEffect()->getFactory().effectClassID();
+
+    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
+    // don't fit.
+    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
+    if ((textureKey | transformKey | attribKey | classID) & kMetaKeyInvalidMask) {
+        return false;
+    }
+
+    uint32_t* key = b->add32n(2);
+    key[0] = (textureKey << 16 | transformKey);
+    key[1] = (classID << 16 | attribKey);
+    return true;
+}
+
 bool GrGLProgramDesc::GetEffectKey(const GrEffectStage& stage, const GrGLCaps& caps,
                                    bool useExplicitLocalCoords, GrEffectKeyBuilder* b,
                                    uint16_t* effectKeySize) {
@@ -26,10 +153,7 @@ bool GrGLProgramDesc::GetEffectKey(const GrEffectStage& stage, const GrGLCaps& c
         return false;
     }
     *effectKeySize = SkToU16(size);
-    if (!GrGLProgramEffects::GenEffectMetaKey(stage,
-                                              useExplicitLocalCoords,
-                                              caps,
-                                              b)) {
+    if (!gen_effect_meta_key(stage, useExplicitLocalCoords, caps, b)) {
         return false;
     }
     return true;
index 30cec29..1bdcf87 100644 (file)
 #include "gl/GrGLGeometryProcessor.h"
 #include "gl/GrGpuGL.h"
 
-typedef GrGLProgramEffects::TransformedCoords TransformedCoords;
-typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-typedef GrGLProgramEffects::TextureSampler TextureSampler;
-typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
-
-/**
- * We specialize the vertex code for each of these matrix types.
- */
-enum MatrixType {
-    kNoPersp_MatrixType  = 0,
-    kGeneral_MatrixType  = 1,
-};
-
-/**
- * The key for an individual coord transform is made up of a matrix type and a bit that
- * indicates the source of the input coords.
- */
-enum {
-    kMatrixTypeKeyBits   = 1,
-    kMatrixTypeKeyMask   = (1 << kMatrixTypeKeyBits) - 1,
-    kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
-    kTransformKeyBits    = kMatrixTypeKeyBits + 1,
-};
+typedef GrGLEffect::TransformedCoords TransformedCoords;
+typedef GrGLEffect::TransformedCoordsArray TransformedCoordsArray;
+typedef GrGLEffect::TextureSampler TextureSampler;
+typedef GrGLEffect::TextureSamplerArray TextureSamplerArray;
 
 namespace {
-
-/**
- * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
- * present in the texture's config. swizzleComponentMask indicates the channels present in the
- * shader swizzle.
- */
-inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
-                                             uint32_t configComponentMask,
-                                             uint32_t swizzleComponentMask) {
-    if (caps.textureSwizzleSupport()) {
-        // Any remapping is handled using texture swizzling not shader modifications.
-        return false;
-    }
-    // check if the texture is alpha-only
-    if (kA_GrColorComponentFlag == configComponentMask) {
-        if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
-            // we must map the swizzle 'a's to 'r'.
-            return true;
-        }
-        if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
-            // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
-            // alpha-only textures smear alpha across all four channels when read.
-            return true;
-        }
-    }
-    return false;
-}
-
-/**
- * Retrieves the matrix type from transformKey for the transform at transformIdx.
- */
-MatrixType get_matrix_type(uint32_t transformKey, int transformIdx) {
-    return static_cast<MatrixType>(
-               (transformKey >> (kTransformKeyBits * transformIdx)) & kMatrixTypeKeyMask);
-}
-
-/**
- * Retrieves the source coords from transformKey for the transform at transformIdx. It may not be
- * the same coordinate set as the original GrCoordTransform if the position and local coords are
- * identical for this program.
- */
-GrCoordSet get_source_coords(uint32_t transformKey, int transformIdx) {
-    return (transformKey >> (kTransformKeyBits * transformIdx)) & kPositionCoords_Flag ?
-               kPosition_GrCoordSet :
-               kLocal_GrCoordSet;
-}
-
 /**
  * Retrieves the final matrix that a transform needs to apply to its source coords.
  */
@@ -118,87 +52,6 @@ SkMatrix get_transform_matrix(const GrEffectStage& effectStage,
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrGLProgramEffects::GenEffectMetaKey(const GrEffectStage& effectStage,
-                                          bool useExplicitLocalCoords,
-                                          const GrGLCaps& caps,
-                                          GrEffectKeyBuilder* b) {
-
-    uint32_t textureKey = GrGLProgramEffects::GenTextureKey(effectStage.getEffect(), caps);
-    uint32_t transformKey = GrGLProgramEffects::GenTransformKey(effectStage,useExplicitLocalCoords);
-    uint32_t attribKey = GrGLProgramEffects::GenAttribKey(effectStage.getEffect());
-    uint32_t classID = effectStage.getEffect()->getFactory().effectClassID();
-
-    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
-    // don't fit.
-    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
-    if ((textureKey | transformKey | attribKey | classID) & kMetaKeyInvalidMask) {
-        return false;
-    }
-
-    uint32_t* key = b->add32n(2);
-    key[0] = (textureKey << 16 | transformKey);
-    key[1] = (classID << 16 | attribKey);
-    return true;
-}
-
-uint32_t GrGLProgramEffects::GenAttribKey(const GrEffect* effect) {
-    uint32_t key = 0;
-
-    const GrEffect::VertexAttribArray& vars = effect->getVertexAttribs();
-    int numAttributes = vars.count();
-    SkASSERT(numAttributes <= 2);
-    for (int a = 0; a < numAttributes; ++a) {
-        uint32_t value = 1 << a;
-        key |= value;
-    }
-    return key;
-}
-
-uint32_t GrGLProgramEffects::GenTransformKey(const GrEffectStage& effectStage,
-                                             bool useExplicitLocalCoords) {
-    uint32_t totalKey = 0;
-    int numTransforms = effectStage.getEffect()->numTransforms();
-    for (int t = 0; t < numTransforms; ++t) {
-        uint32_t key = 0;
-        const GrCoordTransform& coordTransform = effectStage.getEffect()->coordTransform(t);
-        SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
-        SkMatrix::TypeMask type1 = SkMatrix::kIdentity_Mask;
-        if (kLocal_GrCoordSet == coordTransform.sourceCoords() && !useExplicitLocalCoords) {
-            type1 = effectStage.getCoordChangeMatrix().getType();
-        } else if (kPosition_GrCoordSet == coordTransform.sourceCoords() && useExplicitLocalCoords) {
-            // We only make the key indicate that device coords are referenced when the local coords
-            // are not actually determined by positions. Otherwise the local coords var and position
-            // var are identical.
-            key |= kPositionCoords_Flag;
-        }
-
-        int combinedTypes = type0 | type1;
-
-        if (SkMatrix::kPerspective_Mask & combinedTypes) {
-            key |= kGeneral_MatrixType;
-        } else {
-            key |= kNoPersp_MatrixType;
-        }
-        key <<= kTransformKeyBits * t;
-        SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
-        totalKey |= key;
-    }
-    return totalKey;
-}
-
-uint32_t GrGLProgramEffects::GenTextureKey(const GrEffect* effect, const GrGLCaps& caps) {
-    uint32_t key = 0;
-    int numTextures = effect->numTextures();
-    for (int t = 0; t < numTextures; ++t) {
-        const GrTextureAccess& access = effect->textureAccess(t);
-        uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
-        if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
-            key |= 1 << t;
-        }
-    }
-    return key;
-}
-
 GrGLProgramEffects::~GrGLProgramEffects() {
     int numEffects = fGLEffects.count();
     for (int e = 0; e < numEffects; ++e) {
@@ -206,23 +59,6 @@ GrGLProgramEffects::~GrGLProgramEffects() {
     }
 }
 
-void GrGLProgramEffects::emitSamplers(GrGLProgramBuilder* builder,
-                                      const GrEffect& effect,
-                                      TextureSamplerArray* outSamplers) {
-    SkTArray<Sampler, true>& samplers = fSamplers.push_back();
-    int numTextures = effect.numTextures();
-    samplers.push_back_n(numTextures);
-    SkString name;
-    for (int t = 0; t < numTextures; ++t) {
-        name.printf("Sampler%d", t);
-        samplers[t].fUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
-                                                   kSampler2D_GrSLType,
-                                                   name.c_str());
-        SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
-                               (samplers[t].fUniform, effect.textureAccess(t)));
-    }
-}
-
 void GrGLProgramEffects::initSamplers(const GrGLProgramDataManager& programResourceManager, int* texUnitIdx) {
     int numEffects = fGLEffects.count();
     SkASSERT(numEffects == fSamplers.count());
@@ -252,120 +88,6 @@ void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffect& effect, int
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGLVertexProgramEffects::emitEffect(GrGLFullProgramBuilder* builder,
-                                          const GrEffectStage& stage,
-                                          const GrEffectKey& key,
-                                          const char* outColor,
-                                          const char* inColor,
-                                          int stageIndex) {
-    const GrEffect& effect = *stage.getEffect();
-    SkSTArray<2, TransformedCoords> coords(effect.numTransforms());
-    SkSTArray<4, TextureSampler> samplers(effect.numTextures());
-
-    GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
-    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
-    vsBuilder->emitAttributes(stage);
-    this->emitTransforms(builder, stage, &coords);
-    this->emitSamplers(builder, effect, &samplers);
-
-    GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);
-    fGLEffects.push_back(glEffect);
-
-    // Enclose custom code in a block to avoid namespace conflicts
-    SkString openBrace;
-    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
-    fsBuilder->codeAppend(openBrace.c_str());
-    vsBuilder->codeAppend(openBrace.c_str());
-
-    if (glEffect->isVertexEffect()) {
-        GrGLGeometryProcessor* vertexEffect = static_cast<GrGLGeometryProcessor*>(glEffect);
-        vertexEffect->emitCode(builder, effect, key, outColor, inColor, coords, samplers);
-    } else {
-        glEffect->emitCode(builder, effect, key, outColor, inColor, coords, samplers);
-    }
-
-    vsBuilder->codeAppend("\t}\n");
-    fsBuilder->codeAppend("\t}\n");
-}
-
-void GrGLVertexProgramEffects::emitTransforms(GrGLFullProgramBuilder* builder,
-                                              const GrEffectStage& effectStage,
-                                              TransformedCoordsArray* outCoords) {
-    SkTArray<Transform, true>& transforms = fTransforms.push_back();
-    uint32_t totalKey = GenTransformKey(effectStage, fHasExplicitLocalCoords);
-    int numTransforms = effectStage.getEffect()->numTransforms();
-    transforms.push_back_n(numTransforms);
-
-    SkTArray<PathTransform, true>* pathTransforms = NULL;
-    const GrGLCaps* glCaps = builder->ctxInfo().caps();
-    if (glCaps->pathRenderingSupport() &&
-        builder->gpu()->glPathRendering()->texturingMode() ==
-           GrGLPathRendering::SeparableShaders_TexturingMode) {
-        pathTransforms = &fPathTransforms.push_back();
-        pathTransforms->push_back_n(numTransforms);
-    }
-
-    for (int t = 0; t < numTransforms; t++) {
-        GrSLType varyingType = kVoid_GrSLType;
-        const char* uniName;
-        switch (get_matrix_type(totalKey, t)) {
-            case kNoPersp_MatrixType:
-                uniName = "StageMatrix";
-                varyingType = kVec2f_GrSLType;
-                break;
-            case kGeneral_MatrixType:
-                uniName = "StageMatrix";
-                varyingType = kVec3f_GrSLType;
-                break;
-            default:
-                SkFAIL("Unexpected key.");
-        }
-        SkString suffixedUniName;
-        if (0 != t) {
-            suffixedUniName.append(uniName);
-            suffixedUniName.appendf("_%i", t);
-            uniName = suffixedUniName.c_str();
-        }
-        transforms[t].fHandle = builder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
-                                                    kMat33f_GrSLType,
-                                                    uniName,
-                                                    &uniName);
-
-        const char* varyingName = "MatrixCoord";
-        SkString suffixedVaryingName;
-        if (0 != t) {
-            suffixedVaryingName.append(varyingName);
-            suffixedVaryingName.appendf("_%i", t);
-            varyingName = suffixedVaryingName.c_str();
-        }
-        const char* vsVaryingName;
-        const char* fsVaryingName;
-        GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
-        if (pathTransforms) {
-            (*pathTransforms)[t].fHandle =
-                builder->addSeparableVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
-            (*pathTransforms)[t].fType = varyingType;
-        } else {
-            builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
-        }
-
-        const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ?
-                                          vsBuilder->positionAttribute() :
-                                          vsBuilder->localCoordsAttribute();
-        // varying = matrix * coords (logically)
-        SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
-        if (kVec2f_GrSLType == varyingType) {
-            vsBuilder->codeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
-                                   vsVaryingName, uniName, coords.c_str());
-        } else {
-            vsBuilder->codeAppendf("\t%s = %s * vec3(%s, 1);\n",
-                                   vsVaryingName, uniName, coords.c_str());
-        }
-        SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
-                               (SkString(fsVaryingName), varyingType));
-    }
-}
-
 void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
                                        GrGpu::DrawType drawType,
                                        const GrGLProgramDataManager& programDataManager,
@@ -387,24 +109,6 @@ void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
     }
 }
 
-void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
-                                       GrGpu::DrawType drawType,
-                                       const GrGLProgramDataManager& programDataManager,
-                                       const GrEffectStage* effectStage) {
-    SkASSERT(1 == fTransforms.count());
-    SkASSERT(1 == fSamplers.count());
-    SkASSERT(1 == fGLEffects.count());
-    const GrEffect& effect = *effectStage->getEffect();
-    fGLEffects[0]->setData(programDataManager, effect);
-    if (GrGpu::IsPathRenderingDrawType(drawType)) {
-        this->setPathTransformData(gpu, programDataManager, *effectStage, 0);
-    } else {
-        this->setTransformData(gpu, programDataManager, *effectStage, 0);
-    }
-
-    this->bindTextures(gpu, effect, 0);
-}
-
 void GrGLVertexProgramEffects::setTransformData(GrGpuGL* gpu,
                                                 const GrGLProgramDataManager& pdman,
                                                 const GrEffectStage& effectStage,
@@ -449,70 +153,8 @@ void GrGLVertexProgramEffects::setPathTransformData(GrGpuGL* gpu,
     }
 }
 
-GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullProgramBuilder* builder,
-                                                                 int reserveCount)
-    : fBuilder(builder)
-    , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
-                                 (reserveCount,
-                                  fBuilder->getVertexShaderBuilder()->hasExplicitLocalCoords()))) {
-}
-void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
-                                                 const GrEffectKey& key,
-                                                 const char* outColor,
-                                                 const char* inColor,
-                                                 int stageIndex) {
-    SkASSERT(fProgramEffects.get());
-    fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyProgramBuilder* builder,
-                                          const GrEffectStage& stage,
-                                          const GrEffectKey& key,
-                                          const char* outColor,
-                                          const char* inColor,
-                                          int stageIndex) {
-    const GrEffect& effect = *stage.getEffect();
-    SkSTArray<2, TransformedCoords> coords(effect.numTransforms());
-    SkSTArray<4, TextureSampler> samplers(effect.numTextures());
-
-    SkASSERT(0 == effect.getVertexAttribs().count());
-    this->setupPathTexGen(builder, stage, &coords);
-    this->emitSamplers(builder, effect, &samplers);
-
-    GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);
-    fGLEffects.push_back(glEffect);
-
-    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
-    // Enclose custom code in a block to avoid namespace conflicts
-    SkString openBrace;
-    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
-    fsBuilder->codeAppend(openBrace.c_str());
-
-    SkASSERT(!glEffect->isVertexEffect());
-    glEffect->emitCode(builder, effect, key, outColor, inColor, coords, samplers);
-
-    fsBuilder->codeAppend("\t}\n");
-}
-
-void GrGLPathTexGenProgramEffects::setupPathTexGen(GrGLFragmentOnlyProgramBuilder* builder,
-                                           const GrEffectStage& effectStage,
-                                           TransformedCoordsArray* outCoords) {
-    int numTransforms = effectStage.getEffect()->numTransforms();
-    uint32_t totalKey = GenTransformKey(effectStage, false);
-    int texCoordIndex = builder->addTexCoordSets(numTransforms);
-    SkNEW_APPEND_TO_TARRAY(&fTransforms, Transforms, (totalKey, texCoordIndex));
-    SkString name;
-    for (int t = 0; t < numTransforms; ++t) {
-        GrSLType type = kGeneral_MatrixType == get_matrix_type(totalKey, t) ?
-                            kVec3f_GrSLType :
-                            kVec2f_GrSLType;
-        name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
-        SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (name, type));
-    }
-}
-
 void GrGLPathTexGenProgramEffects::setData(GrGpuGL* gpu,
                                            GrGpu::DrawType,
                                            const GrGLProgramDataManager& pdman,
@@ -532,45 +174,15 @@ void GrGLPathTexGenProgramEffects::setData(GrGpuGL* gpu,
 void GrGLPathTexGenProgramEffects::setPathTexGenState(GrGpuGL* gpu,
                                               const GrEffectStage& effectStage,
                                               int effectIdx) {
-    uint32_t totalKey = fTransforms[effectIdx].fTransformKey;
     int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex;
     int numTransforms = effectStage.getEffect()->numTransforms();
     for (int t = 0; t < numTransforms; ++t) {
-        switch (get_matrix_type(totalKey, t)) {
-            case kNoPersp_MatrixType: {
-                const SkMatrix& transform = get_transform_matrix(effectStage, false, t);
-                gpu->glPathRendering()->enablePathTexGen(
-                        texCoordIndex++,
-                        GrGLPathRendering::kST_PathTexGenComponents,
-                        transform);
-                break;
-            }
-            case kGeneral_MatrixType: {
-                const SkMatrix& transform = get_transform_matrix(effectStage, false, t);
-                gpu->glPathRendering()->enablePathTexGen(
-                        texCoordIndex++,
-                        GrGLPathRendering::kSTR_PathTexGenComponents,
-                        transform);
-                break;
-            }
-            default:
-                SkFAIL("Unexpected matrixs type.");
+        const SkMatrix& transform = get_transform_matrix(effectStage, false, t);
+        GrGLPathRendering::PathTexGenComponents components =
+                GrGLPathRendering::kST_PathTexGenComponents;
+        if (effectStage.isPerspectiveCoordTransform(t, false)) {
+            components = GrGLPathRendering::kSTR_PathTexGenComponents;
         }
+        gpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform);
     }
 }
-
-GrGLPathTexGenProgramEffectsBuilder::GrGLPathTexGenProgramEffectsBuilder(
-        GrGLFragmentOnlyProgramBuilder* builder,
-        int reserveCount)
-    : fBuilder(builder)
-    , fProgramEffects(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (reserveCount))) {
-}
-void GrGLPathTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
-                                                     const GrEffectKey& key,
-                                                     const char* outColor,
-                                                     const char* inColor,
-                                                     int stageIndex) {
-    SkASSERT(fProgramEffects.get());
-    fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
-}
-
index dd3feab..8b870d4 100644 (file)
@@ -31,19 +31,6 @@ public:
     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
     typedef GrGLProgramDataManager::VaryingHandle VaryingHandle;
 
-    /**
-     * This class emits some of the code inserted into the shaders for an effect. The code it
-     * creates may be dependent on properties of the effect that the effect itself doesn't use
-     * in its key (e.g. the pixel format of textures used). So this class inserts a meta-key for
-     * every effect using this function. It is also responsible for inserting the effect's class ID
-     * which must be different for every GrEffect subclass. It can fail if an effect uses too many
-     * textures, attributes, etc for the space allotted in the meta-key.
-     */
-    static bool GenEffectMetaKey(const GrEffectStage&,
-                                 bool,
-                                 const GrGLCaps&,
-                                 GrEffectKeyBuilder*);
-
     virtual ~GrGLProgramEffects();
 
     /**
@@ -60,80 +47,13 @@ public:
                          const GrGLProgramDataManager&,
                          const GrEffectStage* effectStages[]) = 0;
 
-    virtual void setData(GrGpuGL*,
-                         GrGpu::DrawType,
-                         const GrGLProgramDataManager&,
-                         const GrEffectStage* effectStages) { SkFAIL("DO NOT USE"); }
-
-    void addEffect(GrGLEffect* effect) { fGLEffects.push_back(effect); }
-
-    /**
-     * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
-     */
-    class TransformedCoords {
-    public:
-        TransformedCoords(const SkString& name, GrSLType type)
-            : fName(name), fType(type) {
-        }
-
-        const char* c_str() const { return fName.c_str(); }
-        GrSLType type() const { return fType; }
-        const SkString& getName() const { return fName; }
-
-    private:
-        SkString fName;
-        GrSLType fType;
-    };
-
-    typedef SkTArray<TransformedCoords> TransformedCoordsArray;
-
-    /**
-     * Passed to GrGLEffects so they can add texture reads to their shader code.
-     */
-    class TextureSampler {
-    public:
-        TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
-            : fSamplerUniform(uniform)
-            , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
-            SkASSERT(0 != fConfigComponentMask);
-            memcpy(fSwizzle, access.getSwizzle(), 5);
-        }
-
-        UniformHandle samplerUniform() const { return fSamplerUniform; }
-        // bitfield of GrColorComponentFlags present in the texture's config.
-        uint32_t configComponentMask() const { return fConfigComponentMask; }
-        const char* swizzle() const { return fSwizzle; }
-
-    private:
-        UniformHandle fSamplerUniform;
-        uint32_t      fConfigComponentMask;
-        char          fSwizzle[5];
-    };
-
-    typedef SkTArray<TextureSampler> TextureSamplerArray;
-
 protected:
-
-    /**
-     * Helpers for GenEffectMetaKey.
-     */
-    static uint32_t GenAttribKey(const GrEffect*);
-    static uint32_t GenTransformKey(const GrEffectStage&, bool useExplicitLocalCoords);
-    static uint32_t GenTextureKey(const GrEffect*, const GrGLCaps&);
-
     GrGLProgramEffects(int reserveCount)
         : fGLEffects(reserveCount)
         , fSamplers(reserveCount) {
     }
 
     /**
-     * Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and
-     * appends the necessary data to the TextureSamplerArray* object so effects can add texture
-     * lookups to their code. This method is only meant to be called during the construction phase.
-     */
-    void emitSamplers(GrGLProgramBuilder*, const GrEffect&, TextureSamplerArray*);
-
-    /**
      * Helper for setData(). Binds all the textures for an effect.
      */
     void bindTextures(GrGpuGL*, const GrEffect&, int effectIdx);
@@ -144,27 +64,21 @@ protected:
         int           fTextureUnit;
     };
 
+    /*
+     * Helpers for shader builders to build up program effects objects alongside shader code
+     */
+    void addEffect(GrGLEffect* effect) { fGLEffects.push_back(effect); }
+    SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); }
+
     SkTArray<GrGLEffect*>                  fGLEffects;
     SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
 
 private:
-    typedef SkRefCnt INHERITED;
-};
+    friend class GrGLProgramBuilder;
+    friend class GrGLFullProgramBuilder;
+    friend class GrGLFragmentOnlyShaderBuilder;
 
-/**
- * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
- */
-class GrGLProgramEffectsBuilder {
-public:
-    virtual ~GrGLProgramEffectsBuilder() { }
-    /**
-     * Emits the effect's shader code, and stores the necessary uniforms internally.
-     */
-    virtual void emitEffect(const GrEffectStage&,
-                            const GrEffectKey&,
-                            const char* outColor,
-                            const char* inColor,
-                            int stageIndex) = 0;
+    typedef SkRefCnt INHERITED;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -179,52 +93,12 @@ public:
                          const GrGLProgramDataManager&,
                          const GrEffectStage* effectStages[]) SK_OVERRIDE;
 
-    virtual void setData(GrGpuGL*,
-                         GrGpu::DrawType,
-                         const GrGLProgramDataManager&,
-                         const GrEffectStage* effectStages) SK_OVERRIDE;
-
 private:
-    friend class GrGLFullProgramBuilder;
-
     GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
         : INHERITED(reserveCount)
         , fTransforms(reserveCount)
         , fHasExplicitLocalCoords(explicitLocalCoords) {
     }
-    /**
-     * This method is meant to only be called during the construction phase.
-     */
-    void emitEffect(GrGLFullProgramBuilder*,
-                    const GrEffectStage&,
-                    const GrEffectKey&,
-                    const char* outColor,
-                    const char* inColor,
-                    int stageIndex);
-
-    /**
-     * Helper for emitEffect(). Emits any attributes an effect may have.
-     */
-    void emitAttributes(GrGLFullProgramBuilder*, const GrEffectStage&);
-
-    /**
-     * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
-     * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
-     * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
-     * of the varyings in the VS and FS as well their types are appended to the
-     * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
-     */
-    void emitTransforms(GrGLFullProgramBuilder*,
-                        const GrEffectStage&,
-                        TransformedCoordsArray*);
-
-    /**
-     * Helper for setData(). Sets all the transform matrices for an effect.
-     */
-    void setTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrEffectStage&,
-                          int effectIdx);
-    void setPathTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrEffectStage&,
-                              int effectIdx);
 
     struct Transform {
         Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
@@ -239,38 +113,30 @@ private:
         GrSLType fType;
     };
 
+    /*
+     * These functions are used by the builders to build up program effects along side the shader
+     * code itself
+     */
+    SkSTArray<2, Transform, true>& addTransforms() { return fTransforms.push_back(); }
+    SkTArray<PathTransform, true>& addPathTransforms() { return fPathTransforms.push_back(); }
+
+    /**
+     * Helper for setData(). Sets all the transform matrices for an effect.
+     */
+    void setTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrEffectStage&,
+                          int effectIdx);
+    void setPathTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrEffectStage&,
+                              int effectIdx);
+
     SkTArray<SkSTArray<2, Transform, true> > fTransforms;
     SkTArray<SkTArray<PathTransform, true> > fPathTransforms;
     bool                                     fHasExplicitLocalCoords;
 
-    friend class GrGLVertexProgramEffectsBuilder;
+    friend class GrGLFullProgramBuilder;
 
     typedef GrGLProgramEffects INHERITED;
 };
 
-/**
- * This class is used to construct a GrGLVertexProgramEffects* object.
- */
-class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
-public:
-    GrGLVertexProgramEffectsBuilder(GrGLFullProgramBuilder*, int reserveCount);
-    virtual ~GrGLVertexProgramEffectsBuilder() { }
-    virtual void emitEffect(const GrEffectStage&,
-                            const GrEffectKey&,
-                            const char* outColor,
-                            const char* inColor,
-                            int stageIndex) SK_OVERRIDE;
-    /**
-     * Finalizes the building process and returns the effect array. After this call, the builder
-     * becomes invalid.
-     */
-    GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
-private:
-    GrGLFullProgramBuilder*                 fBuilder;
-    SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
-    typedef GrGLProgramEffectsBuilder INHERITED;
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -285,75 +151,34 @@ public:
                          const GrEffectStage* effectStages[]) SK_OVERRIDE;
 
 private:
-    friend class GrGLFragmentOnlyProgramBuilder;
-
     GrGLPathTexGenProgramEffects(int reserveCount)
         : INHERITED(reserveCount)
         , fTransforms(reserveCount) {
     }
 
     /**
-     * This method is meant to only be called during the construction phase.
-     */
-    void emitEffect(GrGLFragmentOnlyProgramBuilder*,
-                    const GrEffectStage&,
-                    const GrEffectKey&,
-                    const char* outColor,
-                    const char* inColor,
-                    int stageIndex);
-
-    /**
-     * Helper for emitEffect(). Allocates texture units from the builder for each transform in an
-     * effect. The transforms all use adjacent texture units. They either use two or three of the
-     * coordinates at a given texture unit, depending on if they need perspective interpolation.
-     * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
-     * types are appended to the TransformedCoordsArray* object, which is in turn passed to the
-     * effect's emitCode() function.
-     */
-    void setupPathTexGen(GrGLFragmentOnlyProgramBuilder*,
-                         const GrEffectStage&,
-                         TransformedCoordsArray*);
-
-    /**
      * Helper for setData(). Sets the PathTexGen state for each transform in an effect.
      */
     void setPathTexGenState(GrGpuGL*, const GrEffectStage&, int effectIdx);
 
     struct Transforms {
-        Transforms(uint32_t transformKey, int texCoordIndex)
-            : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
-        uint32_t    fTransformKey;
-        int         fTexCoordIndex;
+        Transforms(int texCoordIndex)
+            : fTexCoordIndex(texCoordIndex) {}
+        int fTexCoordIndex;
     };
 
+    /*
+     * Helper for fragment only shader builder to build up the program effects alongside the shader
+     */
+    void addTransforms(int coordIndex) {
+        fTransforms.push_back(Transforms(coordIndex));
+    }
+
     SkTArray<Transforms> fTransforms;
 
-    friend class GrGLPathTexGenProgramEffectsBuilder;
-    typedef GrGLProgramEffects INHERITED;
-};
+    friend class GrGLFragmentOnlyProgramBuilder;
 
-/**
- * This class is used to construct a GrGLPathTexGenProgramEffects* object.
- */
-class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
-public:
-    GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyProgramBuilder*, int reserveCount);
-    virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
-    virtual void emitEffect(const GrEffectStage&,
-                            const GrEffectKey&,
-                            const char* outColor,
-                            const char* inColor,
-                            int stageIndex) SK_OVERRIDE;
-    /**
-     * Finalizes the building process and returns the effect array. After this call, the builder
-     * becomes invalid.
-     */
-    GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
-private:
-    GrGLFragmentOnlyProgramBuilder*          fBuilder;
-    SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
-    typedef GrGLProgramEffectsBuilder INHERITED;
+    typedef GrGLProgramEffects INHERITED;
 };
 
-
 #endif
index 3ad6b44..16def63 100644 (file)
@@ -24,16 +24,85 @@ int GrGLFragmentOnlyProgramBuilder::addTexCoordSets(int count) {
     return firstFreeCoordSet;
 }
 
-GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(
+void
+GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProcessor,
+                                                     const GrEffectStage* colorStages[],
+                                                     const GrEffectStage* coverageStages[],
+                                                     GrGLSLExpr4* inputColor,
+                                                     GrGLSLExpr4* inputCoverage) {
+    ///////////////////////////////////////////////////////////////////////////
+    // emit the per-effect code for both color and coverage effects
+
+    EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
+    fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
+                                                     this->desc().numColorEffects(),
+                                                     colorKeyProvider,
+                                                     inputColor));
+
+    EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
+    fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
+                                                        this->desc().numCoverageEffects(),
+                                                        coverageKeyProvider,
+                                                        inputCoverage));
+}
+
+GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::onCreateAndEmitEffects(
         const GrEffectStage* effectStages[], int effectCnt,
         const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) {
 
-    GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this,
-                                                                 effectCnt);
-    this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder,
-                                          effectStages,
+    fProgramEffects.reset(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (effectCnt)));
+    this->INHERITED::createAndEmitEffects(effectStages,
                                           effectCnt,
                                           keyProvider,
                                           inOutFSColor);
-    return pathTexGenEffectsBuilder.finish();
+    return fProgramEffects.detach();
+}
+
+void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrEffectStage& stage,
+                                                 const GrEffectKey& key,
+                                                 const char* outColor,
+                                                 const char* inColor,
+                                                 int stageIndex) {
+    SkASSERT(fProgramEffects.get());
+    const GrEffect& effect = *stage.getEffect();
+    SkASSERT(0 == effect.getVertexAttribs().count());
+
+    SkSTArray<2, GrGLEffect::TransformedCoords> coords(effect.numTransforms());
+    SkSTArray<4, GrGLEffect::TextureSampler> samplers(effect.numTextures());
+
+    this->setupPathTexGen(stage, &coords);
+    this->emitSamplers(effect, &samplers);
+
+    GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);
+    SkASSERT(!glEffect->isVertexEffect());
+    fProgramEffects->addEffect(glEffect);
+
+    GrGLFragmentShaderBuilder* fsBuilder = this->getFragmentShaderBuilder();
+    // Enclose custom code in a block to avoid namespace conflicts
+    SkString openBrace;
+    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
+    fsBuilder->codeAppend(openBrace.c_str());
+
+    glEffect->emitCode(this, effect, key, outColor, inColor, coords, samplers);
+
+    fsBuilder->codeAppend("\t}\n");
+}
+
+void GrGLFragmentOnlyProgramBuilder::setupPathTexGen(const GrEffectStage& effectStage,
+                                           GrGLEffect::TransformedCoordsArray* outCoords) {
+    int numTransforms = effectStage.getEffect()->numTransforms();
+    int texCoordIndex = this->addTexCoordSets(numTransforms);
+
+    fProgramEffects->addTransforms(texCoordIndex);
+
+    SkString name;
+    for (int t = 0; t < numTransforms; ++t) {
+        GrSLType type =
+                effectStage.isPerspectiveCoordTransform(t, false) ?
+                        kVec3f_GrSLType :
+                        kVec2f_GrSLType;
+
+        name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
+        SkNEW_APPEND_TO_TARRAY(outCoords, GrGLEffect::TransformedCoords, (name, type));
+    }
 }
index 5a4c4ad..291669c 100644 (file)
@@ -17,20 +17,38 @@ public:
     int addTexCoordSets(int count);
 
 private:
-    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color,
-                                       GrGLSLExpr4* coverage) SK_OVERRIDE {}
-
-    virtual void emitGeometryProcessor(const GrEffectStage* geometryProcessor,
-                                       GrGLSLExpr4* coverage) SK_OVERRIDE {
-        SkASSERT(NULL == geometryProcessor);
-    }
-
-    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
-                                                     int effectCnt,
-                                                     const GrGLProgramDesc::EffectKeyProvider&,
-                                                     GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
-
-    virtual void emitCodeAfterEffects() SK_OVERRIDE {}
+    virtual void createAndEmitEffects(const GrEffectStage* geometryProcessor,
+                                      const GrEffectStage* colorStages[],
+                                      const GrEffectStage* coverageStages[],
+                                      GrGLSLExpr4* inputColor,
+                                      GrGLSLExpr4* inputCoverage) SK_OVERRIDE;
+
+    GrGLProgramEffects* onCreateAndEmitEffects(const GrEffectStage* effectStages[],
+                                               int effectCnt,
+                                               const GrGLProgramDesc::EffectKeyProvider&,
+                                                   GrGLSLExpr4* inOutFSColor);
+
+    virtual void emitEffect(const GrEffectStage& stage,
+                            const GrEffectKey& key,
+                            const char* outColor,
+                            const char* inColor,
+                            int stageIndex) SK_OVERRIDE;
+
+    /**
+     * Helper for emitEffect(). Allocates texture units from the builder for each transform in an
+     * effect. The transforms all use adjacent texture units. They either use two or three of the
+     * coordinates at a given texture unit, depending on if they need perspective interpolation.
+     * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
+     * types are appended to the TransformedCoordsArray* object, which is in turn passed to the
+     * effect's emitCode() function.
+     */
+    void setupPathTexGen(const GrEffectStage&, GrGLEffect::TransformedCoordsArray*);
+
+    virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); }
+
+    typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
+
+    SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
 
     typedef GrGLProgramBuilder INHERITED;
 };
index 6c92684..182ebfb 100644 (file)
@@ -120,8 +120,8 @@ bool GrGLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
 }
 
 SkString GrGLFragmentShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) {
-    if (kVec3f_GrSLType != coords[index].type()) {
-        SkASSERT(kVec2f_GrSLType == coords[index].type());
+    if (kVec3f_GrSLType != coords[index].getType()) {
+        SkASSERT(kVec2f_GrSLType == coords[index].getType());
         return coords[index].getName();
     }
 
index 8a791c0..dd6409e 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "GrGLFullProgramBuilder.h"
+#include "../GrGLGeometryProcessor.h"
 #include "../GrGpuGL.h"
 
 GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu,
@@ -15,25 +16,43 @@ GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu,
     , fVS(this) {
 }
 
-void GrGLFullProgramBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color,
-                                                   GrGLSLExpr4* coverage) {
-    fVS.emitCodeBeforeEffects(color, coverage);
-}
+void
+GrGLFullProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProcessor,
+                                             const GrEffectStage* colorStages[],
+                                             const GrEffectStage* coverageStages[],
+                                             GrGLSLExpr4* inputColor,
+                                             GrGLSLExpr4* inputCoverage) {
+    fVS.emitCodeBeforeEffects(inputColor, inputCoverage);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // emit the per-effect code for both color and coverage effects
+
+    bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords();
+    EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
+    fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
+                                                     this->desc().numColorEffects(),
+                                                     colorKeyProvider,
+                                                     inputColor));
 
-void GrGLFullProgramBuilder::emitGeometryProcessor(const GrEffectStage* geometryProcessor,
-                                                   GrGLSLExpr4* coverage) {
     if (geometryProcessor) {
-        GrGLProgramDesc::EffectKeyProvider geometryProcessorKeyProvider(
-                &this->desc(), GrGLProgramDesc::EffectKeyProvider::kGeometryProcessor_EffectType);
-        fGeometryProcessor.reset(this->createAndEmitEffect(
-                                 geometryProcessor,
-                                 geometryProcessorKeyProvider,
-                                 coverage));
+        GrGLSLExpr4 gpInputCoverage = *inputCoverage;
+        GrGLSLExpr4 gpOutputCoverage;
+        EffectKeyProvider gpKeyProvider(&this->desc(),
+                EffectKeyProvider::kGeometryProcessor_EffectType);
+        fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalCoords)));
+        this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInputCoverage,
+                                    &gpOutputCoverage);
+        fGeometryProcessor.reset(fProgramEffects.detach());
+        *inputCoverage = gpOutputCoverage;
     }
-}
 
-void GrGLFullProgramBuilder::emitCodeAfterEffects() {
-    fVS.emitCodeAfterEffects();
+    EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
+    fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
+                                                        this->desc().numCoverageEffects(),
+                                                        coverageKeyProvider,
+                                                        inputCoverage));
+
+     fVS.emitCodeAfterEffects();
 }
 
 void GrGLFullProgramBuilder::addVarying(GrSLType type,
@@ -66,70 +85,123 @@ GrGLFullProgramBuilder::addSeparableVarying(GrSLType type,
     return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos.count() - 1);
 }
 
-
-GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffects(
+GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects(
         const GrEffectStage* effectStages[],
         int effectCnt,
         const GrGLProgramDesc::EffectKeyProvider& keyProvider,
         GrGLSLExpr4* inOutFSColor) {
-
-    GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
-    this->INHERITED::createAndEmitEffects(&programEffectsBuilder,
-                                          effectStages,
+    fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects,
+                                 (effectCnt,
+                                  this->getVertexShaderBuilder()->hasExplicitLocalCoords())));
+    this->INHERITED::createAndEmitEffects(effectStages,
                                           effectCnt,
                                           keyProvider,
                                           inOutFSColor);
-    return programEffectsBuilder.finish();
+    return fProgramEffects.detach();
 }
 
-void GrGLFullProgramBuilder::createAndEmitEffect(GrGLProgramEffectsBuilder* programEffectsBuilder,
-                                              const GrEffectStage* effectStages,
-                                              const GrGLProgramDesc::EffectKeyProvider& keyProvider,
-                                              GrGLSLExpr4* fsInOutColor) {
-    GrGLSLExpr4 inColor = *fsInOutColor;
-    GrGLSLExpr4 outColor;
-
-    SkASSERT(effectStages && effectStages->getEffect());
-    const GrEffectStage& stage = *effectStages;
+void GrGLFullProgramBuilder::emitEffect(const GrEffectStage& stage,
+                                                 const GrEffectKey& key,
+                                                 const char* outColor,
+                                                 const char* inColor,
+                                                 int stageIndex) {
+    SkASSERT(fProgramEffects.get());
+    const GrEffect& effect = *stage.getEffect();
+    SkSTArray<2, GrGLEffect::TransformedCoords> coords(effect.numTransforms());
+    SkSTArray<4, GrGLEffect::TextureSampler> samplers(effect.numTextures());
+
+    fVS.emitAttributes(stage);
+    this->emitTransforms(stage, &coords);
+    this->emitSamplers(effect, &samplers);
+
+    GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);
+    fProgramEffects->addEffect(glEffect);
+
+    // Enclose custom code in a block to avoid namespace conflicts
+    SkString openBrace;
+    openBrace.printf("{ // Stage %d: %s\n", stageIndex, glEffect->name());
+    fFS.codeAppend(openBrace.c_str());
+    fVS.codeAppend(openBrace.c_str());
+
+    if (glEffect->isVertexEffect()) {
+        GrGLGeometryProcessor* vertexEffect = static_cast<GrGLGeometryProcessor*>(glEffect);
+        vertexEffect->emitCode(this, effect, key, outColor, inColor, coords, samplers);
+    } else {
+        glEffect->emitCode(this, effect, key, outColor, inColor, coords, samplers);
+    }
 
-    // Using scope to force ASR destructor to be triggered
-    {
-        CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
+    fVS.codeAppend("\t}\n");
+    fFS.codeAppend("\t}\n");
+}
 
-        if (inColor.isZeros()) {
-            SkString inColorName;
+void GrGLFullProgramBuilder::emitTransforms(const GrEffectStage& effectStage,
+                                            GrGLEffect::TransformedCoordsArray* outCoords) {
+    SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms =
+            fProgramEffects->addTransforms();
+    const GrEffect* effect = effectStage.getEffect();
+    int numTransforms = effect->numTransforms();
+    transforms.push_back_n(numTransforms);
+
+    SkTArray<GrGLVertexProgramEffects::PathTransform, true>* pathTransforms = NULL;
+    const GrGLCaps* glCaps = this->ctxInfo().caps();
+    if (glCaps->pathRenderingSupport() &&
+        this->gpu()->glPathRendering()->texturingMode() ==
+           GrGLPathRendering::SeparableShaders_TexturingMode) {
+        pathTransforms = &fProgramEffects->addPathTransforms();
+        pathTransforms->push_back_n(numTransforms);
+    }
 
-            // Effects have no way to communicate zeros, they treat an empty string as ones.
-            this->nameVariable(&inColorName, '\0', "input");
-            fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str());
-            inColor = inColorName;
+    for (int t = 0; t < numTransforms; t++) {
+        const char* uniName = "StageMatrix";
+        GrSLType varyingType =
+                effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
+                        kVec3f_GrSLType :
+                        kVec2f_GrSLType;
+
+        SkString suffixedUniName;
+        if (0 != t) {
+            suffixedUniName.append(uniName);
+            suffixedUniName.appendf("_%i", t);
+            uniName = suffixedUniName.c_str();
+        }
+        transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                                                 kMat33f_GrSLType,
+                                                 uniName,
+                                                 &uniName);
+
+        const char* varyingName = "MatrixCoord";
+        SkString suffixedVaryingName;
+        if (0 != t) {
+            suffixedVaryingName.append(varyingName);
+            suffixedVaryingName.appendf("_%i", t);
+            varyingName = suffixedVaryingName.c_str();
+        }
+        const char* vsVaryingName;
+        const char* fsVaryingName;
+        if (pathTransforms) {
+            (*pathTransforms)[t].fHandle =
+                this->addSeparableVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+            (*pathTransforms)[t].fType = varyingType;
+        } else {
+            this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
         }
 
-        // create var to hold stage result
-        SkString outColorName;
-        this->nameVariable(&outColorName, '\0', "output");
-        fFS.codeAppendf("vec4 %s;", outColorName.c_str());
-        outColor = outColorName;
-
-
-        programEffectsBuilder->emitEffect(stage,
-                                          keyProvider.get(0),
-                                          outColor.c_str(),
-                                          inColor.isOnes() ? NULL : inColor.c_str(),
-                                          fCodeStage.stageIndex());
+        const GrGLShaderVar& coords =
+                kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
+                                          fVS.positionAttribute() :
+                                          fVS.localCoordsAttribute();
+        // varying = matrix * coords (logically)
+        SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+        if (kVec2f_GrSLType == varyingType) {
+            fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+                            vsVaryingName, uniName, coords.c_str());
+        } else {
+            fVS.codeAppendf("%s = %s * vec3(%s, 1);",
+                            vsVaryingName, uniName, coords.c_str());
+        }
+        SkNEW_APPEND_TO_TARRAY(outCoords, GrGLEffect::TransformedCoords,
+                               (SkString(fsVaryingName), varyingType));
     }
-
-    *fsInOutColor = outColor;
-}
-
-GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffect(
-        const GrEffectStage* geometryProcessor,
-        const GrGLProgramDesc::EffectKeyProvider& keyProvider,
-        GrGLSLExpr4* inOutFSColor) {
-
-    GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, 1);
-    this->createAndEmitEffect(&programEffectsBuilder, geometryProcessor, keyProvider, inOutFSColor);
-    return programEffectsBuilder.finish();
 }
 
 bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId,
index 3ba5724..7480ff3 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "GrGLProgramBuilder.h"
 
+class GrGLVertexProgramEffects;
+
 class GrGLFullProgramBuilder : public GrGLProgramBuilder {
 public:
     GrGLFullProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
@@ -37,39 +39,45 @@ public:
     GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; }
 
 private:
-    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color,
-                                       GrGLSLExpr4* coverage) SK_OVERRIDE;
-
-    virtual void emitGeometryProcessor(const GrEffectStage* geometryProcessor,
-                                       GrGLSLExpr4* coverage) SK_OVERRIDE;
-
-    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
-                                                     int effectCnt,
-                                                     const GrGLProgramDesc::EffectKeyProvider&,
-                                                     GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
-
-    /*
-     * These functions are temporary and will eventually operate not on effects but on
-     * geometry processors
+    virtual void createAndEmitEffects(const GrEffectStage* geometryProcessor,
+                                      const GrEffectStage* colorStages[],
+                                      const GrEffectStage* coverageStages[],
+                                      GrGLSLExpr4* inputColor,
+                                      GrGLSLExpr4* inputCoverage) SK_OVERRIDE;
+
+    GrGLProgramEffects* onCreateAndEmitEffects(const GrEffectStage* effectStages[],
+                                               int effectCnt,
+                                               const GrGLProgramDesc::EffectKeyProvider&,
+                                               GrGLSLExpr4* inOutFSColor);
+
+    virtual void emitEffect(const GrEffectStage& stage,
+                            const GrEffectKey& key,
+                            const char* outColor,
+                            const char* inColor,
+                            int stageIndex) SK_OVERRIDE;
+
+    /**
+     * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
+     * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
+     * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
+     * of the varyings in the VS and FS as well their types are appended to the
+     * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
      */
-    void createAndEmitEffect(GrGLProgramEffectsBuilder*,
-                             const GrEffectStage* effectStage,
-                             const GrGLProgramDesc::EffectKeyProvider&,
-                             GrGLSLExpr4* inOutFSColor);
-
-    GrGLProgramEffects* createAndEmitEffect(const GrEffectStage* geometryProcessor,
-                                            const GrGLProgramDesc::EffectKeyProvider&,
-                                            GrGLSLExpr4* inOutFSColor);
-
-    virtual void emitCodeAfterEffects() SK_OVERRIDE;
+    void emitTransforms(const GrEffectStage& effectStage,
+                        GrGLEffect::TransformedCoordsArray* outCoords);
 
     virtual bool compileAndAttachShaders(GrGLuint programId,
                                          SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
 
     virtual void bindProgramLocations(GrGLuint programId) SK_OVERRIDE;
 
+    virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); }
+
+    typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
+
     GrGLGeometryShaderBuilder fGS;
     GrGLVertexShaderBuilder   fVS;
+    SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
 
     typedef GrGLProgramBuilder INHERITED;
 };
index d306776..a0dd555 100644 (file)
@@ -67,28 +67,9 @@ bool GrGLProgramBuilder::genProgram(const GrEffectStage* geometryProcessor,
         inputCoverage = GrGLSLExpr4(1);
     }
 
-    this->emitCodeBeforeEffects(&inputColor, &inputCoverage);
-
-    ///////////////////////////////////////////////////////////////////////////
-    // emit the per-effect code for both color and coverage effects
-
-    GrGLProgramDesc::EffectKeyProvider colorKeyProvider(
-        &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType);
-    fColorEffects.reset(this->createAndEmitEffects(colorStages,
-                                                   this->desc().numColorEffects(),
-                                                   colorKeyProvider,
-                                                   &inputColor));
-
-    this->emitGeometryProcessor(geometryProcessor, &inputCoverage);
-
-    GrGLProgramDesc::EffectKeyProvider coverageKeyProvider(
-        &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType);
-    fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
-                                                      this->desc().numCoverageEffects(),
-                                                      coverageKeyProvider,
-                                                      &inputCoverage));
-
-    this->emitCodeAfterEffects();
+    // Subclasses drive effect emitting
+    this->createAndEmitEffects(geometryProcessor, colorStages, coverageStages, &inputColor,
+                               &inputCoverage);
 
     fFS.emitCodeAfterEffects(inputColor, inputCoverage);
 
@@ -178,8 +159,7 @@ void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
     }
 }
 
-void GrGLProgramBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder,
-                                              const GrEffectStage* effectStages[],
+void GrGLProgramBuilder::createAndEmitEffects(const GrEffectStage* effectStages[],
                                               int effectCnt,
                                               const GrGLProgramDesc::EffectKeyProvider& keyProvider,
                                               GrGLSLExpr4* fsInOutColor) {
@@ -189,39 +169,59 @@ void GrGLProgramBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* program
     GrGLSLExpr4 outColor;
 
     for (int e = 0; e < effectCnt; ++e) {
-        SkASSERT(effectStages[e] && effectStages[e]->getEffect());
-        const GrEffectStage& stage = *effectStages[e];
-
-        CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
-
-        if (inColor.isZeros()) {
-            SkString inColorName;
+        // calls into the subclass to emit the actual effect into the program effect object
+        this->emitEffect(*effectStages[e], e, keyProvider, &inColor, &outColor);
+        effectEmitted = true;
+    }
 
-            // Effects have no way to communicate zeros, they treat an empty string as ones.
-            this->nameVariable(&inColorName, '\0', "input");
-            fFS.codeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str());
-            inColor = inColorName;
-        }
+    if (effectEmitted) {
+        *fsInOutColor = outColor;
+    }
+}
 
-        // create var to hold stage result
-        SkString outColorName;
-        this->nameVariable(&outColorName, '\0', "output");
-        fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
-        outColor = outColorName;
+void GrGLProgramBuilder::emitEffect(const GrEffectStage& effectStage,
+                                    int effectIndex,
+                                    const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+                                    GrGLSLExpr4* inColor,
+                                    GrGLSLExpr4* outColor) {
+    SkASSERT(effectStage.getEffect());
+    CodeStage::AutoStageRestore csar(&fCodeStage, &effectStage);
+
+    if (inColor->isZeros()) {
+        SkString inColorName;
+
+        // Effects have no way to communicate zeros, they treat an empty string as ones.
+        this->nameVariable(&inColorName, '\0', "input");
+        fFS.codeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor->c_str());
+        *inColor = inColorName;
+    }
 
+    // create var to hold stage result
+    SkString outColorName;
+    this->nameVariable(&outColorName, '\0', "output");
+    fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
+    *outColor = outColorName;
 
-        programEffectsBuilder->emitEffect(stage,
-                                          keyProvider.get(e),
-                                          outColor.c_str(),
-                                          inColor.isOnes() ? NULL : inColor.c_str(),
-                                          fCodeStage.stageIndex());
+    this->emitEffect(effectStage, keyProvider.get(effectIndex), outColor->c_str(),
+                     inColor->isOnes() ? NULL : inColor->c_str(), fCodeStage.stageIndex());
 
-        inColor = outColor;
-        effectEmitted = true;
-    }
+    *inColor = *outColor;
+}
 
-    if (effectEmitted) {
-        *fsInOutColor = outColor;
+void GrGLProgramBuilder::emitSamplers(const GrEffect& effect,
+                                      GrGLEffect::TextureSamplerArray* outSamplers) {
+    SkTArray<GrGLProgramEffects::Sampler, true>& samplers =
+            this->getProgramEffects()->addSamplers();
+    int numTextures = effect.numTextures();
+    samplers.push_back_n(numTextures);
+    SkString name;
+    for (int t = 0; t < numTextures; ++t) {
+        name.printf("Sampler%d", t);
+        samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                                kSampler2D_GrSLType,
+                                                name.c_str());
+        SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLEffect::TextureSampler,
+                               (samplers[t].fUniform, effect.textureAccess(t)));
     }
 }
 
index 9915ad3..9f8defb 100644 (file)
@@ -149,12 +149,28 @@ protected:
     const GrGLProgramDesc& desc() const { return fDesc; }
 
     // Helper for emitEffects().
-    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
-                              const GrEffectStage* effectStages[],
+    void createAndEmitEffects(const GrEffectStage* effectStages[],
                               int effectCnt,
                               const GrGLProgramDesc::EffectKeyProvider&,
                               GrGLSLExpr4* inOutFSColor);
 
+    /*
+     * A helper function called to emit the geometry processor as well as individual coverage
+     * and color stages.  this will call into subclasses emit effect
+     */
+    void emitEffect(const GrEffectStage& effectStage,
+                    int effectIndex,
+                    const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+                    GrGLSLExpr4* inColor,
+                    GrGLSLExpr4* outColor);
+
+    /**
+     * Helper for emitEffect() in subclasses. Emits uniforms for an effect's texture accesses and
+     * appends the necessary data to the TextureSamplerArray* object so effects can add texture
+     * lookups to their code. This method is only meant to be called during the construction phase.
+     */
+    void emitSamplers(const GrEffect& effect, GrGLEffect::TextureSamplerArray* outSamplers);
+
     // Generates a name for a variable. The generated string will be name prefixed by the prefix
     // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
     // generating stage code.
@@ -168,16 +184,6 @@ protected:
     void appendDecls(const VarArray&, SkString*) const;
     void appendUniformDecls(ShaderVisibility, SkString*) const;
 
-    SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor;
-    SkAutoTUnref<GrGLProgramEffects> fColorEffects;
-    SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
-    BuiltinUniformHandles            fUniformHandles;
-    bool                             fFragOnly;
-    int                              fTexCoordSetCnt;
-    GrGLuint                         fProgramID;
-    GrGLFragmentShaderBuilder        fFS;
-    SeparableVaryingInfoArray        fSeparableVaryingInfos;
-
     class CodeStage : SkNoncopyable {
     public:
         CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
@@ -227,43 +233,39 @@ protected:
         int                     fNextIndex;
         int                     fCurrentIndex;
         const GrEffectStage*    fEffectStage;
-    } fCodeStage;
-
-private:
+    };
 
-    /**
-     * The base class will emit the fragment code that precedes the per-effect code and then call
-     * this function. The subclass can use it to insert additional fragment code that should
-     * execute before the effects' code and/or emit other shaders (e.g. geometry, vertex).
-     *
-     * The subclass can modify the initial color or coverage 
-     */
-    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color,
-                                       GrGLSLExpr4* coverage) = 0;
+    CodeStage                        fCodeStage;
+    SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor;
+    SkAutoTUnref<GrGLProgramEffects> fColorEffects;
+    SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
+    BuiltinUniformHandles            fUniformHandles;
+    bool                             fFragOnly;
+    int                              fTexCoordSetCnt;
+    GrGLuint                         fProgramID;
+    GrGLFragmentShaderBuilder        fFS;
+    SeparableVaryingInfoArray        fSeparableVaryingInfos;
 
+private:
+    virtual void createAndEmitEffects(const GrEffectStage* geometryProcessor,
+                                      const GrEffectStage* colorStages[],
+                                      const GrEffectStage* coverageStages[],
+                                      GrGLSLExpr4* inputColor,
+                                      GrGLSLExpr4* inputCoverage) = 0;
     /*
-     * Full shader builder needs to emit code after the color stages and before the coverage stages
+     * Subclasses override emitEffect below to emit data and code for a specific single effect
      */
-    virtual void emitGeometryProcessor(const GrEffectStage* geometryProcessor,
-                                       GrGLSLExpr4* coverage) = 0;
+    virtual void emitEffect(const GrEffectStage&,
+                            const GrEffectKey&,
+                            const char* outColor,
+                            const char* inColor,
+                            int stageIndex) = 0;
 
-    /**
-    * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
-    * deleting it when finished. effectStages contains the effects to add. The effect key provider 
-    * is used to communicate the key each effect created in its GenKey function. inOutFSColor
-    * specifies the input color to the first stage and is updated to be the output color of the
-    * last stage. The handles to texture samplers for effectStage[i] are added to
-    * effectSamplerHandles[i].
-    */
-    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
-                                                     int effectCnt,
-                                                     const GrGLProgramDesc::EffectKeyProvider&,
-                                                     GrGLSLExpr4* inOutFSColor) = 0;
-
-    /**
-     * Similar to emitCodeBeforeEffects() but called after per-effect code is emitted.
+    /*
+     * Because we have fragment only builders, and those builders need to implement a subclass
+     * of program effects, we have to have base classes overload the program effects here
      */
-    virtual void emitCodeAfterEffects() = 0;
+    virtual GrGLProgramEffects* getProgramEffects() = 0;
 
     /**
      * Compiles all the shaders, links them into a program, and writes the program id to the output
index 004e09b..33474e6 100644 (file)
@@ -97,7 +97,7 @@ void GrGLShaderBuilder::appendTextureLookup(SkString* out,
                                             GrSLType varyingType) const {
     append_texture_lookup(out,
                           fProgramBuilder->gpu(),
-                          fProgramBuilder->getUniformCStr(sampler.samplerUniform()),
+                          fProgramBuilder->getUniformCStr(sampler.fSamplerUniform),
                           coordName,
                           sampler.configComponentMask(),
                           sampler.swizzle(),
index 3abd0c0..45d3d1e 100644 (file)
@@ -30,8 +30,8 @@ class GrGLFullProgramBuilder;
 */
 class GrGLShaderBuilder {
 public:
-    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-    typedef GrGLProgramEffects::TextureSampler TextureSampler;
+    typedef GrGLEffect::TransformedCoordsArray TransformedCoordsArray;
+    typedef GrGLEffect::TextureSampler TextureSampler;
     GrGLShaderBuilder(GrGLProgramBuilder* program);
 
     void addInput(GrGLShaderVar i) { fInputs.push_back(i); }
index 7445676..9e666ad 100644 (file)
@@ -118,9 +118,9 @@ bool GrGLVertexShaderBuilder::compileAndAttachShaders(GrGLuint programId,
     fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &vertShaderSrc);
     fProgramBuilder->appendDecls(fInputs, &vertShaderSrc);
     fProgramBuilder->appendDecls(fOutputs, &vertShaderSrc);
-    vertShaderSrc.append("void main() {\n");
+    vertShaderSrc.append("void main() {");
     vertShaderSrc.append(fCode);
-    vertShaderSrc.append("}\n");
+    vertShaderSrc.append("}");
     GrGLuint vertShaderId = GrGLCompileAndAttachShader(glCtx, programId,
             GR_GL_VERTEX_SHADER, vertShaderSrc);
     if (!vertShaderId) {
@@ -140,7 +140,7 @@ void GrGLVertexShaderBuilder::emitCodeAfterEffects() {
 
     // Transform from Skia's device coords to GL's normalized device coords.
     this->codeAppendf(
-        "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n",
+        "gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
         rtAdjustName, rtAdjustName);
 }
 
@@ -148,12 +148,12 @@ void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLEx
     const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
 
     fPositionVar = &fInputs.push_back();
-    fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
+    fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "inPosition");
     if (-1 != header.fLocalCoordAttributeIndex) {
         fLocalCoordsVar = &fInputs.push_back();
         fLocalCoordsVar->set(kVec2f_GrSLType,
                              GrGLShaderVar::kAttribute_TypeModifier,
-                             "aLocalCoords");
+                             "inLocalCoords");
     } else {
         fLocalCoordsVar = fPositionVar;
     }
@@ -166,7 +166,7 @@ void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLEx
                                  &viewMName);
 
     // Transform the position into Skia's device coords.
-    this->codeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n",
+    this->codeAppendf("vec3 pos3 = %s * vec3(%s, 1);",
                       viewMName, fPositionVar->c_str());
 
     // we output point size in the GS if present
@@ -175,7 +175,7 @@ void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLEx
         && !header.fExperimentalGS
 #endif
         ) {
-        this->codeAppend("\tgl_PointSize = 1.0;\n");
+        this->codeAppend("gl_PointSize = 1.0;");
     }
 
     if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
@@ -184,7 +184,7 @@ void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLEx
                                        GrShaderVar::kAttribute_TypeModifier));
         const char *vsName, *fsName;
         fFullProgramBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
-        this->codeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
+        this->codeAppendf("%s = %s;", vsName, color_attribute_name());
         *color = fsName;
     }
 
@@ -194,7 +194,7 @@ void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLEx
                                        GrShaderVar::kAttribute_TypeModifier));
         const char *vsName, *fsName;
         fFullProgramBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
-        this->codeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
+        this->codeAppendf("%s = %s;", vsName, coverage_attribute_name());
         *coverage = fsName;
     }
     fEffectAttribOffset = fInputs.count();