aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-01 20:16:34 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-01 20:16:34 +0000
commit302cffba86a188373c99833d83392f33e6014542 (patch)
tree04b0fb01a92ec3c0fbf5ddfc17c7e8f5298ead62
parenta2d71482db8b6d752a51c96da74768d7dfc27932 (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.h29
-rw-r--r--include/effects/SkBlurImageFilter.h5
-rw-r--r--include/effects/SkMorphologyImageFilter.h5
-rw-r--r--src/core/SkPaint.cpp20
-rw-r--r--src/effects/SkBlurImageFilter.cpp11
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp16
-rw-r--r--src/gpu/SkGpuDevice.cpp26
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;