aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/SkBlurImageFilter.cpp
diff options
context:
space:
mode:
authorGravatar senorblanco <senorblanco@chromium.org>2015-11-02 12:55:47 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-11-02 12:55:47 -0800
commit29a440d2d6f306498a7b54e978e3b034bd625c19 (patch)
tree91146ce2aaf66d90a716f2d583ded6ab79252746 /src/effects/SkBlurImageFilter.cpp
parent9c58654fa27d85f51f54e904fbfa4e250921c261 (diff)
Make SkBlurImageFilter capable of cropping during blur (raster path)
SkBlurImageFilter can currently only process a source image which is larger than or equal to the destination rect. If the source image (or crop rect) is smaller, it is padded out to dest size with transparent black via the 6-param version of applyCropRect(). Fixing this requires modifying all the flavours of RGBA box_blur() to accept a src crop rect. BUG=skia:4502, skia:4526 CQ_EXTRA_TRYBOTS=client.skia.android:Test-Android-GCC-Nexus5-CPU-NEON-Arm7-Release-Trybot;client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot Committed: https://skia.googlesource.com/skia/+/1b82ceb737c73327412f2e8a91748481e1aec9e4 Review URL: https://codereview.chromium.org/1415653003
Diffstat (limited to 'src/effects/SkBlurImageFilter.cpp')
-rw-r--r--src/effects/SkBlurImageFilter.cpp44
1 files changed, 23 insertions, 21 deletions
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index c77a444da5..3f4c852c12 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -82,7 +82,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
}
SkIRect srcBounds, dstBounds;
- if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) {
+ if (!this->applyCropRect(ctx, src, srcOffset, &dstBounds, &srcBounds)) {
return false;
}
@@ -91,13 +91,12 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
return false;
}
- SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(srcBounds.width(), srcBounds.height()));
+ SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
if (!device) {
return false;
}
*dst = device->accessBitmap(false);
SkAutoLockPixels alp_dst(*dst);
- dst->getBounds(&dstBounds);
SkVector sigma = mapSigma(fSigma, ctx.ctm());
@@ -112,8 +111,8 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
if (kernelSizeX == 0 && kernelSizeY == 0) {
src.copyTo(dst, dst->colorType());
- offset->fX = srcBounds.fLeft;
- offset->fY = srcBounds.fTop;
+ offset->fX = dstBounds.x() + srcOffset.x();
+ offset->fY = dstBounds.y() + srcOffset.y();
return true;
}
@@ -124,13 +123,16 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
SkBitmap temp = tempDevice->accessBitmap(false);
SkAutoLockPixels alpTemp(temp);
- offset->fX = srcBounds.fLeft;
- offset->fY = srcBounds.fTop;
- srcBounds.offset(-srcOffset);
- const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top());
+ offset->fX = dstBounds.fLeft;
+ offset->fY = dstBounds.fTop;
SkPMColor* t = temp.getAddr32(0, 0);
SkPMColor* d = dst->getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
+ const SkPMColor* s = src.getAddr32(srcBounds.x() - srcOffset.x(), srcBounds.y() - srcOffset.y());
+ srcBounds.offset(-dstBounds.x(), -dstBounds.y());
+ dstBounds.offset(-dstBounds.x(), -dstBounds.y());
+ SkIRect srcBoundsT = SkIRect::MakeLTRB(srcBounds.top(), srcBounds.left(), srcBounds.bottom(), srcBounds.right());
+ SkIRect dstBoundsT = SkIRect::MakeWH(dstBounds.height(), dstBounds.width());
int sw = src.rowBytesAsPixels();
/**
@@ -152,20 +154,20 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
* images, and all memory reads are contiguous.
*/
if (kernelSizeX > 0 && kernelSizeY > 0) {
- SkOpts::box_blur_xx(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
- SkOpts::box_blur_xx(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
- SkOpts::box_blur_xy(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
- SkOpts::box_blur_xx(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
- SkOpts::box_blur_xx(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
- SkOpts::box_blur_xy(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
+ SkOpts::box_blur_xx(s, sw, srcBounds, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
+ SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
+ SkOpts::box_blur_xy(d, w, dstBounds, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
+ SkOpts::box_blur_xx(t, h, dstBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
+ SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
+ SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
} else if (kernelSizeX > 0) {
- SkOpts::box_blur_xx(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
- SkOpts::box_blur_xx(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
- SkOpts::box_blur_xx(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
+ SkOpts::box_blur_xx(s, sw, srcBounds, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
+ SkOpts::box_blur_xx(d, w, dstBounds, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
+ SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
} else if (kernelSizeY > 0) {
- SkOpts::box_blur_yx(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
- SkOpts::box_blur_xx(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
- SkOpts::box_blur_xy(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
+ SkOpts::box_blur_yx(s, sw, srcBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
+ SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
+ SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
}
return true;
}