aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-27 21:57:45 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-27 21:57:45 +0000
commit9c39744a00573b7133fc765b0a9d50a0ceace7b8 (patch)
treef416a1bf3e821884974ec2cf4e0d383ad75d16e2 /src
parent200e53fa5fe7dae717a73224064a2fc37302e003 (diff)
Fix recursive GPU processing for SkImageFilter. Plumb through the
SkImageFilter::Proxy parameter to the GPU recursion path. Extract DeviceImageFilterProxy from SkCanvas.cpp into its own .h, and rename it. https://codereview.appspot.com/6575059/ git-svn-id: http://skia.googlecode.com/svn/trunk@5720 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/core/SkCanvas.cpp28
-rw-r--r--src/core/SkDeviceImageFilterProxy.h34
-rw-r--r--src/core/SkImageFilter.cpp2
-rw-r--r--src/effects/SkBlendImageFilter.cpp13
-rw-r--r--src/effects/SkBlurImageFilter.cpp4
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp8
-rw-r--r--src/effects/SkSingleInputImageFilter.cpp9
-rw-r--r--src/gpu/SkGpuDevice.cpp15
8 files changed, 65 insertions, 48 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 28a2bc4363..1f8d6af10f 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -10,6 +10,7 @@
#include "SkCanvas.h"
#include "SkBounder.h"
#include "SkDevice.h"
+#include "SkDeviceImageFilterProxy.h"
#include "SkDraw.h"
#include "SkDrawFilter.h"
#include "SkDrawLooper.h"
@@ -975,29 +976,6 @@ void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, const SkIRect* srcRect
this->commonDrawBitmap(bitmap, srcRect, matrix, *paint);
}
-#include "SkImageFilter.h"
-
-class DeviceImageFilterProxy : public SkImageFilter::Proxy {
-public:
- DeviceImageFilterProxy(SkDevice* device) : fDevice(device) {}
-
- virtual SkDevice* createDevice(int w, int h) SK_OVERRIDE {
- return fDevice->createCompatibleDevice(SkBitmap::kARGB_8888_Config,
- w, h, false);
- }
- virtual bool canHandleImageFilter(SkImageFilter* filter) SK_OVERRIDE {
- return fDevice->canHandleImageFilter(filter);
- }
- virtual bool filterImage(SkImageFilter* filter, const SkBitmap& src,
- const SkMatrix& ctm,
- SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
- return fDevice->filterImage(filter, src, ctm, result, offset);
- }
-
-private:
- SkDevice* fDevice;
-};
-
void SkCanvas::internalDrawDevice(SkDevice* srcDev, int x, int y,
const SkPaint* paint) {
SkPaint tmp;
@@ -1013,7 +991,7 @@ void SkCanvas::internalDrawDevice(SkDevice* srcDev, int x, int y,
SkImageFilter* filter = paint->getImageFilter();
SkIPoint pos = { x - iter.getX(), y - iter.getY() };
if (filter && !dstDev->canHandleImageFilter(filter)) {
- DeviceImageFilterProxy proxy(dstDev);
+ SkDeviceImageFilterProxy proxy(dstDev);
SkBitmap dst;
const SkBitmap& src = srcDev->accessBitmap(false);
if (filter->filterImage(&proxy, src, *iter.fMatrix, &dst, &pos)) {
@@ -1048,7 +1026,7 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
SkImageFilter* filter = paint->getImageFilter();
SkIPoint pos = { x - iter.getX(), y - iter.getY() };
if (filter && !iter.fDevice->canHandleImageFilter(filter)) {
- DeviceImageFilterProxy proxy(iter.fDevice);
+ SkDeviceImageFilterProxy proxy(iter.fDevice);
SkBitmap dst;
if (filter->filterImage(&proxy, bitmap, *iter.fMatrix,
&dst, &pos)) {
diff --git a/src/core/SkDeviceImageFilterProxy.h b/src/core/SkDeviceImageFilterProxy.h
new file mode 100644
index 0000000000..98a120cd0d
--- /dev/null
+++ b/src/core/SkDeviceImageFilterProxy.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDeviceImageFilterProxy_DEFINED
+#define SkDeviceImageFilterProxy_DEFINED
+
+#include "SkImageFilter.h"
+
+class SkDeviceImageFilterProxy : public SkImageFilter::Proxy {
+public:
+ SkDeviceImageFilterProxy(SkDevice* device) : fDevice(device) {}
+
+ virtual SkDevice* createDevice(int w, int h) SK_OVERRIDE {
+ return fDevice->createCompatibleDevice(SkBitmap::kARGB_8888_Config,
+ w, h, false);
+ }
+ virtual bool canHandleImageFilter(SkImageFilter* filter) SK_OVERRIDE {
+ return fDevice->canHandleImageFilter(filter);
+ }
+ virtual bool filterImage(SkImageFilter* filter, const SkBitmap& src,
+ const SkMatrix& ctm,
+ SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
+ return fDevice->filterImage(filter, src, ctm, result, offset);
+ }
+
+private:
+ SkDevice* fDevice;
+};
+
+#endif
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 21582bd2db..bb31b79f04 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -39,7 +39,7 @@ bool SkImageFilter::canFilterImageGPU() const {
return false;
}
-GrTexture* SkImageFilter::onFilterImageGPU(GrTexture* texture, const SkRect& rect) {
+GrTexture* SkImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* texture, const SkRect& rect) {
return NULL;
}
diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp
index 2328d95aec..b604bc2dfe 100644
--- a/src/effects/SkBlendImageFilter.cpp
+++ b/src/effects/SkBlendImageFilter.cpp
@@ -165,7 +165,8 @@ private:
};
// FIXME: This should be refactored with SkSingleInputImageFilter's version.
-static GrTexture* getInputResultAsTexture(SkImageFilter* input,
+static GrTexture* getInputResultAsTexture(SkImageFilter::Proxy* proxy,
+ SkImageFilter* input,
GrTexture* src,
const SkRect& rect) {
GrTexture* resultTex;
@@ -173,13 +174,13 @@ static GrTexture* getInputResultAsTexture(SkImageFilter* input,
resultTex = src;
} else if (input->canFilterImageGPU()) {
// onFilterImageGPU() already refs the result, so just return it here.
- return input->onFilterImageGPU(src, rect);
+ return input->onFilterImageGPU(proxy, src, rect);
} else {
SkBitmap srcBitmap, result;
srcBitmap.setConfig(SkBitmap::kARGB_8888_Config, src->width(), src->height());
srcBitmap.setPixelRef(new SkGrPixelRef(src))->unref();
SkIPoint offset;
- if (input->filterImage(NULL, srcBitmap, SkMatrix(), &result, &offset)) {
+ if (input->filterImage(proxy, srcBitmap, SkMatrix(), &result, &offset)) {
if (result.getTexture()) {
resultTex = (GrTexture*) result.getTexture();
} else {
@@ -196,9 +197,9 @@ static GrTexture* getInputResultAsTexture(SkImageFilter* input,
return resultTex;
}
-GrTexture* SkBlendImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) {
- SkAutoTUnref<GrTexture> background(getInputResultAsTexture(fBackground, src, rect));
- SkAutoTUnref<GrTexture> foreground(getInputResultAsTexture(fForeground, src, rect));
+GrTexture* SkBlendImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* src, const SkRect& rect) {
+ SkAutoTUnref<GrTexture> background(getInputResultAsTexture(proxy, fBackground, src, rect));
+ SkAutoTUnref<GrTexture> foreground(getInputResultAsTexture(proxy, fForeground, src, rect));
GrContext* context = src->getContext();
GrTextureDesc desc;
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index 2a61460788..fb76269823 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -187,9 +187,9 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
return true;
}
-GrTexture* SkBlurImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) {
+GrTexture* SkBlurImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* src, const SkRect& rect) {
#if SK_SUPPORT_GPU
- SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(src, rect));
+ SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(proxy, src, rect));
return src->getContext()->gaussianBlur(input.get(), false, rect,
fSigma.width(), fSigma.height());
#else
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 5bf9a99786..b1ee602b25 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -478,13 +478,13 @@ GrTexture* apply_morphology(GrTexture* srcTexture,
};
-GrTexture* SkDilateImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) {
- SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(src, rect));
+GrTexture* SkDilateImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* src, const SkRect& rect) {
+ SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(proxy, src, rect));
return apply_morphology(src, rect, GrMorphologyEffect::kDilate_MorphologyType, radius());
}
-GrTexture* SkErodeImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) {
- SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(src, rect));
+GrTexture* SkErodeImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* src, const SkRect& rect) {
+ SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(proxy, src, rect));
return apply_morphology(src, rect, GrMorphologyEffect::kErode_MorphologyType, radius());
}
diff --git a/src/effects/SkSingleInputImageFilter.cpp b/src/effects/SkSingleInputImageFilter.cpp
index a1c4292fae..3dd9ef9c90 100644
--- a/src/effects/SkSingleInputImageFilter.cpp
+++ b/src/effects/SkSingleInputImageFilter.cpp
@@ -51,20 +51,21 @@ SkBitmap SkSingleInputImageFilter::getInputResult(Proxy* proxy,
}
#if SK_SUPPORT_GPU
-GrTexture* SkSingleInputImageFilter::getInputResultAsTexture(GrTexture* src,
+GrTexture* SkSingleInputImageFilter::getInputResultAsTexture(Proxy* proxy,
+ GrTexture* src,
const SkRect& rect) {
- GrTexture* resultTex;
+ GrTexture* resultTex = NULL;
if (!fInput) {
resultTex = src;
} else if (fInput->canFilterImageGPU()) {
// onFilterImageGPU() already refs the result, so just return it here.
- return fInput->onFilterImageGPU(src, rect);
+ return fInput->onFilterImageGPU(proxy, src, rect);
} else {
SkBitmap srcBitmap, result;
srcBitmap.setConfig(SkBitmap::kARGB_8888_Config, src->width(), src->height());
srcBitmap.setPixelRef(new SkGrPixelRef(src))->unref();
SkIPoint offset;
- if (fInput->filterImage(NULL, srcBitmap, SkMatrix(), &result, &offset)) {
+ if (fInput->filterImage(proxy, srcBitmap, SkMatrix(), &result, &offset)) {
if (result.getTexture()) {
resultTex = (GrTexture*) result.getTexture();
} else {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 322748e2d2..59a3b61739 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -16,6 +16,7 @@
#include "SkGrTexturePixelRef.h"
#include "SkColorFilter.h"
+#include "SkDeviceImageFilterProxy.h"
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
#include "SkImageFilter.h"
@@ -1514,9 +1515,11 @@ void apply_custom_stage(GrContext* context,
};
-static GrTexture* filter_texture(GrContext* context, GrTexture* texture,
- SkImageFilter* filter, const GrRect& rect) {
+static GrTexture* filter_texture(SkDevice* device, GrContext* context,
+ GrTexture* texture, SkImageFilter* filter,
+ const GrRect& rect) {
GrAssert(filter);
+ SkDeviceImageFilterProxy proxy(device);
GrTextureDesc desc;
desc.fFlags = kRenderTarget_GrTextureFlagBit,
@@ -1526,7 +1529,7 @@ static GrTexture* filter_texture(GrContext* context, GrTexture* texture,
GrCustomStage* stage;
if (filter->canFilterImageGPU()) {
- texture = filter->onFilterImageGPU(texture, rect);
+ texture = filter->onFilterImageGPU(&proxy, texture, rect);
} else if (filter->asNewCustomStage(&stage, texture)) {
GrAutoScratchTexture dst(context, desc);
apply_custom_stage(context, texture, dst.texture(), rect, stage);
@@ -1567,7 +1570,7 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
SkImageFilter* filter = paint.getImageFilter();
if (NULL != filter) {
- GrTexture* filteredTexture = filter_texture(fContext, texture, filter,
+ GrTexture* filteredTexture = filter_texture(this, fContext, texture, filter,
GrRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)));
if (filteredTexture) {
grPaint.textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
@@ -1653,7 +1656,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device,
if (NULL != filter) {
GrRect rect = GrRect::MakeWH(SkIntToScalar(devTex->width()),
SkIntToScalar(devTex->height()));
- GrTexture* filteredTexture = filter_texture(fContext, devTex, filter, rect);
+ GrTexture* filteredTexture = filter_texture(this, fContext, devTex, filter, rect);
if (filteredTexture) {
grPaint.textureSampler(kBitmapTextureIdx)->setCustomStage(SkNEW_ARGS
(GrSingleTextureEffect, (filteredTexture)))->unref();
@@ -1712,7 +1715,7 @@ bool SkGpuDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
result->setConfig(src.config(), src.width(), src.height());
GrRect rect = GrRect::MakeWH(SkIntToScalar(src.width()),
SkIntToScalar(src.height()));
- GrTexture* resultTexture = filter_texture(fContext, texture, filter, rect);
+ GrTexture* resultTexture = filter_texture(this, fContext, texture, filter, rect);
if (resultTexture) {
result->setPixelRef(SkNEW_ARGS(SkGrTexturePixelRef,
(resultTexture)))->unref();