From: Stephen White Date: Wed, 3 Feb 2016 14:38:46 +0000 (-0500) Subject: Fix zero-sized blur with crop rect. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~184^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3a2b4d5906625f5178e6da69c1f62ab4e6f275e7;p=platform%2Fupstream%2FlibSkiaSharp.git Fix zero-sized blur with crop rect. [Cherry-pick of 6404981b0c3984ba91b3bda35e60c6c8a8a773c2 to chrome/m49.] Neither the GPU nor CPU paths were correctly handling the crop rect in this case. NOTE: this change adds a new test case to the imageblurcropped GM, so it will have to be rebaselined. BUG=skia:4876 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1657773002 NOTREECHECKS=true NOTRY=true NOPRESUBMIT=true Review URL: https://codereview.chromium.org/1663533003 . --- diff --git a/gm/imagefilterscropped.cpp b/gm/imagefilterscropped.cpp index 4c6ef62..d39e6b0 100644 --- a/gm/imagefilterscropped.cpp +++ b/gm/imagefilterscropped.cpp @@ -72,11 +72,11 @@ public: ImageFiltersCroppedGM () {} protected: - virtual SkString onShortName() override { + SkString onShortName() override { return SkString("imagefilterscropped"); } - virtual SkISize onISize() override { return SkISize::Make(400, 880); } + SkISize onISize() override { return SkISize::Make(400, 960); } void make_checkerboard() { fCheckerboard.allocN32Pixels(80, 80); @@ -131,6 +131,7 @@ protected: SkImageFilter* filters[] = { nullptr, SkColorFilterImageFilter::Create(cf.get(), nullptr, &cropRect), + SkBlurImageFilter::Create(0.0f, 0.0f, nullptr, &cropRect), SkBlurImageFilter::Create(1.0f, 1.0f, nullptr, &cropRect), SkBlurImageFilter::Create(8.0f, 0.0f, nullptr, &cropRect), SkBlurImageFilter::Create(0.0f, 8.0f, nullptr, &cropRect), diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp index 5d58369..a1d6a2f 100644 --- a/src/effects/SkBlurImageFilter.cpp +++ b/src/effects/SkBlurImageFilter.cpp @@ -25,7 +25,7 @@ // raster paths. #define MAX_SIGMA SkIntToScalar(532) -static SkVector mapSigma(const SkSize& localSigma, const SkMatrix& ctm) { +static SkVector map_sigma(const SkSize& localSigma, const SkMatrix& ctm) { SkVector sigma = SkVector::Make(localSigma.width(), localSigma.height()); ctm.mapVectors(&sigma, 1); sigma.fX = SkMinScalar(SkScalarAbs(sigma.fX), MAX_SIGMA); @@ -90,19 +90,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, return false; } - SkAutoLockPixels alp(src); - if (!src.getPixels()) { - return false; - } - - SkAutoTUnref device(proxy->createDevice(dstBounds.width(), dstBounds.height())); - if (!device) { - return false; - } - *dst = device->accessBitmap(false); - SkAutoLockPixels alp_dst(*dst); - - SkVector sigma = mapSigma(fSigma, ctx.ctm()); + SkVector sigma = map_sigma(fSigma, ctx.ctm()); int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; @@ -114,12 +102,24 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, } if (kernelSizeX == 0 && kernelSizeY == 0) { - src.copyTo(dst, dst->colorType()); - offset->fX = dstBounds.x() + srcOffset.x(); - offset->fY = dstBounds.y() + srcOffset.y(); + src.extractSubset(dst, srcBounds); + offset->fX = srcBounds.x(); + offset->fY = srcBounds.y(); return true; } + SkAutoLockPixels alp(src); + if (!src.getPixels()) { + return false; + } + + SkAutoTUnref device(proxy->createDevice(dstBounds.width(), dstBounds.height())); + if (!device) { + return false; + } + *dst = device->accessBitmap(false); + SkAutoLockPixels alp_dst(*dst); + SkAutoTUnref tempDevice(proxy->createDevice(dst->width(), dst->height())); if (!tempDevice) { return false; @@ -191,7 +191,7 @@ void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const void SkBlurImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst, MapDirection) const { *dst = src; - SkVector sigma = mapSigma(fSigma, ctm); + SkVector sigma = map_sigma(fSigma, ctm); dst->outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))), SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3)))); } @@ -211,15 +211,21 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const if (!srcBounds.intersect(dstBounds)) { return false; } - GrTexture* source = input.getTexture(); - SkVector sigma = mapSigma(fSigma, ctx.ctm()); + SkVector sigma = map_sigma(fSigma, ctx.ctm()); + if (sigma.x() == 0 && sigma.y() == 0) { + input.extractSubset(result, srcBounds); + offset->fX = srcBounds.x(); + offset->fY = srcBounds.y(); + return true; + } offset->fX = dstBounds.fLeft; offset->fY = dstBounds.fTop; srcBounds.offset(-srcOffset); dstBounds.offset(-srcOffset); SkRect srcBoundsF(SkRect::Make(srcBounds)); - SkAutoTUnref tex(SkGpuBlurUtils::GaussianBlur(source->getContext(), - source, + GrTexture* inputTexture = input.getTexture(); + SkAutoTUnref tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(), + inputTexture, false, SkRect::Make(dstBounds), &srcBoundsF,