From 0ac6af49975c54c2debf41e9200af416ecd2d973 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Wed, 16 Jan 2013 15:16:18 +0000 Subject: [PATCH] Wrap GrEffects in GrEffectPtr. This is the first step towards automatic recycling of scratch resouces in the cache via ref-cnts. R=robertphillips@google.com Review URL: https://codereview.appspot.com/7092061 git-svn-id: http://skia.googlecode.com/svn/trunk@7222 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/texdata.cpp | 3 +- include/core/SkColorFilter.h | 4 +- include/core/SkImageFilter.h | 4 +- include/core/SkPostConfig.h | 14 ++-- include/core/SkShader.h | 5 +- include/effects/SkColorMatrixFilter.h | 2 +- include/effects/SkMagnifierImageFilter.h | 3 +- .../effects/SkMatrixConvolutionImageFilter.h | 2 +- include/gpu/GrEffect.h | 64 +++++++++++++++- include/gpu/GrEffectStage.h | 49 ++++++------ include/gpu/GrEffectUnitTest.h | 12 +-- src/core/SkBitmapProcShader.cpp | 4 +- src/core/SkBitmapProcShader.h | 2 +- src/core/SkColorFilter.cpp | 2 +- src/core/SkImageFilter.cpp | 2 +- src/core/SkShader.cpp | 2 +- src/effects/SkBlendImageFilter.cpp | 11 ++- src/effects/SkColorMatrixFilter.cpp | 21 ++++-- src/effects/SkDisplacementMapEffect.cpp | 35 ++++++--- src/effects/SkLightingImageFilter.cpp | 75 ++++++++++++------- src/effects/SkMagnifierImageFilter.cpp | 70 ++++++++++------- .../SkMatrixConvolutionImageFilter.cpp | 75 ++++++++++++------- src/effects/SkMorphologyImageFilter.cpp | 24 +++--- src/effects/SkTableColorFilter.cpp | 21 ++++-- src/effects/gradients/SkLinearGradient.cpp | 28 ++++--- src/effects/gradients/SkLinearGradient.h | 2 +- src/effects/gradients/SkRadialGradient.cpp | 29 ++++--- src/effects/gradients/SkRadialGradient.h | 2 +- src/effects/gradients/SkSweepGradient.cpp | 25 ++++--- src/effects/gradients/SkSweepGradient.h | 2 +- .../gradients/SkTwoPointConicalGradient.cpp | 34 +++++---- .../gradients/SkTwoPointConicalGradient.h | 2 +- .../gradients/SkTwoPointRadialGradient.cpp | 34 +++++---- .../gradients/SkTwoPointRadialGradient.h | 2 +- src/gpu/GrContext.cpp | 17 +++-- src/gpu/GrDrawState.h | 9 +-- src/gpu/GrEffect.cpp | 23 +++++- src/gpu/GrSWMaskHelper.cpp | 2 +- src/gpu/SkGpuDevice.cpp | 34 +++++---- src/gpu/effects/GrConfigConversionEffect.cpp | 57 +++++++------- src/gpu/effects/GrConfigConversionEffect.h | 1 + src/gpu/effects/GrConvolutionEffect.cpp | 8 +- src/gpu/effects/GrConvolutionEffect.h | 31 ++++++-- src/gpu/effects/GrSingleTextureEffect.cpp | 26 +------ src/gpu/effects/GrSingleTextureEffect.h | 30 +++++--- src/gpu/effects/GrTextureDomainEffect.cpp | 28 ++++--- src/gpu/effects/GrTextureDomainEffect.h | 10 +-- tests/GLProgramsTest.cpp | 10 +-- 48 files changed, 598 insertions(+), 354 deletions(-) diff --git a/gm/texdata.cpp b/gm/texdata.cpp index e36feef0cb..1f888267ad 100644 --- a/gm/texdata.cpp +++ b/gm/texdata.cpp @@ -113,8 +113,7 @@ protected: SkMatrix tm; tm = vm; tm.postIDiv(2*S, 2*S); - paint.colorStage(0)->setEffect(SkNEW_ARGS(GrSingleTextureEffect, - (texture, tm)))->unref(); + paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(texture, tm))->unref(); ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S)); diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h index 4f67c8dbfe..65a8cf33c2 100644 --- a/include/core/SkColorFilter.h +++ b/include/core/SkColorFilter.h @@ -15,7 +15,7 @@ #include "SkXfermode.h" class SkBitmap; -class GrEffect; +class GrEffectRef; class GrContext; class SK_API SkColorFilter : public SkFlattenable { @@ -118,7 +118,7 @@ public: /** A subclass may implement this factory function to work with the GPU backend. If the return is non-NULL then the caller owns a ref on the returned object. */ - virtual GrEffect* asNewEffect(GrContext*) const; + virtual GrEffectRef* asNewEffect(GrContext*) const; SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() protected: diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h index ea38137b85..196d788580 100644 --- a/include/core/SkImageFilter.h +++ b/include/core/SkImageFilter.h @@ -17,7 +17,7 @@ class SkMatrix; struct SkIPoint; struct SkIRect; struct SkRect; -class GrEffect; +class GrEffectRef; class GrTexture; /** @@ -93,7 +93,7 @@ public: * The effect can assume its vertexCoords space maps 1-to-1 with texels * in the texture. */ - virtual bool asNewEffect(GrEffect** effect, GrTexture*) const; + virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const; /** * Returns true if the filter can be processed on the GPU. This is most diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h index 128cfa4dc3..14a4a45f2d 100644 --- a/include/core/SkPostConfig.h +++ b/include/core/SkPostConfig.h @@ -92,14 +92,14 @@ /////////////////////////////////////////////////////////////////////////////// #ifndef SkNEW - #define SkNEW(type_name) new type_name - #define SkNEW_ARGS(type_name, args) new type_name args - #define SkNEW_ARRAY(type_name, count) new type_name[count] - #define SkNEW_PLACEMENT(buf, type_name) new (buf) type_name + #define SkNEW(type_name) (new type_name) + #define SkNEW_ARGS(type_name, args) (new type_name args) + #define SkNEW_ARRAY(type_name, count) (new type_name[(count)]) + #define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name) #define SkNEW_PLACEMENT_ARGS(buf, type_name, args) \ - new (buf) type_name args - #define SkDELETE(obj) delete obj - #define SkDELETE_ARRAY(array) delete[] array + (new (buf) type_name args) + #define SkDELETE(obj) (delete (obj)) + #define SkDELETE_ARRAY(array) (delete[] (array)) #endif #ifndef SK_CRASH diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 899e3b6122..faa795fba4 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -18,8 +18,7 @@ class SkPath; class GrContext; -class GrEffect; -class GrEffectStage; +class GrEffectRef; /** \class SkShader * @@ -322,7 +321,7 @@ public: * The GrContext may be used by the effect to create textures. The GPU device does not call * setContext. Instead we pass the paint here in case the shader needs paint info. */ - virtual GrEffect* asNewEffect(GrContext* context, const SkPaint& paint) const; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const; ////////////////////////////////////////////////////////////////////////// // Factory methods for stock shaders diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h index 222646e032..e44a7cd750 100644 --- a/include/effects/SkColorMatrixFilter.h +++ b/include/effects/SkColorMatrixFilter.h @@ -22,7 +22,7 @@ public: virtual uint32_t getFlags() const SK_OVERRIDE; virtual bool asColorMatrix(SkScalar matrix[20]) const SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual GrEffect* asNewEffect(GrContext*) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE; #endif struct State { diff --git a/include/effects/SkMagnifierImageFilter.h b/include/effects/SkMagnifierImageFilter.h index 400a010188..e013426957 100644 --- a/include/effects/SkMagnifierImageFilter.h +++ b/include/effects/SkMagnifierImageFilter.h @@ -16,8 +16,7 @@ class SK_API SkMagnifierImageFilter : public SkImageFilter { public: SkMagnifierImageFilter(SkRect srcRect, SkScalar inset); - virtual bool asNewEffect(GrEffect** effect, - GrTexture* texture) const SK_OVERRIDE; + virtual bool asNewEffect(GrEffectRef** effect, GrTexture* texture) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter) diff --git a/include/effects/SkMatrixConvolutionImageFilter.h b/include/effects/SkMatrixConvolutionImageFilter.h index f4d2c8e8cc..09cb5ef2cd 100644 --- a/include/effects/SkMatrixConvolutionImageFilter.h +++ b/include/effects/SkMatrixConvolutionImageFilter.h @@ -62,7 +62,7 @@ protected: SkBitmap* result, SkIPoint* loc) SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual bool asNewEffect(GrEffect**, GrTexture*) const SK_OVERRIDE; + virtual bool asNewEffect(GrEffectRef**, GrTexture*) const SK_OVERRIDE; #endif private: diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h index 5fca4b2344..431159ca89 100644 --- a/include/gpu/GrEffect.h +++ b/include/gpu/GrEffect.h @@ -17,19 +17,52 @@ class GrBackendEffectFactory; class GrContext; +class GrEffect; class SkString; +/** + * A Wrapper class for GrEffect. Its ref-count will track owners that may use effects to enqueue + * new draw operations separately from ownership within a deferred drawing queue. When the + * GrEffectRef ref count reaches zero the scratch GrResources owned by the effect can be recycled + * in service of later draws. However, the deferred draw queue may still own direct references to + * the underlying GrEffect. + */ +class GrEffectRef : public SkRefCnt { +public: + SK_DECLARE_INST_COUNT(GrEffectRef); + + GrEffect* get() { return fEffect; } + const GrEffect* get() const { return fEffect; } + + void* operator new(size_t size); + void operator delete(void* target); + +private: + friend GrEffect; // to construct these + + explicit GrEffectRef(GrEffect* effect); + + virtual ~GrEffectRef(); + + GrEffect* fEffect; + + typedef SkRefCnt INHERITED; +}; + /** Provides custom vertex shader, fragment shader, uniform data for a particular stage of the Ganesh shading pipeline. Subclasses must have a function that produces a human-readable name: static const char* Name(); GrEffect objects *must* be immutable: after being constructed, their fields may not change. + + GrEffect subclass objects should be created by factory functions that return GrEffectRef. + There is no public way to wrap a GrEffect in a GrEffectRef. Thus, a factory should be a static + member function of a GrEffect subclass. */ class GrEffect : public GrRefCnt { public: SK_DECLARE_INST_COUNT(GrEffect) - GrEffect() {}; virtual ~GrEffect(); /** @@ -120,9 +153,36 @@ protected: */ void addTextureAccess(const GrTextureAccess* textureAccess); + GrEffect() : fEffectPtr(NULL) {}; + + /** This should be called by GrEffect subclass factories */ + static GrEffectRef* CreateEffectPtr(GrEffect* effect) { + if (NULL == effect->fEffectPtr) { + effect->fEffectPtr = SkNEW_ARGS(GrEffectRef, (effect)); + } else { + effect->fEffectPtr->ref(); + GrCrash("This function should only be called once per effect currently."); + } + return effect->fEffectPtr; + } + private: - SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; + void effectPtrDestroyed() { + fEffectPtr = NULL; + } + + friend GrEffectRef; // to call GrEffectRef destroyed + + SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; + GrEffectRef* fEffectPtr; + typedef GrRefCnt INHERITED; }; +inline GrEffectRef::GrEffectRef(GrEffect* effect) { + GrAssert(NULL != effect); + effect->ref(); + fEffect = effect; +} + #endif diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h index e42f19834a..0b532d6e06 100644 --- a/include/gpu/GrEffectStage.h +++ b/include/gpu/GrEffectStage.h @@ -22,28 +22,28 @@ class GrEffectStage { public: GrEffectStage() - : fEffect (NULL) { + : fEffectPtr (NULL) { GR_DEBUGCODE(fSavedCoordChangeCnt = 0;) } ~GrEffectStage() { - GrSafeUnref(fEffect); + GrSafeUnref(fEffectPtr); GrAssert(0 == fSavedCoordChangeCnt); } bool operator ==(const GrEffectStage& other) const { // first handle cases where one or the other has no effect - if (NULL == fEffect) { - return NULL == other.fEffect; - } else if (NULL == other.fEffect) { + if (NULL == fEffectPtr) { + return NULL == other.fEffectPtr; + } else if (NULL == other.fEffectPtr) { return false; } - if (fEffect->getFactory() != other.fEffect->getFactory()) { + if (this->getEffect()->getFactory() != other.getEffect()->getFactory()) { return false; } - if (!fEffect->isEqual(*other.fEffect)) { + if (!this->getEffect()->isEqual(*other.getEffect())) { return false; } @@ -53,8 +53,8 @@ public: bool operator !=(const GrEffectStage& s) const { return !(*this == s); } GrEffectStage& operator =(const GrEffectStage& other) { - GrSafeAssign(fEffect, other.fEffect); - if (NULL != fEffect) { + GrSafeAssign(fEffectPtr, other.fEffectPtr); + if (NULL != fEffectPtr) { fCoordChangeMatrix = other.fCoordChangeMatrix; } return *this; @@ -70,7 +70,7 @@ public: class SavedCoordChange { private: SkMatrix fCoordChangeMatrix; - GR_DEBUGCODE(mutable SkAutoTUnref fEffect;) + GR_DEBUGCODE(mutable SkAutoTUnref fEffectPtr;) friend class GrEffectStage; }; @@ -83,9 +83,9 @@ public: */ void saveCoordChange(SavedCoordChange* savedCoordChange) const { savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix; - GrAssert(NULL == savedCoordChange->fEffect.get()); - GR_DEBUGCODE(GrSafeRef(fEffect);) - GR_DEBUGCODE(savedCoordChange->fEffect.reset(fEffect);) + GrAssert(NULL == savedCoordChange->fEffectPtr.get()); + GR_DEBUGCODE(GrSafeRef(fEffectPtr);) + GR_DEBUGCODE(savedCoordChange->fEffectPtr.reset(fEffectPtr);) GR_DEBUGCODE(++fSavedCoordChangeCnt); } @@ -94,9 +94,9 @@ public: */ void restoreCoordChange(const SavedCoordChange& savedCoordChange) { fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix; - GrAssert(savedCoordChange.fEffect.get() == fEffect); + GrAssert(savedCoordChange.fEffectPtr.get() == fEffectPtr); GR_DEBUGCODE(--fSavedCoordChangeCnt); - GR_DEBUGCODE(savedCoordChange.fEffect.reset(NULL);) + GR_DEBUGCODE(savedCoordChange.fEffectPtr.reset(NULL);) } /** @@ -106,21 +106,28 @@ public: const SkMatrix& getCoordChangeMatrix() const { return fCoordChangeMatrix; } void reset() { - GrSafeSetNull(fEffect); + GrSafeSetNull(fEffectPtr); } - const GrEffect* setEffect(const GrEffect* effect) { + const GrEffectRef* setEffect(const GrEffectRef* effectPtr) { GrAssert(0 == fSavedCoordChangeCnt); - GrSafeAssign(fEffect, effect); + GrSafeAssign(fEffectPtr, effectPtr); fCoordChangeMatrix.reset(); - return effect; + return effectPtr; } - const GrEffect* getEffect() const { return fEffect; } + // TODO: Push GrEffectRef deeper and make this getter return it rather than GrEffect. + const GrEffect* getEffect() const { + if (NULL != fEffectPtr) { + return fEffectPtr->get(); + } else { + return NULL; + } + } private: SkMatrix fCoordChangeMatrix; - const GrEffect* fEffect; + const GrEffectRef* fEffectPtr; GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;) }; diff --git a/include/gpu/GrEffectUnitTest.h b/include/gpu/GrEffectUnitTest.h index 8cc2689d91..51fa637e21 100644 --- a/include/gpu/GrEffectUnitTest.h +++ b/include/gpu/GrEffectUnitTest.h @@ -31,22 +31,22 @@ const SkMatrix& TestMatrix(SkRandom*); #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS class GrContext; -class GrEffect; +class GrEffectRef; class GrTexture; class GrEffectTestFactory : GrNoncopyable { public: - typedef GrEffect* (*CreateProc)(SkRandom*, GrContext*, GrTexture* dummyTextures[]); + typedef GrEffectRef* (*CreateProc)(SkRandom*, GrContext*, GrTexture* dummyTextures[]); GrEffectTestFactory(CreateProc createProc) { fCreateProc = createProc; GetFactories()->push_back(this); } - static GrEffect* CreateStage(SkRandom* random, - GrContext* context, - GrTexture* dummyTextures[]) { + static GrEffectRef* CreateStage(SkRandom* random, + GrContext* context, + GrTexture* dummyTextures[]) { uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1); GrEffectTestFactory* factory = (*GetFactories())[idx]; return factory->fCreateProc(random, context, dummyTextures); @@ -62,7 +62,7 @@ private: */ #define GR_DECLARE_EFFECT_TEST \ static GrEffectTestFactory gTestFactory; \ - static GrEffect* TestCreate(SkRandom*, GrContext*, GrTexture* dummyTextures[2]) + static GrEffectRef* TestCreate(SkRandom*, GrContext*, GrTexture* dummyTextures[2]) /** GrEffect subclasses should insert this macro in their implementation file. They must then * also implement this static function: diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index aa790717a1..2f7173e446 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -335,7 +335,7 @@ void SkBitmapProcShader::toString(SkString* str) const { #include "effects/GrSingleTextureEffect.h" #include "SkGr.h" -GrEffect* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const { +GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const { SkMatrix matrix; matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); @@ -360,7 +360,7 @@ GrEffect* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& pai return NULL; } - GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix, params)); + GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix, params); GrUnlockCachedBitmapTexture(texture); return effect; } diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index 0cff88ca17..5a599c3b92 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -33,7 +33,7 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader) #if SK_SUPPORT_GPU - GrEffect* asNewEffect(GrContext*, const SkPaint&) const SK_OVERRIDE; + GrEffectRef* asNewEffect(GrContext*, const SkPaint&) const SK_OVERRIDE; #endif protected: diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index 90e8df84f3..383397dbca 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -41,7 +41,7 @@ SkColor SkColorFilter::filterColor(SkColor c) const { return SkUnPreMultiply::PMColorToColor(dst); } -GrEffect* SkColorFilter::asNewEffect(GrContext*) const { +GrEffectRef* SkColorFilter::asNewEffect(GrContext*) const { return NULL; } diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index a8edbf42bc..fddb5befd0 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -117,7 +117,7 @@ bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, return true; } -bool SkImageFilter::asNewEffect(GrEffect**, GrTexture*) const { +bool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*) const { return false; } diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index d895801ba4..d51c2ef530 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -173,7 +173,7 @@ SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { return kNone_GradientType; } -GrEffect* SkShader::asNewEffect(GrContext*, const SkPaint&) const { +GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { return NULL; } diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp index 74ec7e31a0..d9fb320f65 100644 --- a/src/effects/SkBlendImageFilter.cpp +++ b/src/effects/SkBlendImageFilter.cpp @@ -143,7 +143,13 @@ private: class GrBlendEffect : public GrEffect { public: - GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTexture* background); + static GrEffectRef* Create(SkBlendImageFilter::Mode mode, + GrTexture* foreground, + GrTexture* background) { + SkAutoTUnref effect(SkNEW_ARGS(GrBlendEffect, (mode, foreground, background))); + return CreateEffectPtr(effect); + } + virtual ~GrBlendEffect(); virtual bool isEqual(const GrEffect&) const SK_OVERRIDE; @@ -156,6 +162,7 @@ public: void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; private: + GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTexture* background); GrTextureAccess fForegroundAccess; GrTextureAccess fBackgroundAccess; SkBlendImageFilter::Mode fMode; @@ -218,7 +225,7 @@ GrTexture* SkBlendImageFilter::filterImageGPU(Proxy* proxy, GrTexture* src, cons GrPaint paint; paint.colorStage(0)->setEffect( - SkNEW_ARGS(GrBlendEffect, (fMode, foreground.get(), background.get())))->unref(); + GrBlendEffect::Create(fMode, foreground.get(), background.get()))->unref(); context->drawRect(paint, rect); return dst; } diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp index 2ff4fd6f48..85f6ccd21d 100644 --- a/src/effects/SkColorMatrixFilter.cpp +++ b/src/effects/SkColorMatrixFilter.cpp @@ -325,9 +325,12 @@ bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const { class ColorMatrixEffect : public GrEffect { public: - static const char* Name() { return "Color Matrix"; } + static GrEffectRef* Create(const SkColorMatrix& matrix) { + SkAutoTUnref effect(SkNEW_ARGS(ColorMatrixEffect, (matrix))); + return CreateEffectPtr(effect); + } - ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {} + static const char* Name() { return "Color Matrix"; } virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { return GrTBackendEffectFactory::getInstance(); @@ -451,6 +454,8 @@ public: }; private: + ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {} + SkColorMatrix fMatrix; typedef GrGLEffect INHERITED; @@ -458,18 +463,18 @@ private: GR_DEFINE_EFFECT_TEST(ColorMatrixEffect); -GrEffect* ColorMatrixEffect::TestCreate(SkRandom* random, - GrContext*, - GrTexture* dummyTextures[2]) { +GrEffectRef* ColorMatrixEffect::TestCreate(SkRandom* random, + GrContext*, + GrTexture* dummyTextures[2]) { SkColorMatrix colorMatrix; for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) { colorMatrix.fMat[i] = random->nextSScalar1(); } - return SkNEW_ARGS(ColorMatrixEffect, (colorMatrix)); + return ColorMatrixEffect::Create(colorMatrix); } -GrEffect* SkColorMatrixFilter::asNewEffect(GrContext*) const { - return SkNEW_ARGS(ColorMatrixEffect, (fMatrix)); +GrEffectRef* SkColorMatrixFilter::asNewEffect(GrContext*) const { + return ColorMatrixEffect::Create(fMatrix); } #endif diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index b5f33ee574..36ca6af813 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -232,9 +232,17 @@ private: class GrDisplacementMapEffect : public GrEffect { public: - GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, - SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, - SkScalar scale, GrTexture* displacement, GrTexture* color); + static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, + SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, + SkScalar scale, GrTexture* displacement, GrTexture* color) { + SkAutoTUnref effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector, + yChannelSelector, + scale, + displacement, + color))); + return CreateEffectPtr(effect); + } + virtual ~GrDisplacementMapEffect(); virtual bool isEqual(const GrEffect&) const SK_OVERRIDE; @@ -251,6 +259,10 @@ public: void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; private: + GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, + SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, + SkScalar scale, GrTexture* displacement, GrTexture* color); + GR_DECLARE_EFFECT_TEST; GrTextureAccess fDisplacementAccess; @@ -319,8 +331,11 @@ GrTexture* SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, GrTexture* src, GrPaint paint; paint.colorStage(0)->setEffect( - SkNEW_ARGS(GrDisplacementMapEffect, (fXChannelSelector, fYChannelSelector, fScale, - displacement.get(), color.get())))->unref(); + GrDisplacementMapEffect::Create(fXChannelSelector, + fYChannelSelector, + fScale, + displacement.get(), + color.get()))->unref(); context->drawRect(paint, rect); return dst; } @@ -369,9 +384,9 @@ void GrDisplacementMapEffect::getConstantColorComponents(GrColor* color, GR_DEFINE_EFFECT_TEST(GrDisplacementMapEffect); -GrEffect* GrDisplacementMapEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrDisplacementMapEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { int texIdxDispl = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : GrEffectUnitTest::kAlphaTextureIdx; int texIdxColor = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : @@ -385,8 +400,8 @@ GrEffect* GrDisplacementMapEffect::TestCreate(SkRandom* random, random->nextRangeU(1, kMaxComponent)); SkScalar scale = random->nextUScalar1(); - return SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale, - textures[texIdxDispl], textures[texIdxColor])); + return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, scale, + textures[texIdxDispl], textures[texIdxColor]); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index fc819deb17..337e883403 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -264,7 +264,7 @@ public: SkScalar kd, SkImageFilter* input); SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter) - virtual bool asNewEffect(GrEffect** effect, GrTexture*) const SK_OVERRIDE; + virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const SK_OVERRIDE; SkScalar kd() const { return fKD; } protected: @@ -284,7 +284,7 @@ public: SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input); SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter) - virtual bool asNewEffect(GrEffect** effect, GrTexture*) const SK_OVERRIDE; + virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const SK_OVERRIDE; SkScalar ks() const { return fKS; } SkScalar shininess() const { return fShininess; } @@ -326,10 +326,16 @@ private: class GrDiffuseLightingEffect : public GrLightingEffect { public: - GrDiffuseLightingEffect(GrTexture* texture, - const SkLight* light, - SkScalar surfaceScale, - SkScalar kd); + static GrEffectRef* Create(GrTexture* texture, + const SkLight* light, + SkScalar surfaceScale, + SkScalar kd) { + SkAutoTUnref effect(SkNEW_ARGS(GrDiffuseLightingEffect, (texture, + light, + surfaceScale, + kd))); + return CreateEffectPtr(effect); + } static const char* Name() { return "DiffuseLighting"; } @@ -339,6 +345,11 @@ public: virtual bool isEqual(const GrEffect&) const SK_OVERRIDE; SkScalar kd() const { return fKD; } private: + GrDiffuseLightingEffect(GrTexture* texture, + const SkLight* light, + SkScalar surfaceScale, + SkScalar kd); + GR_DECLARE_EFFECT_TEST; typedef GrLightingEffect INHERITED; SkScalar fKD; @@ -346,12 +357,18 @@ private: class GrSpecularLightingEffect : public GrLightingEffect { public: - GrSpecularLightingEffect(GrTexture* texture, - const SkLight* light, - SkScalar surfaceScale, - SkScalar ks, - SkScalar shininess); - + static GrEffectRef* Create(GrTexture* texture, + const SkLight* light, + SkScalar surfaceScale, + SkScalar ks, + SkScalar shininess) { + SkAutoTUnref effect(SkNEW_ARGS(GrSpecularLightingEffect, (texture, + light, + surfaceScale, + ks, + shininess))); + return CreateEffectPtr(effect); + } static const char* Name() { return "SpecularLighting"; } typedef GrGLSpecularLightingEffect GLEffect; @@ -362,6 +379,12 @@ public: SkScalar shininess() const { return fShininess; } private: + GrSpecularLightingEffect(GrTexture* texture, + const SkLight* light, + SkScalar surfaceScale, + SkScalar ks, + SkScalar shininess); + GR_DECLARE_EFFECT_TEST; typedef GrLightingEffect INHERITED; SkScalar fKS; @@ -832,12 +855,12 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy*, return true; } -bool SkDiffuseLightingImageFilter::asNewEffect(GrEffect** effect, +bool SkDiffuseLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const { #if SK_SUPPORT_GPU if (effect) { SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255)); - *effect = SkNEW_ARGS(GrDiffuseLightingEffect, (texture, light(), scale, kd())); + *effect = GrDiffuseLightingEffect::Create(texture, light(), scale, kd()); } return true; #else @@ -901,12 +924,12 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy*, return true; } -bool SkSpecularLightingImageFilter::asNewEffect(GrEffect** effect, +bool SkSpecularLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const { #if SK_SUPPORT_GPU if (effect) { SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255)); - *effect = SkNEW_ARGS(GrSpecularLightingEffect, (texture, light(), scale, ks(), shininess())); + *effect = GrSpecularLightingEffect::Create(texture, light(), scale, ks(), shininess()); } return true; #else @@ -1054,14 +1077,14 @@ bool GrDiffuseLightingEffect::isEqual(const GrEffect& sBase) const { GR_DEFINE_EFFECT_TEST(GrDiffuseLightingEffect); -GrEffect* GrDiffuseLightingEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrDiffuseLightingEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { SkScalar surfaceScale = random->nextSScalar1(); SkScalar kd = random->nextUScalar1(); SkAutoTUnref light(create_random_light(random)); - return SkNEW_ARGS(GrDiffuseLightingEffect, (textures[GrEffectUnitTest::kAlphaTextureIdx], - light, surfaceScale, kd)); + return GrDiffuseLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], + light, surfaceScale, kd); } @@ -1267,15 +1290,15 @@ bool GrSpecularLightingEffect::isEqual(const GrEffect& sBase) const { GR_DEFINE_EFFECT_TEST(GrSpecularLightingEffect); -GrEffect* GrSpecularLightingEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrSpecularLightingEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { SkScalar surfaceScale = random->nextSScalar1(); SkScalar ks = random->nextUScalar1(); SkScalar shininess = random->nextUScalar1(); SkAutoTUnref light(create_random_light(random)); - return SkNEW_ARGS(GrSpecularLightingEffect, (textures[GrEffectUnitTest::kAlphaTextureIdx], - light, surfaceScale, ks, shininess)); + return GrSpecularLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], + light, surfaceScale, ks, shininess); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index 8cb1030ce0..9b57bdcd65 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -26,20 +26,22 @@ class GrGLMagnifierEffect; class GrMagnifierEffect : public GrSingleTextureEffect { public: - GrMagnifierEffect(GrTexture* texture, - float xOffset, - float yOffset, - float xZoom, - float yZoom, - float xInset, - float yInset) - : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture)) - , fXOffset(xOffset) - , fYOffset(yOffset) - , fXZoom(xZoom) - , fYZoom(yZoom) - , fXInset(xInset) - , fYInset(yInset) {} + static GrEffectRef* Create(GrTexture* texture, + float xOffset, + float yOffset, + float xZoom, + float yZoom, + float xInset, + float yInset) { + SkAutoTUnref effect(SkNEW_ARGS(GrMagnifierEffect, (texture, + xOffset, + yOffset, + xZoom, + yZoom, + xInset, + yInset))); + return CreateEffectPtr(effect); + } virtual ~GrMagnifierEffect() {}; @@ -58,6 +60,21 @@ public: typedef GrGLMagnifierEffect GLEffect; private: + GrMagnifierEffect(GrTexture* texture, + float xOffset, + float yOffset, + float xZoom, + float yZoom, + float xInset, + float yInset) + : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture)) + , fXOffset(xOffset) + , fYOffset(yOffset) + , fXZoom(xZoom) + , fYZoom(yZoom) + , fXInset(xInset) + , fYInset(yInset) {} + GR_DECLARE_EFFECT_TEST; float fXOffset; @@ -184,9 +201,9 @@ GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrEffectStage& stage, co GR_DEFINE_EFFECT_TEST(GrMagnifierEffect); -GrEffect* GrMagnifierEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture** textures) { +GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture** textures) { const int kMaxWidth = 200; const int kMaxHeight = 200; const int kMaxInset = 20; @@ -201,7 +218,7 @@ GrEffect* GrMagnifierEffect::TestCreate(SkRandom* random, SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(width), SkIntToScalar(height)), inset)); - GrEffect* effect; + GrEffectRef* effect; filter->asNewEffect(&effect, textures[0]); GrAssert(NULL != effect); return effect; @@ -243,17 +260,16 @@ SkMagnifierImageFilter::SkMagnifierImageFilter(SkRect srcRect, SkScalar inset) SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); } -bool SkMagnifierImageFilter::asNewEffect(GrEffect** effect, - GrTexture* texture) const { +bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const { #if SK_SUPPORT_GPU if (effect) { - *effect = SkNEW_ARGS(GrMagnifierEffect, (texture, - fSrcRect.x() / texture->width(), - fSrcRect.y() / texture->height(), - texture->width() / fSrcRect.width(), - texture->height() / fSrcRect.height(), - fInset / texture->width(), - fInset / texture->height())); + *effect = GrMagnifierEffect::Create(texture, + fSrcRect.x() / texture->width(), + fSrcRect.y() / texture->height(), + texture->width() / fSrcRect.width(), + texture->height() / fSrcRect.height(), + fInset / texture->width(), + fInset / texture->height()); } return true; #else diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp index 657c996a40..690cdd8239 100644 --- a/src/effects/SkMatrixConvolutionImageFilter.cpp +++ b/src/effects/SkMatrixConvolutionImageFilter.cpp @@ -247,14 +247,24 @@ class GrGLMatrixConvolutionEffect; class GrMatrixConvolutionEffect : public GrSingleTextureEffect { public: typedef SkMatrixConvolutionImageFilter::TileMode TileMode; - GrMatrixConvolutionEffect(GrTexture*, - const SkISize& kernelSize, - const SkScalar* kernel, - SkScalar gain, - SkScalar bias, - const SkIPoint& target, - TileMode tileMode, - bool convolveAlpha); + static GrEffectRef* Create(GrTexture* texture, + const SkISize& kernelSize, + const SkScalar* kernel, + SkScalar gain, + SkScalar bias, + const SkIPoint& target, + TileMode tileMode, + bool convolveAlpha) { + SkAutoTUnref effect(SkNEW_ARGS(GrMatrixConvolutionEffect, (texture, + kernelSize, + kernel, + gain, + bias, + target, + tileMode, + convolveAlpha))); + return CreateEffectPtr(effect); + } virtual ~GrMatrixConvolutionEffect(); virtual void getConstantColorComponents(GrColor* color, @@ -280,6 +290,15 @@ public: virtual bool isEqual(const GrEffect&) const SK_OVERRIDE; private: + GrMatrixConvolutionEffect(GrTexture*, + const SkISize& kernelSize, + const SkScalar* kernel, + SkScalar gain, + SkScalar bias, + const SkIPoint& target, + TileMode tileMode, + bool convolveAlpha); + SkISize fKernelSize; float *fKernel; float fGain; @@ -518,9 +537,9 @@ GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect); // Allows for a 5x5 kernel (or 25x1, for that matter). #define MAX_KERNEL_SIZE 25 -GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrMatrixConvolutionEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : GrEffectUnitTest::kAlphaTextureIdx; int width = random->nextRangeU(1, MAX_KERNEL_SIZE); @@ -536,29 +555,29 @@ GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random, random->nextRangeU(0, kernelSize.height())); TileMode tileMode = static_cast(random->nextRangeU(0, 2)); bool convolveAlpha = random->nextBool(); - return SkNEW_ARGS(GrMatrixConvolutionEffect, (textures[texIdx], - kernelSize, - kernel, - gain, - bias, - target, - tileMode, - convolveAlpha)); + return GrMatrixConvolutionEffect::Create(textures[texIdx], + kernelSize, + kernel, + gain, + bias, + target, + tileMode, + convolveAlpha); } -bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffect** effect, +bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const { bool ok = fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE; if (ok && effect) { - *effect = SkNEW_ARGS(GrMatrixConvolutionEffect, (texture, - fKernelSize, - fKernel, - fGain, - fBias, - fTarget, - fTileMode, - fConvolveAlpha)); + *effect = GrMatrixConvolutionEffect::Create(texture, + fKernelSize, + fKernel, + fGain, + fBias, + fTarget, + fTileMode, + fConvolveAlpha); } return ok; } diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 07b6449c33..7ce76c8af3 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -243,7 +243,11 @@ public: kDilate_MorphologyType, }; - GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); + static GrEffectRef* Create(GrTexture* tex, Direction dir, int radius, MorphologyType type) { + SkAutoTUnref effect(SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type))); + return CreateEffectPtr(effect); + } + virtual ~GrMorphologyEffect(); MorphologyType type() const { return fType; } @@ -260,6 +264,8 @@ protected: MorphologyType fType; private: + GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); + GR_DECLARE_EFFECT_TEST; typedef Gr1DKernelEffect INHERITED; @@ -406,9 +412,9 @@ bool GrMorphologyEffect::isEqual(const GrEffect& sBase) const { GR_DEFINE_EFFECT_TEST(GrMorphologyEffect); -GrEffect* GrMorphologyEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrMorphologyEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : GrEffectUnitTest::kAlphaTextureIdx; Direction dir = random->nextBool() ? kX_Direction : kY_Direction; @@ -417,7 +423,7 @@ GrEffect* GrMorphologyEffect::TestCreate(SkRandom* random, MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_MorphologyType : GrMorphologyEffect::kDilate_MorphologyType; - return SkNEW_ARGS(GrMorphologyEffect, (textures[texIdx], dir, radius, type)); + return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type); } namespace { @@ -429,10 +435,10 @@ void apply_morphology_pass(GrContext* context, GrMorphologyEffect::MorphologyType morphType, Gr1DKernelEffect::Direction direction) { GrPaint paint; - paint.colorStage(0)->setEffect(SkNEW_ARGS(GrMorphologyEffect, (texture, - direction, - radius, - morphType)))->unref(); + paint.colorStage(0)->setEffect(GrMorphologyEffect::Create(texture, + direction, + radius, + morphType))->unref(); context->drawRect(paint, rect); } diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 6713c203b2..7c2b4dfd1a 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -41,7 +41,7 @@ public: virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual GrEffect* asNewEffect(GrContext* context) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context) const SK_OVERRIDE; #endif virtual void filterSpan(const SkPMColor src[], int count, @@ -226,8 +226,11 @@ class GLColorTableEffect; class ColorTableEffect : public GrEffect { public: + static GrEffectRef* Create(GrTexture* texture, unsigned flags) { + SkAutoTUnref effect(SkNEW_ARGS(ColorTableEffect, (texture, flags))); + return CreateEffectPtr(effect); + } - explicit ColorTableEffect(GrTexture* texture, unsigned flags); virtual ~ColorTableEffect(); static const char* Name() { return "ColorTable"; } @@ -239,6 +242,8 @@ public: typedef GLColorTableEffect GLEffect; private: + explicit ColorTableEffect(GrTexture* texture, unsigned flags); + GR_DECLARE_EFFECT_TEST; GrTextureAccess fTextureAccess; @@ -365,20 +370,20 @@ void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* vali GR_DEFINE_EFFECT_TEST(ColorTableEffect); -GrEffect* ColorTableEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* ColorTableEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag | SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag; - return SkNEW_ARGS(ColorTableEffect, (textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags)); + return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags); } -GrEffect* SkTable_ColorFilter::asNewEffect(GrContext* context) const { +GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const { SkBitmap bitmap; this->asComponentTable(&bitmap); // passing NULL because this effect does no tiling or filtering. GrTexture* texture = GrLockCachedBitmapTexture(context, bitmap, NULL); - GrEffect* effect = SkNEW_ARGS(ColorTableEffect, (texture, fFlags)); + GrEffectRef* effect = ColorTableEffect::Create(texture, fFlags); // Unlock immediately, this is not great, but we don't have a way of // knowing when else to unlock it currently. TODO: Remove this when diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp index 1788b7ada7..2785806b5d 100644 --- a/src/effects/gradients/SkLinearGradient.cpp +++ b/src/effects/gradients/SkLinearGradient.cpp @@ -484,11 +484,14 @@ private: class GrLinearGradient : public GrGradientEffect { public: - GrLinearGradient(GrContext* ctx, - const SkLinearGradient& shader, - const SkMatrix& matrix, - SkShader::TileMode tm) - : INHERITED(ctx, shader, matrix, tm) { } + static GrEffectRef* Create(GrContext* ctx, + const SkLinearGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) { + SkAutoTUnref effect(SkNEW_ARGS(GrLinearGradient, (ctx, shader, matrix, tm))); + return CreateEffectPtr(effect); + } + virtual ~GrLinearGradient() { } static const char* Name() { return "Linear Gradient"; } @@ -499,6 +502,11 @@ public: typedef GrGLLinearGradient GLEffect; private: + GrLinearGradient(GrContext* ctx, + const SkLinearGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) + : INHERITED(ctx, shader, matrix, tm) { } GR_DECLARE_EFFECT_TEST; typedef GrGradientEffect INHERITED; @@ -508,9 +516,9 @@ private: GR_DEFINE_EFFECT_TEST(GrLinearGradient); -GrEffect* GrLinearGradient::TestCreate(SkRandom* random, - GrContext* context, - GrTexture**) { +GrEffectRef* GrLinearGradient::TestCreate(SkRandom* random, + GrContext* context, + GrTexture**) { SkPoint points[] = {{random->nextUScalar1(), random->nextUScalar1()}, {random->nextUScalar1(), random->nextUScalar1()}}; @@ -546,14 +554,14 @@ void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrEffect* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&) const { SkASSERT(NULL != context); SkMatrix matrix; if (!this->getLocalMatrix().invert(&matrix)) { return NULL; } matrix.postConcat(fPtsToUnit); - return SkNEW_ARGS(GrLinearGradient, (context, *this, matrix, fTileMode)); + return GrLinearGradient::Create(context, *this, matrix, fTileMode); } #else diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h index e7935e46d6..046a1e10b4 100644 --- a/src/effects/gradients/SkLinearGradient.h +++ b/src/effects/gradients/SkLinearGradient.h @@ -22,7 +22,7 @@ public: virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE; virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; SK_DEVELOPER_TO_STRING() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient) diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp index a33a9cd842..4609db1b75 100644 --- a/src/effects/gradients/SkRadialGradient.cpp +++ b/src/effects/gradients/SkRadialGradient.cpp @@ -504,12 +504,12 @@ private: class GrRadialGradient : public GrGradientEffect { public: - - GrRadialGradient(GrContext* ctx, - const SkRadialGradient& shader, - const SkMatrix& matrix, - SkShader::TileMode tm) - : INHERITED(ctx, shader, matrix, tm) { + static GrEffectRef* Create(GrContext* ctx, + const SkRadialGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) { + SkAutoTUnref effect(SkNEW_ARGS(GrRadialGradient, (ctx, shader, matrix, tm))); + return CreateEffectPtr(effect); } virtual ~GrRadialGradient() { } @@ -522,6 +522,13 @@ public: typedef GrGLRadialGradient GLEffect; private: + GrRadialGradient(GrContext* ctx, + const SkRadialGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) + : INHERITED(ctx, shader, matrix, tm) { + } + GR_DECLARE_EFFECT_TEST; typedef GrGradientEffect INHERITED; @@ -531,9 +538,9 @@ private: GR_DEFINE_EFFECT_TEST(GrRadialGradient); -GrEffect* GrRadialGradient::TestCreate(SkRandom* random, - GrContext* context, - GrTexture**) { +GrEffectRef* GrRadialGradient::TestCreate(SkRandom* random, + GrContext* context, + GrTexture**) { SkPoint center = {random->nextUScalar1(), random->nextUScalar1()}; SkScalar radius = random->nextUScalar1(); @@ -569,7 +576,7 @@ void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrEffect* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const { SkASSERT(NULL != context); SkMatrix matrix; @@ -577,7 +584,7 @@ GrEffect* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&) cons return NULL; } matrix.postConcat(fPtsToUnit); - return SkNEW_ARGS(GrRadialGradient, (context, *this, matrix, fTileMode)); + return GrRadialGradient::Create(context, *this, matrix, fTileMode); } #else diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h index 0bb75c57d7..88530cd51e 100644 --- a/src/effects/gradients/SkRadialGradient.h +++ b/src/effects/gradients/SkRadialGradient.h @@ -24,7 +24,7 @@ public: SkMatrix* matrix, TileMode* xy) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; SK_DEVELOPER_TO_STRING() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient) diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index 493109e7ee..91e239c423 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -413,11 +413,12 @@ private: class GrSweepGradient : public GrGradientEffect { public: - - GrSweepGradient(GrContext* ctx, - const SkSweepGradient& shader, - const SkMatrix& matrix) - : INHERITED(ctx, shader, matrix, SkShader::kClamp_TileMode) { } + static GrEffectRef* Create(GrContext* ctx, + const SkSweepGradient& shader, + const SkMatrix& matrix) { + SkAutoTUnref effect(SkNEW_ARGS(GrSweepGradient, (ctx, shader, matrix))); + return CreateEffectPtr(effect); + } virtual ~GrSweepGradient() { } static const char* Name() { return "Sweep Gradient"; } @@ -428,6 +429,10 @@ public: typedef GrGLSweepGradient GLEffect; private: + GrSweepGradient(GrContext* ctx, + const SkSweepGradient& shader, + const SkMatrix& matrix) + : INHERITED(ctx, shader, matrix, SkShader::kClamp_TileMode) { } GR_DECLARE_EFFECT_TEST; typedef GrGradientEffect INHERITED; @@ -437,9 +442,9 @@ private: GR_DEFINE_EFFECT_TEST(GrSweepGradient); -GrEffect* GrSweepGradient::TestCreate(SkRandom* random, - GrContext* context, - GrTexture**) { +GrEffectRef* GrSweepGradient::TestCreate(SkRandom* random, + GrContext* context, + GrTexture**) { SkPoint center = {random->nextUScalar1(), random->nextUScalar1()}; SkColor colors[kMaxRandomGradientColors]; @@ -472,13 +477,13 @@ void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrEffect* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&) const { SkMatrix matrix; if (!this->getLocalMatrix().invert(&matrix)) { return NULL; } matrix.postConcat(fPtsToUnit); - return SkNEW_ARGS(GrSweepGradient, (context, *this, matrix)); + return GrSweepGradient::Create(context, *this, matrix); } #else diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h index 4148966590..95c1419b6f 100644 --- a/src/effects/gradients/SkSweepGradient.h +++ b/src/effects/gradients/SkSweepGradient.h @@ -24,7 +24,7 @@ public: virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; SK_DEVELOPER_TO_STRING() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient) diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp index 23e4dcc295..8d03c13426 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp @@ -369,14 +369,13 @@ private: class GrConical2Gradient : public GrGradientEffect { public: - GrConical2Gradient(GrContext* ctx, - const SkTwoPointConicalGradient& shader, - const SkMatrix& matrix, - SkShader::TileMode tm) - : INHERITED(ctx, shader, matrix, tm) - , fCenterX1(shader.getCenterX1()) - , fRadius0(shader.getStartRadius()) - , fDiffRadius(shader.getDiffRadius()) { } + static GrEffectRef* Create(GrContext* ctx, + const SkTwoPointConicalGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) { + SkAutoTUnref effect(SkNEW_ARGS(GrConical2Gradient, (ctx, shader, matrix, tm))); + return CreateEffectPtr(effect); + } virtual ~GrConical2Gradient() { } @@ -401,6 +400,15 @@ public: typedef GrGLConical2Gradient GLEffect; private: + GrConical2Gradient(GrContext* ctx, + const SkTwoPointConicalGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) + : INHERITED(ctx, shader, matrix, tm) + , fCenterX1(shader.getCenterX1()) + , fRadius0(shader.getStartRadius()) + , fDiffRadius(shader.getDiffRadius()) { } + GR_DECLARE_EFFECT_TEST; // @{ @@ -418,9 +426,9 @@ private: GR_DEFINE_EFFECT_TEST(GrConical2Gradient); -GrEffect* GrConical2Gradient::TestCreate(SkRandom* random, - GrContext* context, - GrTexture**) { +GrEffectRef* GrConical2Gradient::TestCreate(SkRandom* random, + GrContext* context, + GrTexture**) { SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()}; SkScalar radius1 = random->nextUScalar1(); SkPoint center2; @@ -684,7 +692,7 @@ GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrEffectStage& s, const ///////////////////////////////////////////////////////////////////// -GrEffect* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&) const { SkASSERT(NULL != context); SkASSERT(fPtsToUnit.isIdentity()); // invert the localM, translate to center1, rotate so center2 is on x axis. @@ -704,7 +712,7 @@ GrEffect* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPai matrix.postConcat(rot); } - return SkNEW_ARGS(GrConical2Gradient, (context, *this, matrix, fTileMode)); + return GrConical2Gradient::Create(context, *this, matrix, fTileMode); } #else diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h index 44432cc6be..32a7b80ed8 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.h +++ b/src/effects/gradients/SkTwoPointConicalGradient.h @@ -61,7 +61,7 @@ public: SkMatrix* matrix, TileMode* xy) const; virtual SkShader::GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffect* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE; SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); } SkScalar getStartRadius() const { return fRadius1; } diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp index 2e458097d1..8380a3f5b9 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.cpp +++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp @@ -428,15 +428,14 @@ private: class GrRadial2Gradient : public GrGradientEffect { public: + static GrEffectRef* Create(GrContext* ctx, + const SkTwoPointRadialGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) { + SkAutoTUnref effect(SkNEW_ARGS(GrRadial2Gradient, (ctx, shader, matrix, tm))); + return CreateEffectPtr(effect); + } - GrRadial2Gradient(GrContext* ctx, - const SkTwoPointRadialGradient& shader, - const SkMatrix& matrix, - SkShader::TileMode tm) - : INHERITED(ctx, shader, matrix, tm) - , fCenterX1(shader.getCenterX1()) - , fRadius0(shader.getStartRadius()) - , fPosRoot(shader.getDiffRadius() < 0) { } virtual ~GrRadial2Gradient() { } static const char* Name() { return "Two-Point Radial Gradient"; } @@ -460,6 +459,15 @@ public: typedef GrGLRadial2Gradient GLEffect; private: + GrRadial2Gradient(GrContext* ctx, + const SkTwoPointRadialGradient& shader, + const SkMatrix& matrix, + SkShader::TileMode tm) + : INHERITED(ctx, shader, matrix, tm) + , fCenterX1(shader.getCenterX1()) + , fRadius0(shader.getStartRadius()) + , fPosRoot(shader.getDiffRadius() < 0) { } + GR_DECLARE_EFFECT_TEST; // @{ @@ -479,9 +487,9 @@ private: GR_DEFINE_EFFECT_TEST(GrRadial2Gradient); -GrEffect* GrRadial2Gradient::TestCreate(SkRandom* random, - GrContext* context, - GrTexture**) { +GrEffectRef* GrRadial2Gradient::TestCreate(SkRandom* random, + GrContext* context, + GrTexture**) { SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()}; SkScalar radius1 = random->nextUScalar1(); SkPoint center2; @@ -683,7 +691,7 @@ GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrEffectStage& s, const ///////////////////////////////////////////////////////////////////// -GrEffect* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const { SkASSERT(NULL != context); // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis. SkMatrix matrix; @@ -701,7 +709,7 @@ GrEffect* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPain matrix.postConcat(rot); } - return SkNEW_ARGS(GrRadial2Gradient, (context, *this, matrix, fTileMode)); + return GrRadial2Gradient::Create(context, *this, matrix, fTileMode); } #else diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h index e0b00827e1..273d1c932e 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.h +++ b/src/effects/gradients/SkTwoPointRadialGradient.h @@ -23,7 +23,7 @@ public: SkMatrix* matrix, TileMode* xy) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; virtual void shadeSpan(int x, int y, SkPMColor* dstCParam, int count) SK_OVERRIDE; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 9d80ebc548..a8ce05510a 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -200,9 +200,10 @@ void convolve_gaussian(GrDrawTarget* target, GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit); GrDrawState* drawState = target->drawState(); drawState->setRenderTarget(rt); - SkAutoTUnref conv(SkNEW_ARGS(GrConvolutionEffect, - (texture, direction, radius, - sigma))); + SkAutoTUnref conv(GrConvolutionEffect::Create(texture, + direction, + radius, + sigma)); drawState->stage(0)->setEffect(conv); target->drawSimpleRect(rect, NULL); } @@ -1859,8 +1860,9 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, i < scaleFactorY ? 0.5f : 1.0f); - paint.colorStage(0)->setEffect(SkNEW_ARGS(GrSingleTextureEffect, - (srcTexture, matrix, true)))->unref(); + paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(srcTexture, + matrix, + true))->unref(); this->drawRectToRect(paint, dstRect, srcRect); srcRect = dstRect; srcTexture = dstTexture; @@ -1917,8 +1919,9 @@ 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(SkNEW_ARGS(GrSingleTextureEffect,(srcTexture, - matrix, true)))->unref(); + paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(srcTexture, + matrix, + true))->unref(); SkRect dstRect(srcRect); scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); this->drawRectToRect(paint, dstRect, srcRect); diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 1208b776ed..993076bcb3 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -195,13 +195,9 @@ public: /** * Creates a GrSingleTextureEffect. */ - void createTextureEffect(int stageIdx, GrTexture* texture) { - GrAssert(!this->getStage(stageIdx).getEffect()); - this->stage(stageIdx)->setEffect(SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); - } void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) { GrAssert(!this->getStage(stageIdx).getEffect()); - GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix)); + GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix); this->stage(stageIdx)->setEffect(effect)->unref(); } void createTextureEffect(int stageIdx, @@ -209,11 +205,10 @@ public: const SkMatrix& matrix, const GrTextureParams& params) { GrAssert(!this->getStage(stageIdx).getEffect()); - GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix, params)); + GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix, params); this->stage(stageIdx)->setEffect(effect)->unref(); } - bool stagesDisabled() { for (int i = 0; i < kNumStages; ++i) { if (NULL != fStages[i].getEffect()) { diff --git a/src/gpu/GrEffect.cpp b/src/gpu/GrEffect.cpp index 534489fd4e..6db44f4c52 100644 --- a/src/gpu/GrEffect.cpp +++ b/src/gpu/GrEffect.cpp @@ -58,7 +58,28 @@ private: int32_t GrBackendEffectFactory::fCurrEffectClassID = GrBackendEffectFactory::kIllegalEffectClassID; +/////////////////////////////////////////////////////////////////////////////// + +SK_DEFINE_INST_COUNT(GrEffectRef) + +GrEffectRef::~GrEffectRef() { + GrAssert(1 == this->getRefCnt()); + fEffect->effectPtrDestroyed(); + fEffect->unref(); +} + +void* GrEffectRef::operator new(size_t size) { + return GrEffect_Globals::GetTLS()->allocate(size); +} + +void GrEffectRef::operator delete(void* target) { + GrEffect_Globals::GetTLS()->release(target); +} + +/////////////////////////////////////////////////////////////////////////////// + GrEffect::~GrEffect() { + GrAssert(NULL == fEffectPtr); } const char* GrEffect::name() const { @@ -81,7 +102,7 @@ void GrEffect::addTextureAccess(const GrTextureAccess* access) { fTextureAccesses.push_back(access); } -void * GrEffect::operator new(size_t size) { +void* GrEffect::operator new(size_t size) { return GrEffect_Globals::GetTLS()->allocate(size); } diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 32a945b8b1..0a4fe6a8dd 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -198,7 +198,7 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture, }; GrAssert(!drawState->isStageEnabled(kPathMaskStage)); drawState->stage(kPathMaskStage)->reset(); - drawState->createTextureEffect(kPathMaskStage, texture); + drawState->createTextureEffect(kPathMaskStage, texture, SkMatrix::I()); SkScalar w = SkIntToScalar(rect.width()); SkScalar h = SkIntToScalar(rect.height()); GrRect maskRect = GrRect::MakeWH(w / texture->width(), diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index a2c388e45e..f205569fa0 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -443,7 +443,7 @@ bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { GrTexture* texture = fRenderTarget->asTexture(); if (NULL != texture) { paint->colorStage(kBitmapTextureIdx)->setEffect( - SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); + GrSingleTextureEffect::Create(texture, SkMatrix::I()))->unref(); return true; } return false; @@ -512,7 +512,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev, SkColor filtered = colorFilter->filterColor(skPaint.getColor()); grPaint->setColor(SkColor2GrColor(filtered)); } else { - SkAutoTUnref effect(colorFilter->asNewEffect(dev->context())); + SkAutoTUnref effect(colorFilter->asNewEffect(dev->context())); if (NULL != effect.get()) { grPaint->colorStage(kColorFilterTextureIdx)->setEffect(effect); } else { @@ -544,7 +544,7 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev, return false; } - SkAutoTUnref effect(shader->asNewEffect(dev->context(), skPaint)); + SkAutoTUnref effect(shader->asNewEffect(dev->context(), skPaint)); if (NULL != effect.get()) { grPaint->colorStage(kShaderTextureIdx)->setEffect(effect); return true; @@ -796,7 +796,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkSt matrix.setIDiv(pathTexture->width(), pathTexture->height()); // Blend pathTexture over blurTexture. context->setRenderTarget(blurTexture->asRenderTarget()); - paint.colorStage(0)->setEffect(SkNEW_ARGS(GrSingleTextureEffect, (pathTexture, matrix)))->unref(); + paint.colorStage(0)->setEffect( + GrSingleTextureEffect::Create(pathTexture, matrix))->unref(); if (SkMaskFilter::kInner_BlurType == blurType) { // inner: dst = dst * src paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); @@ -827,7 +828,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkSt matrix.postIDiv(blurTexture->width(), blurTexture->height()); grp->coverageStage(MASK_IDX)->reset(); - grp->coverageStage(MASK_IDX)->setEffect(SkNEW_ARGS(GrSingleTextureEffect, (blurTexture, matrix)))->unref(); + grp->coverageStage(MASK_IDX)->setEffect( + GrSingleTextureEffect::Create(blurTexture, matrix))->unref(); context->drawRect(*grp, finalRect); return true; } @@ -883,7 +885,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(SkNEW_ARGS(GrSingleTextureEffect, (texture, m)))->unref(); + grp->coverageStage(MASK_IDX)->setEffect(GrSingleTextureEffect::Create(texture, m))->unref(); GrRect d; d.setLTRB(SkIntToScalar(dstM.fBounds.fLeft), SkIntToScalar(dstM.fBounds.fTop), @@ -1313,7 +1315,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, } GrRect textureDomain = GrRect::MakeEmpty(); - SkAutoTUnref effect; + SkAutoTUnref effect; if (needsTextureDomain) { // Use a constrained texture domain to avoid color bleeding SkScalar left, top, right, bottom; @@ -1338,7 +1340,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, GrTextureDomainEffect::kClamp_WrapMode, params.isBilerp())); } else { - effect.reset(SkNEW_ARGS(GrSingleTextureEffect, (texture, params))); + effect.reset(GrSingleTextureEffect::Create(texture, SkMatrix::I(), params)); } grPaint->colorStage(kBitmapTextureIdx)->setEffect(effect); fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); @@ -1350,7 +1352,7 @@ void apply_effect(GrContext* context, GrTexture* srcTexture, GrTexture* dstTexture, const GrRect& rect, - GrEffect* effect) { + GrEffectRef* effect) { SkASSERT(srcTexture && srcTexture->getContext() == context); GrContext::AutoMatrix am; am.setIdentity(context); @@ -1375,7 +1377,7 @@ static GrTexture* filter_texture(SkDevice* device, GrContext* context, desc.fWidth = SkScalarCeilToInt(rect.width()); desc.fHeight = SkScalarCeilToInt(rect.height()); desc.fConfig = kRGBA_8888_GrPixelConfig; - GrEffect* effect; + GrEffectRef* effect; if (filter->canFilterImageGPU()) { // Save the render target and set it to NULL, so we don't accidentally draw to it in the @@ -1415,16 +1417,16 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, stage->reset(); // draw sprite uses the default texture params SkAutoCachedTexture act(this, bitmap, NULL, &texture); - grPaint.colorStage(kBitmapTextureIdx)->setEffect(SkNEW_ARGS - (GrSingleTextureEffect, (texture)))->unref(); + grPaint.colorStage(kBitmapTextureIdx)->setEffect( + GrSingleTextureEffect::Create(texture, SkMatrix::I()))->unref(); SkImageFilter* filter = paint.getImageFilter(); if (NULL != filter) { GrTexture* filteredTexture = filter_texture(this, fContext, texture, filter, GrRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h))); if (filteredTexture) { - grPaint.colorStage(kBitmapTextureIdx)->setEffect(SkNEW_ARGS - (GrSingleTextureEffect, (filteredTexture)))->unref(); + grPaint.colorStage(kBitmapTextureIdx)->setEffect( + GrSingleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref(); texture = filteredTexture; filteredTexture->unref(); } @@ -1497,8 +1499,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, SkIntToScalar(devTex->height())); GrTexture* filteredTexture = filter_texture(this, fContext, devTex, filter, rect); if (filteredTexture) { - grPaint.colorStage(kBitmapTextureIdx)->setEffect(SkNEW_ARGS - (GrSingleTextureEffect, (filteredTexture)))->unref(); + grPaint.colorStage(kBitmapTextureIdx)->setEffect( + GrSingleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref(); devTex = filteredTexture; filteredTexture->unref(); } diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index d42896d210..a547c1a2da 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -124,9 +124,9 @@ bool GrConfigConversionEffect::isEqual(const GrEffect& s) const { GR_DEFINE_EFFECT_TEST(GrConfigConversionEffect); -GrEffect* GrConfigConversionEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrConfigConversionEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { PMConversion pmConv = static_cast(random->nextULessThan(kPMConversionCnt)); bool swapRB; if (kNone_PMConversion == pmConv) { @@ -134,10 +134,12 @@ GrEffect* GrConfigConversionEffect::TestCreate(SkRandom* random, } else { swapRB = random->nextBool(); } - return SkNEW_ARGS(GrConfigConversionEffect, (textures[GrEffectUnitTest::kSkiaPMTextureIdx], - swapRB, - pmConv, - GrEffectUnitTest::TestMatrix(random))); + SkAutoTUnref effect(SkNEW_ARGS(GrConfigConversionEffect, + (textures[GrEffectUnitTest::kSkiaPMTextureIdx], + swapRB, + pmConv, + GrEffectUnitTest::TestMatrix(random)))); + return CreateEffectPtr(effect); } /////////////////////////////////////////////////////////////////////////////// @@ -204,21 +206,22 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context // We then verify that two reads produced the same values. GrPaint paint; - SkAutoTUnref pmToUPMEffect1(SkNEW_ARGS(GrConfigConversionEffect, - (dataTex, - false, - *pmToUPMRule, - SkMatrix::I()))); - SkAutoTUnref upmToPMEffect(SkNEW_ARGS(GrConfigConversionEffect, - (readTex, - false, - *upmToPMRule, - SkMatrix::I()))); - SkAutoTUnref pmToUPMEffect2(SkNEW_ARGS(GrConfigConversionEffect, - (tempTex, - false, - *pmToUPMRule, - SkMatrix::I()))); + SkAutoTUnref pmToUPM1(SkNEW_ARGS(GrConfigConversionEffect, (dataTex, + false, + *pmToUPMRule, + SkMatrix::I()))); + SkAutoTUnref upmToPM(SkNEW_ARGS(GrConfigConversionEffect, (readTex, + false, + *upmToPMRule, + SkMatrix::I()))); + SkAutoTUnref pmToUPM2(SkNEW_ARGS(GrConfigConversionEffect, (tempTex, + false, + *pmToUPMRule, + SkMatrix::I()))); + + SkAutoTUnref pmToUPMEffect1(CreateEffectPtr(pmToUPM1)); + SkAutoTUnref upmToPMEffect(CreateEffectPtr(upmToPM)); + SkAutoTUnref pmToUPMEffect2(CreateEffectPtr(pmToUPM2)); context->setRenderTarget(readTex->asRenderTarget()); paint.colorStage(0)->setEffect(pmToUPMEffect1); @@ -260,7 +263,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(SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix)))->unref(); + stage->setEffect(GrSingleTextureEffect::Create(texture, matrix))->unref(); return true; } else { if (kRGBA_8888_GrPixelConfig != texture->config() && @@ -269,9 +272,11 @@ bool GrConfigConversionEffect::InstallEffect(GrTexture* texture, // The PM conversions assume colors are 0..255 return false; } - stage->setEffect(SkNEW_ARGS(GrConfigConversionEffect, (texture, - swapRedAndBlue, - pmConversion, matrix)))->unref(); + SkAutoTUnref effect(SkNEW_ARGS(GrConfigConversionEffect, (texture, + swapRedAndBlue, + pmConversion, + matrix))); + stage->setEffect(CreateEffectPtr(effect))->unref(); return true; } } diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h index 48c776ccf4..b8dd7d0ed4 100644 --- a/src/gpu/effects/GrConfigConversionEffect.h +++ b/src/gpu/effects/GrConfigConversionEffect.h @@ -10,6 +10,7 @@ #include "GrSingleTextureEffect.h" +class GrEffectStage; class GrGLConfigConversionEffect; /** diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp index 047dc4165e..1f4c094814 100644 --- a/src/gpu/effects/GrConvolutionEffect.cpp +++ b/src/gpu/effects/GrConvolutionEffect.cpp @@ -180,9 +180,9 @@ bool GrConvolutionEffect::isEqual(const GrEffect& sBase) const { GR_DEFINE_EFFECT_TEST(GrConvolutionEffect); -GrEffect* GrConvolutionEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrConvolutionEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : GrEffectUnitTest::kAlphaTextureIdx; Direction dir = random->nextBool() ? kX_Direction : kY_Direction; @@ -192,6 +192,6 @@ GrEffect* GrConvolutionEffect::TestCreate(SkRandom* random, kernel[i] = random->nextSScalar1(); } - return SkNEW_ARGS(GrConvolutionEffect, (textures[texIdx], dir, radius, kernel)); + return GrConvolutionEffect::Create(textures[texIdx], dir, radius,kernel); } diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h index 3638c0cf6a..ff661b2adb 100644 --- a/src/gpu/effects/GrConvolutionEffect.h +++ b/src/gpu/effects/GrConvolutionEffect.h @@ -22,13 +22,26 @@ class GrConvolutionEffect : public Gr1DKernelEffect { public: /// Convolve with an arbitrary user-specified kernel - GrConvolutionEffect(GrTexture*, Direction, - int halfWidth, const float* kernel); + static GrEffectRef* Create(GrTexture* tex, Direction dir, int halfWidth, const float* kernel) { + SkAutoTUnref effect(SkNEW_ARGS(GrConvolutionEffect, (tex, + dir, + halfWidth, + kernel))); + return CreateEffectPtr(effect); + } /// Convolve with a Gaussian kernel - GrConvolutionEffect(GrTexture*, Direction, - int halfWidth, - float gaussianSigma); + static GrEffectRef* Create(GrTexture* tex, + Direction dir, + int halfWidth, + float gaussianSigma) { + SkAutoTUnref effect(SkNEW_ARGS(GrConvolutionEffect, (tex, + dir, + halfWidth, + gaussianSigma))); + return CreateEffectPtr(effect); + } + virtual ~GrConvolutionEffect(); const float* kernel() const { return fKernel; } @@ -56,6 +69,14 @@ protected: float fKernel[kMaxKernelWidth]; private: + GrConvolutionEffect(GrTexture*, Direction, + int halfWidth, const float* kernel); + + /// Convolve with a Gaussian kernel + GrConvolutionEffect(GrTexture*, Direction, + int halfWidth, + float gaussianSigma); + GR_DECLARE_EFFECT_TEST; typedef Gr1DKernelEffect INHERITED; diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index 2cf83472d7..18e35e4349 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -57,24 +57,6 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture) - : fTextureAccess(texture) { - fMatrix.reset(); - this->addTextureAccess(&fTextureAccess); -} - -GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, bool bilerp) - : fTextureAccess(texture, bilerp) { - fMatrix.reset(); - this->addTextureAccess(&fTextureAccess); -} - -GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const GrTextureParams& params) - : fTextureAccess(texture, params) { - fMatrix.reset(); - this->addTextureAccess(&fTextureAccess); -} - GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m) : fTextureAccess(texture) , fMatrix(m) { @@ -117,11 +99,11 @@ const GrBackendEffectFactory& GrSingleTextureEffect::getFactory() const { GR_DEFINE_EFFECT_TEST(GrSingleTextureEffect); -GrEffect* GrSingleTextureEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrSingleTextureEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : GrEffectUnitTest::kAlphaTextureIdx; const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); - return SkNEW_ARGS(GrSingleTextureEffect, (textures[texIdx], matrix)); + return GrSingleTextureEffect::Create(textures[texIdx], matrix); } diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index b732913c38..fad2c21239 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -19,17 +19,23 @@ class GrTexture; * output color is the texture color is modulated against the input color. */ class GrSingleTextureEffect : public GrEffect { - public: - /** These three constructors assume an identity matrix. TODO: Remove these.*/ - GrSingleTextureEffect(GrTexture* texture); /* unfiltered, clamp mode */ - GrSingleTextureEffect(GrTexture* texture, bool bilerp); /* clamp mode */ - GrSingleTextureEffect(GrTexture* texture, const GrTextureParams&); + /* unfiltered, clamp mode */ + static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) { + SkAutoTUnref effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix))); + return CreateEffectPtr(effect); + } - /** These three constructors take an explicit matrix */ - GrSingleTextureEffect(GrTexture*, const SkMatrix&); /* unfiltered, clamp mode */ - GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp); /* clamp mode */ - GrSingleTextureEffect(GrTexture*, const SkMatrix&, const GrTextureParams&); + /* clamp mode */ + static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) { + SkAutoTUnref effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix, bilerp))); + return CreateEffectPtr(effect); + } + + static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) { + SkAutoTUnref effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix, p))); + return CreateEffectPtr(effect); + } virtual ~GrSingleTextureEffect(); @@ -50,7 +56,13 @@ public: 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: + GR_DECLARE_EFFECT_TEST; GrTextureAccess fTextureAccess; diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp index 6884682829..74727a05c5 100644 --- a/src/gpu/effects/GrTextureDomainEffect.cpp +++ b/src/gpu/effects/GrTextureDomainEffect.cpp @@ -121,14 +121,14 @@ GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrEffectStage& stage /////////////////////////////////////////////////////////////////////////////// -GrEffect* GrTextureDomainEffect::Create(GrTexture* texture, - const SkMatrix& matrix, - const GrRect& domain, - WrapMode wrapMode, - bool bilerp) { +GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture, + const SkMatrix& matrix, + const GrRect& domain, + WrapMode wrapMode, + bool bilerp) { static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) { - return SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix, bilerp)); + return GrSingleTextureEffect::Create(texture, matrix, bilerp); } else { SkRect clippedDomain; // We don't currently handle domains that are empty or don't intersect the texture. @@ -142,8 +142,14 @@ GrEffect* GrTextureDomainEffect::Create(GrTexture* texture, clippedDomain.fBottom = SkMinScalar(domain.fBottom, kFullRect.fBottom); GrAssert(clippedDomain.fLeft <= clippedDomain.fRight); GrAssert(clippedDomain.fTop <= clippedDomain.fBottom); - return SkNEW_ARGS(GrTextureDomainEffect, - (texture, matrix, clippedDomain, wrapMode, bilerp)); + + SkAutoTUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture, + matrix, + clippedDomain, + wrapMode, + bilerp))); + return CreateEffectPtr(effect); + } } @@ -174,9 +180,9 @@ bool GrTextureDomainEffect::isEqual(const GrEffect& sBase) const { GR_DEFINE_EFFECT_TEST(GrTextureDomainEffect); -GrEffect* GrTextureDomainEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { +GrEffectRef* GrTextureDomainEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : GrEffectUnitTest::kAlphaTextureIdx; GrRect domain; diff --git a/src/gpu/effects/GrTextureDomainEffect.h b/src/gpu/effects/GrTextureDomainEffect.h index c1ce6d11a6..a5c2d70198 100644 --- a/src/gpu/effects/GrTextureDomainEffect.h +++ b/src/gpu/effects/GrTextureDomainEffect.h @@ -34,11 +34,11 @@ public: kDecal_WrapMode, }; - static GrEffect* Create(GrTexture*, - const SkMatrix&, - const SkRect& domain, - WrapMode, - bool bilerp = false); + static GrEffectRef* Create(GrTexture*, + const SkMatrix&, + const SkRect& domain, + WrapMode, + bool bilerp = false); virtual ~GrTextureDomainEffect(); diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index 46d0820079..aafde3552c 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -31,13 +31,13 @@ bool random_bool(SkRandom* r) { return r->nextF() > .5f; } -const GrEffect* create_random_effect(SkRandom* random, - GrContext* context, - GrTexture* dummyTextures[]) { +const GrEffectRef* create_random_effect(SkRandom* random, + GrContext* context, + GrTexture* dummyTextures[]) { SkRandom sk_random; sk_random.setSeed(random->nextU()); - GrEffect* effect = GrEffectTestFactory::CreateStage(&sk_random, context, dummyTextures); + GrEffectRef* effect = GrEffectTestFactory::CreateStage(&sk_random, context, dummyTextures); GrAssert(effect); return effect; } @@ -122,7 +122,7 @@ bool GrGpuGL::programUnitTest() { } GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()}; - SkAutoTUnref effect(create_random_effect(&random, + SkAutoTUnref effect(create_random_effect(&random, getContext(), dummyTextures)); stages[s].setEffect(effect.get());