Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Unified Diff: src/opts/SkBlurImageFilter_opts.h

Issue 1415653003: Make SkBlurImageFilter capable of cropping during blur (Closed) Base URL: senorblanco-linux.mon:src/skia@blur-applyCropRect4
Patch Set: More ASAN fixes Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/effects/SkBlurImageFilter.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/opts/SkBlurImageFilter_opts.h
diff --git a/src/opts/SkBlurImageFilter_opts.h b/src/opts/SkBlurImageFilter_opts.h
index 720130b1ecf032f303ee50bc67f3ed7ef365aa4a..8d22391b5fe1cbdd69b7082876657f2565c7bd8b 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, left - right);
+ 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,12 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int
INCREMENT_SUMS_DOUBLE(rptr);
rptr += srcStrideX;
}
+ // Clear to zero when sampling to the left our domain. "sum" is zero here because we
+ // initialized it above, and the preceeding loop has no effect in this case.
+ for (x = 0; x < incrementStart; ++x) {
+ STORE_SUMS_DOUBLE
+ dptr += dstStrideX;
+ }
for (; x < decrementStart && x < incrementEnd; ++x) {
STORE_SUMS_DOUBLE
dptr += dstStrideX;
@@ -136,15 +147,22 @@ 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;
}
+ // Clear to zero when sampling to the right of our domain. "sum" is zero here because we
+ // added on then subtracted off all of the pixels, leaving zero.
+ for (; x < width; ++x) {
+ STORE_SUMS_DOUBLE
+ dptr += dstStrideX;
+ }
*src += srcStrideY * 2;
*dst += dstStrideY * 2;
}
+ return top;
}
// ARGB -> 0A0R 0G0B
@@ -166,8 +184,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 +219,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, left - right);
+ 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 +236,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 +259,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 +284,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>,
« no previous file with comments | « src/effects/SkBlurImageFilter.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698