diff options
author | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-01 20:16:34 +0000 |
---|---|---|
committer | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-01 20:16:34 +0000 |
commit | 302cffba86a188373c99833d83392f33e6014542 (patch) | |
tree | 04b0fb01a92ec3c0fbf5ddfc17c7e8f5298ead62 | |
parent | a2d71482db8b6d752a51c96da74768d7dfc27932 (diff) |
Replace the asAFoo() functions in SkImageFilter with canFilterImageGPU() and
onFilterImageGPU() virtuals. This allows each filter to implement its own GPU
processing code, even for multi-pass filters.
Review URL: http://codereview.appspot.com/6449075/
git-svn-id: http://skia.googlecode.com/svn/trunk@4900 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/core/SkImageFilter.h | 29 | ||||
-rw-r--r-- | include/effects/SkBlurImageFilter.h | 5 | ||||
-rw-r--r-- | include/effects/SkMorphologyImageFilter.h | 5 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 20 | ||||
-rw-r--r-- | src/effects/SkBlurImageFilter.cpp | 11 | ||||
-rw-r--r-- | src/effects/SkMorphologyImageFilter.cpp | 16 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 26 |
7 files changed, 45 insertions, 67 deletions
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h index 0915b90714..b16fb0f7a2 100644 --- a/include/core/SkImageFilter.h +++ b/include/core/SkImageFilter.h @@ -90,28 +90,21 @@ public: virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const; /** - * Experimental. - * - * If the filter can be expressed as a gaussian-blur, return true and - * set the sigma to the values for horizontal and vertical. - */ - virtual bool asABlur(SkSize* sigma) const; - - /** - * Experimental. - * - * If the filter can be expressed as an erode, return true and - * set the radius in X and Y. + * Returns true if the filter can be processed on the GPU. This is most + * often used for multi-pass effects, where intermediate results must be + * rendered to textures. For single-pass effects, use asNewCustomStage(). + * The default implementation returns false. */ - virtual bool asAnErode(SkISize* radius) const; + virtual bool canFilterImageGPU() const; /** - * Experimental. - * - * If the filter can be expressed as a dilation, return true and - * set the radius in X and Y. + * Process this image filter on the GPU. texture is the source texture + * for processing, and rect is the effect region to process. The + * function must allocate a new texture of at least rect width/height + * size, and return it to the caller. The default implementation returns + * NULL. */ - virtual bool asADilate(SkISize* radius) const; + virtual GrTexture* onFilterImageGPU(GrTexture* texture, const SkRect& rect); protected: SkImageFilter() {} diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h index bf5173d381..ab84a0ecdf 100644 --- a/include/effects/SkBlurImageFilter.h +++ b/include/effects/SkBlurImageFilter.h @@ -15,8 +15,6 @@ class SK_API SkBlurImageFilter : public SkImageFilter { public: SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY); - virtual bool asABlur(SkSize* sigma) const SK_OVERRIDE; - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter) protected: @@ -26,6 +24,9 @@ protected: virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; + bool canFilterImageGPU() const SK_OVERRIDE { return true; } + virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; + private: SkSize fSigma; typedef SkImageFilter INHERITED; diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h index 5450576de9..4df90aedec 100644 --- a/include/effects/SkMorphologyImageFilter.h +++ b/include/effects/SkMorphologyImageFilter.h @@ -18,6 +18,7 @@ public: protected: SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer); virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; + virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; } SkISize radius() const { return fRadius; } @@ -30,9 +31,9 @@ class SK_API SkDilateImageFilter : public SkMorphologyImageFilter { public: SkDilateImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {} - virtual bool asADilate(SkISize* radius) const SK_OVERRIDE; virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; + virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter) @@ -47,9 +48,9 @@ class SK_API SkErodeImageFilter : public SkMorphologyImageFilter { public: SkErodeImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {} - virtual bool asAnErode(SkISize* radius) const SK_OVERRIDE; virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; + virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter) diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 04a8f5a756..94a4d22d7d 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -2280,25 +2280,21 @@ bool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, return false; } -bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, - SkIRect* dst) { - *dst = src; - return true; -} - -bool SkImageFilter::asNewCustomStage(GrCustomStage**, GrTexture*) const { +bool SkImageFilter::canFilterImageGPU() const { return false; } -bool SkImageFilter::asABlur(SkSize* sigma) const { - return false; +GrTexture* SkImageFilter::onFilterImageGPU(GrTexture* texture, const SkRect& rect) { + return NULL; } -bool SkImageFilter::asAnErode(SkISize* radius) const { - return false; +bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, + SkIRect* dst) { + *dst = src; + return true; } -bool SkImageFilter::asADilate(SkISize* radius) const { +bool SkImageFilter::asNewCustomStage(GrCustomStage**, GrTexture*) const { return false; } diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp index e3ac346653..ed76743dbc 100644 --- a/src/effects/SkBlurImageFilter.cpp +++ b/src/effects/SkBlurImageFilter.cpp @@ -8,6 +8,7 @@ #include "SkBitmap.h" #include "SkBlurImageFilter.h" #include "SkColorPriv.h" +#include "GrContext.h" SkBlurImageFilter::SkBlurImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { @@ -20,11 +21,6 @@ SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY) SkASSERT(sigmaX >= 0 && sigmaY >= 0); } -bool SkBlurImageFilter::asABlur(SkSize* sigma) const { - *sigma = fSigma; - return true; -} - void SkBlurImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); buffer.writeScalar(fSigma.fWidth); @@ -187,4 +183,9 @@ bool SkBlurImageFilter::onFilterImage(Proxy*, return true; } +GrTexture* SkBlurImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) { + return src->getContext()->gaussianBlur(src, false, rect, + fSigma.width(), fSigma.height()); +} + SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurImageFilter) diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 869ba6d97e..3c2e385fe2 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -8,6 +8,8 @@ #include "SkMorphologyImageFilter.h" #include "SkBitmap.h" #include "SkColorPriv.h" +#include "GrContext.h" +#include "GrTexture.h" SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { @@ -210,14 +212,16 @@ bool SkDilateImageFilter::onFilterImage(Proxy*, return true; } -bool SkDilateImageFilter::asADilate(SkISize* radius) const { - *radius = this->radius(); - return true; +GrTexture* SkDilateImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) { + return src->getContext()->applyMorphology(src, rect, + GrContext::kDilate_MorphologyType, + radius()); } -bool SkErodeImageFilter::asAnErode(SkISize* radius) const { - *radius = this->radius(); - return true; +GrTexture* SkErodeImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) { + return src->getContext()->applyMorphology(src, rect, + GrContext::kErode_MorphologyType, + radius()); } SK_DEFINE_FLATTENABLE_REGISTRAR(SkDilateImageFilter) diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 8860d6e6a5..27d3724792 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1501,9 +1501,6 @@ static GrTexture* filter_texture(GrContext* context, GrTexture* texture, SkImageFilter* filter, const GrRect& rect) { GrAssert(filter); - SkSize blurSize; - SkISize radius; - GrTextureDesc desc; desc.fFlags = kRenderTarget_GrTextureFlagBit, desc.fWidth = SkScalarCeilToInt(rect.width()); @@ -1511,23 +1508,13 @@ static GrTexture* filter_texture(GrContext* context, GrTexture* texture, desc.fConfig = kRGBA_8888_PM_GrPixelConfig; GrCustomStage* stage; - if (filter->asNewCustomStage(&stage, texture)) { + if (filter->canFilterImageGPU()) { + texture = filter->onFilterImageGPU(texture, rect); + } else if (filter->asNewCustomStage(&stage, texture)) { GrAutoScratchTexture dst(context, desc); apply_custom_stage(context, texture, dst.texture(), rect, stage); texture = dst.detach(); stage->unref(); - } else if (filter->asABlur(&blurSize)) { - texture = context->gaussianBlur(texture, false, rect, - blurSize.width(), - blurSize.height()); - } else if (filter->asADilate(&radius)) { - texture = context->applyMorphology(texture, rect, - GrContext::kDilate_MorphologyType, - radius); - } else if (filter->asAnErode(&radius)) { - texture = context->applyMorphology(texture, rect, - GrContext::kErode_MorphologyType, - radius); } return texture; } @@ -1635,13 +1622,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, } bool SkGpuDevice::canHandleImageFilter(SkImageFilter* filter) { - SkSize size; - SkISize radius; - if (!filter->asNewCustomStage(NULL, NULL) && - !filter->asABlur(&size) && - !filter->asADilate(&radius) && - !filter->asAnErode(&radius)) { + !filter->canFilterImageGPU()) { return false; } return true; |