diff options
author | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-09-27 21:57:45 +0000 |
---|---|---|
committer | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-09-27 21:57:45 +0000 |
commit | 9c39744a00573b7133fc765b0a9d50a0ceace7b8 (patch) | |
tree | f416a1bf3e821884974ec2cf4e0d383ad75d16e2 | |
parent | 200e53fa5fe7dae717a73224064a2fc37302e003 (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
-rw-r--r-- | include/core/SkDevice.h | 2 | ||||
-rw-r--r-- | include/core/SkImageFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkBlendImageFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkBlurImageFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkMorphologyImageFilter.h | 6 | ||||
-rw-r--r-- | include/effects/SkSingleInputImageFilter.h | 2 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 28 | ||||
-rw-r--r-- | src/core/SkDeviceImageFilterProxy.h | 34 | ||||
-rw-r--r-- | src/core/SkImageFilter.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkBlendImageFilter.cpp | 13 | ||||
-rw-r--r-- | src/effects/SkBlurImageFilter.cpp | 4 | ||||
-rw-r--r-- | src/effects/SkMorphologyImageFilter.cpp | 8 | ||||
-rw-r--r-- | src/effects/SkSingleInputImageFilter.cpp | 9 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 15 |
14 files changed, 74 insertions, 55 deletions
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 851a167982..f0aa8e0a02 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -389,7 +389,7 @@ private: friend class SkDraw; friend class SkDrawIter; friend class SkDeviceFilteredPaint; - friend class DeviceImageFilterProxy; + friend class SkDeviceImageFilterProxy; friend class SkSurface_Raster; // used to change the backend's pixels (and possibly config/rowbytes) diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h index dd5aecde0f..92a5a58d28 100644 --- a/include/core/SkImageFilter.h +++ b/include/core/SkImageFilter.h @@ -106,7 +106,7 @@ public: * size, and return it to the caller. The default implementation returns * NULL. */ - virtual GrTexture* onFilterImageGPU(GrTexture* texture, const SkRect& rect); + virtual GrTexture* onFilterImageGPU(Proxy*, GrTexture* texture, const SkRect& rect); protected: SkImageFilter() {} diff --git a/include/effects/SkBlendImageFilter.h b/include/effects/SkBlendImageFilter.h index c13140f9fd..be1be68054 100644 --- a/include/effects/SkBlendImageFilter.h +++ b/include/effects/SkBlendImageFilter.h @@ -34,7 +34,7 @@ public: SkIPoint* offset) SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; } - virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; + virtual GrTexture* onFilterImageGPU(Proxy* proxy, GrTexture* src, const SkRect& rect) SK_OVERRIDE; #endif protected: diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h index 9e86f7a38a..eeafbb9a31 100644 --- a/include/effects/SkBlurImageFilter.h +++ b/include/effects/SkBlurImageFilter.h @@ -26,7 +26,7 @@ protected: SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; bool canFilterImageGPU() const SK_OVERRIDE { return true; } - virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; + virtual GrTexture* onFilterImageGPU(Proxy* proxy, GrTexture* src, const SkRect& rect) SK_OVERRIDE; private: SkSize fSigma; diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h index d1d43ba732..edee221781 100644 --- a/include/effects/SkMorphologyImageFilter.h +++ b/include/effects/SkMorphologyImageFilter.h @@ -38,7 +38,8 @@ public: virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; + virtual GrTexture* onFilterImageGPU(Proxy* proxy, GrTexture* src, + const SkRect& rect) SK_OVERRIDE; #endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter) @@ -58,7 +59,8 @@ public: virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; + virtual GrTexture* onFilterImageGPU(Proxy* proxy, GrTexture* src, + const SkRect& rect) SK_OVERRIDE; #endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter) diff --git a/include/effects/SkSingleInputImageFilter.h b/include/effects/SkSingleInputImageFilter.h index fd2c6aa11d..b29eca039d 100644 --- a/include/effects/SkSingleInputImageFilter.h +++ b/include/effects/SkSingleInputImageFilter.h @@ -32,7 +32,7 @@ protected: #if SK_SUPPORT_GPU // Recurses on input (if non-NULL), and returns the processed result as // a texture, otherwise returns src. - GrTexture* getInputResultAsTexture(GrTexture* src, const SkRect& rect); + GrTexture* getInputResultAsTexture(Proxy* proxy, GrTexture* src, const SkRect& rect); #endif SkImageFilter* input() const { return fInput; } 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(); |