diff options
31 files changed, 364 insertions, 242 deletions
diff --git a/gm/texdata.cpp b/gm/texdata.cpp index 1f888267ad..da52aade6a 100644 --- a/gm/texdata.cpp +++ b/gm/texdata.cpp @@ -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)); diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 3248f03d83..bf301bb012 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -128,6 +128,8 @@ '<(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', diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h index 1e0ce794b1..507bd5736b 100644 --- a/include/gpu/GrEffect.h +++ b/include/gpu/GrEffect.h @@ -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; } diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h index 597ea4957c..0060152815 100644 --- a/include/gpu/GrEffectStage.h +++ b/include/gpu/GrEffectStage.h @@ -39,10 +39,6 @@ public: return false; } - if (this->getEffect()->getFactory() != other.getEffect()->getFactory()) { - return false; - } - if (!this->getEffect()->isEqual(*other.getEffect())) { return false; } diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 2f7173e446..d91b978dcc 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -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; } diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp index 5a93b479d2..43915b3a79 100644 --- a/src/effects/SkBlendImageFilter.cpp +++ b/src/effects/SkBlendImageFilter.cpp @@ -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 { diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp index 0fb438d2f4..06fb4efed0 100644 --- a/src/effects/SkColorMatrixFilter.cpp +++ b/src/effects/SkColorMatrixFilter.cpp @@ -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; diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 9a67ac36c7..17abe28b18 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -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 { diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index ddb033def3..780a3a42bd 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -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(); } diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index e7f266eeff..bcf0baf751 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -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 //////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp index 03b10be041..50933eeeb6 100644 --- a/src/effects/SkMatrixConvolutionImageFilter.cpp +++ b/src/effects/SkMatrixConvolutionImageFilter.cpp @@ -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() && diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index ed30aca8b2..c409435926 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -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); diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 0a922e712a..afb4a9926c 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -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 { diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index ba72eeadd4..76450245ff 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -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, diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index 27c443814b..18289051b6 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -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; diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp index 0a154246c3..23b976a8f8 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp @@ -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, diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp index 0f79a2bec6..4f7351003a 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.cpp +++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp @@ -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, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index a8ce05510a..43dda9c75c 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -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); diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 993076bcb3..13ed287803 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -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(); } diff --git a/src/gpu/GrEffect.cpp b/src/gpu/GrEffect.cpp index d1ef4b78cb..40a519aa83 100644 --- a/src/gpu/GrEffect.cpp +++ b/src/gpu/GrEffect.cpp @@ -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); } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index f205569fa0..0cf3b35f2a 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -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(); } diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 5e99dad601..309dcd8876 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -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() && diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h index b8dd7d0ed4..3845d32bbd 100644 --- a/src/gpu/effects/GrConfigConversionEffect.h +++ b/src/gpu/effects/GrConfigConversionEffect.h @@ -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; diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp index 1f4c094814..82c908aa3c 100644 --- a/src/gpu/effects/GrConvolutionEffect.cpp +++ b/src/gpu/effects/GrConvolutionEffect.cpp @@ -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))); diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h index 4f0c9eca93..944d34f49b 100644 --- a/src/gpu/effects/GrConvolutionEffect.h +++ b/src/gpu/effects/GrConvolutionEffect.h @@ -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 index 0000000000..69ab13ebe1 --- /dev/null +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -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 index 0000000000..5ccbe33497 --- /dev/null +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -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 diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index 18e35e4349..7183ba3244 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -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); -} diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index e475cb5751..4f25ddb38d 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -11,60 +11,48 @@ #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; diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp index f82c62f3ff..c4a59d8dae 100644 --- a/src/gpu/effects/GrTextureDomainEffect.cpp +++ b/src/gpu/effects/GrTextureDomainEffect.cpp @@ -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); + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrTextureDomainEffect.h b/src/gpu/effects/GrTextureDomainEffect.h index a5c2d70198..b7f665cba3 100644 --- a/src/gpu/effects/GrTextureDomainEffect.h +++ b/src/gpu/effects/GrTextureDomainEffect.h @@ -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; |