Attempt to reland 8264-5 with warning-as-error fixes.
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 20 Mar 2013 19:19:53 +0000 (19:19 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 20 Mar 2013 19:19:53 +0000 (19:19 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@8272 2bbb7eff-a529-9590-31e7-b0007b416f81

53 files changed:
include/core/SkTLazy.h
include/gpu/GrBackendEffectFactory.h
include/gpu/GrContext.h
include/gpu/GrDrawEffect.h [new file with mode: 0644]
include/gpu/GrEffect.h
include/gpu/GrEffectStage.h
include/gpu/GrPaint.h
include/gpu/GrTBackendEffectFactory.h
src/effects/SkBicubicImageFilter.cpp
src/effects/SkBlendImageFilter.cpp
src/effects/SkColorMatrixFilter.cpp
src/effects/SkDisplacementMapEffect.cpp
src/effects/SkLightingImageFilter.cpp
src/effects/SkMagnifierImageFilter.cpp
src/effects/SkMatrixConvolutionImageFilter.cpp
src/effects/SkMorphologyImageFilter.cpp
src/effects/SkTableColorFilter.cpp
src/effects/gradients/SkGradientShader.cpp
src/effects/gradients/SkGradientShaderPriv.h
src/effects/gradients/SkLinearGradient.cpp
src/effects/gradients/SkRadialGradient.cpp
src/effects/gradients/SkSweepGradient.cpp
src/effects/gradients/SkTwoPointConicalGradient.cpp
src/effects/gradients/SkTwoPointRadialGradient.cpp
src/gpu/GrClipMaskManager.cpp
src/gpu/GrContext.cpp
src/gpu/GrDrawState.cpp
src/gpu/GrDrawState.h
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h
src/gpu/GrSWMaskHelper.cpp
src/gpu/GrTextContext.cpp
src/gpu/effects/GrCircleEdgeEffect.cpp
src/gpu/effects/GrConfigConversionEffect.cpp
src/gpu/effects/GrConvolutionEffect.cpp
src/gpu/effects/GrEllipseEdgeEffect.cpp
src/gpu/effects/GrSimpleTextureEffect.cpp
src/gpu/effects/GrSimpleTextureEffect.h
src/gpu/effects/GrSingleTextureEffect.cpp
src/gpu/effects/GrSingleTextureEffect.h
src/gpu/effects/GrTextureDomainEffect.cpp
src/gpu/effects/GrTextureDomainEffect.h
src/gpu/gl/GrGLEffect.cpp
src/gpu/gl/GrGLEffect.h
src/gpu/gl/GrGLEffectMatrix.cpp
src/gpu/gl/GrGLEffectMatrix.h
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGLShaderBuilder.cpp
src/gpu/gl/GrGLShaderBuilder.h
tests/GLProgramsTest.cpp

index b9052f0d99736c9e861dfc7e8038e2b37dace689..1934b5dff9fa115349b6e5f505d02629f2346d2e 100644 (file)
@@ -14,6 +14,9 @@
 #include "SkTypes.h"
 #include <new>
 
+template <typename T> class SkTLazy;
+template <typename T> void* operator new(size_t, SkTLazy<T>* lazy);
+
 /**
  *  Efficient way to defer allocating/initializing a class until it is needed
  *  (if ever).
@@ -44,7 +47,7 @@ public:
 
     /**
      *  Return a pointer to a default-initialized instance of the class. If a
-     *  previous instance had been initialzied (either from init() or set()) it
+     *  previous instance had been initialized (either from init() or set()) it
      *  will first be destroyed, so that a freshly initialized instance is
      *  always returned.
      */
@@ -84,10 +87,27 @@ public:
     T* get() const { SkASSERT(this->isValid()); return fPtr; }
 
 private:
+    friend void* operator new<T>(size_t, SkTLazy* lazy);
+
     T*   fPtr; // NULL or fStorage
     char fStorage[sizeof(T)];
 };
 
+// Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly
+template <typename T> void* operator new(size_t, SkTLazy<T>* lazy) {
+    SkASSERT(!lazy->isValid());
+    lazy->fPtr = reinterpret_cast<T*>(lazy->fStorage);
+    return lazy->fPtr;
+}
+
+// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
+// to match the op new silences warnings about missing op delete when a constructor throws an
+// exception.
+template <typename T> void operator delete(void*, SkTLazy<T>) { SK_CRASH(); }
+
+// Use this to construct a T inside an SkTLazy using a non-default constructor.
+#define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args)
+
 /**
  * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized
  * with a const pointer but provides a non-const pointer accessor. The first time the
index 99d6a73a25c7b68cf06d65cf76976aaddd0a09ad..da296c94690a7986a272a1c9444fb2352678f8de 100644 (file)
  */
 
 class GrEffectRef;
-class GrEffectStage;
 class GrGLEffect;
 class GrGLCaps;
+class GrDrawEffect;
 
 class GrBackendEffectFactory : public GrNoncopyable {
 public:
     typedef uint32_t EffectKey;
     enum {
         kNoEffectKey = 0,
-        kEffectKeyBits = 12,
+        kEffectKeyBits = 16,
         /**
          * Some aspects of the generated code may be determined by the particular textures that are
          * associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond
@@ -44,8 +44,8 @@ public:
         kAttribKeyBits = 6
     };
 
-    virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
-    virtual GrGLEffect* createGLInstance(const GrEffectRef&) const = 0;
+    virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
+    virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0;
 
     bool operator ==(const GrBackendEffectFactory& b) const {
         return fEffectClassID == b.fEffectClassID;
index 79edd0b11bcde928b9733db58cfb87929bfa94f0..2d5766056b2a187973b35fe1c29899c5b5f84ec6 100644 (file)
@@ -390,25 +390,23 @@ public:
                   const SkMatrix* matrix = NULL);
 
     /**
-     * Maps a rect of paint coordinates onto the a rect of destination
-     * coordinates. Each rect can optionally be transformed. The srcRect
+     * Maps a rect of local coordinates onto the a rect of destination
+     * coordinates. Each rect can optionally be transformed. The localRect
      * is stretched over the dstRect. The dstRect is transformed by the
-     * context's matrix and the srcRect is transformed by the paint's matrix.
-     * Additional optional matrices can be provided by parameters.
+     * context's matrix. Additional optional matrices for both rects can be
+     * provided by parameters.
      *
-     * @param paint     describes how to color pixels.
-     * @param dstRect   the destination rect to draw.
-     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
-     * @param dstMatrix Optional matrix to transform dstRect. Applied before
-     *                  context's matrix.
-     * @param srcMatrix Optional matrix to transform srcRect Applied before
-     *                  paint's matrix.
+     * @param paint         describes how to color pixels.
+     * @param dstRect       the destination rect to draw.
+     * @param localRect     rect of local coordinates to be mapped onto dstRect
+     * @param dstMatrix     Optional matrix to transform dstRect. Applied before context's matrix.
+     * @param localMatrix   Optional matrix to transform localRect.
      */
     void drawRectToRect(const GrPaint& paint,
                         const GrRect& dstRect,
-                        const GrRect& srcRect,
+                        const GrRect& localRect,
                         const SkMatrix* dstMatrix = NULL,
-                        const SkMatrix* srcMatrix = NULL);
+                        const SkMatrix* localMatrix = NULL);
 
     /**
      * Draws a path.
@@ -699,7 +697,7 @@ public:
             this->restore();
 
             if (NULL != paint) {
-                if (!paint->sourceCoordChangeByInverse(context->getMatrix())) {
+                if (!paint->localCoordChangeInverse(context->getMatrix())) {
                     return false;
                 }
             }
@@ -737,7 +735,7 @@ public:
          */
         void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
             if (NULL != paint) {
-                paint->sourceCoordChange(preConcat);
+                paint->localCoordChange(preConcat);
             }
             fContext->concatMatrix(preConcat);
         }
diff --git a/include/gpu/GrDrawEffect.h b/include/gpu/GrDrawEffect.h
new file mode 100644 (file)
index 0000000..005de41
--- /dev/null
@@ -0,0 +1,51 @@
+
+#ifndef GrDrawEffect_DEFINED
+#define GrDrawEffect_DEFINED
+
+#include "GrEffectStage.h"
+
+/**
+ * This class is used to communicate the particular GrEffect used in a draw to the backend-specific
+ * effect subclass (e.g. GrGLEffect). It is used to by the backend-specific class to generate a
+ * cache key for the effect, generate code on a program cache miss, and to upload uniform values to
+ * the program.
+ * In addition to the effect, it also communicates any changes between the relationship between
+ * the view matrix and local coordinate system since the effect was installed in its GrDrawState.
+ * The typical use case is that sometime after an effect was installed a decision was made to draw
+ * in device coordinates (i.e. use an identity view-matrix). In such a case the GrDrawEffect's
+ * coord-change-matrix would be the inverse of the view matrix that was set when the effect was
+ * installed. GrGLEffectMatrix is a handy class that implements a local coordinate matrix that
+ * automatically accounts for the coord-change matrix.
+ */
+class GrDrawEffect {
+public:
+    GrDrawEffect(const GrEffectStage& stage, bool explicitLocalCoords)
+        : fEffectStage(&stage)
+        , fExplicitLocalCoords(explicitLocalCoords) {
+        GrAssert(NULL != fEffectStage);
+        GrAssert(NULL != fEffectStage->getEffect());
+    }
+    const GrEffectRef* effect() const { return fEffectStage->getEffect(); }
+
+    template <typename T>
+    const T& castEffect() const { return *static_cast<const T*>(this->effect()->get()); }
+
+    const SkMatrix& getCoordChangeMatrix() const {
+        if (fExplicitLocalCoords) {
+            return SkMatrix::I();
+        } else {
+            return fEffectStage->getCoordChangeMatrix();
+        }
+    }
+
+    bool programHasExplicitLocalCoords() const { return fExplicitLocalCoords; }
+
+    const int* getVertexAttribIndices() const { return fEffectStage->getVertexAttribIndices(); }
+    int getVertexAttribIndexCount() const { return fEffectStage->getVertexAttribIndexCount(); }
+
+private:
+    const GrEffectStage*    fEffectStage;
+    bool                    fExplicitLocalCoords;
+};
+
+#endif
index 1b2604114d62518d3f92382e008c00ec303b976a..883438603d7a72909d5956aa146e321632fdf2bb 100644 (file)
@@ -70,6 +70,20 @@ class GrEffect : private GrRefCnt {
 public:
     SK_DECLARE_INST_COUNT(GrEffect)
 
+    /**
+     * The types of vertex coordinates available to an effect in the vertex shader. Effects can
+     * require their own vertex attribute but these coordinates are made available by the framework
+     * in all programs. kCustom_CoordsType is provided to signify that an alternative set of coords
+     * is used (usually an explicit vertex attribute) but its meaning is determined by the effect
+     * subclass.
+     */
+    enum CoordsType {
+        kLocal_CoordsType,
+        kPosition_CoordsType,
+
+        kCustom_CoordsType,
+    };
+
     virtual ~GrEffect();
 
     /**
index f4e46b0dea866e0c2d6cdc6b07d1f9728613ff8e..94ff779a185e525ac2fcf5587308e8a47c764d89 100644 (file)
@@ -58,9 +58,10 @@ public:
     /**
      * This is called when the coordinate system in which the geometry is specified will change.
      *
-     * @param matrix    The transformation from the old coord system to the new one.
+     * @param matrix    The transformation from the old coord system in which geometry is specified
+     *                  to the new one from which it will actually be drawn.
      */
-    void preConcatCoordChange(const SkMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
+    void localCoordChange(const SkMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
 
     class SavedCoordChange {
     private:
@@ -72,7 +73,7 @@ public:
 
     /**
      * This gets the current coordinate system change. It is the accumulation of
-     * preConcatCoordChange calls since the effect was installed. It is used when then caller
+     * localCoordChange calls since the effect was installed. It is used when then caller
      * wants to temporarily change the source geometry coord system, draw something, and then
      * restore the previous coord system (e.g. temporarily draw in device coords).
      */
index 0fd42f9f7faa8766b0ab75959e957791e870e910..e0a9203a3761b6077dd86219be9b53e82b30b7ab 100644 (file)
@@ -169,54 +169,6 @@ public:
 
     bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
 
-    /**
-     * Called when the source coord system is changing. preConcatInverse is the inverse of the
-     * transformation from the old coord system to the new coord system. Returns false if the matrix
-     * cannot be inverted.
-     */
-    bool sourceCoordChangeByInverse(const SkMatrix& preConcatInverse) {
-        SkMatrix inv;
-        bool computed = false;
-        for (int i = 0; i < kMaxColorStages; ++i) {
-            if (this->isColorStageEnabled(i)) {
-                if (!computed && !preConcatInverse.invert(&inv)) {
-                    return false;
-                } else {
-                    computed = true;
-                }
-                fColorStages[i].preConcatCoordChange(inv);
-            }
-        }
-        for (int i = 0; i < kMaxCoverageStages; ++i) {
-            if (this->isCoverageStageEnabled(i)) {
-                if (!computed && !preConcatInverse.invert(&inv)) {
-                    return false;
-                } else {
-                    computed = true;
-                }
-                fCoverageStages[i].preConcatCoordChange(inv);
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Called when the source coord system is changing. preConcat gives the transformation from the
-     * old coord system to the new coord system.
-     */
-    void sourceCoordChange(const SkMatrix& preConcat) {
-        for (int i = 0; i < kMaxColorStages; ++i) {
-            if (this->isColorStageEnabled(i)) {
-                fColorStages[i].preConcatCoordChange(preConcat);
-            }
-        }
-        for (int i = 0; i < kMaxCoverageStages; ++i) {
-            if (this->isCoverageStageEnabled(i)) {
-                fCoverageStages[i].preConcatCoordChange(preConcat);
-            }
-        }
-    }
-
     GrPaint& operator=(const GrPaint& paint) {
         fSrcBlendCoeff = paint.fSrcBlendCoeff;
         fDstBlendCoeff = paint.fDstBlendCoeff;
@@ -264,6 +216,51 @@ public:
     };
 
 private:
+    /**
+     * Called when the source coord system from which geometry is rendered changes. It ensures that
+     * the local coordinates seen by effects remains unchanged. oldToNew gives the transformation
+     * from the previous coord system to the new coord system.
+     */
+    void localCoordChange(const SkMatrix& oldToNew) {
+        for (int i = 0; i < kMaxColorStages; ++i) {
+            if (this->isColorStageEnabled(i)) {
+                fColorStages[i].localCoordChange(oldToNew);
+            }
+        }
+        for (int i = 0; i < kMaxCoverageStages; ++i) {
+            if (this->isCoverageStageEnabled(i)) {
+                fCoverageStages[i].localCoordChange(oldToNew);
+            }
+        }
+    }
+
+    bool localCoordChangeInverse(const SkMatrix& newToOld) {
+        SkMatrix oldToNew;
+        bool computed = false;
+        for (int i = 0; i < kMaxColorStages; ++i) {
+            if (this->isColorStageEnabled(i)) {
+                if (!computed && !newToOld.invert(&oldToNew)) {
+                    return false;
+                } else {
+                    computed = true;
+                }
+                fColorStages[i].localCoordChange(oldToNew);
+            }
+        }
+        for (int i = 0; i < kMaxCoverageStages; ++i) {
+            if (this->isCoverageStageEnabled(i)) {
+                if (!computed && !newToOld.invert(&oldToNew)) {
+                    return false;
+                } else {
+                    computed = true;
+                }
+                fCoverageStages[i].localCoordChange(oldToNew);
+            }
+        }
+        return true;
+    }
+
+    friend class GrContext; // To access above two functions
 
     GrEffectStage               fColorStages[kMaxColorStages];
     GrEffectStage               fCoverageStages[kMaxCoverageStages];
index 1b6f8167bf94a6c0970e47ebe24d30b3287fc95b..8697f8eb7a57d1fb30c76a192a7616fdbd3689b3 100644 (file)
@@ -9,7 +9,7 @@
 #define GrTBackendEffectFactory_DEFINED
 
 #include "GrBackendEffectFactory.h"
-#include "GrEffectStage.h"
+#include "GrDrawEffect.h"
 
 /**
  * Implements GrBackendEffectFactory for a GrEffect subclass as a singleton.
@@ -30,12 +30,12 @@ public:
         id identifies the GrEffect subclass. The remainder is based
         on the aspects of the GrEffect object's configuration that affect
         GLSL code generation. */
-    virtual EffectKey glEffectKey(const GrEffectStage& stage,
+    virtual EffectKey glEffectKey(const GrDrawEffect& drawEffect,
                                   const GrGLCaps& caps) const SK_OVERRIDE {
         GrAssert(kIllegalEffectClassID != fEffectClassID);
-        EffectKey effectKey = GLEffect::GenKey(stage, caps);
-        EffectKey textureKey = GLEffect::GenTextureKey(stage.getEffect(), caps);
-        EffectKey attribKey = GLEffect::GenAttribKey(stage);
+        EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
+        EffectKey textureKey = GLEffect::GenTextureKey(drawEffect, caps);
+        EffectKey attribKey = GLEffect::GenAttribKey(drawEffect);
 #if GR_DEBUG
         static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
         GrAssert(!(kIllegalIDMask & effectKey));
@@ -53,8 +53,8 @@ public:
     /** Returns a new instance of the appropriate *GL* implementation class
         for the given GrEffect; caller is responsible for deleting
         the object. */
-    virtual GLEffect* createGLInstance(const GrEffectRef& effect) const SK_OVERRIDE {
-        return SkNEW_ARGS(GLEffect, (*this, effect));
+    virtual GLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE {
+        return SkNEW_ARGS(GLEffect, (*this, drawEffect));
     }
 
     /** This class is a singleton. This function returns the single instance.
index f4d474d6978d757f593163092f724d0ab15db610..507612e99feea51b76a6f32e817f843f61ca8981 100644 (file)
@@ -185,18 +185,17 @@ private:
 class GrGLBicubicEffect : public GrGLEffect {
 public:
     GrGLBicubicEffect(const GrBackendEffectFactory& factory,
-                      const GrEffectRef& effect);
+                      const GrDrawEffect&);
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
     typedef GrGLUniformManager::UniformHandle        UniformHandle;
@@ -210,21 +209,21 @@ private:
 };
 
 GrGLBicubicEffect::GrGLBicubicEffect(const GrBackendEffectFactory& factory,
-                                     const GrEffectRef& effect)
+                                     const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fCoefficientsUni(GrGLUniformManager::kInvalidUniformHandle)
-    , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle) {
+    , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrBicubicEffect>().coordsType()) {
 }
 
 void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
-                                 const GrEffectStage&,
+                                 const GrDrawEffect&,
                                  EffectKey key,
-                                 const char* vertexCoords,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TextureSamplerArray& samplers) {
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
     fCoefficientsUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                            kMat44f_GrSLType, "Coefficients");
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
@@ -269,17 +268,18 @@ void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
     builder->fsCodeAppendf("\t%s = %s(%s, f.y, s0, s1, s2, s3);\n", outputColor, cubicBlendName.c_str(), coeff);
 }
 
-GrGLEffect::EffectKey GrGLBicubicEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
-    const GrBicubicEffect& m = GetEffectFromStage<GrBicubicEffect>(s);
-    EffectKey matrixKey = GrGLEffectMatrix::GenKey(m.getMatrix(),
-                                                   s.getCoordChangeMatrix(),
-                                                   m.texture(0));
+GrGLEffect::EffectKey GrGLBicubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    const GrBicubicEffect& bicubic = drawEffect.castEffect<GrBicubicEffect>();
+    EffectKey matrixKey = GrGLEffectMatrix::GenKey(bicubic.getMatrix(),
+                                                   drawEffect,
+                                                   bicubic.coordsType(),
+                                                   bicubic.texture(0));
     return matrixKey;
 }
 
 void GrGLBicubicEffect::setData(const GrGLUniformManager& uman,
-                                const GrEffectStage& stage) {
-    const GrBicubicEffect& effect = GetEffectFromStage<GrBicubicEffect>(stage);
+                                const GrDrawEffect& drawEffect) {
+    const GrBicubicEffect& effect = drawEffect.castEffect<GrBicubicEffect>();
     GrTexture& texture = *effect.texture(0);
     float imageIncrement[2];
     imageIncrement[0] = 1.0f / texture.width();
@@ -288,7 +288,7 @@ void GrGLBicubicEffect::setData(const GrGLUniformManager& uman,
     uman.setMatrix4f(fCoefficientsUni, effect.coefficients());
     fEffectMatrix.setData(uman,
                           effect.getMatrix(),
-                          stage.getCoordChangeMatrix(),
+                          drawEffect,
                           effect.texture(0));
 }
 
index ae129eb08ea856c828aff9d573637ff99b21ab67..1c85fe5f293598b650706fa83c6133ac20654328 100644 (file)
@@ -94,23 +94,23 @@ bool SkBlendImageFilter::onFilterImage(Proxy* proxy,
 #if SK_SUPPORT_GPU
 class GrGLBlendEffect : public GrGLEffect {
 public:
-    GrGLBlendEffect(const GrBackendEffectFactory& factory,
-                    const GrEffectRef& effect);
+    GrGLBlendEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
     virtual ~GrGLBlendEffect();
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
+    static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
+
     SkBlendImageFilter::Mode    fMode;
     GrGLEffectMatrix            fForegroundEffectMatrix;
     GrGLEffectMatrix            fBackgroundEffectMatrix;
@@ -131,13 +131,13 @@ public:
 
     virtual ~GrBlendEffect();
 
-    const GrBackendEffectFactory& getFactory() const;
+    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
     SkBlendImageFilter::Mode mode() const { return fMode; }
 
     typedef GrGLBlendEffect GLEffect;
     static const char* Name() { return "Blend"; }
 
-    void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
     virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
@@ -224,27 +224,27 @@ void GrBlendEffect::getConstantColorComponents(GrColor* color, uint32_t* validFl
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrGLBlendEffect::GrGLBlendEffect(const GrBackendEffectFactory& factory, const GrEffectRef& effect)
-    : INHERITED(factory),
-      fMode(CastEffect<GrBlendEffect>(effect).mode()) {
+GrGLBlendEffect::GrGLBlendEffect(const GrBackendEffectFactory& factory,
+                                 const GrDrawEffect& drawEffect)
+    : INHERITED(factory)
+    , fMode(drawEffect.castEffect<GrBlendEffect>().mode())
+    , fForegroundEffectMatrix(kCoordsType)
+    , fBackgroundEffectMatrix(kCoordsType) {
 }
 
 GrGLBlendEffect::~GrGLBlendEffect() {
 }
 
 void GrGLBlendEffect::emitCode(GrGLShaderBuilder* builder,
-                               const GrEffectStage&,
+                               const GrDrawEffect&,
                                EffectKey key,
-                               const char* vertexCoords,
                                const char* outputColor,
                                const char* inputColor,
                                const TextureSamplerArray& samplers) {
     const char* fgCoords;
     const char* bgCoords;
-    GrSLType fgCoordsType =  fForegroundEffectMatrix.emitCode(
-        builder, key, vertexCoords, &fgCoords, NULL, "FG");
-    GrSLType bgCoordsType =  fBackgroundEffectMatrix.emitCode(
-        builder, key, vertexCoords, &bgCoords, NULL, "BG");
+    GrSLType fgCoordsType = fForegroundEffectMatrix.emitCode(builder, key, &fgCoords, NULL, "FG");
+    GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &bgCoords, NULL, "BG");
 
     const char* bgColor = "bgColor";
     const char* fgColor = "fgColor";
@@ -283,33 +283,35 @@ void GrGLBlendEffect::emitCode(GrGLShaderBuilder* builder,
     }
 }
 
-void GrGLBlendEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrBlendEffect& blend = GetEffectFromStage<GrBlendEffect>(stage);
+void GrGLBlendEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
+    const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>();
     GrTexture* fgTex = blend.texture(0);
     GrTexture* bgTex = blend.texture(1);
     fForegroundEffectMatrix.setData(uman,
                                     GrEffect::MakeDivByTextureWHMatrix(fgTex),
-                                    stage.getCoordChangeMatrix(),
+                                    drawEffect,
                                     fgTex);
     fBackgroundEffectMatrix.setData(uman,
                                     GrEffect::MakeDivByTextureWHMatrix(bgTex),
-                                    stage.getCoordChangeMatrix(),
+                                    drawEffect,
                                     bgTex);
 
 }
 
-GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-    const GrBlendEffect& blend = GetEffectFromStage<GrBlendEffect>(stage);
+GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>();
 
     GrTexture* fgTex = blend.texture(0);
     GrTexture* bgTex = blend.texture(1);
 
     EffectKey fgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(fgTex),
-                                               stage.getCoordChangeMatrix(),
+                                               drawEffect,
+                                               kCoordsType,
                                                fgTex);
 
     EffectKey bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTex),
-                                               stage.getCoordChangeMatrix(),
+                                               drawEffect,
+                                               kCoordsType,
                                                bgTex);
     bgKey <<= GrGLEffectMatrix::kKeyBits;
     EffectKey modeKey = blend.mode() << (2 * GrGLEffectMatrix::kKeyBits);
index b39c5f863fe6d22a5d2127d3b192984073aae419..55e8bba1d7b400665411aece6e90ef13b7cff8a8 100644 (file)
@@ -386,18 +386,17 @@ public:
     class GLEffect : public GrGLEffect {
     public:
         // this class always generates the same code.
-        static EffectKey GenKey(const GrEffectStage&, const GrGLCaps&) { return 0; }
+        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
 
         GLEffect(const GrBackendEffectFactory& factory,
-                 const GrEffectRef& effect)
+                 const GrDrawEffect&)
         : INHERITED(factory)
         , fMatrixHandle(GrGLUniformManager::kInvalidUniformHandle)
         , fVectorHandle(GrGLUniformManager::kInvalidUniformHandle) {}
 
         virtual void emitCode(GrGLShaderBuilder* builder,
-                              const GrEffectStage&,
+                              const GrDrawEffect&,
                               EffectKey,
-                              const char* vertexCoords,
                               const char* outputColor,
                               const char* inputColor,
                               const TextureSamplerArray&) SK_OVERRIDE {
@@ -424,8 +423,8 @@ public:
         }
 
         virtual void setData(const GrGLUniformManager& uniManager,
-                             const GrEffectStage& stage) SK_OVERRIDE {
-            const ColorMatrixEffect& cme = GetEffectFromStage<ColorMatrixEffect>(stage);
+                             const GrDrawEffect& drawEffect) SK_OVERRIDE {
+            const ColorMatrixEffect& cme = drawEffect.castEffect<ColorMatrixEffect>();
             const float* m = cme.fMatrix.fMat;
             // The GL matrix is transposed from SkColorMatrix.
             GrGLfloat mt[]  = {
index 9c89a6a9a67bb6840198204f0e23a5bfedc6c103..ae570ced13f93e7f7c3ae96003963df39ec384c1 100644 (file)
@@ -201,22 +201,23 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy,
 class GrGLDisplacementMapEffect : public GrGLEffect {
 public:
     GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
-                              const GrEffectRef& effect);
+                              const GrDrawEffect& drawEffect);
     virtual ~GrGLDisplacementMapEffect();
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
+    static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
+
     SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
     SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
     GrGLEffectMatrix fDisplacementEffectMatrix;
@@ -245,7 +246,7 @@ public:
 
     virtual ~GrDisplacementMapEffect();
 
-    const GrBackendEffectFactory& getFactory() const;
+    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
         { return fXChannelSelector; }
     SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const
@@ -255,9 +256,10 @@ public:
     typedef GrGLDisplacementMapEffect GLEffect;
     static const char* Name() { return "DisplacementMap"; }
 
-    void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
+    
     virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
 
     GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
@@ -382,32 +384,33 @@ GrEffectRef* GrDisplacementMapEffect::TestCreate(SkMWCRandom* random,
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
-                                                     const GrEffectRef& effect)
+                                                     const GrDrawEffect& drawEffect)
     : INHERITED(factory)
-    , fXChannelSelector(CastEffect<GrDisplacementMapEffect>(effect).xChannelSelector())
-    , fYChannelSelector(CastEffect<GrDisplacementMapEffect>(effect).yChannelSelector()) {
+    , fXChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().xChannelSelector())
+    , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChannelSelector())
+    , fDisplacementEffectMatrix(kCoordsType)
+    , fColorEffectMatrix(kCoordsType) {
 }
 
 GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() {
 }
 
 void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
-                               const GrEffectStage&,
-                               EffectKey key,
-                               const char* vertexCoords,
-                               const char* outputColor,
-                               const char* inputColor,
-                               const TextureSamplerArray& samplers) {
+                                         const GrDrawEffect&,
+                                         EffectKey key,
+                                         const char* outputColor,
+                                         const char* inputColor,
+                                         const TextureSamplerArray& samplers) {
     fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                     kVec2f_GrSLType, "Scale");
     const char* scaleUni = builder->getUniformCStr(fScaleUni);
 
     const char* dCoordsIn;
     GrSLType dCoordsType = fDisplacementEffectMatrix.emitCode(
-                                builder, key, vertexCoords, &dCoordsIn, NULL, "DISPL");
+                                builder, key, &dCoordsIn, NULL, "DISPL");
     const char* cCoordsIn;
     GrSLType cCoordsType = fColorEffectMatrix.emitCode(
-                                builder, key, vertexCoords, &cCoordsIn, NULL, "COLOR");
+                                builder, key, &cCoordsIn, NULL, "COLOR");
 
     const char* dColor = "dColor";
     const char* cCoords = "cCoords";
@@ -478,17 +481,19 @@ void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
     builder->fsCodeAppend(";\n");
 }
 
-void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrDisplacementMapEffect& displacementMap = GetEffectFromStage<GrDisplacementMapEffect>(stage);
+void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman,
+                                        const GrDrawEffect& drawEffect) {
+    const GrDisplacementMapEffect& displacementMap =
+        drawEffect.castEffect<GrDisplacementMapEffect>();
     GrTexture* displTex = displacementMap.texture(0);
     GrTexture* colorTex = displacementMap.texture(1);
     fDisplacementEffectMatrix.setData(uman,
                                      GrEffect::MakeDivByTextureWHMatrix(displTex),
-                                     stage.getCoordChangeMatrix(),
+                                     drawEffect,
                                      displTex);
     fColorEffectMatrix.setData(uman,
                                GrEffect::MakeDivByTextureWHMatrix(colorTex),
-                               stage.getCoordChangeMatrix(),
+                               drawEffect,
                                colorTex);
 
     SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->width()));
@@ -498,20 +503,22 @@ void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman, const Gr
                SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY));
 }
 
-GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrEffectStage& stage,
+GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& drawEffect,
                                                         const GrGLCaps&) {
     const GrDisplacementMapEffect& displacementMap =
-        GetEffectFromStage<GrDisplacementMapEffect>(stage);
+        drawEffect.castEffect<GrDisplacementMapEffect>();
 
     GrTexture* displTex = displacementMap.texture(0);
     GrTexture* colorTex = displacementMap.texture(1);
 
     EffectKey displKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(displTex),
-                                                  stage.getCoordChangeMatrix(),
+                                                  drawEffect,
+                                                  kCoordsType,
                                                   displTex);
 
     EffectKey colorKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(colorTex),
-                                                  stage.getCoordChangeMatrix(),
+                                                  drawEffect,
+                                                  kCoordsType,
                                                   colorTex);
 
     colorKey <<= GrGLEffectMatrix::kKeyBits;
index 177ba09c8ee55b61a2f3a86d8d41cb94abbd61e1..8ada08a322aacf02fbbafc462997c4484264e54e 100644 (file)
@@ -980,23 +980,22 @@ SkLight* create_random_light(SkMWCRandom* random) {
 class GrGLLightingEffect  : public GrGLEffect {
 public:
     GrGLLightingEffect(const GrBackendEffectFactory& factory,
-                       const GrEffectRef& effect);
+                       const GrDrawEffect& effect);
     virtual ~GrGLLightingEffect();
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
     /**
      * Subclasses of GrGLLightingEffect must call INHERITED::setData();
      */
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 protected:
     virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0;
@@ -1015,9 +1014,9 @@ private:
 class GrGLDiffuseLightingEffect  : public GrGLLightingEffect {
 public:
     GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
-                              const GrEffectRef& effect);
+                              const GrDrawEffect& drawEffect);
     virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
     typedef GrGLLightingEffect INHERITED;
@@ -1030,9 +1029,9 @@ private:
 class GrGLSpecularLightingEffect  : public GrGLLightingEffect {
 public:
     GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory,
-                               const GrEffectRef& effect);
+                               const GrDrawEffect& effect);
     virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
     typedef GrGLLightingEffect INHERITED;
@@ -1093,11 +1092,12 @@ GrEffectRef* GrDiffuseLightingEffect::TestCreate(SkMWCRandom* random,
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGLLightingEffect::GrGLLightingEffect(const GrBackendEffectFactory& factory,
-                                       const GrEffectRef& effect)
+                                       const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fImageIncrementUni(kInvalidUniformHandle)
-    , fSurfaceScaleUni(kInvalidUniformHandle) {
-    const GrLightingEffect& m = CastEffect<GrLightingEffect>(effect);
+    , fSurfaceScaleUni(kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrLightingEffect>().coordsType()) {
+    const GrLightingEffect& m = drawEffect.castEffect<GrLightingEffect>();
     fLight = m.light()->createGLLight();
 }
 
@@ -1106,14 +1106,13 @@ GrGLLightingEffect::~GrGLLightingEffect() {
 }
 
 void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
-                                  const GrEffectStage&,
+                                  const GrDrawEffect&,
                                   EffectKey key,
-                                  const char* vertexCoords,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TextureSamplerArray& samplers) {
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
 
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                               kVec2f_GrSLType,
@@ -1207,28 +1206,30 @@ void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
     builder->fsCodeAppend(modulate.c_str());
 }
 
-GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrEffectStage& s,
+GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrDrawEffect& drawEffect,
                                                  const GrGLCaps& caps) {
-    const GrLightingEffect& effect = GetEffectFromStage<GrLightingEffect>(s);
-    EffectKey key = effect.light()->type();
+    const GrLightingEffect& lighting = drawEffect.castEffect<GrLightingEffect>();
+    EffectKey key = lighting.light()->type();
     key <<= GrGLEffectMatrix::kKeyBits;
-    EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
-                                                   s.getCoordChangeMatrix(),
-                                                   effect.texture(0));
+    EffectKey matrixKey = GrGLEffectMatrix::GenKey(lighting.getMatrix(),
+                                                   drawEffect,
+                                                   lighting.coordsType(),
+                                                   lighting.texture(0));
     return key | matrixKey;
 }
 
-void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrLightingEffect& effect = GetEffectFromStage<GrLightingEffect>(stage);
-    GrTexture* texture = effect.texture(0);
+void GrGLLightingEffect::setData(const GrGLUniformManager& uman,
+                                 const GrDrawEffect& drawEffect) {
+    const GrLightingEffect& lighting = drawEffect.castEffect<GrLightingEffect>();
+    GrTexture* texture = lighting.texture(0);
     float ySign = texture->origin() == kTopLeft_GrSurfaceOrigin ? -1.0f : 1.0f;
     uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
-    uman.set1f(fSurfaceScaleUni, effect.surfaceScale());
-    fLight->setData(uman, effect.light());
+    uman.set1f(fSurfaceScaleUni, lighting.surfaceScale());
+    fLight->setData(uman, lighting.light());
     fEffectMatrix.setData(uman,
-                          effect.getMatrix(),
-                          stage.getCoordChangeMatrix(),
-                          effect.texture(0));
+                          lighting.getMatrix(),
+                          drawEffect,
+                          lighting.texture(0));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1236,8 +1237,8 @@ void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffectS
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
-                                                     const GrEffectRef& effect)
-    : INHERITED(factory, effect)
+                                                     const GrDrawEffect& drawEffect)
+    : INHERITED(factory, drawEffect)
     , fKDUni(kInvalidUniformHandle) {
 }
 
@@ -1266,10 +1267,10 @@ void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkStri
 }
 
 void GrGLDiffuseLightingEffect::setData(const GrGLUniformManager& uman,
-                                        const GrEffectStage& stage) {
-    INHERITED::setData(uman, stage);
-    const GrDiffuseLightingEffect& effect = GetEffectFromStage<GrDiffuseLightingEffect>(stage);
-    uman.set1f(fKDUni, effect.kd());
+                                        const GrDrawEffect& drawEffect) {
+    INHERITED::setData(uman, drawEffect);
+    const GrDiffuseLightingEffect& diffuse = drawEffect.castEffect<GrDiffuseLightingEffect>();
+    uman.set1f(fKDUni, diffuse.kd());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1307,8 +1308,8 @@ GrEffectRef* GrSpecularLightingEffect::TestCreate(SkMWCRandom* random,
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory,
-                                                       const GrEffectRef& effect)
-    : GrGLLightingEffect(factory, effect)
+                                                       const GrDrawEffect& drawEffect)
+    : GrGLLightingEffect(factory, drawEffect)
     , fKSUni(kInvalidUniformHandle)
     , fShininessUni(kInvalidUniformHandle) {
 }
@@ -1342,11 +1343,11 @@ void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkStr
 }
 
 void GrGLSpecularLightingEffect::setData(const GrGLUniformManager& uman,
-                                         const GrEffectStage& stage) {
-    INHERITED::setData(uman, stage);
-    const GrSpecularLightingEffect& effect = GetEffectFromStage<GrSpecularLightingEffect>(stage);
-    uman.set1f(fKSUni, effect.ks());
-    uman.set1f(fShininessUni, effect.shininess());
+                                         const GrDrawEffect& drawEffect) {
+    INHERITED::setData(uman, drawEffect);
+    const GrSpecularLightingEffect& spec = drawEffect.castEffect<GrSpecularLightingEffect>();
+    uman.set1f(fKSUni, spec.ks());
+    uman.set1f(fShininessUni, spec.shininess());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1360,8 +1361,7 @@ void GrGLLight::emitLightColor(GrGLShaderBuilder* builder,
     builder->fsCodeAppend(builder->getUniformCStr(this->lightColorUni()));
 }
 
-void GrGLLight::setData(const GrGLUniformManager& uman,
-                        const SkLight* light) const {
+void GrGLLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
     setUniformPoint3(uman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255)));
 }
 
@@ -1383,8 +1383,7 @@ void GrGLDistantLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLPointLight::setData(const GrGLUniformManager& uman,
-                             const SkLight* light) const {
+void GrGLPointLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
     INHERITED::setData(uman, light);
     SkASSERT(light->type() == SkLight::kPoint_LightType);
     const SkPointLight* pointLight = static_cast<const SkPointLight*>(light);
@@ -1400,8 +1399,7 @@ void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char*
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLSpotLight::setData(const GrGLUniformManager& uman,
-                            const SkLight* light) const {
+void GrGLSpotLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
     INHERITED::setData(uman, light);
     SkASSERT(light->type() == SkLight::kSpot_LightType);
     const SkSpotLight* spotLight = static_cast<const SkSpotLight *>(light);
index 215ebc0872318f1e73c9563405d6413adb0d5209..0c4cde15c29d4c4ae1834f694420359829413839 100644 (file)
@@ -92,22 +92,20 @@ typedef GrGLUniformManager::UniformHandle UniformHandle;
 
 class GrGLMagnifierEffect : public GrGLEffect {
 public:
-    GrGLMagnifierEffect(const GrBackendEffectFactory& factory, const GrEffectRef& effect);
+    GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
 private:
-
     UniformHandle       fOffsetVar;
     UniformHandle       fZoomVar;
     UniformHandle       fInsetVar;
@@ -117,22 +115,23 @@ private:
     typedef GrGLEffect INHERITED;
 };
 
-GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
+GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
+                                         const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fOffsetVar(GrGLUniformManager::kInvalidUniformHandle)
     , fZoomVar(GrGLUniformManager::kInvalidUniformHandle)
-    , fInsetVar(GrGLUniformManager::kInvalidUniformHandle) {
+    , fInsetVar(GrGLUniformManager::kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrMagnifierEffect>().coordsType()) {
 }
 
 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
-                                   const GrEffectStage&,
+                                   const GrDrawEffect&,
                                    EffectKey key,
-                                   const char* vertexCoords,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TextureSamplerArray& samplers) {
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
     fOffsetVar = builder->addUniform(
         GrGLShaderBuilder::kFragment_ShaderType |
         GrGLShaderBuilder::kVertex_ShaderType,
@@ -179,18 +178,20 @@ void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
 }
 
 void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman,
-                                  const GrEffectStage& stage) {
-    const GrMagnifierEffect& zoom = GetEffectFromStage<GrMagnifierEffect>(stage);
+                                  const GrDrawEffect& drawEffect) {
+    const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>();
     uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
     uman.set2f(fZoomVar, zoom.x_zoom(), zoom.y_zoom());
     uman.set2f(fInsetVar, zoom.x_inset(), zoom.y_inset());
-    fEffectMatrix.setData(uman, zoom.getMatrix(), stage.getCoordChangeMatrix(), zoom.texture(0));
+    fEffectMatrix.setData(uman, zoom.getMatrix(), drawEffect, zoom.texture(0));
 }
 
-GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-    const GrMagnifierEffect& zoom = GetEffectFromStage<GrMagnifierEffect>(stage);
+GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrDrawEffect& drawEffect,
+                                                  const GrGLCaps&) {
+    const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>();
     return GrGLEffectMatrix::GenKey(zoom.getMatrix(),
-                                    stage.getCoordChangeMatrix(),
+                                    drawEffect,
+                                    zoom.coordsType(),
                                     zoom.texture(0));
 }
 
index cda4f28081fdcf519817d0964edf0c37ef56ba6c..c4cffeafab3202cf8693f9749bb0b16f39a5759d 100644 (file)
@@ -284,8 +284,6 @@ public:
 
     typedef GrGLMatrixConvolutionEffect GLEffect;
 
-
-
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
 
 private:
@@ -316,18 +314,17 @@ private:
 class GrGLMatrixConvolutionEffect : public GrGLEffect {
 public:
     GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                const GrEffectRef& effect);
+                                const GrDrawEffect& effect);
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
     typedef GrGLUniformManager::UniformHandle        UniformHandle;
@@ -348,14 +345,15 @@ private:
 };
 
 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                                         const GrEffectRef& effect)
+                                                         const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fKernelUni(GrGLUniformManager::kInvalidUniformHandle)
     , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle)
     , fTargetUni(GrGLUniformManager::kInvalidUniformHandle)
     , fGainUni(GrGLUniformManager::kInvalidUniformHandle)
-    , fBiasUni(GrGLUniformManager::kInvalidUniformHandle) {
-    const GrMatrixConvolutionEffect& m = CastEffect<GrMatrixConvolutionEffect>(effect);
+    , fBiasUni(GrGLUniformManager::kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrMatrixConvolutionEffect>().coordsType()) {
+    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
     fKernelSize = m.kernelSize();
     fTileMode = m.tileMode();
     fConvolveAlpha = m.convolveAlpha();
@@ -383,14 +381,13 @@ static void appendTextureLookup(GrGLShaderBuilder* builder,
 }
 
 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
-                                           const GrEffectStage&,
+                                           const GrDrawEffect&,
                                            EffectKey key,
-                                           const char* vertexCoords,
                                            const char* outputColor,
                                            const char* inputColor,
                                            const TextureSamplerArray& samplers) {
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                              kVec2f_GrSLType, "ImageIncrement");
     fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
@@ -450,38 +447,40 @@ int encodeXY(int x, int y) {
 
 };
 
-GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
-    const GrMatrixConvolutionEffect& m = GetEffectFromStage<GrMatrixConvolutionEffect>(s);
+GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
+                                                          const GrGLCaps&) {
+    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
     EffectKey key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
     key |= m.tileMode() << 7;
     key |= m.convolveAlpha() ? 1 << 9 : 0;
     key <<= GrGLEffectMatrix::kKeyBits;
     EffectKey matrixKey = GrGLEffectMatrix::GenKey(m.getMatrix(),
-                                                   s.getCoordChangeMatrix(),
+                                                   drawEffect,
+                                                   m.coordsType(),
                                                    m.texture(0));
     return key | matrixKey;
 }
 
 void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
-                                          const GrEffectStage& stage) {
-    const GrMatrixConvolutionEffect& effect = GetEffectFromStage<GrMatrixConvolutionEffect>(stage);
-    GrTexture& texture = *effect.texture(0);
+                                          const GrDrawEffect& drawEffect) {
+    const GrMatrixConvolutionEffect& conv = drawEffect.castEffect<GrMatrixConvolutionEffect>();
+    GrTexture& texture = *conv.texture(0);
     // the code we generated was for a specific kernel size
-    GrAssert(effect.kernelSize() == fKernelSize);
-    GrAssert(effect.tileMode() == fTileMode);
+    GrAssert(conv.kernelSize() == fKernelSize);
+    GrAssert(conv.tileMode() == fTileMode);
     float imageIncrement[2];
     float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
     imageIncrement[0] = 1.0f / texture.width();
     imageIncrement[1] = ySign / texture.height();
     uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
-    uman.set2fv(fTargetUni, 0, 1, effect.target());
-    uman.set1fv(fKernelUni, 0, fKernelSize.width() * fKernelSize.height(), effect.kernel());
-    uman.set1f(fGainUni, effect.gain());
-    uman.set1f(fBiasUni, effect.bias());
+    uman.set2fv(fTargetUni, 0, 1, conv.target());
+    uman.set1fv(fKernelUni, 0, fKernelSize.width() * fKernelSize.height(), conv.kernel());
+    uman.set1f(fGainUni, conv.gain());
+    uman.set1f(fBiasUni, conv.bias());
     fEffectMatrix.setData(uman,
-                          effect.getMatrix(),
-                          stage.getCoordChangeMatrix(),
-                          effect.texture(0));
+                          conv.getMatrix(),
+                          drawEffect,
+                          conv.texture(0));
 }
 
 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
index bca18e668ff48195d8193395cc960949074f6ad0..f2b37f2a8aba1967efcd86348ceedc588cf915b8 100644 (file)
@@ -278,19 +278,18 @@ private:
 
 class GrGLMorphologyEffect : public GrGLEffect {
 public:
-    GrGLMorphologyEffect (const GrBackendEffectFactory&, const GrEffectRef&);
+    GrGLMorphologyEffect (const GrBackendEffectFactory&, const GrDrawEffect&);
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 private:
     int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); }
@@ -304,23 +303,23 @@ private:
 };
 
 GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory,
-                                           const GrEffectRef& effect)
+                                           const GrDrawEffect& drawEffect)
     : INHERITED(factory)
-    , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle) {
-    const GrMorphologyEffect& m = CastEffect<GrMorphologyEffect>(effect);
+    , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrMorphologyEffect>().coordsType()) {
+    const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
     fRadius = m.radius();
     fType = m.type();
 }
 
 void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
-                                    const GrEffectStage&,
+                                    const GrDrawEffect&,
                                     EffectKey key,
-                                    const char* vertexCoords,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TextureSamplerArray& samplers) {
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                              kVec2f_GrSLType, "ImageIncrement");
 
@@ -353,19 +352,22 @@ void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
     builder->fsCodeAppend(modulate.c_str());
 }
 
-GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
-    const GrMorphologyEffect& m = GetEffectFromStage<GrMorphologyEffect>(s);
+GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrDrawEffect& drawEffect,
+                                                   const GrGLCaps&) {
+    const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
     EffectKey key = static_cast<EffectKey>(m.radius());
     key |= (m.type() << 8);
     key <<= GrGLEffectMatrix::kKeyBits;
     EffectKey matrixKey = GrGLEffectMatrix::GenKey(m.getMatrix(),
-                                                   s.getCoordChangeMatrix(),
+                                                   drawEffect,
+                                                   m.coordsType(),
                                                    m.texture(0));
     return key | matrixKey;
 }
 
-void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const Gr1DKernelEffect& kern = GetEffectFromStage<Gr1DKernelEffect>(stage);
+void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman,
+                                   const GrDrawEffect& drawEffect) {
+    const Gr1DKernelEffect& kern = drawEffect.castEffect<Gr1DKernelEffect>();
     GrTexture& texture = *kern.texture(0);
     // the code we generated was for a specific kernel radius
     GrAssert(kern.radius() == fRadius);
@@ -381,7 +383,7 @@ void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, const GrEffec
             GrCrash("Unknown filter direction.");
     }
     uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
-    fEffectMatrix.setData(uman, kern.getMatrix(), stage.getCoordChangeMatrix(), kern.texture(0));
+    fEffectMatrix.setData(uman, kern.getMatrix(), drawEffect, kern.texture(0));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index 16f2876af0f3b495b08a638c39a9bb486a583a22..e0c497806d01198d99dcece3a31d75010258ea91 100644 (file)
@@ -256,33 +256,31 @@ private:
 
 class GLColorTableEffect : public GrGLEffect {
 public:
-    GLColorTableEffect(const GrBackendEffectFactory&, const GrEffectRef&);
+    GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE {}
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
 
-    static EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
 private:
 
     typedef GrGLEffect INHERITED;
 };
 
-GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
+GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
     : INHERITED(factory) {
  }
 
 void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
-                                  const GrEffectStage&,
+                                  const GrDrawEffect&,
                                   EffectKey,
-                                  const char* vertexCoords,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TextureSamplerArray& samplers) {
@@ -323,7 +321,7 @@ void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
     builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
 }
 
-GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrEffectStage&, const GrGLCaps&) {
+GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
     return 0;
 }
 
index 1158dcf92a9570e9e50ae63a9226fc778a1b3098..d3b2fd41f8791e1fd75e06a7ad3a87ef5da6a6a4 100644 (file)
@@ -734,12 +734,14 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
 #if SK_SUPPORT_GPU
 
 #include "effects/GrTextureStripAtlas.h"
+#include "GrTBackendEffectFactory.h"
 #include "SkGr.h"
 
 GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
     : INHERITED(factory)
     , fCachedYCoord(SK_ScalarMax)
-    , fFSYUni(GrGLUniformManager::kInvalidUniformHandle) {
+    , fFSYUni(GrGLUniformManager::kInvalidUniformHandle)
+    , fEffectMatrix(kCoordsType) {
 }
 
 GrGLGradientEffect::~GrGLGradientEffect() { }
@@ -749,10 +751,11 @@ void GrGLGradientEffect::emitYCoordUniform(GrGLShaderBuilder* builder) {
                                   kFloat_GrSLType, "GradientYCoordFS");
 }
 
-void GrGLGradientEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrGradientEffect& e = GetEffectFromStage<GrGradientEffect>(stage);
+void GrGLGradientEffect::setData(const GrGLUniformManager& uman,
+                                 const GrDrawEffect& drawEffect) {
+    const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
     const GrTexture* texture = e.texture(0);
-    fEffectMatrix.setData(uman, e.getMatrix(), stage.getCoordChangeMatrix(), texture);
+    fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, texture);
 
     SkScalar yCoord = e.getYCoord();
     if (yCoord != fCachedYCoord) {
@@ -761,21 +764,19 @@ void GrGLGradientEffect::setData(const GrGLUniformManager& uman, const GrEffectS
     }
 }
 
-GrGLEffect::EffectKey GrGLGradientEffect::GenMatrixKey(const GrEffectStage& s) {
-    const GrGradientEffect& e = GetEffectFromStage<GrGradientEffect>(s);
+GrGLEffect::EffectKey GrGLGradientEffect::GenMatrixKey(const GrDrawEffect& drawEffect) {
+    const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
     const GrTexture* texture = e.texture(0);
-    return GrGLEffectMatrix::GenKey(e.getMatrix(), s.getCoordChangeMatrix(), texture);
+    return GrGLEffectMatrix::GenKey(e.getMatrix(), drawEffect, kCoordsType, texture);
 }
 
 void GrGLGradientEffect::setupMatrix(GrGLShaderBuilder* builder,
                                      EffectKey key,
-                                     const char* vertexCoords,
                                      const char** fsCoordName,
                                      const char** vsVaryingName,
                                      GrSLType* vsVaryingType) {
     fEffectMatrix.emitCodeMakeFSCoords2D(builder,
                                          key & kMatrixKeyMask,
-                                         vertexCoords,
                                          fsCoordName,
                                          vsVaryingName,
                                          vsVaryingType);
index 271a2b6e51804441d7366225cd67e9472b9edbd2..b9dbf1b87b062c193c49d7ab696ea6533aec2a8b 100644 (file)
@@ -274,7 +274,7 @@ public:
     GrGLGradientEffect(const GrBackendEffectFactory& factory);
     virtual ~GrGLGradientEffect();
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 protected:
     /**
@@ -290,7 +290,7 @@ protected:
      * Subclasses must call this. It will return a value restricted to the lower kMatrixKeyBitCnt
      * bits.
      */
-    static EffectKey GenMatrixKey(const GrEffectStage& s);
+    static EffectKey GenMatrixKey(const GrDrawEffect&);
 
     /**
      * Inserts code to implement the GrGradientEffect's matrix. This should be called before a
@@ -302,7 +302,6 @@ protected:
      */
     void setupMatrix(GrGLShaderBuilder* builder,
                      EffectKey key,
-                     const char* vertexCoords,
                      const char** fsCoordName,
                      const char** vsVaryingName = NULL,
                      GrSLType* vsVaryingType = NULL);
@@ -321,6 +320,8 @@ protected:
                          const GrGLShaderBuilder::TextureSampler&);
 
 private:
+    static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
+
     SkScalar fCachedYCoord;
     GrGLUniformManager::UniformHandle fFSYUni;
     GrGLEffectMatrix fEffectMatrix;
index 3f8d7cccba912bbe89ce6c995dab8cafa880f253..76168a932d621c55393cd59d260763cd4bffbd7d 100644 (file)
@@ -453,21 +453,20 @@ void SkLinearGradient::shadeSpan16(int x, int y,
 class GrGLLinearGradient : public GrGLGradientEffect {
 public:
 
-    GrGLLinearGradient(const GrBackendEffectFactory& factory, const GrEffectRef&)
+    GrGLLinearGradient(const GrBackendEffectFactory& factory, const GrDrawEffect&)
                        : INHERITED (factory) { }
 
     virtual ~GrGLLinearGradient() { }
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        return GenMatrixKey(stage);
+    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        return GenMatrixKey(drawEffect);
     }
 
 private:
@@ -533,15 +532,14 @@ GrEffectRef* GrLinearGradient::TestCreate(SkMWCRandom* random,
 /////////////////////////////////////////////////////////////////////
 
 void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
-                                  const GrEffectStage& stage,
+                                  const GrDrawEffect&,
                                   EffectKey key,
-                                  const char* vertexCoords,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TextureSamplerArray& samplers) {
     this->emitYCoordUniform(builder);
     const char* coords;
-    this->setupMatrix(builder, key, vertexCoords, &coords);
+    this->setupMatrix(builder, key, &coords);
     SkString t;
     t.append(coords);
     t.append(".x");
index 3f670ad6291d266339b677cebae24338d304a85e..a80cb810afcb015fab50c93687cc82489d20385a 100644 (file)
@@ -474,19 +474,18 @@ class GrGLRadialGradient : public GrGLGradientEffect {
 public:
 
     GrGLRadialGradient(const GrBackendEffectFactory& factory,
-                       const GrEffectRef&) : INHERITED (factory) { }
+                       const GrDrawEffect&) : INHERITED (factory) { }
     virtual ~GrGLRadialGradient() { }
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        return GenMatrixKey(stage);
+    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        return GenMatrixKey(drawEffect);
     }
 
 private:
@@ -554,15 +553,14 @@ GrEffectRef* GrRadialGradient::TestCreate(SkMWCRandom* random,
 /////////////////////////////////////////////////////////////////////
 
 void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
-                                  const GrEffectStage&,
+                                  const GrDrawEffect&,
                                   EffectKey key,
-                                  const char* vertexCoords,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TextureSamplerArray& samplers) {
     this->emitYCoordUniform(builder);
     const char* coords;
-    this->setupMatrix(builder, key, vertexCoords, &coords);
+    this->setupMatrix(builder, key, &coords);
     SkString t("length(");
     t.append(coords);
     t.append(")");
index 44b03d6b873beb638c7b5cb3a1df596e424553bf..9d24d401067dbfd7ed102dd67f4c8657adf1ba49 100644 (file)
@@ -391,19 +391,18 @@ class GrGLSweepGradient : public GrGLGradientEffect {
 public:
 
     GrGLSweepGradient(const GrBackendEffectFactory& factory,
-                      const GrEffectRef&) : INHERITED (factory) { }
+                      const GrDrawEffect&) : INHERITED (factory) { }
     virtual ~GrGLSweepGradient() { }
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        return GenMatrixKey(stage);
+    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        return GenMatrixKey(drawEffect);
     }
 
 private:
@@ -464,15 +463,14 @@ GrEffectRef* GrSweepGradient::TestCreate(SkMWCRandom* random,
 /////////////////////////////////////////////////////////////////////
 
 void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
-                                 const GrEffectStage&,
+                                 const GrDrawEffect&,
                                  EffectKey key,
-                                 const char* vertexCoords,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TextureSamplerArray& samplers) {
     this->emitYCoordUniform(builder);
     const char* coords;
-    this->setupMatrix(builder, key, vertexCoords, &coords);
+    this->setupMatrix(builder, key, &coords);
     SkString t;
     t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords, coords);
     this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, samplers[0]);
index 04cf1ebfe56b26018f6572a11493428636e800e7..0b6e30de3923f58b70562b62177fdb7430edde22 100644 (file)
@@ -343,20 +343,18 @@ static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
 class GrGLConical2Gradient : public GrGLGradientEffect {
 public:
 
-    GrGLConical2Gradient(const GrBackendEffectFactory& factory,
-                         const GrEffectRef&);
+    GrGLConical2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffect&);
     virtual ~GrGLConical2Gradient() { }
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps);
+    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
 
 protected:
 
@@ -476,7 +474,7 @@ GrEffectRef* GrConical2Gradient::TestCreate(SkMWCRandom* random,
 /////////////////////////////////////////////////////////////////////
 
 GrGLConical2Gradient::GrGLConical2Gradient(const GrBackendEffectFactory& factory,
-                                           const GrEffectRef& baseData)
+                                           const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fVSParamUni(kInvalidUniformHandle)
     , fFSParamUni(kInvalidUniformHandle)
@@ -486,21 +484,20 @@ GrGLConical2Gradient::GrGLConical2Gradient(const GrBackendEffectFactory& factory
     , fCachedRadius(-SK_ScalarMax)
     , fCachedDiffRadius(-SK_ScalarMax) {
 
-    const GrConical2Gradient& data = CastEffect<GrConical2Gradient>(baseData);
+    const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>();
     fIsDegenerate = data.isDegenerate();
 }
 
 void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder,
-                                    const GrEffectStage&,
+                                    const GrDrawEffect&,
                                     EffectKey key,
-                                    const char* vertexCoords,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TextureSamplerArray& samplers) {
     const char* fsCoords;
     const char* vsCoordsVarying;
     GrSLType coordsVaryingType;
-    this->setupMatrix(builder, key, vertexCoords, &fsCoords, &vsCoordsVarying, &coordsVaryingType);
+    this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingType);
 
     this->emitYCoordUniform(builder);
     // 2 copies of uniform array, 1 for each of vertex & fragment shader,
@@ -658,9 +655,10 @@ void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder,
     }
 }
 
-void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    INHERITED::setData(uman, stage);
-    const GrConical2Gradient& data = GetEffectFromStage<GrConical2Gradient>(stage);
+void GrGLConical2Gradient::setData(const GrGLUniformManager& uman,
+                                   const GrDrawEffect& drawEffect) {
+    INHERITED::setData(uman, drawEffect);
+    const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>();
     GrAssert(data.isDegenerate() == fIsDegenerate);
     SkScalar centerX1 = data.center();
     SkScalar radius0 = data.radius();
@@ -694,13 +692,14 @@ void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffec
     }
 }
 
-GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrDrawEffect& drawEffect,
+                                                   const GrGLCaps&) {
     enum {
         kIsDegenerate = 1 << kMatrixKeyBitCnt,
     };
 
-    EffectKey key = GenMatrixKey(s);
-    if (GetEffectFromStage<GrConical2Gradient>(s).isDegenerate()) {
+    EffectKey key = GenMatrixKey(drawEffect);
+    if (drawEffect.castEffect<GrConical2Gradient>().isDegenerate()) {
         key |= kIsDegenerate;
     }
     return key;
index 0bf308bdb1184645d75f21c5db7369c477c95999..6784818761b8591ba41eefea4466d8de5c0c8880 100644 (file)
@@ -384,19 +384,18 @@ class GrGLRadial2Gradient : public GrGLGradientEffect {
 
 public:
 
-    GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrEffectRef&);
+    GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffect&);
     virtual ~GrGLRadial2Gradient() { }
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps);
+    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
 
 protected:
 
@@ -516,7 +515,7 @@ GrEffectRef* GrRadial2Gradient::TestCreate(SkMWCRandom* random,
 /////////////////////////////////////////////////////////////////////
 
 GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory,
-                                         const GrEffectRef& baseData)
+                                         const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fVSParamUni(kInvalidUniformHandle)
     , fFSParamUni(kInvalidUniformHandle)
@@ -526,14 +525,13 @@ GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory,
     , fCachedRadius(-SK_ScalarMax)
     , fCachedPosRoot(0) {
 
-    const GrRadial2Gradient& data = CastEffect<GrRadial2Gradient>(baseData);
+    const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>();
     fIsDegenerate = data.isDegenerate();
 }
 
 void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
-                                   const GrEffectStage&,
+                                   const GrDrawEffect& drawEffect,
                                    EffectKey key,
-                                   const char* vertexCoords,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TextureSamplerArray& samplers) {
@@ -542,7 +540,7 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
     const char* fsCoords;
     const char* vsCoordsVarying;
     GrSLType coordsVaryingType;
-    this->setupMatrix(builder, key, vertexCoords, &fsCoords, &vsCoordsVarying, &coordsVaryingType);
+    this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingType);
 
     // 2 copies of uniform array, 1 for each of vertex & fragment shader,
     // to work around Xoom bug. Doesn't seem to cause performance decrease
@@ -639,9 +637,10 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
     }
 }
 
-void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    INHERITED::setData(uman, stage);
-    const GrRadial2Gradient& data = GetEffectFromStage<GrRadial2Gradient>(stage);
+void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman,
+                                  const GrDrawEffect& drawEffect) {
+    INHERITED::setData(uman, drawEffect);
+    const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>();
     GrAssert(data.isDegenerate() == fIsDegenerate);
     SkScalar centerX1 = data.center();
     SkScalar radius0 = data.radius();
@@ -673,13 +672,14 @@ void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, const GrEffect
     }
 }
 
-GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect,
+                                                  const GrGLCaps&) {
     enum {
         kIsDegenerate = 1 << kMatrixKeyBitCnt,
     };
 
-    EffectKey key = GenMatrixKey(s);
-    if (GetEffectFromStage<GrRadial2Gradient>(s).isDegenerate()) {
+    EffectKey key = GenMatrixKey(drawEffect);
+    if (drawEffect.castEffect<GrRadial2Gradient>().isDegenerate()) {
         key |= kIsDegenerate;
     }
     return key;
index 99068c75ed14c863635e384e9dcfeac46441d042..6415859db9a0d5d997db7d0e333790960c4f1c27 100644 (file)
@@ -40,6 +40,9 @@ void setup_drawstate_aaclip(GrGpu* gpu,
     static const int kMaskStage = GrPaint::kTotalStages+1;
 
     SkMatrix mat;
+    // We want to use device coords to compute the texture coordinates. We set our matrix to be
+    // equal to the view matrix followed by an offset to the devBound, and then a scaling matrix to
+    // normalized coords. We apply this matrix to the vertex positions rather than local coords.
     mat.setIDiv(result->width(), result->height());
     mat.preTranslate(SkIntToScalar(-devBound.fLeft),
                      SkIntToScalar(-devBound.fTop));
@@ -51,7 +54,9 @@ void setup_drawstate_aaclip(GrGpu* gpu,
                          GrTextureDomainEffect::Create(result,
                                       mat,
                                       GrTextureDomainEffect::MakeTexelDomain(result, domainTexels),
-                                      GrTextureDomainEffect::kDecal_WrapMode))->unref();
+                                      GrTextureDomainEffect::kDecal_WrapMode,
+                                      false,
+                                      GrEffect::kPosition_CoordsType))->unref();
 }
 
 bool path_needs_SW_renderer(GrContext* context,
@@ -354,7 +359,8 @@ void GrClipMaskManager::mergeMask(GrTexture* dstMask,
         GrTextureDomainEffect::Create(srcMask,
                                       sampleM,
                                       GrTextureDomainEffect::MakeTexelDomain(srcMask, srcBound),
-                                      GrTextureDomainEffect::kDecal_WrapMode))->unref();
+                                      GrTextureDomainEffect::kDecal_WrapMode,
+                                      false))->unref();
     fGpu->drawSimpleRect(SkRect::MakeFromIRect(dstBound), NULL);
 
     drawState->disableStage(0);
index 4c1857499924567bcef010cc3e807dc4feef4aff..4798297a3aa959e6eaff25e15397b60e137eb490 100644 (file)
@@ -360,12 +360,12 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
             {kVec2f_GrVertexAttribType, 0},
             {kVec2f_GrVertexAttribType, sizeof(GrPoint)}
         };
-        static const GrAttribBindings kAttribBindings =
-            GrDrawState::ExplicitTexCoordAttribBindingsBit(0);
+
+        static const GrAttribBindings kAttribBindings = GrDrawState::kLocalCoords_AttribBindingsBit;
         drawState->setAttribBindings(kAttribBindings);
         drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
         drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
-        drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
+        drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, 1);
         GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
 
         if (arg.succeeded()) {
@@ -852,21 +852,15 @@ void GrContext::drawRect(const GrPaint& paint,
 
 void GrContext::drawRectToRect(const GrPaint& paint,
                                const GrRect& dstRect,
-                               const GrRect& srcRect,
+                               const GrRect& localRect,
                                const SkMatrix* dstMatrix,
-                               const SkMatrix* srcMatrix) {
+                               const SkMatrix* localMatrix) {
     SK_TRACE_EVENT0("GrContext::drawRectToRect");
 
-    // srcRect refers to paint's first color stage
-    if (!paint.isColorStageEnabled(0)) {
-        drawRect(paint, dstRect, -1, dstMatrix);
-        return;
-    }
-
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW);
+    GrDrawState::AutoStageDisable atr(fDrawState);
 
 #if GR_STATIC_RECT_VB
-    GrDrawState::AutoStageDisable atr(fDrawState);
     GrDrawState* drawState = target->drawState();
 
     SkMatrix m;
@@ -878,19 +872,21 @@ void GrContext::drawRectToRect(const GrPaint& paint,
         m.postConcat(*dstMatrix);
     }
 
-    // The first color stage's coords come from srcRect rather than applying a matrix to dstRect.
-    // We explicitly compute a matrix for that stage below, no need to adjust here.
-    static const uint32_t kExplicitCoordMask = 1 << GrPaint::kFirstColorStage;
-    GrDrawState::AutoViewMatrixRestore avmr(drawState, m, kExplicitCoordMask);
+    // This code path plays a little fast and loose with the notion of local coords and coord
+    // change matrices in order to account for localRect and localMatrix. The unit square VB only
+    // has one set of coords. Rather than using AutoViewMatrixRestore we instead directly set concat
+    // with m and then call GrDrawState::localCoordChange() with a matrix that accounts for
+    // localRect and localMatrix. This code path is preventing some encapsulation in GrDrawState.
+    SkMatrix savedViewMatrix = drawState->getViewMatrix();
+    drawState->preConcatViewMatrix(m);
 
-    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
-             0,               srcRect.height(), srcRect.fTop,
-             0,               0,                SkMatrix::I()[8]);
-    if (NULL != srcMatrix) {
-        m.postConcat(*srcMatrix);
+    m.setAll(localRect.width(), 0,                localRect.fLeft,
+             0,               localRect.height(), localRect.fTop,
+             0,               0,                  SkMatrix::I()[8]);
+    if (NULL != localMatrix) {
+        m.postConcat(*localMatrix);
     }
-
-    drawState->preConcatStageMatrices(kExplicitCoordMask, m);
+    drawState->localCoordChange(m);
 
     const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
     if (NULL == sqVB) {
@@ -900,10 +896,9 @@ void GrContext::drawRectToRect(const GrPaint& paint,
     drawState->setDefaultVertexAttribs();
     target->setVertexSourceToBuffer(sqVB);
     target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
+    drawState->setViewMatrix(savedViewMatrix);
 #else
-    GrDrawState::AutoStageDisable atr(fDrawState);
-
-    target->drawRect(dstRect, dstMatrix, &srcRect, srcMatrix, 0);
+    target->drawRect(dstRect, dstMatrix, &localRect, localMatrix);
 #endif
 }
 
@@ -937,8 +932,8 @@ void GrContext::drawVertices(const GrPaint& paint,
 
     // set up optional texture coordinate attributes
     if (NULL != texCoords) {
-        bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(0);
-        drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, attribs.count());
+        bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
+        drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
         currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
         attribs.push_back(currAttrib);
         texOffset = currentOffset;
index cd5fe1c0d6d95ce05b1a0925bc464bf57d9bfca2..79829357ba4d651a9c6179ca4069a2bc712fcc41 100644 (file)
@@ -46,28 +46,6 @@ void GrDrawState::setFromPaint(const GrPaint& paint) {
 
 ////////////////////////////////////////////////////////////////////////////////
 
-namespace {
-
-/**
- * This function generates a mask that we like to have known at compile
- * time. When the number of stages is bumped or the way bits are defined in
- * GrDrawState.h changes this function should be rerun to generate the new mask.
- * (We attempted to force the compiler to generate the mask using recursive
- * templates but always wound up with static initializers under gcc, even if
- * they were just a series of immediate->memory moves.)
- *
- */
-void gen_tex_coord_mask(GrAttribBindings* texCoordMask) {
-    *texCoordMask = 0;
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        *texCoordMask |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s);
-    }
-}
-
-const GrAttribBindings kTexCoord_AttribBindingsMask = (1 << GrDrawState::kNumStages)-1;
-
-} //unnamed namespace
-
 const size_t GrDrawState::kVertexAttribSizes[kGrVertexAttribTypeCount] = {
     sizeof(float),          // kFloat_GrVertexAttribType
     2*sizeof(float),        // kVec2_GrVertexAttribType
@@ -106,7 +84,7 @@ const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = {
     kColor_AttribBindingsBit,
     kCoverage_AttribBindingsBit,
     kEdge_AttribBindingsBit,
-    kTexCoord_AttribBindingsMask
+    kLocalCoords_AttribBindingsBit,
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -210,20 +188,8 @@ bool GrDrawState::validateVertexAttribs() const {
     return true;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-
-bool GrDrawState::AttributesBindExplicitTexCoords(GrAttribBindings attribBindings) {
-    return SkToBool(kTexCoord_AttribBindingsMask & attribBindings);
-}
-
-////////////////////////////////////////////////////////////////////////////////
 
 void GrDrawState::VertexAttributesUnitTest() {
-    // Ensure that our tex coord mask is correct
-    GrAttribBindings texCoordMask;
-    gen_tex_coord_mask(&texCoordMask);
-    GrAssert(texCoordMask == kTexCoord_AttribBindingsMask);
-
     // not necessarily exhaustive
     static bool run;
     if (!run) {
@@ -259,27 +225,11 @@ void GrDrawState::VertexAttributesUnitTest() {
         attribs.push_back(currAttrib);
         GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) + 4*sizeof(float) ==
                  vertex_size(attribs.begin(), attribs.count()));
-
-        GrAttribBindings tcMask = 0;
-        GrAssert(!AttributesBindExplicitTexCoords(0));
-        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-            tcMask |= ExplicitTexCoordAttribBindingsBit(s);
-            GrAssert(AttributesBindExplicitTexCoords(tcMask));
-            GrAssert(StageBindsExplicitTexCoords(tcMask, s));
-            for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
-                GrAssert(!StageBindsExplicitTexCoords(tcMask, s2));
-            }
-        }
-        GrAssert(kTexCoord_AttribBindingsMask == tcMask);
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrDrawState::StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx) {
-    return SkToBool(bindings & ExplicitTexCoordAttribBindingsBit(stageIdx));
-}
-
 bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const {
 
     uint32_t validComponentFlags;
@@ -500,8 +450,7 @@ void GrDrawState::AutoViewMatrixRestore::restore() {
 }
 
 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
-                                             const SkMatrix& preconcatMatrix,
-                                             uint32_t explicitCoordStageMask) {
+                                             const SkMatrix& preconcatMatrix) {
     this->restore();
 
     fDrawState = drawState;
@@ -513,10 +462,10 @@ void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
     fViewMatrix = drawState->getViewMatrix();
     drawState->preConcatViewMatrix(preconcatMatrix);
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
+        if (drawState->isStageEnabled(s)) {
             fRestoreMask |= (1 << s);
             fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]);
-            drawState->fStages[s].preConcatCoordChange(preconcatMatrix);
+            drawState->fStages[s].localCoordChange(preconcatMatrix);
         }
     }
 }
@@ -535,8 +484,7 @@ void GrDrawState::AutoDeviceCoordDraw::restore() {
     fDrawState = NULL;
 }
 
-bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
-                                           uint32_t explicitCoordStageMask) {
+bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState) {
     GrAssert(NULL != drawState);
 
     this->restore();
@@ -552,7 +500,7 @@ bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
     bool inverted = false;
 
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
+        if (drawState->isStageEnabled(s)) {
             if (!inverted && !fViewMatrix.invert(&invVM)) {
                 // sad trombone sound
                 fDrawState = NULL;
@@ -563,7 +511,7 @@ bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
             fRestoreMask |= (1 << s);
             GrEffectStage* stage = drawState->fStages + s;
             stage->saveCoordChange(&fSavedCoordChanges[s]);
-            stage->preConcatCoordChange(invVM);
+            stage->localCoordChange(invVM);
         }
     }
     drawState->viewMatrix()->reset();
index 2203e889e327b88ed5453640225de321c4f83ecd..ffa7b093bba923c31152fc193b392b79ab003f00 100644 (file)
@@ -257,38 +257,26 @@ public:
     /**
      * The vertex data used by the current program is represented as a bitfield
      * of flags. Programs always use positions and may also use texture
-     * coordinates, per-vertex colors, per-vertex coverage and edge data. Each
-     * stage can use the explicit texture coordinates as its input texture
-     * coordinates or it may use the positions as texture coordinates.
+     * coordinates, per-vertex colors, per-vertex coverage and edge data. The
+     * local coords accessible by effects may either come from positions or
+     * be specified explicitly.
      */
 
-    /**
-     * Generates a bit indicating that a texture stage uses texture coordinates
-     *
-     * @param stageIdx    the stage that will use texture coordinates.
-     *
-     * @return the bit to add to a GrAttribBindings bitfield.
-     */
-    static int ExplicitTexCoordAttribBindingsBit(int stageIdx) {
-        GrAssert(stageIdx < kNumStages);
-        return (1 << stageIdx);
-    }
-
-    static bool StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx);
-
     /**
      * Additional Bits that can be specified in GrAttribBindings.
      */
     enum AttribBindingsBits {
+        /** explicit local coords are provided (instead of using pre-view-matrix positions) */
+        kLocalCoords_AttribBindingsBit        = 0x1,
         /* program uses colors (GrColor) */
-        kColor_AttribBindingsBit              = 1 << (kNumStages + 0),
+        kColor_AttribBindingsBit              = 0x2,
         /* program uses coverage (GrColor)
          */
-        kCoverage_AttribBindingsBit           = 1 << (kNumStages + 1),
+        kCoverage_AttribBindingsBit           = 0x4,
         /* program uses edge data. Distance to the edge is used to
          * compute a coverage. See GrDrawState::setVertexEdgeType().
          */
-        kEdge_AttribBindingsBit               = 1 << (kNumStages + 2),
+        kEdge_AttribBindingsBit               = 0x8,
         // for below assert
         kDummyAttribBindingsBit,
         kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
@@ -312,17 +300,6 @@ public:
     ////////////////////////////////////////////////////////////////////////////
     // Helpers for picking apart attribute bindings
 
-    /**
-     * Helper function to determine if program uses explicit texture
-     * coordinates.
-     *
-     * @param  bindings  attribute bindings to query
-     *
-     * @return true if program uses texture coordinates,
-     *         false otherwise.
-     */
-    static bool AttributesBindExplicitTexCoords(GrAttribBindings bindings);
-
     /**
      * Determines whether src alpha is guaranteed to be one for all src pixels
      */
@@ -356,9 +333,9 @@ public:
         kColor_AttribIndex,
         kCoverage_AttribIndex,
         kEdge_AttribIndex,
-        kTexCoord_AttribIndex,
+        kLocalCoords_AttribIndex,
 
-        kLast_AttribIndex = kTexCoord_AttribIndex
+        kLast_AttribIndex = kLocalCoords_AttribIndex
     };
     static const int kAttribIndexCount = kLast_AttribIndex + 1;
 
@@ -410,7 +387,7 @@ public:
 
     /**
      * Add a color filter that can be represented by a color and a mode. Applied
-     * after color-computing texture stages.
+     * after color-computing effect stages.
      */
     void setColorFilter(GrColor c, SkXfermode::Mode mode) {
         fCommon.fColorFilterColor = c;
@@ -497,7 +474,7 @@ public:
     }
 
     /**
-     * Creates a GrSimpleTextureEffect.
+     * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
      */
     void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
         GrAssert(!this->getStage(stageIdx).getEffect());
@@ -556,42 +533,16 @@ public:
     }
 
     /**
-     * Called when the source coord system is changing. preConcat gives the transformation from the
-     * old coord system to the new coord system.
+     * Called when the source coord system is changing. This ensures that effects will see the
+     * correct local coordinates. oldToNew gives the transformation from the old coord system in
+     * which the geometry was specified to the new coordinate system from which it will be rendered.
      */
-    void preConcatStageMatrices(const SkMatrix& preConcat) {
-        this->preConcatStageMatrices(~0U, preConcat);
-    }
-    /**
-     * Version of above that applies the update matrix selectively to stages via a mask.
-     */
-    void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) {
-        for (int i = 0; i < kNumStages; ++i) {
-            if (((1 << i) & stageMask) && this->isStageEnabled(i)) {
-                fStages[i].preConcatCoordChange(preConcat);
-            }
-        }
-    }
-
-    /**
-     * Called when the source coord system is changing. preConcatInverse is the inverse of the
-     * transformation from the old coord system to the new coord system. Returns false if the matrix
-     * cannot be inverted.
-     */
-    bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
-        SkMatrix inv;
-        bool computed = false;
+    void localCoordChange(const SkMatrix& oldToNew) {
         for (int i = 0; i < kNumStages; ++i) {
             if (this->isStageEnabled(i)) {
-                if (!computed && !preConcatInverse.invert(&inv)) {
-                    return false;
-                } else {
-                    computed = true;
-                }
-                fStages[i].preConcatCoordChange(preConcatInverse);
+                fStages[i].localCoordChange(oldToNew);
             }
         }
-        return true;
     }
 
     /// @}
@@ -832,11 +783,9 @@ public:
     public:
         AutoViewMatrixRestore() : fDrawState(NULL) {}
 
-        AutoViewMatrixRestore(GrDrawState* ds,
-                              const SkMatrix& preconcatMatrix,
-                              uint32_t explicitCoordStageMask = 0) {
+        AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
             fDrawState = NULL;
-            this->set(ds, preconcatMatrix, explicitCoordStageMask);
+            this->set(ds, preconcatMatrix);
         }
 
         ~AutoViewMatrixRestore() { this->restore(); }
@@ -846,9 +795,7 @@ public:
          */
         void restore();
 
-        void set(GrDrawState* drawState,
-                 const SkMatrix& preconcatMatrix,
-                 uint32_t explicitCoordStageMask = 0);
+        void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
 
         bool isSet() const { return NULL != fDrawState; }
 
@@ -875,15 +822,14 @@ public:
          * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
          * to specify such stages.
          */
-        AutoDeviceCoordDraw(GrDrawState* drawState,
-                            uint32_t explicitCoordStageMask = 0) {
+        AutoDeviceCoordDraw(GrDrawState* drawState) {
             fDrawState = NULL;
-            this->set(drawState, explicitCoordStageMask);
+            this->set(drawState);
         }
 
         ~AutoDeviceCoordDraw() { this->restore(); }
 
-        bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
+        bool set(GrDrawState* drawState);
 
         /**
          * Returns true if this object was successfully initialized on to a GrDrawState. It may
@@ -1197,8 +1143,7 @@ public:
             return false;
         }
         for (int i = 0; i < kAttribIndexCount; ++i) {
-            if ((i == kPosition_AttribIndex ||
-                    s.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
+            if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
                 fAttribIndices[i] != s.fAttribIndices[i]) {
                 return false;
             }
index 6fdc3a080fd8759a33fe8052e2cae4bf252dee40..cd4d4d2007f853d33b8ac1c681ce63d18fd4da75 100644 (file)
@@ -529,11 +529,9 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
 
 void GrDrawTarget::drawRect(const GrRect& rect,
                             const SkMatrix* matrix,
-                            const GrRect* srcRect,
-                            const SkMatrix* srcMatrix,
-                            int stage) {
+                            const GrRect* localRect,
+                            const SkMatrix* localMatrix) {
     GrAttribBindings bindings = 0;
-    uint32_t explicitCoordMask = 0;
     // position + (optional) texture coord
     static const GrVertexAttrib kAttribs[] = {
         {kVec2f_GrVertexAttribType, 0},
@@ -541,16 +539,15 @@ void GrDrawTarget::drawRect(const GrRect& rect,
     };
     int attribCount = 1;
 
-    if (NULL != srcRect) {
-        bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(stage);
+    if (NULL != localRect) {
+        bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
         attribCount = 2;
-        this->drawState()->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
-        explicitCoordMask = (1 << stage);
+        this->drawState()->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, 1);
     }
 
     GrDrawState::AutoViewMatrixRestore avmr;
     if (NULL != matrix) {
-        avmr.set(this->drawState(), *matrix, explicitCoordMask);
+        avmr.set(this->drawState(), *matrix);
     }
 
     this->drawState()->setVertexAttribs(kAttribs, attribCount);
@@ -564,15 +561,15 @@ void GrDrawTarget::drawRect(const GrRect& rect,
 
     size_t vsize = this->drawState()->getVertexSize();
     geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
-    if (NULL != srcRect) {
+    if (NULL != localRect) {
         GrAssert(attribCount == 2);
         GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
                                             kAttribs[1].fOffset);
-        coords->setRectFan(srcRect->fLeft, srcRect->fTop,
-                            srcRect->fRight, srcRect->fBottom,
-                            vsize);
-        if (NULL != srcMatrix) {
-            srcMatrix->mapPointsWithStride(coords, vsize, 4);
+        coords->setRectFan(localRect->fLeft, localRect->fTop,
+                           localRect->fRight, localRect->fBottom,
+                           vsize);
+        if (NULL != localMatrix) {
+            localMatrix->mapPointsWithStride(coords, vsize, 4);
         }
     }
 
index a011aaef997799ac8234b455a8853ca98638730c..de8c5c4580881f3eb3fac34854aa59aca4402b81 100644 (file)
@@ -388,8 +388,8 @@ public:
     /**
      * Helper function for drawing rects. This does not use the current index
      * and vertex sources. After returning, the vertex and index sources may
-     * have changed. They should be reestablished before the next drawIndexed
-     * or drawNonIndexed. This cannot be called between reserving and releasing
+     * have changed. They should be reestablished before the next draw call.
+     * This cannot be called between reserving and releasing
      * geometry.
      *
      * A subclass may override this to perform more optimal rect rendering. Its
@@ -397,34 +397,29 @@ public:
      * (e.g. drawNonIndexed, drawIndexedInstances, ...). The base class draws a two
      * triangle fan using drawNonIndexed from reserved vertex space.
      *
-     * @param rect      the rect to draw
-     * @param matrix    optional matrix applied to rect (before viewMatrix)
-     * @param srcRects  specifies rect for explicit texture coordinates.
-     *                  if srcRect is non-NULL then that rect will be used
-     *                  as the coordinates for the given stage.
-     * @param srcMatrix   optional matrix applied to srcRect. If
+     * @param rect        the rect to draw
+     * @param matrix      optional matrix applied to rect (before viewMatrix)
+     * @param localRect   optional rect that specifies local coords to map onto
+     *                    rect. If NULL then rect serves as the local coords.
+     * @param localMatrix optional matrix applied to localRect. If
      *                    srcRect is non-NULL and srcMatrix is non-NULL
      *                    then srcRect will be transformed by srcMatrix.
      *                    srcMatrix can be NULL when no srcMatrix is desired.
-     * @param stage     the stage to be given explicit texture coordinates.
-     *                  Ignored if srcRect is NULL.
      */
     virtual void drawRect(const GrRect& rect,
                           const SkMatrix* matrix,
-                          const GrRect* srcRect,
-                          const SkMatrix* srcMatrix,
-                          int stage);
+                          const GrRect* localRect,
+                          const SkMatrix* localMatrix);
 
     /**
-     * Helper for drawRect when the caller doesn't need separate src rects or
-     * matrices.
+     * Helper for drawRect when the caller doesn't need separate local rects or matrices.
      */
     void drawSimpleRect(const GrRect& rect, const SkMatrix* matrix = NULL) {
-        drawRect(rect, matrix, NULL, NULL, 0);
+        drawRect(rect, matrix, NULL, NULL);
     }
     void drawSimpleRect(const GrIRect& irect, const SkMatrix* matrix = NULL) {
         SkRect rect = SkRect::MakeFromIRect(irect);
-        this->drawRect(rect, matrix, NULL, NULL, 0);
+        this->drawRect(rect, matrix, NULL, NULL);
     }
 
     /**
index 31b1a57c1f503fc193ee65fd380b6885a7543984..6966858eae40400b6b51ba21515b98f8e2946aa6 100644 (file)
@@ -74,9 +74,8 @@ void get_vertex_bounds(const void* vertices,
 
 void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
                                    const SkMatrix* matrix,
-                                   const GrRect* srcRect,
-                                   const SkMatrix* srcMatrix,
-                                   int stage) {
+                                   const GrRect* localRect,
+                                   const SkMatrix* localMatrix) {
 
     GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
     GrDrawState::AutoColorRestore acr;
@@ -86,7 +85,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
     GrColor color = drawState->getColor();
     GrVertexAttribArray<3> attribs;
     size_t currentOffset = 0;
-    int colorOffset = -1, texOffset = -1;
+    int colorOffset = -1, localOffset = -1;
 
     // set position attrib
     drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
@@ -115,15 +114,13 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
         acr.set(drawState, 0xFFFFFFFF);
     }
 
-    uint32_t explicitCoordMask = 0;
-    if (NULL != srcRect) {
-        bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(stage);
-        drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, attribs.count());
+    if (NULL != localRect) {
+        bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
+        drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
         currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
         attribs.push_back(currAttrib);
-        texOffset = currentOffset;
+        localOffset = currentOffset;
         currentOffset += sizeof(GrPoint);
-        explicitCoordMask = (1 << stage);
     }
 
     drawState->setVertexAttribs(attribs.begin(), attribs.count());
@@ -145,7 +142,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
     // When the caller has provided an explicit source rect for a stage then we don't want to
     // modify that stage's matrix. Otherwise if the effect is generating its source rect from
     // the vertex positions then we have to account for the view matrix change.
-    GrDrawState::AutoDeviceCoordDraw adcd(drawState, explicitCoordMask);
+    GrDrawState::AutoDeviceCoordDraw adcd(drawState);
     if (!adcd.succeeded()) {
         return;
     }
@@ -161,15 +158,13 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
     // unnecessary clipping in our onDraw().
     get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);
 
-    if (texOffset >= 0) {
-        GrAssert(explicitCoordMask != 0);
-        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
-                                            texOffset);
-        coords->setRectFan(srcRect->fLeft, srcRect->fTop,
-                            srcRect->fRight, srcRect->fBottom,
+    if (localOffset >= 0) {
+        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset);
+        coords->setRectFan(localRect->fLeft, localRect->fTop,
+                           localRect->fRight, localRect->fBottom,
                             vsize);
-        if (NULL != srcMatrix) {
-            srcMatrix->mapPointsWithStride(coords, vsize, 4);
+        if (NULL != localMatrix) {
+            localMatrix->mapPointsWithStride(coords, vsize, 4);
         }
     }
 
index f04bb846d6af67f7a9835382650785e2937f9761..cb51bc46726b8e8f2b5fea96c35efa49bbede30d 100644 (file)
@@ -78,9 +78,8 @@ public:
                        GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
     virtual void drawRect(const GrRect& rect,
                           const SkMatrix* matrix,
-                          const GrRect* srcRect,
-                          const SkMatrix* srcMatrix,
-                          int stage) SK_OVERRIDE;
+                          const GrRect* localRect,
+                          const SkMatrix* localMatrix) SK_OVERRIDE;
 
 protected:
     virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
index fe9fd8228b2e2acc8cc41c2f5ebf0a2855ec79ea..2cf56d63d633eb956144abcb1fbffb626fb353cc 100644 (file)
@@ -197,18 +197,29 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
         // && edge rendering (kEdgeEffectStage in GrContext)
         kPathMaskStage = GrPaint::kTotalStages,
     };
-    GrAssert(!drawState->isStageEnabled(kPathMaskStage));
-    drawState->createTextureEffect(kPathMaskStage, texture, SkMatrix::I());
-    SkScalar w = SkIntToScalar(rect.width());
-    SkScalar h = SkIntToScalar(rect.height());
-    GrRect maskRect = GrRect::MakeWH(w / texture->width(),
-                                     h / texture->height());
 
     GrRect dstRect = GrRect::MakeLTRB(
                             SK_Scalar1 * rect.fLeft,
                             SK_Scalar1 * rect.fTop,
                             SK_Scalar1 * rect.fRight,
                             SK_Scalar1 * rect.fBottom);
-    target->drawRect(dstRect, NULL, &maskRect, NULL, kPathMaskStage);
+
+    // We want to use device coords to compute the texture coordinates. We set our matrix to be
+    // equal to the view matrix followed by a translation so that the top-left of the device bounds
+    // maps to 0,0, and then a scaling matrix to normalized coords. We apply this matrix to the
+    // vertex positions rather than local coords.
+    SkMatrix maskMatrix;
+    maskMatrix.setIDiv(texture->width(), texture->height());
+    maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));
+    maskMatrix.preConcat(drawState->getViewMatrix());
+
+    GrAssert(!drawState->isStageEnabled(kPathMaskStage));
+    drawState->setEffect(kPathMaskStage,
+                         GrSimpleTextureEffect::Create(texture,
+                                                       maskMatrix,
+                                                       false,
+                                                       GrEffect::kPosition_CoordsType))->unref();
+
+    target->drawSimpleRect(dstRect);
     drawState->disableStage(kPathMaskStage);
 }
index 5ff13b0fdce5eab75107446bbe8c1daaeeb4edda..ab2bc424d6cc66e5e9f6f0c4b967c44040d268a5 100644 (file)
 #include "SkPath.h"
 #include "SkStrokeRec.h"
 
-enum {
-    // glyph rendering shares this stage with edge rendering
-    // (kEdgeEffectStage in GrContext) && SW path rendering
-    // (kPathMaskStage in GrSWMaskHelper)
-    kGlyphMaskStage = GrPaint::kTotalStages,
-};
+// glyph rendering shares this stage with edge rendering (kEdgeEffectStage in GrContext) && SW path
+// rendering (kPathMaskStage in GrSWMaskHelper)
+static const int kGlyphMaskStage = GrPaint::kTotalStages;
+static const int kGlyphCoordsAttributeIndex = 1;
 
 void GrTextContext::flushGlyphs() {
     if (NULL == fDrawTarget) {
@@ -35,7 +33,11 @@ void GrTextContext::flushGlyphs() {
         GrAssert(GrIsALIGN4(fCurrVertex));
         GrAssert(fCurrTexture);
         GrTextureParams params(SkShader::kRepeat_TileMode, false);
-        drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, SkMatrix::I(), params);
+
+        // This effect could be stored with one of the cache objects (atlas?)
+        drawState->setEffect(kGlyphMaskStage,
+                             GrSimpleTextureEffect::CreateWithCustomCoords(fCurrTexture, params),
+                             kGlyphCoordsAttributeIndex)->unref();
 
         if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
             if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
@@ -195,7 +197,7 @@ HAS_ATLAS:
             {kVec2f_GrVertexAttribType, 0},
             {kVec2f_GrVertexAttribType, sizeof(GrPoint)}
         };
-        static const GrAttribBindings kAttribBindings = GrDrawState::ExplicitTexCoordAttribBindingsBit(kGlyphMaskStage);
+        static const GrAttribBindings kAttribBindings = 0;
 
        // If we need to reserve vertices allow the draw target to suggest
         // a number of verts to reserve and whether to perform a flush.
@@ -214,7 +216,6 @@ HAS_ATLAS:
             fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
         }
         fDrawTarget->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
-        fDrawTarget->drawState()->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
         fDrawTarget->drawState()->setAttribBindings(kAttribBindings);
         fMaxVertices = kDefaultRequestedVerts;
         // ignore return, no point in flushing again.
index ba7350226b33c323b9e01ce176f3fcd061856a7b..4ecdedbcde58642bdde8b7ae33e03b21c4bbed24 100644 (file)
 
 class GrGLCircleEdgeEffect : public GrGLEffect {
 public:
-    GrGLCircleEdgeEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
+    GrGLCircleEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
     : INHERITED (factory) {}
 
     virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrEffectStage& stage,
+                          const GrDrawEffect& drawEffect,
                           EffectKey key,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        const GrCircleEdgeEffect& effect = GetEffectFromStage<GrCircleEdgeEffect>(stage);
-
+        const GrCircleEdgeEffect& circleEffect = drawEffect.castEffect<GrCircleEdgeEffect>();
         const char *vsName, *fsName;
         builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
 
         const SkString* attrName =
-            builder->getEffectAttributeName(stage.getVertexAttribIndices()[0]);
+            builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
         builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
 
         builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n",
                                builder->fragmentPosition(), fsName);
         builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
-        if (effect.isStroked()) {
+        if (circleEffect.isStroked()) {
             builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
             builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
         }
@@ -48,13 +46,13 @@ public:
         builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
     }
 
-    static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        const GrCircleEdgeEffect& effect = GetEffectFromStage<GrCircleEdgeEffect>(stage);
+    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        const GrCircleEdgeEffect& circleEffect = drawEffect.castEffect<GrCircleEdgeEffect>();
 
-        return effect.isStroked() ? 0x1 : 0x0;
+        return circleEffect.isStroked() ? 0x1 : 0x0;
     }
 
-    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
     }
 
 private:
index 5cc05e2f39edb04abae81711ff0631ae180f92b5..df8ab8d835a24bc15b99c5d418233f4a245d45c0 100644 (file)
 class GrGLConfigConversionEffect : public GrGLEffect {
 public:
     GrGLConfigConversionEffect(const GrBackendEffectFactory& factory,
-                               const GrEffectRef& s) : INHERITED (factory) {
-        const GrConfigConversionEffect& effect = CastEffect<GrConfigConversionEffect>(s);
+                               const GrDrawEffect& drawEffect)
+    : INHERITED (factory)
+    , fEffectMatrix(drawEffect.castEffect<GrConfigConversionEffect>().coordsType()) {
+        const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigConversionEffect>();
         fSwapRedAndBlue = effect.swapsRedAndBlue();
         fPMConversion = effect.pmConversion();
     }
 
     virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey key,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
         const char* coords;
-        GrSLType coordsType = fEffectMatrix.emitCode(builder, key, vertexCoords, &coords);
+        GrSLType coordsType = fEffectMatrix.emitCode(builder, key, &coords);
         builder->fsCodeAppendf("\t\t%s = ", outputColor);
         builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
                                      samplers[0],
@@ -71,23 +72,19 @@ public:
         builder->fsCodeAppend(modulate.c_str());
     }
 
-    void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-        const GrConfigConversionEffect& effect =
-            GetEffectFromStage<GrConfigConversionEffect>(stage);
-        fEffectMatrix.setData(uman,
-                              effect.getMatrix(),
-                              stage.getCoordChangeMatrix(),
-                              effect.texture(0));
+    void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
+        const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
+        fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0));
     }
 
-    static inline EffectKey GenKey(const GrEffectStage& s, const GrGLCaps&) {
-        const GrConfigConversionEffect& effect = GetEffectFromStage<GrConfigConversionEffect>(s);
-        EffectKey key = static_cast<EffectKey>(effect.swapsRedAndBlue()) |
-                        (effect.pmConversion() << 1);
+    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
+        EffectKey key = static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1);
         key <<= GrGLEffectMatrix::kKeyBits;
-        EffectKey matrixKey =  GrGLEffectMatrix::GenKey(effect.getMatrix(),
-                                                        s.getCoordChangeMatrix(),
-                                                        effect.texture(0));
+        EffectKey matrixKey =  GrGLEffectMatrix::GenKey(conv.getMatrix(),
+                                                        drawEffect,
+                                                        conv.coordsType(),
+                                                        conv.texture(0));
         GrAssert(!(matrixKey & key));
         return matrixKey | key;
     }
index 794a9367df63f15b3c5a314decd1c10706463f65..924b03c1779c5cc40e1ee334f297b303921a27bb 100644 (file)
@@ -18,19 +18,18 @@ static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
 
 class GrGLConvolutionEffect : public GrGLEffect {
 public:
-    GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrEffectRef&);
+    GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
 private:
     int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
@@ -44,23 +43,23 @@ private:
 };
 
 GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
-                                             const GrEffectRef& effect)
+                                             const GrDrawEffect& drawEffect)
     : INHERITED(factory)
     , fKernelUni(kInvalidUniformHandle)
-    , fImageIncrementUni(kInvalidUniformHandle) {
-    const GrConvolutionEffect& c = CastEffect<GrConvolutionEffect>(effect);
+    , fImageIncrementUni(kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrConvolutionEffect>().coordsType()) {
+    const GrConvolutionEffect& c = drawEffect.castEffect<GrConvolutionEffect>();
     fRadius = c.radius();
 }
 
 void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
-                                     const GrEffectStage&,
+                                     const GrDrawEffect&,
                                      EffectKey key,
-                                     const char* vertexCoords,
                                      const char* outputColor,
                                      const char* inputColor,
                                      const TextureSamplerArray& samplers) {
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                              kVec2f_GrSLType, "ImageIncrement");
     fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
@@ -90,8 +89,9 @@ void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
     builder->fsCodeAppend(modulate.c_str());
 }
 
-void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(stage);
+void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman,
+                                    const GrDrawEffect& drawEffect) {
+    const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
     GrTexture& texture = *conv.texture(0);
     // the code we generated was for a specific kernel radius
     GrAssert(conv.radius() == fRadius);
@@ -108,15 +108,17 @@ void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffe
     }
     uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
     uman.set1fv(fKernelUni, 0, this->width(), conv.kernel());
-    fEffectMatrix.setData(uman, conv.getMatrix(), stage.getCoordChangeMatrix(), conv.texture(0));
+    fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0));
 }
 
-GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
-    const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(s);
+GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
+                                                    const GrGLCaps&) {
+    const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
     EffectKey key = conv.radius();
     key <<= GrGLEffectMatrix::kKeyBits;
     EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(),
-                                                   s.getCoordChangeMatrix(),
+                                                   drawEffect,
+                                                   conv.coordsType(),
                                                    conv.texture(0));
     return key | matrixKey;
 }
index 37432f05659627f1976c60a794df415109bfcf7d..12f3197d55273a8f629c4b5fc6466fe202955dba 100644 (file)
 
 class GrGLEllipseEdgeEffect : public GrGLEffect {
 public:
-    GrGLEllipseEdgeEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
+    GrGLEllipseEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
     : INHERITED (factory) {}
 
     virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrEffectStage& stage,
+                          const GrDrawEffect& drawEffect,
                           EffectKey key,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        const GrEllipseEdgeEffect& effect = GetEffectFromStage<GrEllipseEdgeEffect>(stage);
+        const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>();
 
         const char *vsCenterName, *fsCenterName;
         const char *vsEdgeName, *fsEdgeName;
 
         builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName);
         const SkString* attr0Name =
-            builder->getEffectAttributeName(stage.getVertexAttribIndices()[0]);
+            builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
         builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_str());
 
         builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fsEdgeName);
         const SkString* attr1Name =
-            builder->getEffectAttributeName(stage.getVertexAttribIndices()[1]);
+            builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
         builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str());
 
         // translate to origin
@@ -50,7 +49,7 @@ public:
         // compare outer lengths against xOuterRadius
         builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", fsEdgeName);
 
-        if (effect.isStroked()) {
+        if (ellipseEffect.isStroked()) {
             builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName);
             builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n");
 
@@ -64,13 +63,13 @@ public:
         builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
     }
 
-    static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        const GrEllipseEdgeEffect& effect = GetEffectFromStage<GrEllipseEdgeEffect>(stage);
+    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>();
 
-        return effect.isStroked() ? 0x1 : 0x0;
+        return ellipseEffect.isStroked() ? 0x1 : 0x0;
     }
 
-    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
     }
 
 private:
index 37e6eb4b25204b203002d42f1f9e8c6f5e613dbe..80627aabd22c45c0e970057b85f31e29e865a7db 100644 (file)
 
 class GrGLSimpleTextureEffect : public GrGLEffect {
 public:
-    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
-    : INHERITED (factory) {}
+    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
+    : INHERITED (factory) {
+        GrEffect::CoordsType coordsType =
+            drawEffect.castEffect<GrSimpleTextureEffect>().coordsType();
+        if (GrEffect::kCustom_CoordsType != coordsType) {
+            SkNEW_IN_TLAZY(&fEffectMatrix, GrGLEffectMatrix, (coordsType));
+        }
+    }
 
     virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrEffectStage&,
+                          const GrDrawEffect& drawEffect,
                           EffectKey key,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        const char* coordName;
-        GrSLType coordType = fEffectMatrix.emitCode(builder, key, vertexCoords, &coordName);
+        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
+        const char* fsCoordName;
+        GrSLType fsCoordSLType;
+        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
+            GrAssert(ste.getMatrix().isIdentity());
+            GrAssert(1 == ste.numVertexAttribs());
+            fsCoordSLType = kVec2f_GrSLType;
+            const char* vsVaryingName;
+            builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsCoordName);
+            const char* attrName =
+                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
+            builder->vsCodeAppendf("\t%s = %s;", vsVaryingName, attrName);
+        } else {
+            fsCoordSLType = fEffectMatrix.get()->emitCode(builder, key, &fsCoordName);
+        }
         builder->fsCodeAppendf("\t%s = ", outputColor);
         builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
                                                 inputColor,
                                                 samplers[0],
-                                                coordName,
-                                                coordType);
+                                                fsCoordName,
+                                                fsCoordSLType);
         builder->fsCodeAppend(";\n");
     }
 
-    static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        const GrSimpleTextureEffect& ste = GetEffectFromStage<GrSimpleTextureEffect>(stage);
-        return GrGLEffectMatrix::GenKey(ste.getMatrix(),
-                                        stage.getCoordChangeMatrix(),
-                                        ste.texture(0));
+    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
+        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
+            return 1 << GrGLEffectMatrix::kKeyBits;
+        } else {
+            return GrGLEffectMatrix::GenKey(ste.getMatrix(),
+                                            drawEffect,
+                                            ste.coordsType(),
+                                            ste.texture(0));
+        }
     }
 
-    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
-        const GrSimpleTextureEffect& ste = GetEffectFromStage<GrSimpleTextureEffect>(stage);
-        fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
+    virtual void setData(const GrGLUniformManager& uman,
+                         const GrDrawEffect& drawEffect) SK_OVERRIDE {
+        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
+        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
+            GrAssert(ste.getMatrix().isIdentity());
+        } else {
+            fEffectMatrix.get()->setData(uman, ste.getMatrix(), drawEffect, ste.texture(0));
+        }
     }
 
 private:
-    GrGLEffectMatrix fEffectMatrix;
+    SkTLazy<GrGLEffectMatrix> fEffectMatrix;
     typedef GrGLEffect INHERITED;
 };
 
@@ -72,6 +100,28 @@ GrEffectRef* GrSimpleTextureEffect::TestCreate(SkMWCRandom* random,
                                                GrTexture* textures[]) {
     int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
                                       GrEffectUnitTest::kAlphaTextureIdx;
-    const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
-    return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
+    static const SkShader::TileMode kTileModes[] = {
+        SkShader::kClamp_TileMode,
+        SkShader::kRepeat_TileMode,
+        SkShader::kMirror_TileMode,
+    };
+    SkShader::TileMode tileModes[] = {
+        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
+        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
+    };
+    GrTextureParams params(tileModes, random->nextBool());
+
+    static const CoordsType kCoordsTypes[] = {
+        kLocal_CoordsType,
+        kPosition_CoordsType,
+        kCustom_CoordsType
+    };
+    CoordsType coordsType = kCoordsTypes[random->nextULessThan(GR_ARRAY_COUNT(kCoordsTypes))];
+
+    if (kCustom_CoordsType == coordsType) {
+        return GrSimpleTextureEffect::CreateWithCustomCoords(textures[texIdx], params);
+    } else {
+        const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
+        return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
+    }
 }
index ffc05e5b52263ac917287a60e59fb843b3689156..661f40f037246fd4fa2406c0d00975db2dc7024d 100644 (file)
@@ -14,25 +14,50 @@ class GrGLSimpleTextureEffect;
 
 /**
  * The output color of this effect is a modulation of the input color and a sample from a texture.
- * The coord to sample the texture is determine by a matrix. It allows explicit specification of
- * the filtering and wrap modes (GrTextureParams).
+ * It allows explicit specification of the filtering and wrap modes (GrTextureParams). It can use
+ * local coords, positions, or a custom vertex attribute as input texture coords. The input coords
+ * can have a matrix applied in the VS in both the local and position cases but not with a custom
+ * attribute coords at this time. It will add a varying to input interpolate texture coords to the
+ * FS.
  */
 class GrSimpleTextureEffect : public GrSingleTextureEffect {
 public:
     /* unfiltered, clamp mode */
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix)));
+    static GrEffectRef* Create(GrTexture* tex,
+                               const SkMatrix& matrix,
+                               CoordsType coordsType = kLocal_CoordsType) {
+        GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, false, coordsType)));
         return CreateEffectRef(effect);
     }
 
     /* clamp mode */
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp)));
+    static GrEffectRef* Create(GrTexture* tex,
+                               const SkMatrix& matrix,
+                               bool bilerp,
+                               CoordsType coordsType = kLocal_CoordsType) {
+        GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+        AutoEffectUnref effect(
+            SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp, coordsType)));
         return CreateEffectRef(effect);
     }
 
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p)));
+    static GrEffectRef* Create(GrTexture* tex,
+                               const SkMatrix& matrix,
+                               const GrTextureParams& p,
+                               CoordsType coordsType = kLocal_CoordsType) {
+        GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordsType)));
+        return CreateEffectRef(effect);
+    }
+
+    /** Variant that requires the client to install a custom kVec2 vertex attribute that will be
+        the source of the coords. No matrix is allowed in this mode. */
+    static GrEffectRef* CreateWithCustomCoords(GrTexture* tex, const GrTextureParams& p) {
+        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex,
+                                                                  SkMatrix::I(),
+                                                                  p,
+                                                                  kCustom_CoordsType)));
         return CreateEffectRef(effect);
     }
 
@@ -47,16 +72,28 @@ public:
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix)
-        : GrSingleTextureEffect(texture, matrix) {}
-    GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, bool bilerp)
-        : GrSingleTextureEffect(texture, matrix, bilerp) {}
-    GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params)
-        : GrSingleTextureEffect(texture, matrix, params) {}
+    GrSimpleTextureEffect(GrTexture* texture,
+                          const SkMatrix& matrix,
+                          bool bilerp,
+                          CoordsType coordsType)
+        : GrSingleTextureEffect(texture, matrix, bilerp, coordsType) {
+        GrAssert(kLocal_CoordsType == coordsType || kPosition_CoordsType == coordsType);
+    }
+
+    GrSimpleTextureEffect(GrTexture* texture,
+                          const SkMatrix& matrix,
+                          const GrTextureParams& params,
+                          CoordsType coordsType)
+        : GrSingleTextureEffect(texture, matrix, params, coordsType) {
+        if (kCustom_CoordsType == coordsType) {
+            GrAssert(matrix.isIdentity());
+            this->addVertexAttrib(kVec2f_GrSLType);
+        }
+    }
 
     virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
         const GrSimpleTextureEffect& ste = CastEffect<GrSimpleTextureEffect>(other);
-        return this->hasSameTextureParamsAndMatrix(ste);
+        return this->hasSameTextureParamsMatrixAndCoordsType(ste);
     }
 
     GR_DECLARE_EFFECT_TEST;
index 7183ba324432b45db696918541dbdec5e86738bb..0c671f16d039450aafc9e868fa6f36e7ba22a548 100644 (file)
@@ -7,23 +7,32 @@
 
 #include "effects/GrSingleTextureEffect.h"
 
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m)
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+                                             const SkMatrix& m,
+                                             CoordsType coordsType)
     : fTextureAccess(texture)
-    , fMatrix(m) {
+    , fMatrix(m)
+    , fCoordsType(coordsType) {
     this->addTextureAccess(&fTextureAccess);
 }
 
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m, bool bilerp)
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+                                             const SkMatrix& m,
+                                             bool bilerp,
+                                             CoordsType coordsType)
     : fTextureAccess(texture, bilerp)
-    , fMatrix(m) {
+    , fMatrix(m)
+    , fCoordsType(coordsType) {
     this->addTextureAccess(&fTextureAccess);
 }
 
 GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
                                              const SkMatrix& m,
-                                             const GrTextureParams& params)
+                                             const GrTextureParams& params,
+                                             CoordsType coordsType)
     : fTextureAccess(texture, params)
-    , fMatrix(m) {
+    , fMatrix(m)
+    , fCoordsType(coordsType) {
     this->addTextureAccess(&fTextureAccess);
 }
 
index 4f25ddb38dc1dde6ac7ad8f72ce17cc10e416f0b..82037cf6e9056702310bde87c55eb34ef8505a5c 100644 (file)
@@ -14,7 +14,8 @@
 class GrTexture;
 
 /**
- * A base class for effects that draw a single texture with a texture matrix.
+ * A base class for effects that draw a single texture with a texture matrix. This effect has no
+ * backend implementations. One must be provided by the subclass.
  */
 class GrSingleTextureEffect : public GrEffect {
 public:
@@ -22,20 +23,29 @@ public:
 
     const SkMatrix& getMatrix() const { return fMatrix; }
 
+    /** Indicates whether the matrix operates on local coords or positions */
+    CoordsType coordsType() const { return fCoordsType; }
+
 protected:
-    GrSingleTextureEffect(GrTexture*, const SkMatrix&); /* unfiltered, clamp mode */
-    GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp); /* clamp mode */
-    GrSingleTextureEffect(GrTexture*, const SkMatrix&, const GrTextureParams&);
+    /** unfiltered, clamp mode */
+    GrSingleTextureEffect(GrTexture*, const SkMatrix&, CoordsType = kLocal_CoordsType);
+    /** clamp mode */
+    GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp, CoordsType = kLocal_CoordsType);
+    GrSingleTextureEffect(GrTexture*,
+                          const SkMatrix&,
+                          const GrTextureParams&,
+                          CoordsType = kLocal_CoordsType);
 
     /**
      * Helper for subclass onIsEqual() functions.
      */
-    bool hasSameTextureParamsAndMatrix(const GrSingleTextureEffect& other) const {
+    bool hasSameTextureParamsMatrixAndCoordsType(const GrSingleTextureEffect& other) const {
         const GrTextureAccess& otherAccess = other.fTextureAccess;
         // We don't have to check the accesses' swizzles because they are inferred from the texture.
         return fTextureAccess.getTexture() == otherAccess.getTexture() &&
                fTextureAccess.getParams() == otherAccess.getParams() &&
-               this->getMatrix().cheapEqualTo(other.getMatrix());
+               this->getMatrix().cheapEqualTo(other.getMatrix()) &&
+               fCoordsType == other.fCoordsType;
     }
 
     /**
@@ -55,6 +65,7 @@ protected:
 private:
     GrTextureAccess fTextureAccess;
     SkMatrix        fMatrix;
+    CoordsType      fCoordsType;
 
     typedef GrEffect INHERITED;
 };
index e54af25ca05ce23718ccdf10116436121c65d411..b1fd3ed6d5445dff484960492f4f68fd53228e7f 100644 (file)
 
 class GrGLTextureDomainEffect : public GrGLEffect {
 public:
-    GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrEffectRef&);
+    GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
 
     virtual void emitCode(GrGLShaderBuilder*,
-                          const GrEffectStage&,
+                          const GrDrawEffect&,
                           EffectKey,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
 
 private:
     GrGLUniformManager::UniformHandle fNameUni;
@@ -37,27 +36,27 @@ private:
 };
 
 GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
-                                                 const GrEffectRef&)
+                                                 const GrDrawEffect& drawEffect)
     : INHERITED(factory)
-    , fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
+    , fNameUni(GrGLUniformManager::kInvalidUniformHandle)
+    , fEffectMatrix(drawEffect.castEffect<GrTextureDomainEffect>().coordsType()) {
     fPrevDomain[0] = SK_FloatNaN;
 }
 
 void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
-                                       const GrEffectStage& stage,
+                                       const GrDrawEffect& drawEffect,
                                        EffectKey key,
-                                       const char* vertexCoords,
                                        const char* outputColor,
                                        const char* inputColor,
                                        const TextureSamplerArray& samplers) {
-    const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
+    const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
 
     const char* coords;
-    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
     const char* domain;
     fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                     kVec4f_GrSLType, "TexDom", &domain);
-    if (GrTextureDomainEffect::kClamp_WrapMode == effect.wrapMode()) {
+    if (GrTextureDomainEffect::kClamp_WrapMode == texDom.wrapMode()) {
 
         builder->fsCodeAppendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
                                 coords, domain, domain);
@@ -69,7 +68,7 @@ void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
                                                 "clampCoord");
         builder->fsCodeAppend(";\n");
     } else {
-        GrAssert(GrTextureDomainEffect::kDecal_WrapMode == effect.wrapMode());
+        GrAssert(GrTextureDomainEffect::kDecal_WrapMode == texDom.wrapMode());
 
         if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
             // On the NexusS and GalaxyNexus, the other path (with the 'any'
@@ -106,9 +105,10 @@ void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
     }
 }
 
-void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
-    const GrRect& domain = effect.domain();
+void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
+                                      const GrDrawEffect& drawEffect) {
+    const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
+    const GrRect& domain = texDom.domain();
 
     float values[4] = {
         SkScalarToFloat(domain.left()),
@@ -117,7 +117,7 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEf
         SkScalarToFloat(domain.bottom())
     };
     // vertical flip if necessary
-    if (kBottomLeft_GrSurfaceOrigin == effect.texture(0)->origin()) {
+    if (kBottomLeft_GrSurfaceOrigin == texDom.texture(0)->origin()) {
         values[1] = 1.0f - values[1];
         values[3] = 1.0f - values[3];
         // The top and bottom were just flipped, so correct the ordering
@@ -128,18 +128,20 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEf
         uman.set4fv(fNameUni, 0, 1, values);
     }
     fEffectMatrix.setData(uman,
-                          effect.getMatrix(),
-                          stage.getCoordChangeMatrix(),
-                          effect.texture(0));
+                          texDom.getMatrix(),
+                          drawEffect,
+                          texDom.texture(0));
 }
 
-GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-    const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
-    EffectKey key = effect.wrapMode();
+GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
+                                                      const GrGLCaps&) {
+    const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
+    EffectKey key = texDom.wrapMode();
     key <<= GrGLEffectMatrix::kKeyBits;
-    EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
-                                                   stage.getCoordChangeMatrix(),
-                                                   effect.texture(0));
+    EffectKey matrixKey = GrGLEffectMatrix::GenKey(texDom.getMatrix(),
+                                                   drawEffect,
+                                                   texDom.coordsType(),
+                                                   texDom.texture(0));
     return key | matrixKey;
 }
 
@@ -150,7 +152,8 @@ GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
                                            const SkMatrix& matrix,
                                            const GrRect& domain,
                                            WrapMode wrapMode,
-                                           bool bilerp) {
+                                           bool bilerp,
+                                           CoordsType coordsType) {
     static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
     if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
         return GrSimpleTextureEffect::Create(texture, matrix, bilerp);
@@ -172,7 +175,8 @@ GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
                                                                   matrix,
                                                                   clippedDomain,
                                                                   wrapMode,
-                                                                  bilerp)));
+                                                                  bilerp,
+                                                                  coordsType)));
         return CreateEffectRef(effect);
 
     }
@@ -182,8 +186,9 @@ GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
                                              const SkMatrix& matrix,
                                              const GrRect& domain,
                                              WrapMode wrapMode,
-                                             bool bilerp)
-    : GrSingleTextureEffect(texture, matrix, bilerp)
+                                             bool bilerp,
+                                             CoordsType coordsType)
+    : GrSingleTextureEffect(texture, matrix, bilerp, coordsType)
     , fWrapMode(wrapMode)
     , fTextureDomain(domain) {
 }
@@ -198,7 +203,8 @@ const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const {
 
 bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
     const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
-    return this->hasSameTextureParamsAndMatrix(s) && this->fTextureDomain == s.fTextureDomain;
+    return this->hasSameTextureParamsMatrixAndCoordsType(s) &&
+           this->fTextureDomain == s.fTextureDomain;
 }
 
 void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
@@ -225,5 +231,12 @@ GrEffectRef* GrTextureDomainEffect::TestCreate(SkMWCRandom* random,
     domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
     WrapMode wrapMode = random->nextBool() ? kClamp_WrapMode : kDecal_WrapMode;
     const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
-    return GrTextureDomainEffect::Create(textures[texIdx], matrix, domain, wrapMode);
+    bool bilerp = random->nextBool();
+    CoordsType coords = random->nextBool() ? kLocal_CoordsType : kPosition_CoordsType;
+    return GrTextureDomainEffect::Create(textures[texIdx],
+                                         matrix,
+                                         domain,
+                                         wrapMode,
+                                         bilerp,
+                                         coords);
 }
index b7f665cba3f08d1765d791575c3fc9a7174bc8c6..8b1f2b6f611066c9a55987fd9bc091de2aa3f0dc 100644 (file)
@@ -38,7 +38,8 @@ public:
                                const SkMatrix&,
                                const SkRect& domain,
                                WrapMode,
-                               bool bilerp = false);
+                               bool bilerp,
+                               CoordsType = kLocal_CoordsType);
 
     virtual ~GrTextureDomainEffect();
 
@@ -75,7 +76,8 @@ private:
                           const SkMatrix&,
                           const GrRect& domain,
                           WrapMode,
-                          bool bilerp);
+                          bool bilerp,
+                          CoordsType type);
 
     virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
 
index 478d03dee109e8ca264736448940ec07e5111406..e21ab1dab9471f7f1ddd11d9d1194b143554dfc2 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "GrGLSL.h"
 #include "GrGLEffect.h"
+#include "GrDrawEffect.h"
 
 GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory)
     : fFactory(factory) {
@@ -17,14 +18,15 @@ GrGLEffect::~GrGLEffect() {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLEffect::setData(const GrGLUniformManager&, const GrEffectStage&) {
+void GrGLEffect::setData(const GrGLUniformManager&, const GrDrawEffect&) {
 }
 
-GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect,
+GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrDrawEffect& drawEffect,
                                                 const GrGLCaps& caps) {
     EffectKey key = 0;
-    for (int index = 0; index < (*effect)->numTextures(); ++index) {
-        const GrTextureAccess& access = (*effect)->textureAccess(index);
+    int numTextures = (*drawEffect.effect())->numTextures();
+    for (int index = 0; index < numTextures; ++index) {
+        const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(index);
         EffectKey value = GrGLShaderBuilder::KeyForTextureAccess(access, caps) << index;
         GrAssert(0 == (value & key)); // keys for each access ought not to overlap
         key |= value;
@@ -32,12 +34,12 @@ GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect,
     return key;
 }
 
-GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrEffectStage& stage) {
+GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrDrawEffect& drawEffect) {
     EffectKey key = 0;
 
-    int numAttributes = stage.getVertexAttribIndexCount();
+    int numAttributes = drawEffect.getVertexAttribIndexCount();
     GrAssert(numAttributes <= 2);
-    const int* attributeIndices = stage.getVertexAttribIndices();
+    const int* attributeIndices = drawEffect.getVertexAttribIndices();
     for (int index = 0; index < numAttributes; ++index) {
         EffectKey value = attributeIndices[index] << 3*index;
         GrAssert(0 == (value & key)); // keys for each attribute ought not to overlap
index 869fbdad7fb7f8ed47188bd4a5e300771b87ae4c..5df22811c4c60dfef25794d2294ad49117a60a05 100644 (file)
@@ -12,7 +12,6 @@
 #include "GrGLShaderBuilder.h"
 #include "GrGLShaderVar.h"
 #include "GrGLSL.h"
-#include "GrEffectStage.h"
 
 class GrGLTexture;
 
@@ -21,13 +20,20 @@ class GrGLTexture;
     include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
     GLSL code that implements a GrEffect and for uploading uniforms at draw time. They also
     must have a function:
-        static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&)
+        static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&)
     that is used to implement a program cache. When two GrEffects produce the same key this means
     that their GrGLEffects would emit the same GLSL code.
 
+    The GrGLEffect subclass must also have a constructor of the form:
+        EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrDrawEffect&)
+    The effect held by the GrDrawEffect is guaranteed to be of the type that generated the
+    GrGLEffect subclass instance.
+
     These objects are created by the factory object returned by the GrEffect::getFactory().
 */
 
+class GrDrawEffect;
+
 class GrGLEffect {
 
 public:
@@ -50,14 +56,10 @@ public:
         stages.
 
         @param builder      Interface used to emit code in the shaders.
-        @param stage        The effect stage that generated this program stage.
+        @param drawEffect   A wrapper on the effect that generated this program stage.
         @param key          The key that was computed by GenKey() from the generating GrEffect.
                             Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
                             guaranteed to match the value produced by GenKey();
-        @param vertexCoords A vec2 in the VS that holds the position in local coords. This is either
-                            the pre-view-matrix vertex position or if explicit per-vertex texture
-                            coords are used with a stage then it is those coordinates. See
-                            GrVertexLayout.
         @param outputColor  A predefined vec4 in the FS in which the stage should place its output
                             color (or coverage).
         @param inputColor   A vec4 that holds the input color to the stage in the FS. This may be
@@ -70,9 +72,8 @@ public:
                             reads in the generated code.
         */
     virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrEffectStage& stage,
+                          const GrDrawEffect& drawEffect,
                           EffectKey key,
-                          const char* vertexCoords,
                           const char* outputColor,
                           const char* inputColor,
                           const TextureSamplerArray& samplers) = 0;
@@ -81,34 +82,15 @@ public:
         key; this function reads data from a stage and uploads any uniform variables required
         by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
         guaranteed to be of the same type that created this GrGLEffect and to have an identical
-        EffectKey as the one that created this GrGLEffect. */
-    virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
+        EffectKey as the one that created this GrGLEffect. Effects that use local coords have
+        to consider whether the GrEffectStage's coord change matrix should be used. When explicit
+        local coordinates are used it can be ignored. */
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&);
 
     const char* name() const { return fFactory.name(); }
 
-    static EffectKey GenTextureKey(const GrEffectRef*, const GrGLCaps&);
-    static EffectKey GenAttribKey(const GrEffectStage& stage);
-
-   /**
-    * GrGLEffect subclasses get passed a GrEffectStage in their emitCode and setData functions.
-    * The GrGLEffect usually needs to cast the stage's effect to the GrEffect subclass that
-    * generated the GrGLEffect. This helper does just that.
-    */
-    template <typename T>
-    static const T& GetEffectFromStage(const GrEffectStage& effectStage) {
-        GrAssert(NULL != effectStage.getEffect());
-        return CastEffect<T>(*effectStage.getEffect());
-    }
-
-   /**
-    * Extracts the GrEffect from a GrEffectRef and down-casts to a GrEffect subclass. Usually used
-    * in a GrGLEffect subclass's constructor (which takes const GrEffectRef&).
-    */
-    template <typename T>
-    static const T& CastEffect(const GrEffectRef& effectRef) {
-        GrAssert(NULL != effectRef.get());
-        return *static_cast<const T*>(effectRef.get());
-    }
+    static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
+    static EffectKey GenAttribKey(const GrDrawEffect& stage);
 
 protected:
     const GrBackendEffectFactory& fFactory;
index c37098e2f09a0d9a4bd19ce1fb0a63d8bd5be0c3..e2e88077265574f6099a85c73b422a03fe5bbac0 100644 (file)
@@ -6,58 +6,67 @@
  */
 
 #include "GrGLEffectMatrix.h"
+#include "GrDrawEffect.h"
 #include "GrTexture.h"
 
 GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix,
-                                               const SkMatrix& coordChangeMatrix,
+                                               const GrDrawEffect& drawEffect,
+                                               CoordsType coordsType,
                                                const GrTexture* texture) {
+    EffectKey key = 0;
     SkMatrix::TypeMask type0 = effectMatrix.getType();
-    SkMatrix::TypeMask type1 = coordChangeMatrix.getType();
+    SkMatrix::TypeMask type1;
+    if (GrEffect::kLocal_CoordsType == coordsType) {
+        type1 = drawEffect.getCoordChangeMatrix().getType();
+    } else {
+        if (drawEffect.programHasExplicitLocalCoords()) {
+            // We only make the key indicate that device coords are referenced when the local coords
+            // are not actually determined by positions.
+            key |= kPositionCoords_Flag;
+        }
+        type1 = SkMatrix::kIdentity_Mask;
+    }
 
-    static const int kNonTransMask = SkMatrix::kAffine_Mask |
-                                     SkMatrix::kScale_Mask  |
-                                     SkMatrix::kPerspective_Mask;
     int combinedTypes = type0 | type1;
 
     bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture->origin();
 
     if (SkMatrix::kPerspective_Mask & combinedTypes) {
-        return kGeneral_Key;
-    } else if ((kNonTransMask & combinedTypes) || reverseY) {
-        return kNoPersp_Key;
-    } else if (kTrans_Key & combinedTypes) {
-        return kTrans_Key;
+        key |= kGeneral_MatrixType;
+    } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) {
+        key |= kNoPersp_MatrixType;
+    } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
+        key |= kTrans_MatrixType;
     } else {
-        GrAssert(effectMatrix.isIdentity() && coordChangeMatrix.isIdentity());
-        return kIdentity_Key;
+        key |= kIdentity_MatrixType;
     }
+    return key;
 }
 
 GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
                                     EffectKey key,
-                                    const char* vertexCoords,
                                     const char** fsCoordName,
                                     const char** vsCoordName,
                                     const char* suffix) {
     GrSLType varyingType;
     const char* uniName;
     key &= kKeyMask;
-    switch (key) {
-        case kIdentity_Key:
+    switch (key & kMatrixTypeKeyMask) {
+        case kIdentity_MatrixType:
             fUniType = kVoid_GrSLType;
             varyingType = kVec2f_GrSLType;
             break;
-        case kTrans_Key:
+        case kTrans_MatrixType:
             fUniType = kVec2f_GrSLType;
             uniName = "StageTranslate";
             varyingType = kVec2f_GrSLType;
             break;
-        case kNoPersp_Key:
+        case kNoPersp_MatrixType:
             fUniType = kMat33f_GrSLType;
             uniName = "StageMatrix";
             varyingType = kVec2f_GrSLType;
             break;
-        case kGeneral_Key:
+        case kGeneral_MatrixType:
             fUniType = kMat33f_GrSLType;
             uniName = "StageMatrix";
             varyingType = kVec3f_GrSLType;
@@ -89,24 +98,39 @@ GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
     const char* fsVaryingName;
     builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
 
-    // varying = matrix * vertex-coords (logically)
+    const GrGLShaderVar* coords;
+    switch (fCoordsType) {
+        case GrEffect::kLocal_CoordsType:
+            GrAssert(!(kPositionCoords_Flag & key));
+            coords = &builder->localCoordsAttribute();
+            break;
+        case GrEffect::kPosition_CoordsType:
+            GrAssert((kPositionCoords_Flag & key) || !builder->hasExplicitLocalCoords());
+            coords = &builder->positionAttribute();
+            break;
+        default:
+            coords = NULL; // prevents warning
+            GrCrash("Unexpected coords type.");
+    }
+    // varying = matrix * coords (logically)
     switch (fUniType) {
         case kVoid_GrSLType:
             GrAssert(kVec2f_GrSLType == varyingType);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, vertexCoords);
+            builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->c_str());
             break;
         case kVec2f_GrSLType:
             GrAssert(kVec2f_GrSLType == varyingType);
-            builder->vsCodeAppendf("\t%s = %s + %s;\n", vsVaryingName, uniName, vertexCoords);
+            builder->vsCodeAppendf("\t%s = %s + %s;\n",
+                                   vsVaryingName, uniName, coords->c_str());
             break;
         case kMat33f_GrSLType: {
             GrAssert(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
             if (kVec2f_GrSLType == varyingType) {
                 builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
-                                       vsVaryingName, uniName, vertexCoords);
+                                       vsVaryingName, uniName, coords->c_str());
             } else {
                 builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
-                                       vsVaryingName, uniName, vertexCoords);
+                                       vsVaryingName, uniName, coords->c_str());
             }
             break;
         }
@@ -128,7 +152,6 @@ GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
     */
 void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
                                               EffectKey key,
-                                              const char* vertexCoords,
                                               const char** fsCoordName,
                                               const char** vsVaryingName,
                                               GrSLType* vsVaryingType,
@@ -137,7 +160,6 @@ void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
 
     GrSLType varyingType = this->emitCode(builder,
                                           key,
-                                          vertexCoords,
                                           &fsVaryingName,
                                           vsVaryingName,
                                           suffix);
@@ -164,11 +186,14 @@ void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
 }
 
 void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
-                              const SkMatrix& matrix,
-                              const SkMatrix& coordChangeMatrix,
-                              const GrTexture* texture) {
+                               const SkMatrix& matrix,
+                               const GrDrawEffect& drawEffect,
+                               const GrTexture* texture) {
     GrAssert((GrGLUniformManager::kInvalidUniformHandle == fUni) ==
-                (kVoid_GrSLType == fUniType));
+             (kVoid_GrSLType == fUniType));
+    const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsType ?
+                                            drawEffect.getCoordChangeMatrix() :
+                                            SkMatrix::I();
     switch (fUniType) {
         case kVoid_GrSLType:
             GrAssert(matrix.isIdentity());
@@ -178,8 +203,8 @@ void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
         case kVec2f_GrSLType: {
             GrAssert(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
             GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
-            SkScalar tx = matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX];
-            SkScalar ty = matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY];
+            SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
+            SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
             if (fPrevMatrix.get(SkMatrix::kMTransX) != tx ||
                 fPrevMatrix.get(SkMatrix::kMTransY) != ty) {
                 uniformManager.set2f(fUni, tx, ty);
index 1a116565342958c8a33652f4f7937c5e4678d3eb..fc4b7831336d69a5fd1f65c29ee176384b58e4d6 100644 (file)
 class GrTexture;
 
 /**
- * This is a helper to implement a texture matrix in a GrGLEffect.
+ * This is a helper to implement a matrix in a GrGLEffect that operates on incoming coords in the
+ * vertex shader and writes them to an attribute to be used in the fragment shader. When the input
+ * coords in the vertex shader are local coordinates this class accounts for the coord change matrix
+ * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord
+ * change matrix is ignored. The GrGLEffectMatrix will emit different code based on the type of
+ * matrix and thus must contribute to the effect's key.
+ *
+ * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex
+ * attributes.
  */
 class GrGLEffectMatrix {
+private:
+    // We specialize the generated code for each of these matrix types.
+    enum MatrixTypes {
+        kIdentity_MatrixType    = 0,
+        kTrans_MatrixType       = 1,
+        kNoPersp_MatrixType     = 2,
+        kGeneral_MatrixType     = 3,
+    };
+    // The key for is made up of a matrix type and a bit that indicates the source of the input
+    // coords.
+    enum {
+        kMatrixTypeKeyBits      = 2,
+        kMatrixTypeKeyMask      = (1 << kMatrixTypeKeyBits) - 1,
+        kPositionCoords_Flag    = (1 << kMatrixTypeKeyBits),
+        kKeyBitsPrivate         = kMatrixTypeKeyBits + 1,
+    };
+
 public:
+
+    typedef GrEffect::CoordsType CoordsType;
+
     typedef GrGLEffect::EffectKey EffectKey;
+
     /**
      * The matrix uses kKeyBits of the effect's EffectKey. A GrGLEffect may place these bits at an
      * arbitrary shift in its final key. However, when GrGLEffectMatrix::emitCode*() code is called
      * the relevant bits must be in the lower kKeyBits of the key parameter.
      */
     enum {
-        kKeyBits = 2,
+        kKeyBits = kKeyBitsPrivate,
         kKeyMask = (1 << kKeyBits) - 1,
     };
 
-    GrGLEffectMatrix() : fUni(GrGLUniformManager::kInvalidUniformHandle) {
+    GrGLEffectMatrix(CoordsType coordsType)
+        : fUni(GrGLUniformManager::kInvalidUniformHandle)
+        , fCoordsType(coordsType) {
+        GrAssert(GrEffect::kLocal_CoordsType == coordsType ||
+                 GrEffect::kPosition_CoordsType == coordsType);
         fPrevMatrix = SkMatrix::InvalidMatrix();
     }
 
     /**
      * Generates the key for the portion of the code emitted by this class's emitCode() function.
      * Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass
-     * NULL when not using the EffectMatrix for a texture lookups, or if the GrGLEffect subclass
-     * wants to handle origin adjustments in some other manner. coordChangeMatrix is the matrix
-     * from GrEffectStage.
+     * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass
+     * wants to handle origin adjustments in some other manner. The coords type param must match the
+     * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect.
      */
     static EffectKey GenKey(const SkMatrix& effectMatrix,
-                            const SkMatrix& coordChangeMatrix,
+                            const GrDrawEffect&,
+                            CoordsType,
                             const GrTexture*);
 
     /**
@@ -55,7 +89,6 @@ public:
      */
     GrSLType emitCode(GrGLShaderBuilder*,
                       EffectKey,
-                      const char* vertexCoords,
                       const char** fsCoordName, /* optional */
                       const char** vsCoordName = NULL,
                       const char* suffix = NULL);
@@ -66,31 +99,23 @@ public:
      */
     void emitCodeMakeFSCoords2D(GrGLShaderBuilder*,
                                 EffectKey,
-                                const char* vertexCoords,
                                 const char** fsCoordName, /* optional */
                                 const char** vsVaryingName = NULL,
                                 GrSLType* vsVaryingType = NULL,
                                 const char* suffix = NULL);
     /**
-     * Call from a GrGLEffect's subclass to update the texture matrix. The matrix,
-     * coordChangeMatrix, and texture params should match those used with GenKey.
+     * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture
+     * params should match those used with GenKey.
      */
     void setData(const GrGLUniformManager& uniformManager,
                  const SkMatrix& effectMatrix,
-                 const SkMatrix& coordChangeMatrix,
+                 const GrDrawEffect& drawEffect,
                  const GrTexture*);
 
-private:
-    enum {
-        kIdentity_Key   = 0,
-        kTrans_Key      = 1,
-        kNoPersp_Key    = 2,
-        kGeneral_Key    = 3,
-    };
-
     GrGLUniformManager::UniformHandle fUni;
     GrSLType                          fUniType;
     SkMatrix                          fPrevMatrix;
+    CoordsType                        fCoordsType;
 };
 
 #endif
index 7d6420ead4d4bcd371022a2aa3be2fe2c34a24cc..21729cd33bff873a9f9c2f5dc155b00eee77305b 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "GrAllocator.h"
 #include "GrEffect.h"
+#include "GrDrawEffect.h"
 #include "GrGLEffect.h"
 #include "GrGpuGL.h"
 #include "GrGLShaderVar.h"
@@ -26,7 +27,6 @@ SK_DEFINE_INST_COUNT(GrGLProgram)
 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
                 "Print the source code for all shaders generated.");
 
-#define TEX_ATTR_NAME "aTexCoord"
 #define COL_ATTR_NAME "aColor"
 #define COV_ATTR_NAME "aCoverage"
 #define EDGE_ATTR_NAME "aEdge"
@@ -134,7 +134,10 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
             lastEnabledStage = s;
             const GrEffectRef& effect = *drawState.getStage(s).getEffect();
             const GrBackendEffectFactory& factory = effect->getFactory();
-            desc->fEffectKeys[s] = factory.glEffectKey(drawState.getStage(s), gpu->glCaps());
+            bool explicitLocalCoords = (drawState.getAttribBindings() &
+                                        GrDrawState::kLocalCoords_AttribBindingsBit);
+            GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords);
+            desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
         } else {
             desc->fEffectKeys[s] = 0;
         }
@@ -207,8 +210,8 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
     if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
         desc->fEdgeAttributeIndex = drawState.getAttribIndex(GrDrawState::kEdge_AttribIndex);
     }
-    if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
-        desc->fTexCoordAttributeIndex = drawState.getAttribIndex(GrDrawState::kTexCoord_AttribIndex);
+    if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+        desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState::kLocalCoords_AttribIndex);
     }
 
 #if GR_DEBUG
@@ -227,10 +230,10 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
     if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
         GrAssert(desc->fEdgeAttributeIndex < GrDrawState::kVertexAttribCnt);
         GrAssert(kAttribLayouts[vertexAttribs[desc->fEdgeAttributeIndex].fType].fCount == 4);
-     }
-    if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
-        GrAssert(desc->fTexCoordAttributeIndex < GrDrawState::kVertexAttribCnt);
-        GrAssert(kAttribLayouts[vertexAttribs[desc->fTexCoordAttributeIndex].fType].fCount == 2);
+    }
+    if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+        GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
+        GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2);
     }
 #endif
 }
@@ -679,8 +682,10 @@ bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) {
 bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
     GrAssert(0 == fProgramID);
 
-    GrGLShaderBuilder builder(fContext.info(), fUniformManager);
     const GrAttribBindings& attribBindings = fDesc.fAttribBindings;
+    bool hasExplicitLocalCoords =
+        SkToBool(attribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
+    GrGLShaderBuilder builder(fContext.info(), fUniformManager, hasExplicitLocalCoords);
 
 #if GR_GL_EXPERIMENTAL_GS
     builder.fUsesGS = fDesc.fExperimentalGS;
@@ -760,11 +765,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
         builder.vsCodeAppend("\tgl_PointSize = 1.0;\n");
     }
 
-    // add texture coordinates that are used to the list of vertex attr decls
-    if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) {
-        builder.addAttribute(kVec2f_GrSLType, TEX_ATTR_NAME);
-    }
-
     ///////////////////////////////////////////////////////////////////////////
     // compute the final color
 
@@ -779,21 +779,11 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
                 outColor.appendS32(s);
                 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
 
-                const char* inCoords;
-                // figure out what our input coords are
-                if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
-                    inCoords = builder.positionAttribute().c_str();
-                } else {
-                    // must have input tex coordinates if stage is enabled.
-                    inCoords = TEX_ATTR_NAME;
-                }
-
                 builder.setCurrentStage(s);
                 fEffects[s] = builder.createAndEmitGLEffect(*stages[s],
                                                             fDesc.fEffectKeys[s],
                                                             inColor.size() ? inColor.c_str() : NULL,
                                                             outColor.c_str(),
-                                                            inCoords,
                                                             &fUniformHandles.fSamplerUnis[s]);
                 builder.setNonStage();
                 inColor = outColor;
@@ -871,16 +861,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
                     outCoverage.appendS32(s);
                     builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
 
-                    const char* inCoords;
-                    // figure out what our input coords are
-                    if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
-                        inCoords = builder.positionAttribute().c_str();
-                    } else {
-                        // must have input tex coordinates if stage is
-                        // enabled.
-                        inCoords = TEX_ATTR_NAME;
-                    }
-
                     // stages don't know how to deal with a scalar input. (Maybe they should. We
                     // could pass a GrGLShaderVar)
                     if (inCoverageIsScalar) {
@@ -894,7 +874,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
                                                     fDesc.fEffectKeys[s],
                                                     inCoverage.size() ? inCoverage.c_str() : NULL,
                                                     outCoverage.c_str(),
-                                                    inCoords,
                                                     &fUniformHandles.fSamplerUnis[s]);
                     builder.setNonStage();
                     inCoverage = outCoverage;
@@ -1008,8 +987,10 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
     if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
         GL_CALL(BindAttribLocation(fProgramID, fDesc.fEdgeAttributeIndex, EDGE_ATTR_NAME));
     }
-    if (GrDrawState::AttributesBindExplicitTexCoords(fDesc.fAttribBindings)) {
-        GL_CALL(BindAttribLocation(fProgramID, fDesc.fTexCoordAttributeIndex, TEX_ATTR_NAME));
+    if (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+        GL_CALL(BindAttribLocation(fProgramID,
+                                   fDesc.fLocalCoordsAttributeIndex,
+                                   builder.localCoordsAttribute().c_str()));
     }
 
     const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end();
@@ -1088,7 +1069,11 @@ void GrGLProgram::setData(GrGpuGL* gpu,
         if (NULL != fEffects[s]) {
             const GrEffectStage& stage = drawState.getStage(s);
             GrAssert(NULL != stage.getEffect());
-            fEffects[s]->setData(fUniformManager, stage);
+
+            bool explicitLocalCoords =
+                (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
+            GrDrawEffect drawEffect(stage, explicitLocalCoords);
+            fEffects[s]->setData(fUniformManager, drawEffect);
             int numSamplers = fUniformHandles.fSamplerUnis[s].count();
             for (int u = 0; u < numSamplers; ++u) {
                 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
index cde918b54b1d17cfbb5b3e4cf8fe5a5bf6e14cd7..9fd01fd816ac0648e36ce3fef656e09f0f8c3311 100644 (file)
@@ -192,7 +192,7 @@ public:
         int8_t                      fColorAttributeIndex;
         int8_t                      fCoverageAttributeIndex;
         int8_t                      fEdgeAttributeIndex;
-        int8_t                      fTexCoordAttributeIndex;
+        int8_t                      fLocalCoordsAttributeIndex;
 
         friend class GrGLProgram;
     };
index b3b09cc477dd148e71e9683e8580c45ed0cac6f2..117962633fe46aa12a6bec9ba0b6660090daf025 100644 (file)
@@ -8,6 +8,7 @@
 #include "gl/GrGLShaderBuilder.h"
 #include "gl/GrGLProgram.h"
 #include "gl/GrGLUniformHandle.h"
+#include "GrDrawEffect.h"
 #include "GrTexture.h"
 
 // number of each input/output type in a single allocation block
@@ -82,7 +83,8 @@ void append_swizzle(SkString* outAppend,
 //const int GrGLShaderBuilder::fCoordDims = 2;
 
 GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
-                                     GrGLUniformManager& uniformManager)
+                                     GrGLUniformManager& uniformManager,
+                                     bool explicitLocalCoords)
     : fUniforms(kVarsPerBlock)
     , fVSAttrs(kVarsPerBlock)
     , fVSOutputs(kVarsPerBlock)
@@ -99,6 +101,14 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
 
     fPositionVar = &fVSAttrs.push_back();
     fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
+    if (explicitLocalCoords) {
+        fLocalCoordsVar = &fVSAttrs.push_back();
+        fLocalCoordsVar->set(kVec2f_GrSLType,
+                             GrGLShaderVar::kAttribute_TypeModifier,
+                             "aLocalCoords");
+    } else {
+        fLocalCoordsVar = fPositionVar;
+    }
 }
 
 void GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_list args) {
@@ -494,7 +504,6 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
                                 GrGLEffect::EffectKey key,
                                 const char* fsInColor,
                                 const char* fsOutColor,
-                                const char* vsInCoord,
                                 SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
     GrAssert(NULL != stage.getEffect());
 
@@ -506,6 +515,7 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
         textureSamplers[i].init(this, &effect->textureAccess(i), i);
         samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
     }
+    GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
 
     int numAttributes = stage.getVertexAttribIndexCount();
     const int* attributeIndices = stage.getVertexAttribIndices();
@@ -519,15 +529,15 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
         }
     }
 
-    GrGLEffect* glEffect = effect->getFactory().createGLInstance(effect);
+    GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
 
     // Enclose custom code in a block to avoid namespace conflicts
     this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
     this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
+
     glEffect->emitCode(this,
-                       stage,
+                       drawEffect,
                        key,
-                       vsInCoord,
                        fsOutColor,
                        fsInColor,
                        textureSamplers);
index 524a8853ca9a3d014b1e0ee34f6d0b59eb651ed7..9d64143802be318bd5371ea5084d6b595da8c4d1 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdarg.h>
 
 class GrGLContextInfo;
+class GrEffectStage;
 
 /**
   Contains all the incremental state of a shader as it is being built,as well as helpers to
@@ -80,7 +81,7 @@ public:
         kFragment_ShaderType = 0x4,
     };
 
-    GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
+    GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, bool explicitLocalCoords);
 
     /**
      * Called by GrGLEffects to add code to one of the shaders.
@@ -205,6 +206,16 @@ public:
       */
     const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
 
+    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
+        as positionAttribute() or it may not be. It depends upon whether the rendering code
+        specified explicit local coords or not in the GrDrawState. */
+    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
+
+    /**
+     * Are explicit local coordinates provided as input to the vertex shader.
+     */
+    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+
     /**
      * Interfaces used by GrGLProgram.
      * TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
@@ -223,7 +234,6 @@ public:
                                 GrBackendEffectFactory::EffectKey key,
                                 const char* fsInColor, // NULL means no incoming color
                                 const char* fsOutColor,
-                                const char* vsInCoord,
                                 SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles);
     GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
 
@@ -290,6 +300,8 @@ private:
     SkSTArray<10, AttributePair, true>  fEffectAttributes;
 
     GrGLShaderVar*                      fPositionVar;
+    GrGLShaderVar*                      fLocalCoordsVar;
+
 };
 
 #endif
index d12aeb57dd5fba462d6e2b4e44759d9c53ed3e43..aeb7ecc11ee3fa3244487fc66b917b2ebecfeb78 100644 (file)
@@ -15,6 +15,7 @@
 #include "gl/GrGpuGL.h"
 #include "GrBackendEffectFactory.h"
 #include "GrContextFactory.h"
+#include "GrDrawEffect.h"
 #include "effects/GrConfigConversionEffect.h"
 
 #include "SkRandom.h"
@@ -57,16 +58,18 @@ void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
         fDualSrcOutput = kNone_DualSrcOutput;
     }
 
-    bool useOnce = false;
+    // use separate tex coords?
+    if (random->nextBool()) {
+        fAttribBindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
+    }
+
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         if (NULL != stages[s].getEffect()) {
             const GrBackendEffectFactory& factory = (*stages[s].getEffect())->getFactory();
-            fEffectKeys[s] = factory.glEffectKey(stages[s], gpu->glCaps());
-            // use separate tex coords?
-            if (!useOnce && random->nextBool()) {
-                fAttribBindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s);
-                useOnce = true;
-            }
+            bool explicitLocalCoords = (fAttribBindings &
+                                        GrDrawState::kLocalCoords_AttribBindingsBit);
+            GrDrawEffect drawEffect(stages[s], explicitLocalCoords);
+            fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
         }
     }
 
@@ -85,8 +88,8 @@ void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
         fEdgeAttributeIndex = attributeIndex;
         ++attributeIndex;
     }
-    if (GrDrawState::AttributesBindExplicitTexCoords(fAttribBindings)) {
-        fTexCoordAttributeIndex = attributeIndex;
+    if (fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+        fLocalCoordsAttributeIndex = attributeIndex;
         ++attributeIndex;
     }
 }