aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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;