From 59dc0d22f557a20669126fa425baefe6dd4b727a Mon Sep 17 00:00:00 2001 From: reed Date: Mon, 19 Oct 2015 08:24:21 -0700 Subject: change SkImage_Gpu to handle all filters (w/ and w/o gpu support The result is that the set of "generic" imagefilters (e.g. SkColorFilterImageFilter) that use drawing commands to return their results will now stay in the same domain as their src (i.e. gpu-src --> gpu-dst). ApplyFilterGM exercises this, and now asserts this same-domain invariant. BUG=skia:4467 Review URL: https://codereview.chromium.org/1401053003 --- src/image/SkImage_Gpu.cpp | 51 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'src/image/SkImage_Gpu.cpp') diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 039bbdd100..9eb909ee2b 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -209,33 +209,52 @@ public: } } - bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, - SkBitmap*, SkIPoint*) override { - return false; + bool filterImage(const SkImageFilter* filter, const SkBitmap& src, + const SkImageFilter::Context& ctx, SkBitmap* dst, SkIPoint* offset) override { + return filter->canFilterImageGPU() && + filter->filterImageGPU(this, src, ctx, dst, offset); } }; +static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBounds) { + SkRect fastBounds; + fastBounds.set(srcBounds); + filter->computeFastBounds(fastBounds, &fastBounds); + return fastBounds.roundOut(); +} + SkImage* SkImage_Gpu::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResult, bool forceResultToOriginalSize) const { - if (!forceResultToOriginalSize || !filter->canFilterImageGPU()) { - return this->INHERITED::onApplyFilter(filter, offsetResult, forceResultToOriginalSize); - } + const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height()); - SkBitmap src; - GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &src); + if (forceResultToOriginalSize) { + SkBitmap src; + GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &src); - GrContext* context = fTexture->getContext(); - SkGpuImageFilterProxy proxy(context); - SkImageFilter::Context ctx(SkMatrix::I(), - SkIRect::MakeWH(this->width(), this->height()), - SkImageFilter::Cache::Get()); + const SkIRect clipBounds = srcBounds; + SkGpuImageFilterProxy proxy(fTexture->getContext()); + SkImageFilter::Context ctx(SkMatrix::I(), clipBounds, SkImageFilter::Cache::Get()); - SkBitmap dst; - if (filter->filterImageGPU(&proxy, src, ctx, &dst, offsetResult)) { + SkBitmap dst; + if (!filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) { + return nullptr; + } return new SkImage_Gpu(dst.width(), dst.height(), kNeedNewImageUniqueID, dst.alphaType(), dst.getTexture(), SkSurface::kNo_Budgeted); } - return nullptr; + + const SkIRect dstR = compute_fast_ibounds(filter, srcBounds); + + SkImageInfo info = SkImageInfo::MakeN32Premul(dstR.width(), dstR.height()); + SkAutoTUnref surface(this->onNewSurface(info)); + + SkPaint paint; + paint.setImageFilter(filter); + surface->getCanvas()->drawImage(this, SkIntToScalar(-dstR.x()), SkIntToScalar(-dstR.y()), + &paint); + + offsetResult->set(dstR.x(), dstR.y()); + return surface->newImageSnapshot(); } /////////////////////////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3