Remove default implementation of GrEffect::isEqual. Make GrSingleTextureEffect abstract.
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 17 Jan 2013 16:50:08 +0000 (16:50 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 17 Jan 2013 16:50:08 +0000 (16:50 +0000)
Review URL: https://codereview.appspot.com/7142049

git-svn-id: http://skia.googlecode.com/svn/trunk@7254 2bbb7eff-a529-9590-31e7-b0007b416f81

31 files changed:
gm/texdata.cpp
gyp/gpu.gypi
include/gpu/GrEffect.h
include/gpu/GrEffectStage.h
src/core/SkBitmapProcShader.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/SkTwoPointConicalGradient.cpp
src/effects/gradients/SkTwoPointRadialGradient.cpp
src/gpu/GrContext.cpp
src/gpu/GrDrawState.h
src/gpu/GrEffect.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/effects/GrConfigConversionEffect.cpp
src/gpu/effects/GrConfigConversionEffect.h
src/gpu/effects/GrConvolutionEffect.cpp
src/gpu/effects/GrConvolutionEffect.h
src/gpu/effects/GrSimpleTextureEffect.cpp [new file with mode: 0644]
src/gpu/effects/GrSimpleTextureEffect.h [new file with mode: 0644]
src/gpu/effects/GrSingleTextureEffect.cpp
src/gpu/effects/GrSingleTextureEffect.h
src/gpu/effects/GrTextureDomainEffect.cpp
src/gpu/effects/GrTextureDomainEffect.h

index 1f888267ad118475c89f8866db9d213a3a74eb0c..da52aade6a573ea50938d76adefd1a149ea4f545 100644 (file)
@@ -12,7 +12,7 @@
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
-#include "effects/GrSingleTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
 #include "SkColorPriv.h"
 #include "SkDevice.h"
 
@@ -113,7 +113,7 @@ protected:
                 SkMatrix tm;
                 tm = vm;
                 tm.postIDiv(2*S, 2*S);
-                paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(texture, tm))->unref();
+                paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(texture, tm))->unref();
 
                 ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S));
 
index 3248f03d839df221590270ac7755929587abd63f..bf301bb0127e770afae1c71a95a2301ff2dd2586 100644 (file)
       '<(skia_src_path)/gpu/effects/GrConfigConversionEffect.h',
       '<(skia_src_path)/gpu/effects/GrConvolutionEffect.cpp',
       '<(skia_src_path)/gpu/effects/GrConvolutionEffect.h',
+      '<(skia_src_path)/gpu/effects/GrSimpleTextureEffect.cpp',
+      '<(skia_src_path)/gpu/effects/GrSimpleTextureEffect.h',
       '<(skia_src_path)/gpu/effects/GrSingleTextureEffect.cpp',
       '<(skia_src_path)/gpu/effects/GrSingleTextureEffect.h',
       '<(skia_src_path)/gpu/effects/GrTextureDomainEffect.cpp',
index 1e0ce794b1d421082ad7a45f088afb4aebff7c18..507bd5736b685e73fbcd7ce7a9d355e993f43bb5 100644 (file)
@@ -104,21 +104,30 @@ public:
      */
     virtual const GrBackendEffectFactory& getFactory() const = 0;
 
-    /** Returns true if the other effect will generate identical output.
-        Must only be called if the two are already known to be of the
-        same type (i.e.  they return the same value from getFactory()).
-
-        Equality is not the same thing as equivalence.
-        To test for equivalence (that they will generate the same
-        shader code, but may have different uniforms), check equality
-        of the EffectKey produced by the GrBackendEffectFactory:
-        a.getFactory().glEffectKey(a) == b.getFactory().glEffectKey(b).
-
-        The default implementation of this function returns true iff
-        the two stages have the same return value for numTextures() and
-        for texture() over all valid indices.
+    /** Returns true if this and other effect conservatively draw identically. It can only return
+        true when the two effects are of the same subclass (i.e. they return the same object from
+        from getFactory()).
+
+        A return value of true from isEqual() should not be used to test whether the effects would
+        generate the same shader code. To test for identical code generation use the EffectKey
+        computed by the GrBackendEffectFactory:
+            effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
      */
-    virtual bool isEqual(const GrEffect&) const;
+    bool isEqual(const GrEffect& other) const {
+        if (&this->getFactory() != &other.getFactory()) {
+            return false;
+        }
+        bool result = this->onIsEqual(other);
+#if GR_DEBUG
+        if (result) {
+            GrAssert(this->numTextures() == other.numTextures());
+            for (int i = 0; i < this->numTextures(); ++i) {
+                GrAssert(*fTextureAccesses[i] == *other.fTextureAccesses[i]);
+            }
+        }
+#endif
+        return result;
+    }
 
     /** Human-meaningful string to identify this effect; may be embedded
         in generated shader code. */
@@ -167,6 +176,12 @@ protected:
     }
 
 private:
+
+    /** Subclass implements this to support isEqual(). It will only be called if it is known that
+        the two effects are of the same subclass (i.e. they return the same object
+        from getFactory()).*/
+    virtual bool onIsEqual(const GrEffect& other) const = 0;
+
     void EffectRefDestroyed() {
         fEffectRef = NULL;
     }
index 597ea4957c37e2f0bc39458f27fe36b37a91da4b..0060152815890a9e5dda970f72057ee9999c7269 100644 (file)
@@ -39,10 +39,6 @@ public:
             return false;
         }
 
-        if (this->getEffect()->getFactory() != other.getEffect()->getFactory()) {
-            return false;
-        }
-
         if (!this->getEffect()->isEqual(*other.getEffect())) {
             return false;
         }
index 2f7173e446ac68276af7b00db37e7d1174be4c47..d91b978dcc908121cc1277f1088e40da57e4608b 100644 (file)
@@ -332,7 +332,7 @@ void SkBitmapProcShader::toString(SkString* str) const {
 #if SK_SUPPORT_GPU
 
 #include "GrTextureAccess.h"
-#include "effects/GrSingleTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
 #include "SkGr.h"
 
 GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
@@ -360,7 +360,7 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint&
         return NULL;
     }
 
-    GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix, params);
+    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
     GrUnlockCachedBitmapTexture(texture);
     return effect;
 }
index 5a93b479d2b6de60c85afc609a7966b3bd2391a7..43915b3a79c6dadd751d0d475432429d367e8e16 100644 (file)
@@ -152,7 +152,6 @@ public:
 
     virtual ~GrBlendEffect();
 
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
     const GrBackendEffectFactory& getFactory() const;
     SkBlendImageFilter::Mode mode() const { return fMode; }
 
@@ -162,6 +161,8 @@ public:
     void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTexture* background);
     GrTextureAccess             fForegroundAccess;
     GrTextureAccess             fBackgroundAccess;
@@ -245,9 +246,11 @@ GrBlendEffect::GrBlendEffect(SkBlendImageFilter::Mode mode,
 GrBlendEffect::~GrBlendEffect() {
 }
 
-bool GrBlendEffect::isEqual(const GrEffect& sBase) const {
+bool GrBlendEffect::onIsEqual(const GrEffect& sBase) const {
     const GrBlendEffect& s = static_cast<const GrBlendEffect&>(sBase);
-    return INHERITED::isEqual(sBase) && fMode == s.fMode;
+    return fForegroundAccess.getTexture() == s.fForegroundAccess.getTexture() &&
+           fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture() &&
+           fMode == s.fMode;
 }
 
 const GrBackendEffectFactory& GrBlendEffect::getFactory() const {
index 0fb438d2f4a97a19b4e2864eb25c60843ea576f5..06fb4efed0c87505caa314b73c0fd980e72373a0 100644 (file)
@@ -336,11 +336,6 @@ public:
         return GrTBackendEffectFactory<ColorMatrixEffect>::getInstance();
     }
 
-    virtual bool isEqual(const GrEffect& s) const {
-        const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(s);
-        return cme.fMatrix == fMatrix;
-    }
-
     virtual void getConstantColorComponents(GrColor* color,
                                             uint32_t* validFlags) const SK_OVERRIDE {
         // We only bother to check whether the alpha channel will be constant. If SkColorMatrix had
@@ -456,6 +451,11 @@ public:
 private:
     ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {}
 
+    virtual bool onIsEqual(const GrEffect& s) const {
+        const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(s);
+        return cme.fMatrix == fMatrix;
+    }
+
     SkColorMatrix fMatrix;
 
     typedef GrGLEffect INHERITED;
index 9a67ac36c772519289d8402c7987670eb4e8ec8c..17abe28b185389c0ec76a6ed069d7d0e62548c58 100644 (file)
@@ -245,7 +245,6 @@ public:
 
     virtual ~GrDisplacementMapEffect();
 
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
     const GrBackendEffectFactory& getFactory() const;
     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
         { return fXChannelSelector; }
@@ -259,6 +258,8 @@ public:
     void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
                             SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
                             SkScalar scale, GrTexture* displacement, GrTexture* color);
@@ -360,10 +361,13 @@ GrDisplacementMapEffect::GrDisplacementMapEffect(
 GrDisplacementMapEffect::~GrDisplacementMapEffect() {
 }
 
-bool GrDisplacementMapEffect::isEqual(const GrEffect& sBase) const {
+bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const {
     const GrDisplacementMapEffect& s = static_cast<const GrDisplacementMapEffect&>(sBase);
-    return INHERITED::isEqual(sBase) && fXChannelSelector == s.fXChannelSelector &&
-           fYChannelSelector == s.fYChannelSelector && fScale == s.fScale;
+    return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture() &&
+           fColorAccess.getTexture() == s.fColorAccess.getTexture() &&
+           fXChannelSelector == s.fXChannelSelector &&
+           fYChannelSelector == s.fYChannelSelector &&
+           fScale == s.fScale;
 }
 
 const GrBackendEffectFactory& GrDisplacementMapEffect::getFactory() const {
index ddb033def3100381adff29e4146a5f3e8bb8879d..780a3a42bd2524c3039136c9d5320defd1caa35e 100644 (file)
@@ -307,8 +307,6 @@ public:
     GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale);
     virtual ~GrLightingEffect();
 
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
-
     const SkLight* light() const { return fLight; }
     SkScalar surfaceScale() const { return fSurfaceScale; }
 
@@ -318,6 +316,9 @@ public:
         *validFlags = 0;
     }
 
+protected:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
 private:
     typedef GrSingleTextureEffect INHERITED;
     const SkLight* fLight;
@@ -342,9 +343,11 @@ public:
     typedef GrGLDiffuseLightingEffect GLEffect;
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
     SkScalar kd() const { return fKD; }
+
 private:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GrDiffuseLightingEffect(GrTexture* texture,
                             const SkLight* light,
                             SkScalar surfaceScale,
@@ -374,11 +377,12 @@ public:
     typedef GrGLSpecularLightingEffect GLEffect;
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
     SkScalar ks() const { return fKS; }
     SkScalar shininess() const { return fShininess; }
 
 private:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GrSpecularLightingEffect(GrTexture* texture,
                              const SkLight* light,
                              SkScalar surfaceScale,
@@ -1050,10 +1054,9 @@ GrLightingEffect::~GrLightingEffect() {
     fLight->unref();
 }
 
-bool GrLightingEffect::isEqual(const GrEffect& sBase) const {
-    const GrLightingEffect& s =
-        static_cast<const GrLightingEffect&>(sBase);
-    return INHERITED::isEqual(sBase) &&
+bool GrLightingEffect::onIsEqual(const GrEffect& sBase) const {
+    const GrLightingEffect& s = static_cast<const GrLightingEffect&>(sBase);
+    return this->texture(0) == s.texture(0) &&
            fLight->isEqual(*s.fLight) &&
            fSurfaceScale == s.fSurfaceScale;
 }
@@ -1068,10 +1071,10 @@ const GrBackendEffectFactory& GrDiffuseLightingEffect::getFactory() const {
     return GrTBackendEffectFactory<GrDiffuseLightingEffect>::getInstance();
 }
 
-bool GrDiffuseLightingEffect::isEqual(const GrEffect& sBase) const {
+bool GrDiffuseLightingEffect::onIsEqual(const GrEffect& sBase) const {
     const GrDiffuseLightingEffect& s =
         static_cast<const GrDiffuseLightingEffect&>(sBase);
-    return INHERITED::isEqual(sBase) &&
+    return INHERITED::onIsEqual(sBase) &&
             this->kd() == s.kd();
 }
 
@@ -1280,10 +1283,10 @@ const GrBackendEffectFactory& GrSpecularLightingEffect::getFactory() const {
     return GrTBackendEffectFactory<GrSpecularLightingEffect>::getInstance();
 }
 
-bool GrSpecularLightingEffect::isEqual(const GrEffect& sBase) const {
+bool GrSpecularLightingEffect::onIsEqual(const GrEffect& sBase) const {
     const GrSpecularLightingEffect& s =
         static_cast<const GrSpecularLightingEffect&>(sBase);
-    return INHERITED::isEqual(sBase) &&
+    return INHERITED::onIsEqual(sBase) &&
            this->ks() == s.ks() &&
            this->shininess() == s.shininess();
 }
index e7f266eeff6efe17f0c51c5818121509e2d196a6..bcf0baf75145c554ffa557eb19e508eeda146676 100644 (file)
@@ -48,7 +48,7 @@ public:
     static const char* Name() { return "Magnifier"; }
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     float x_offset() const { return fXOffset; }
     float y_offset() const { return fYOffset; }
@@ -75,6 +75,8 @@ private:
         , fXInset(xInset)
         , fYInset(yInset) {}
 
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GR_DECLARE_EFFECT_TEST;
 
     float fXOffset;
@@ -230,10 +232,10 @@ const GrBackendEffectFactory& GrMagnifierEffect::getFactory() const {
     return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance();
 }
 
-bool GrMagnifierEffect::isEqual(const GrEffect& sBase) const {
-     const GrMagnifierEffect& s =
-        static_cast<const GrMagnifierEffect&>(sBase);
-    return (this->fXOffset == s.fXOffset &&
+bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const {
+     const GrMagnifierEffect& s = static_cast<const GrMagnifierEffect&>(sBase);
+    return (this->texture(0) == s.texture(0) &&
+            this->fXOffset == s.fXOffset &&
             this->fYOffset == s.fYOffset &&
             this->fXZoom == s.fXZoom &&
             this->fYZoom == s.fYZoom &&
@@ -241,6 +243,10 @@ bool GrMagnifierEffect::isEqual(const GrEffect& sBase) const {
             this->fYInset == s.fYInset);
 }
 
+void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+    this->updateConstantColorComponentsForModulation(color, validFlags);
+}
+
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
index 03b10be0415930dea451756e36de2e184d5d4540..50933eeeb6bb46826acc712b4cc9cb0b4e5a4da0 100644 (file)
@@ -287,7 +287,6 @@ public:
 
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
 
 private:
     GrMatrixConvolutionEffect(GrTexture*,
@@ -299,6 +298,8 @@ private:
                               TileMode tileMode,
                               bool convolveAlpha);
 
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     SkISize  fKernelSize;
     float   *fKernel;
     float    fGain;
@@ -518,10 +519,10 @@ const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const {
     return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance();
 }
 
-bool GrMatrixConvolutionEffect::isEqual(const GrEffect& sBase) const {
+bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
     const GrMatrixConvolutionEffect& s =
         static_cast<const GrMatrixConvolutionEffect&>(sBase);
-    return INHERITED::isEqual(sBase) &&
+    return this->texture(0) == s.texture(0) &&
            fKernelSize == s.kernelSize() &&
            !memcmp(fKernel, s.kernel(), fKernelSize.width() * fKernelSize.height() * sizeof(float)) &&
            fGain == s.gain() &&
index ed30aca8b2cdcfc617eaa4759d2249ba457c36f7..c40943592674a9dc0916a4501935c68f9baad13a 100644 (file)
@@ -257,13 +257,15 @@ public:
     typedef GrGLMorphologyEffect GLEffect;
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 protected:
 
     MorphologyType fType;
 
 private:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
 
     GR_DECLARE_EFFECT_TEST;
@@ -399,15 +401,21 @@ const GrBackendEffectFactory& GrMorphologyEffect::getFactory() const {
     return GrTBackendEffectFactory<GrMorphologyEffect>::getInstance();
 }
 
-bool GrMorphologyEffect::isEqual(const GrEffect& sBase) const {
+bool GrMorphologyEffect::onIsEqual(const GrEffect& sBase) const {
     const GrMorphologyEffect& s =
         static_cast<const GrMorphologyEffect&>(sBase);
-    return (INHERITED::isEqual(sBase) &&
+    return (this->texture(0) == s.texture(0) &&
             this->radius() == s.radius() &&
             this->direction() == s.direction() &&
             this->type() == s.type());
 }
 
+void GrMorphologyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+    // This is valid because the color components of the result of the kernel all come
+    // exactly from existing values in the source texture.
+    this->updateConstantColorComponentsForModulation(color, validFlags);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 GR_DEFINE_EFFECT_TEST(GrMorphologyEffect);
index 0a922e712a989d1a9ef59491e6e8a7260c7ae160..afb4a9926c99196296beef878d7962fd6a3e0736 100644 (file)
@@ -235,13 +235,14 @@ public:
 
     static const char* Name() { return "ColorTable"; }
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     typedef GLColorTableEffect GLEffect;
 
 private:
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     explicit ColorTableEffect(GrTexture* texture, unsigned flags);
 
     GR_DECLARE_EFFECT_TEST;
@@ -344,8 +345,8 @@ const GrBackendEffectFactory&  ColorTableEffect::getFactory() const {
     return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
 }
 
-bool ColorTableEffect::isEqual(const GrEffect& sBase) const {
-    return INHERITED::isEqual(sBase);
+bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
+    return this->texture(0) == sBase.texture(0);
 }
 
 void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
index ba72eeadd44bcb3e21642090bf7dfaf67839b17d..76450245ff897e8585eb002f135cdcb7b1dfd2bc 100644 (file)
@@ -829,6 +829,24 @@ GrGradientEffect::~GrGradientEffect() {
     }
 }
 
+bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
+    const GrGradientEffect& s = static_cast<const GrGradientEffect&>(effect);
+    return fTextureAccess.getTexture() == s.fTextureAccess.getTexture()  &&
+           fTextureAccess.getParams().getTileModeX() ==
+                s.fTextureAccess.getParams().getTileModeX() &&
+           this->useAtlas() == s.useAtlas() &&
+           fYCoord == s.getYCoord() &&
+           fMatrix.cheapEqualTo(s.getMatrix());
+}
+
+void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+    if (fIsOpaque && (kA_ValidComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) {
+        *validFlags = kA_ValidComponentFlag;
+    } else {
+        *validFlags = 0;
+    }
+}
+
 int GrGradientEffect::RandomGradientParams(SkRandom* random,
                                            SkColor colors[],
                                            SkScalar** stops,
index 27c443814b00852a391beafd63735a2905c3644e..18289051b6c427c1f4cac726993cf2e009eb6d96 100644 (file)
@@ -238,20 +238,7 @@ public:
     SkScalar getYCoord() const { return fYCoord; };
     const SkMatrix& getMatrix() const { return fMatrix;}
 
-    virtual bool isEqual(const GrEffect& effect) const SK_OVERRIDE {
-        const GrGradientEffect& s = static_cast<const GrGradientEffect&>(effect);
-        return INHERITED::isEqual(effect) && this->useAtlas() == s.useAtlas() &&
-               fYCoord == s.getYCoord() && fMatrix.cheapEqualTo(s.getMatrix());
-    }
-
-    virtual void getConstantColorComponents(GrColor* color,
-                                            uint32_t* validFlags) const SK_OVERRIDE {
-        if (fIsOpaque && (kA_ValidComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) {
-            *validFlags = kA_ValidComponentFlag;
-        } else {
-            *validFlags = 0;
-        }
-    }
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 protected:
 
@@ -268,7 +255,10 @@ protected:
                                     SkScalar** stops,
                                     SkShader::TileMode* tm);
 
+    virtual bool onIsEqual(const GrEffect& effect) const SK_OVERRIDE;
+
 private:
+
     GrTextureAccess fTextureAccess;
     SkScalar fYCoord;
     GrTextureStripAtlas* fAtlas;
index 0a154246c3010324cf879c591138817489adaf81..23b976a8f8990a4fb84925fe1a3fafc57b2f17dc 100644 (file)
@@ -383,13 +383,6 @@ public:
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
         return GrTBackendEffectFactory<GrConical2Gradient>::getInstance();
     }
-    virtual bool isEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const GrConical2Gradient& s = static_cast<const GrConical2Gradient&>(sBase);
-        return (INHERITED::isEqual(sBase) &&
-                this->fCenterX1 == s.fCenterX1 &&
-                this->fRadius0 == s.fRadius0 &&
-                this->fDiffRadius == s.fDiffRadius);
-    }
 
     // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
     bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(fCenterX1); }
@@ -400,6 +393,14 @@ public:
     typedef GrGLConical2Gradient GLEffect;
 
 private:
+    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
+        const GrConical2Gradient& s = static_cast<const GrConical2Gradient&>(sBase);
+        return (INHERITED::onIsEqual(sBase) &&
+                this->fCenterX1 == s.fCenterX1 &&
+                this->fRadius0 == s.fRadius0 &&
+                this->fDiffRadius == s.fDiffRadius);
+    }
+
     GrConical2Gradient(GrContext* ctx,
                        const SkTwoPointConicalGradient& shader,
                        const SkMatrix& matrix,
index 0f79a2bec6e82efc1227c10bab23fdf49a1e18fd..4f7351003a30130932341ae6a93724f9a8393e7f 100644 (file)
@@ -442,13 +442,6 @@ public:
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
         return GrTBackendEffectFactory<GrRadial2Gradient>::getInstance();
     }
-    virtual bool isEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
-        return (INHERITED::isEqual(sBase) &&
-                this->fCenterX1 == s.fCenterX1 &&
-                this->fRadius0 == s.fRadius0 &&
-                this->fPosRoot == s.fPosRoot);
-    }
 
     // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
     bool isDegenerate() const { return SK_Scalar1 == fCenterX1; }
@@ -459,6 +452,14 @@ public:
     typedef GrGLRadial2Gradient GLEffect;
 
 private:
+    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
+        const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
+        return (INHERITED::isEqual(sBase) &&
+                this->fCenterX1 == s.fCenterX1 &&
+                this->fRadius0 == s.fRadius0 &&
+                this->fPosRoot == s.fPosRoot);
+    }
+
     GrRadial2Gradient(GrContext* ctx,
                       const SkTwoPointRadialGradient& shader,
                       const SkMatrix& matrix,
index a8ce05510ada974415ed95d0f654e933ad59d441..43dda9c75c537f497582f854de43b839d29a445a 100644 (file)
@@ -1860,7 +1860,7 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
         scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
                              i < scaleFactorY ? 0.5f : 1.0f);
 
-        paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(srcTexture,
+        paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture,
                                                                      matrix,
                                                                      true))->unref();
         this->drawRectToRect(paint, dstRect, srcRect);
@@ -1919,7 +1919,7 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
         // FIXME:  This should be mitchell, not bilinear.
         matrix.setIDiv(srcTexture->width(), srcTexture->height());
         this->setRenderTarget(dstTexture->asRenderTarget());
-        paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(srcTexture,
+        paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture,
                                                                      matrix,
                                                                      true))->unref();
         SkRect dstRect(srcRect);
index 993076bcb3a985af30a11b5c5d31431cd260a272..13ed2878034f7164ad5c6dbd31ee61bbce0ff279 100644 (file)
@@ -16,7 +16,7 @@
 #include "GrStencil.h"
 #include "GrTexture.h"
 #include "GrRenderTarget.h"
-#include "effects/GrSingleTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
 
 #include "SkXfermode.h"
 
@@ -193,11 +193,11 @@ public:
     ////
 
     /**
-     * Creates a GrSingleTextureEffect.
+     * Creates a GrSimpleTextureEffect.
      */
     void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
         GrAssert(!this->getStage(stageIdx).getEffect());
-        GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix);
+        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
         this->stage(stageIdx)->setEffect(effect)->unref();
     }
     void createTextureEffect(int stageIdx,
@@ -205,7 +205,7 @@ public:
                              const SkMatrix& matrix,
                              const GrTextureParams& params) {
         GrAssert(!this->getStage(stageIdx).getEffect());
-        GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix, params);
+        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
         this->stage(stageIdx)->setEffect(effect)->unref();
     }
 
index d1ef4b78cb0a428be37cf83ea2c27d1c1ad4a6dc..40a519aa8357a5dc67ea701322bd57b5645d0ddc 100644 (file)
@@ -86,18 +86,6 @@ const char* GrEffect::name() const {
     return this->getFactory().name();
 }
 
-bool GrEffect::isEqual(const GrEffect& s) const {
-    if (this->numTextures() != s.numTextures()) {
-        return false;
-    }
-    for (int i = 0; i < this->numTextures(); ++i) {
-        if (this->textureAccess(i) != s.textureAccess(i)) {
-            return false;
-        }
-    }
-    return true;
-}
-
 void GrEffect::addTextureAccess(const GrTextureAccess* access) {
     fTextureAccesses.push_back(access);
 }
index f205569fa024daa04c0c1892d1d9973fdd79484e..0cf3b35f2af04980151ea18d5a3f7710281d7987 100644 (file)
@@ -8,6 +8,7 @@
 #include "SkGpuDevice.h"
 
 #include "effects/GrTextureDomainEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
 
 #include "GrContext.h"
 #include "GrTextContext.h"
@@ -443,7 +444,7 @@ bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) {
     GrTexture* texture = fRenderTarget->asTexture();
     if (NULL != texture) {
         paint->colorStage(kBitmapTextureIdx)->setEffect(
-            GrSingleTextureEffect::Create(texture, SkMatrix::I()))->unref();
+            GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref();
         return true;
     }
     return false;
@@ -797,7 +798,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkSt
             // Blend pathTexture over blurTexture.
             context->setRenderTarget(blurTexture->asRenderTarget());
             paint.colorStage(0)->setEffect(
-                GrSingleTextureEffect::Create(pathTexture, matrix))->unref();
+                GrSimpleTextureEffect::Create(pathTexture, matrix))->unref();
             if (SkMaskFilter::kInner_BlurType == blurType) {
                 // inner:  dst = dst * src
                 paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
@@ -829,7 +830,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkSt
 
     grp->coverageStage(MASK_IDX)->reset();
     grp->coverageStage(MASK_IDX)->setEffect(
-        GrSingleTextureEffect::Create(blurTexture, matrix))->unref();
+        GrSimpleTextureEffect::Create(blurTexture, matrix))->unref();
     context->drawRect(*grp, finalRect);
     return true;
 }
@@ -885,7 +886,7 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& devPath,
     m.setTranslate(-dstM.fBounds.fLeft*SK_Scalar1, -dstM.fBounds.fTop*SK_Scalar1);
     m.postIDiv(texture->width(), texture->height());
 
-    grp->coverageStage(MASK_IDX)->setEffect(GrSingleTextureEffect::Create(texture, m))->unref();
+    grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(texture, m))->unref();
     GrRect d;
     d.setLTRB(SkIntToScalar(dstM.fBounds.fLeft),
               SkIntToScalar(dstM.fBounds.fTop),
@@ -1340,7 +1341,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
                                                    GrTextureDomainEffect::kClamp_WrapMode,
                                                    params.isBilerp()));
     } else {
-        effect.reset(GrSingleTextureEffect::Create(texture, SkMatrix::I(), params));
+        effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
     }
     grPaint->colorStage(kBitmapTextureIdx)->setEffect(effect);
     fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
@@ -1418,7 +1419,7 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
     // draw sprite uses the default texture params
     SkAutoCachedTexture act(this, bitmap, NULL, &texture);
     grPaint.colorStage(kBitmapTextureIdx)->setEffect(
-        GrSingleTextureEffect::Create(texture, SkMatrix::I()))->unref();
+        GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref();
 
     SkImageFilter* filter = paint.getImageFilter();
     if (NULL != filter) {
@@ -1426,7 +1427,7 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
                  GrRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)));
         if (filteredTexture) {
             grPaint.colorStage(kBitmapTextureIdx)->setEffect(
-                GrSingleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
+                GrSimpleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
             texture = filteredTexture;
             filteredTexture->unref();
         }
@@ -1500,7 +1501,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device,
         GrTexture* filteredTexture = filter_texture(this, fContext, devTex, filter, rect);
         if (filteredTexture) {
             grPaint.colorStage(kBitmapTextureIdx)->setEffect(
-                GrSingleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
+                GrSimpleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
             devTex = filteredTexture;
             filteredTexture->unref();
         }
index 5e99dad60117924e2a48f61c25d0536cf9e5caf0..309dcd88760d9c7d5c6fb04f54293f434381d5fe 100644 (file)
@@ -8,6 +8,7 @@
 #include "GrConfigConversionEffect.h"
 #include "GrContext.h"
 #include "GrTBackendEffectFactory.h"
+#include "GrSimpleTextureEffect.h"
 #include "gl/GrGLEffect.h"
 #include "gl/GrGLEffectMatrix.h"
 #include "SkMatrix.h"
@@ -115,9 +116,16 @@ const GrBackendEffectFactory& GrConfigConversionEffect::getFactory() const {
     return GrTBackendEffectFactory<GrConfigConversionEffect>::getInstance();
 }
 
-bool GrConfigConversionEffect::isEqual(const GrEffect& s) const {
+bool GrConfigConversionEffect::onIsEqual(const GrEffect& s) const {
     const GrConfigConversionEffect& other = static_cast<const GrConfigConversionEffect&>(s);
-    return other.fSwapRedAndBlue == fSwapRedAndBlue && other.fPMConversion == fPMConversion;
+    return this->texture(0) == s.texture(0) &&
+           other.fSwapRedAndBlue == fSwapRedAndBlue &&
+           other.fPMConversion == fPMConversion;
+}
+
+void GrConfigConversionEffect::getConstantColorComponents(GrColor* color,
+                                                          uint32_t* validFlags) const {
+    this->updateConstantColorComponentsForModulation(color, validFlags);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -263,7 +271,7 @@ bool GrConfigConversionEffect::InstallEffect(GrTexture* texture,
         // If we returned a GrConfigConversionEffect that was equivalent to a GrSingleTextureEffect
         // then we may pollute our texture cache with redundant shaders. So in the case that no
         // conversions were requested we instead return a GrSingleTextureEffect.
-        stage->setEffect(GrSingleTextureEffect::Create(texture, matrix))->unref();
+        stage->setEffect(GrSimpleTextureEffect::Create(texture, matrix))->unref();
         return true;
     } else {
         if (kRGBA_8888_GrPixelConfig != texture->config() &&
index b8dd7d0ed4ce90eefe363a8a5fb26f06a84e0ca5..3845d32bbd65cfb544e3f92c3a1903c9e217ae46 100644 (file)
@@ -45,7 +45,8 @@ public:
     typedef GrGLConfigConversionEffect GLEffect;
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     bool swapsRedAndBlue() const { return fSwapRedAndBlue; }
     PMConversion  pmConversion() const { return fPMConversion; }
@@ -65,6 +66,8 @@ private:
                             PMConversion pmConversion,
                             const SkMatrix& matrix);
 
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     bool            fSwapRedAndBlue;
     PMConversion    fPMConversion;
 
index 1f4c094814a17f29344f9265eb84850ea88fab6c..82c908aa3cacdbca9014b384abf962d14ae6c49e 100644 (file)
@@ -167,10 +167,9 @@ const GrBackendEffectFactory& GrConvolutionEffect::getFactory() const {
     return GrTBackendEffectFactory<GrConvolutionEffect>::getInstance();
 }
 
-bool GrConvolutionEffect::isEqual(const GrEffect& sBase) const {
-     const GrConvolutionEffect& s =
-        static_cast<const GrConvolutionEffect&>(sBase);
-    return (INHERITED::isEqual(sBase) &&
+bool GrConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
+     const GrConvolutionEffect& s = static_cast<const GrConvolutionEffect&>(sBase);
+    return (this->texture(0) == s.texture(0) &&
             this->radius() == s.radius() &&
             this->direction() == s.direction() &&
             0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
index 4f0c9eca93b4dd0a8da94a8296408a94d1b7d383..944d34f49bbfb025bea86ea661b204040c4531b0 100644 (file)
@@ -51,7 +51,12 @@ public:
     typedef GrGLConvolutionEffect GLEffect;
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+        // If the texture was opaque we could know that the output color if we knew the sum of the
+        // kernel values.
+        *validFlags = 0;
+    }
 
     enum {
         // This was decided based on the min allowed value for the max texture
@@ -77,6 +82,8 @@ private:
                         int halfWidth,
                         float gaussianSigma);
 
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GR_DECLARE_EFFECT_TEST;
 
     typedef Gr1DKernelEffect INHERITED;
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
new file mode 100644 (file)
index 0000000..69ab13e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrSimpleTextureEffect.h"
+#include "gl/GrGLEffect.h"
+#include "gl/GrGLEffectMatrix.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLTexture.h"
+#include "GrTBackendEffectFactory.h"
+#include "GrTexture.h"
+
+class GrGLSimpleTextureEffect : public GrGLEffect {
+public:
+    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
+    : INHERITED (factory) {}
+
+    virtual void emitCode(GrGLShaderBuilder* builder,
+                          const GrEffectStage&,
+                          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);
+        builder->fFSCode.appendf("\t%s = ", outputColor);
+        builder->appendTextureLookupAndModulate(&builder->fFSCode,
+                                                inputColor,
+                                                samplers[0],
+                                                coordName,
+                                                coordType);
+        builder->fFSCode.append(";\n");
+    }
+
+    static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
+        const GrSimpleTextureEffect& ste =
+            static_cast<const GrSimpleTextureEffect&>(*stage.getEffect());
+        return GrGLEffectMatrix::GenKey(ste.getMatrix(),
+                                        stage.getCoordChangeMatrix(),
+                                        ste.texture(0));
+    }
+
+    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
+        const GrSimpleTextureEffect& ste =
+            static_cast<const GrSimpleTextureEffect&>(*stage.getEffect());
+        fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
+    }
+
+private:
+    GrGLEffectMatrix fEffectMatrix;
+    typedef GrGLEffect INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+    this->updateConstantColorComponentsForModulation(color, validFlags);
+}
+
+const GrBackendEffectFactory& GrSimpleTextureEffect::getFactory() const {
+    return GrTBackendEffectFactory<GrSimpleTextureEffect>::getInstance();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_EFFECT_TEST(GrSimpleTextureEffect);
+
+GrEffectRef* GrSimpleTextureEffect::TestCreate(SkRandom* random,
+                                               GrContext* context,
+                                               GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
+                                      GrEffectUnitTest::kAlphaTextureIdx;
+    const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
+    return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
+}
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
new file mode 100644 (file)
index 0000000..5ccbe33
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSimpleTextureEffect_DEFINED
+#define GrSimpleTextureEffect_DEFINED
+
+#include "GrSingleTextureEffect.h"
+
+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).
+ */
+class GrSimpleTextureEffect : public GrSingleTextureEffect {
+public:
+    /* unfiltered, clamp mode */
+    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix)));
+        return CreateEffectRef(effect);
+    }
+
+    /* clamp mode */
+    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp)));
+        return CreateEffectRef(effect);
+    }
+
+    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p)));
+        return CreateEffectRef(effect);
+    }
+
+    virtual ~GrSimpleTextureEffect() {}
+
+    static const char* Name() { return "Texture"; }
+
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
+
+    typedef GrGLSimpleTextureEffect GLEffect;
+
+    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) {}
+
+    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
+        const GrSimpleTextureEffect& ste = static_cast<const GrSimpleTextureEffect&>(other);
+        return this->hasSameTextureParamsAndMatrix(ste);
+    }
+
+    GR_DECLARE_EFFECT_TEST;
+
+    typedef GrSingleTextureEffect INHERITED;
+};
+
+#endif
index 18e35e43490c517547e6b55346c7cbc5ccee5c44..7183ba324432b45db696918541dbdec5e86738bb 100644 (file)
@@ -6,56 +6,6 @@
  */
 
 #include "effects/GrSingleTextureEffect.h"
-#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
-#include "gl/GrGLSL.h"
-#include "gl/GrGLTexture.h"
-#include "GrTBackendEffectFactory.h"
-#include "GrTexture.h"
-
-class GrGLSingleTextureEffect : public GrGLEffect {
-public:
-    GrGLSingleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
-    : INHERITED (factory) {}
-
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrEffectStage&,
-                          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);
-        builder->fFSCode.appendf("\t%s = ", outputColor);
-        builder->appendTextureLookupAndModulate(&builder->fFSCode,
-                                                inputColor,
-                                                samplers[0],
-                                                coordName,
-                                                coordType);
-        builder->fFSCode.append(";\n");
-    }
-
-    static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        const GrSingleTextureEffect& ste =
-            static_cast<const GrSingleTextureEffect&>(*stage.getEffect());
-        return GrGLEffectMatrix::GenKey(ste.getMatrix(),
-                                        stage.getCoordChangeMatrix(),
-                                        ste.texture(0));
-    }
-
-    virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
-        const GrSingleTextureEffect& ste =
-            static_cast<const GrSingleTextureEffect&>(*stage.getEffect());
-        fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
-    }
-
-private:
-    GrGLEffectMatrix fEffectMatrix;
-    typedef GrGLEffect INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
 
 GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m)
     : fTextureAccess(texture)
@@ -79,31 +29,3 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
 
 GrSingleTextureEffect::~GrSingleTextureEffect() {
 }
-
-void GrSingleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
-    // If the input alpha is 0xff and the texture has no alpha channel, then the output alpha is
-    // 0xff
-    if ((*validFlags & kA_ValidComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
-        GrPixelConfigIsOpaque(fTextureAccess.getTexture()->config())) {
-        *validFlags = kA_ValidComponentFlag;
-    } else {
-        *validFlags = 0;
-    }
-}
-
-const GrBackendEffectFactory& GrSingleTextureEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrSingleTextureEffect>::getInstance();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GR_DEFINE_EFFECT_TEST(GrSingleTextureEffect);
-
-GrEffectRef* GrSingleTextureEffect::TestCreate(SkRandom* random,
-                                               GrContext* context,
-                                               GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
-    const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
-    return GrSingleTextureEffect::Create(textures[texIdx], matrix);
-}
index e475cb5751b05c086aeff3437324a9ab85292dbd..4f25ddb38dc1dde6ac7ad8f72ce17cc10e416f0b 100644 (file)
 #include "GrEffect.h"
 #include "SkMatrix.h"
 
-class GrGLSingleTextureEffect;
 class GrTexture;
 
 /**
- * An effect that draws a single texture with a texture matrix; commonly used as a base class. The
- * output color is the texture color is modulated against the input color.
+ * A base class for effects that draw a single texture with a texture matrix.
  */
 class GrSingleTextureEffect : public GrEffect {
 public:
-    /* unfiltered, clamp mode */
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix)));
-        return CreateEffectRef(effect);
-    }
-
-    /* clamp mode */
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix, bilerp)));
-        return CreateEffectRef(effect);
-    }
-
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix, p)));
-        return CreateEffectRef(effect);
-    }
-
     virtual ~GrSingleTextureEffect();
 
-    static const char* Name() { return "Single Texture"; }
-
-    /** Note that if this class is sub-classed, the subclass may have to override this function.
-     */
-    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
-
     const SkMatrix& getMatrix() const { return fMatrix; }
 
-    typedef GrGLSingleTextureEffect GLEffect;
-
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-
-    virtual bool isEqual(const GrEffect& effect) const SK_OVERRIDE {
-        const GrSingleTextureEffect& ste = static_cast<const GrSingleTextureEffect&>(effect);
-        return INHERITED::isEqual(effect) && fMatrix.cheapEqualTo(ste.getMatrix());
-    }
-
 protected:
     GrSingleTextureEffect(GrTexture*, const SkMatrix&); /* unfiltered, clamp mode */
     GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp); /* clamp mode */
     GrSingleTextureEffect(GrTexture*, const SkMatrix&, const GrTextureParams&);
 
-private:
+    /**
+     * Helper for subclass onIsEqual() functions.
+     */
+    bool hasSameTextureParamsAndMatrix(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());
+    }
 
-    GR_DECLARE_EFFECT_TEST;
+    /**
+     * Can be used as a helper to implement subclass getConstantColorComponents(). It assumes that
+     * the subclass output color will be a modulation of the input color with a value read from the
+     * texture.
+     */
+    void updateConstantColorComponentsForModulation(GrColor* color, uint32_t* validFlags) const {
+        if ((*validFlags & kA_ValidComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
+            GrPixelConfigIsOpaque(this->texture(0)->config())) {
+            *validFlags = kA_ValidComponentFlag;
+        } else {
+            *validFlags = 0;
+        }
+    }
 
+private:
     GrTextureAccess fTextureAccess;
     SkMatrix        fMatrix;
 
index f82c62f3ff8707b3742f48f5f4adcf33cba9f620..c4a59d8daec44f95943292227f4c80614597f967 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "GrTextureDomainEffect.h"
+#include "GrSimpleTextureEffect.h"
 #include "GrTBackendEffectFactory.h"
 #include "gl/GrGLEffect.h"
 #include "gl/GrGLEffectMatrix.h"
@@ -128,7 +129,7 @@ GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
                                            bool bilerp) {
     static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
     if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
-        return GrSingleTextureEffect::Create(texture, matrix, bilerp);
+        return GrSimpleTextureEffect::Create(texture, matrix, bilerp);
     } else {
         SkRect clippedDomain;
         // We don't currently handle domains that are empty or don't intersect the texture.
@@ -171,9 +172,17 @@ const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const {
     return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance();
 }
 
-bool GrTextureDomainEffect::isEqual(const GrEffect& sBase) const {
+bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
     const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
-    return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
+    return this->hasSameTextureParamsAndMatrix(s) && this->fTextureDomain == s.fTextureDomain;
+}
+
+void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+    if (kDecal_WrapMode == fWrapMode) {
+        *validFlags = 0;
+    } else {
+        this->updateConstantColorComponentsForModulation(color, validFlags);
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index a5c2d7019834beddefb4c8f28507694e0abc46e3..b7f665cba3f08d1765d791575c3fc9a7174bc8c6 100644 (file)
@@ -47,7 +47,7 @@ public:
     typedef GrGLTextureDomainEffect GLEffect;
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-    virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     const SkRect& domain() const { return fTextureDomain; }
     WrapMode wrapMode() const { return fWrapMode; }
@@ -77,6 +77,8 @@ private:
                           WrapMode,
                           bool bilerp);
 
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
     GR_DECLARE_EFFECT_TEST;
 
     typedef GrSingleTextureEffect INHERITED;