Chromium Code Reviews| Index: src/opts/SkBlurImageFilter_opts.h |
| diff --git a/src/opts/SkBlurImageFilter_opts.h b/src/opts/SkBlurImageFilter_opts.h |
| index 720130b1ecf032f303ee50bc67f3ed7ef365aa4a..4ecab6644e3e720763352746f5526d81536849e2 100644 |
| --- a/src/opts/SkBlurImageFilter_opts.h |
| +++ b/src/opts/SkBlurImageFilter_opts.h |
| @@ -84,8 +84,8 @@ static inline __m128i mullo_epi32(__m128i a, __m128i b) { |
| // Fast path for kernel sizes between 2 and 127, working on two rows at a time. |
| template<BlurDirection srcDirection, BlurDirection dstDirection> |
| -void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int kernelSize, |
| - int leftOffset, int rightOffset, int width, int* height) { |
| +int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBounds, SkPMColor** dst, int kernelSize, |
| + int leftOffset, int rightOffset, int width, int height) { |
| // Load 2 pixels from adjacent rows. |
| auto load_2_pixels = [&](const SkPMColor* s) { |
| if (srcDirection == BlurDirection::kX) { |
| @@ -99,16 +99,21 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int |
| return vld1_u8((uint8_t*)s); |
| } |
| }; |
| - int incrementStart = SkMax32(-rightOffset - 1, -width); |
| - int incrementEnd = SkMax32(width - rightOffset - 1, 0); |
| - int decrementStart = SkMin32(leftOffset, width); |
| + int left = srcBounds.left(); |
| + int right = srcBounds.right(); |
| + int top = srcBounds.top(); |
| + int bottom = srcBounds.bottom(); |
| + int incrementStart = SkMax32(left - rightOffset - 1, -width); |
| + int incrementEnd = SkMax32(right - rightOffset - 1, 0); |
| + int decrementStart = SkMin32(left + leftOffset, width); |
| + int decrementEnd = SkMin32(right + leftOffset, width); |
| const int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride; |
| - const int dstStrideX = dstDirection == BlurDirection::kX ? 1 : *height; |
| + const int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height; |
| const int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1; |
| const int dstStrideY = dstDirection == BlurDirection::kX ? width : 1; |
| const uint16x8_t scale = vdupq_n_u16((1 << 15) / kernelSize); |
| - for (; *height >= 2; *height -= 2) { |
| + for (; bottom - top >= 2; top += 2) { |
| uint16x8_t sum = vdupq_n_u16(0); |
| const SkPMColor* lptr = *src; |
| const SkPMColor* rptr = *src; |
| @@ -118,6 +123,10 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int |
| INCREMENT_SUMS_DOUBLE(rptr); |
| rptr += srcStrideX; |
| } |
| + for (x = 0; x < incrementStart; ++x) { |
| + STORE_SUMS_DOUBLE |
|
mtklein
2015/11/02 16:55:44
Should we not be zeroing here and at 155?
Stephen White
2015/11/02 17:08:58
We are: "sum" is always zero in both cases. It's z
|
| + dptr += dstStrideX; |
| + } |
| for (; x < decrementStart && x < incrementEnd; ++x) { |
| STORE_SUMS_DOUBLE |
| dptr += dstStrideX; |
| @@ -136,15 +145,20 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int |
| STORE_SUMS_DOUBLE |
| dptr += dstStrideX; |
| } |
| - for (; x < width; ++x) { |
| + for (; x < decrementEnd; ++x) { |
| STORE_SUMS_DOUBLE |
| dptr += dstStrideX; |
| DECREMENT_SUMS_DOUBLE(lptr); |
| lptr += srcStrideX; |
| } |
| + for (; x < width; ++x) { |
| + STORE_SUMS_DOUBLE |
| + dptr += dstStrideX; |
| + } |
| *src += srcStrideY * 2; |
| *dst += dstStrideY * 2; |
| } |
| + return top; |
| } |
| // ARGB -> 0A0R 0G0B |
| @@ -166,8 +180,9 @@ static inline uint16x4_t expand(SkPMColor p) { |
| #define DOUBLE_ROW_OPTIMIZATION \ |
| if (1 < kernelSize && kernelSize < 128) { \ |
| - box_blur_double<srcDirection, dstDirection>(&src, srcStride, &dst, kernelSize, \ |
| - leftOffset, rightOffset, width, &height); \ |
| + top = box_blur_double<srcDirection, dstDirection>(&src, srcStride, srcBounds, &dst, \ |
| + kernelSize, leftOffset, rightOffset, \ |
| + width, height); \ |
| } |
| #else // Neither NEON nor >=SSE2. |
| @@ -200,11 +215,16 @@ static inline uint16x4_t expand(SkPMColor p) { |
| } |
| template<BlurDirection srcDirection, BlurDirection dstDirection> |
| -static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSize, |
| - int leftOffset, int rightOffset, int width, int height) { |
| - int incrementStart = SkMax32(-rightOffset - 1, -width); |
| - int incrementEnd = SkMax32(width - rightOffset - 1, 0); |
| - int decrementStart = SkMin32(leftOffset, width); |
| +static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBounds, SkPMColor* dst, |
| + int kernelSize, int leftOffset, int rightOffset, int width, int height) { |
| + int left = srcBounds.left(); |
| + int right = srcBounds.right(); |
| + int top = srcBounds.top(); |
| + int bottom = srcBounds.bottom(); |
| + int incrementStart = SkMax32(left - rightOffset - 1, -width); |
| + int incrementEnd = SkMax32(right - rightOffset - 1, 0); |
| + int decrementStart = SkMin32(left + leftOffset, width); |
| + int decrementEnd = SkMin32(right + leftOffset, width); |
| int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride; |
| int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height; |
| int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1; |
| @@ -212,9 +232,19 @@ static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int ke |
| INIT_SCALE |
| INIT_HALF |
| + // Clear to zero when sampling above our domain. |
| + for (int y = 0; y < top; y++) { |
| + SkColor* dptr = dst; |
| + for (int x = 0; x < width; ++x) { |
| + *dptr = 0; |
| + dptr += dstStrideX; |
| + } |
| + dst += dstStrideY; |
| + } |
| + |
| DOUBLE_ROW_OPTIMIZATION |
| - for (int y = 0; y < height; ++y) { |
| + for (int y = top; y < bottom; ++y) { |
| INIT_SUMS |
| const SkPMColor* lptr = src; |
| const SkPMColor* rptr = src; |
| @@ -225,6 +255,11 @@ static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int ke |
| rptr += srcStrideX; |
| PREFETCH_RPTR |
| } |
| + // Clear to zero when sampling to the left of our domain. |
| + for (x = 0; x < incrementStart; ++x) { |
| + *dptr = 0; |
| + dptr += dstStrideX; |
| + } |
| for (; x < decrementStart && x < incrementEnd; ++x) { |
| STORE_SUMS |
| dptr += dstStrideX; |
| @@ -245,15 +280,29 @@ static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int ke |
| STORE_SUMS |
| dptr += dstStrideX; |
| } |
| - for (; x < width; ++x) { |
| + for (; x < decrementEnd; ++x) { |
| STORE_SUMS |
| dptr += dstStrideX; |
| DECREMENT_SUMS(*lptr); |
| lptr += srcStrideX; |
| } |
| + // Clear to zero when sampling to the right of our domain. |
| + for (; x < width; ++x) { |
| + *dptr = 0; |
| + dptr += dstStrideX; |
| + } |
| src += srcStrideY; |
| dst += dstStrideY; |
| } |
| + // Clear to zero when sampling below our domain. |
| + for (int y = bottom; y < height; ++y) { |
| + SkColor* dptr = dst; |
| + for (int x = 0; x < width; ++x) { |
| + *dptr = 0; |
| + dptr += dstStrideX; |
| + } |
| + dst += dstStrideY; |
| + } |
| } |
| static auto box_blur_xx = &box_blur<BlurDirection::kX, BlurDirection::kX>, |