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:
parent
8c07b7ab53
commit
8de01c642c
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>,
|
||||
|
Loading…
Reference in New Issue
Block a user