Revert of Make SkBlurImageFilter capable of cropping during blur (patchset #16 id:400001 of https://codereview.chromium.org/1415653003/ )

Reason for revert:
ASAN failures (see https://codereview.chromium.org/1415653003/)

Original issue's description:
> 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

TBR=mtklein@google.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:4502, skia:4526

Review URL: https://codereview.chromium.org/1428053002
This commit is contained in:
senorblanco 2015-11-02 11:56:18 -08:00 committed by Commit bot
parent 8c07b7ab53
commit 8de01c642c
3 changed files with 39 additions and 94 deletions

View File

@ -33,7 +33,7 @@ namespace SkOpts {
// May return nullptr if we haven't specialized the given Mode.
extern SkXfermode* (*create_xfermode)(const ProcCoeff&, SkXfermode::Mode);
typedef void (*BoxBlur)(const SkPMColor*, int, const SkIRect& srcBounds, SkPMColor*, int, int, int, int, int);
typedef void (*BoxBlur)(const SkPMColor*, int, SkPMColor*, int, int, int, int, int);
extern BoxBlur box_blur_xx, box_blur_xy, box_blur_yx;
typedef void (*Morph)(const SkPMColor*, SkPMColor*, int, int, int, int, int);

View File

@ -82,7 +82,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
}
SkIRect srcBounds, dstBounds;
if (!this->applyCropRect(ctx, src, srcOffset, &dstBounds, &srcBounds)) {
if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) {
return false;
}
@ -91,12 +91,13 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
return false;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(srcBounds.width(), srcBounds.height()));
if (!device) {
return false;
}
*dst = device->accessBitmap(false);
SkAutoLockPixels alp_dst(*dst);
dst->getBounds(&dstBounds);
SkVector sigma = mapSigma(fSigma, ctx.ctm());
@ -111,8 +112,8 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
if (kernelSizeX == 0 && kernelSizeY == 0) {
src.copyTo(dst, dst->colorType());
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
offset->fX = srcBounds.fLeft;
offset->fY = srcBounds.fTop;
return true;
}
@ -123,16 +124,13 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
SkBitmap temp = tempDevice->accessBitmap(false);
SkAutoLockPixels alpTemp(temp);
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
offset->fX = srcBounds.fLeft;
offset->fY = srcBounds.fTop;
srcBounds.offset(-srcOffset);
const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top());
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();
/**
@ -154,20 +152,20 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
* images, and all memory reads are contiguous.
*/
if (kernelSizeX > 0 && kernelSizeY > 0) {
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);
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);
} else if (kernelSizeX > 0) {
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);
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);
} else if (kernelSizeY > 0) {
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);
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);
}
return true;
}

View File

@ -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>
int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBounds, SkPMColor** dst, int kernelSize,
int leftOffset, int rightOffset, int width, int height) {
void box_blur_double(const SkPMColor** src, int srcStride, 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,21 +99,16 @@ int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBoun
return vld1_u8((uint8_t*)s);
}
};
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 incrementStart = SkMax32(-rightOffset - 1, -width);
int incrementEnd = SkMax32(width - rightOffset - 1, 0);
int decrementStart = SkMin32(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 (; bottom - top >= 2; top += 2) {
for (; *height >= 2; *height -= 2) {
uint16x8_t sum = vdupq_n_u16(0);
const SkPMColor* lptr = *src;
const SkPMColor* rptr = *src;
@ -123,12 +118,6 @@ int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBoun
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;
@ -147,22 +136,15 @@ int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBoun
STORE_SUMS_DOUBLE
dptr += dstStrideX;
}
for (; x < decrementEnd; ++x) {
for (; x < width; ++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
@ -184,9 +166,8 @@ static inline uint16x4_t expand(SkPMColor p) {
#define DOUBLE_ROW_OPTIMIZATION \
if (1 < kernelSize && kernelSize < 128) { \
top = box_blur_double<srcDirection, dstDirection>(&src, srcStride, srcBounds, &dst, \
kernelSize, leftOffset, rightOffset, \
width, height); \
box_blur_double<srcDirection, dstDirection>(&src, srcStride, &dst, kernelSize, \
leftOffset, rightOffset, width, &height); \
}
#else // Neither NEON nor >=SSE2.
@ -219,16 +200,11 @@ static inline uint16x4_t expand(SkPMColor p) {
}
template<BlurDirection srcDirection, BlurDirection dstDirection>
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);
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);
int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride;
int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height;
int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
@ -236,19 +212,9 @@ static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBoun
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 = top; y < bottom; ++y) {
for (int y = 0; y < height; ++y) {
INIT_SUMS
const SkPMColor* lptr = src;
const SkPMColor* rptr = src;
@ -259,11 +225,6 @@ static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBoun
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;
@ -284,29 +245,15 @@ static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBoun
STORE_SUMS
dptr += dstStrideX;
}
for (; x < decrementEnd; ++x) {
for (; x < width; ++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>,