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.
|
// May return nullptr if we haven't specialized the given Mode.
|
||||||
extern SkXfermode* (*create_xfermode)(const ProcCoeff&, SkXfermode::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;
|
extern BoxBlur box_blur_xx, box_blur_xy, box_blur_yx;
|
||||||
|
|
||||||
typedef void (*Morph)(const SkPMColor*, SkPMColor*, int, int, int, int, int);
|
typedef void (*Morph)(const SkPMColor*, SkPMColor*, int, int, int, int, int);
|
||||||
|
@ -82,7 +82,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkIRect srcBounds, dstBounds;
|
SkIRect srcBounds, dstBounds;
|
||||||
if (!this->applyCropRect(ctx, src, srcOffset, &dstBounds, &srcBounds)) {
|
if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,12 +91,13 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
|
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(srcBounds.width(), srcBounds.height()));
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*dst = device->accessBitmap(false);
|
*dst = device->accessBitmap(false);
|
||||||
SkAutoLockPixels alp_dst(*dst);
|
SkAutoLockPixels alp_dst(*dst);
|
||||||
|
dst->getBounds(&dstBounds);
|
||||||
|
|
||||||
SkVector sigma = mapSigma(fSigma, ctx.ctm());
|
SkVector sigma = mapSigma(fSigma, ctx.ctm());
|
||||||
|
|
||||||
@ -111,8 +112,8 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
|||||||
|
|
||||||
if (kernelSizeX == 0 && kernelSizeY == 0) {
|
if (kernelSizeX == 0 && kernelSizeY == 0) {
|
||||||
src.copyTo(dst, dst->colorType());
|
src.copyTo(dst, dst->colorType());
|
||||||
offset->fX = dstBounds.fLeft;
|
offset->fX = srcBounds.fLeft;
|
||||||
offset->fY = dstBounds.fTop;
|
offset->fY = srcBounds.fTop;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,16 +124,13 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
|||||||
SkBitmap temp = tempDevice->accessBitmap(false);
|
SkBitmap temp = tempDevice->accessBitmap(false);
|
||||||
SkAutoLockPixels alpTemp(temp);
|
SkAutoLockPixels alpTemp(temp);
|
||||||
|
|
||||||
offset->fX = dstBounds.fLeft;
|
offset->fX = srcBounds.fLeft;
|
||||||
offset->fY = dstBounds.fTop;
|
offset->fY = srcBounds.fTop;
|
||||||
|
srcBounds.offset(-srcOffset);
|
||||||
|
const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top());
|
||||||
SkPMColor* t = temp.getAddr32(0, 0);
|
SkPMColor* t = temp.getAddr32(0, 0);
|
||||||
SkPMColor* d = dst->getAddr32(0, 0);
|
SkPMColor* d = dst->getAddr32(0, 0);
|
||||||
int w = dstBounds.width(), h = dstBounds.height();
|
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();
|
int sw = src.rowBytesAsPixels();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,20 +152,20 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
|
|||||||
* images, and all memory reads are contiguous.
|
* images, and all memory reads are contiguous.
|
||||||
*/
|
*/
|
||||||
if (kernelSizeX > 0 && kernelSizeY > 0) {
|
if (kernelSizeX > 0 && kernelSizeY > 0) {
|
||||||
SkOpts::box_blur_xx(s, sw, srcBounds, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
|
SkOpts::box_blur_xx(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
|
||||||
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
|
SkOpts::box_blur_xx(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
|
||||||
SkOpts::box_blur_xy(d, w, dstBounds, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
|
SkOpts::box_blur_xy(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
|
||||||
SkOpts::box_blur_xx(t, h, dstBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
|
SkOpts::box_blur_xx(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
|
||||||
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
|
SkOpts::box_blur_xx(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
|
||||||
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
|
SkOpts::box_blur_xy(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
|
||||||
} else if (kernelSizeX > 0) {
|
} else if (kernelSizeX > 0) {
|
||||||
SkOpts::box_blur_xx(s, sw, srcBounds, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
|
SkOpts::box_blur_xx(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
|
||||||
SkOpts::box_blur_xx(d, w, dstBounds, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
|
SkOpts::box_blur_xx(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
|
||||||
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
|
SkOpts::box_blur_xx(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
|
||||||
} else if (kernelSizeY > 0) {
|
} else if (kernelSizeY > 0) {
|
||||||
SkOpts::box_blur_yx(s, sw, srcBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
|
SkOpts::box_blur_yx(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
|
||||||
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
|
SkOpts::box_blur_xx(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
|
||||||
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
|
SkOpts::box_blur_xy(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
|
||||||
}
|
}
|
||||||
return true;
|
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.
|
// Fast path for kernel sizes between 2 and 127, working on two rows at a time.
|
||||||
template<BlurDirection srcDirection, BlurDirection dstDirection>
|
template<BlurDirection srcDirection, BlurDirection dstDirection>
|
||||||
int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBounds, SkPMColor** dst, int kernelSize,
|
void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int kernelSize,
|
||||||
int leftOffset, int rightOffset, int width, int height) {
|
int leftOffset, int rightOffset, int width, int* height) {
|
||||||
// Load 2 pixels from adjacent rows.
|
// Load 2 pixels from adjacent rows.
|
||||||
auto load_2_pixels = [&](const SkPMColor* s) {
|
auto load_2_pixels = [&](const SkPMColor* s) {
|
||||||
if (srcDirection == BlurDirection::kX) {
|
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);
|
return vld1_u8((uint8_t*)s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
int left = srcBounds.left();
|
int incrementStart = SkMax32(-rightOffset - 1, -width);
|
||||||
int right = srcBounds.right();
|
int incrementEnd = SkMax32(width - rightOffset - 1, 0);
|
||||||
int top = srcBounds.top();
|
int decrementStart = SkMin32(leftOffset, width);
|
||||||
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 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 srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
|
||||||
const int dstStrideY = dstDirection == BlurDirection::kX ? width : 1;
|
const int dstStrideY = dstDirection == BlurDirection::kX ? width : 1;
|
||||||
const uint16x8_t scale = vdupq_n_u16((1 << 15) / kernelSize);
|
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);
|
uint16x8_t sum = vdupq_n_u16(0);
|
||||||
const SkPMColor* lptr = *src;
|
const SkPMColor* lptr = *src;
|
||||||
const SkPMColor* rptr = *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);
|
INCREMENT_SUMS_DOUBLE(rptr);
|
||||||
rptr += srcStrideX;
|
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) {
|
for (; x < decrementStart && x < incrementEnd; ++x) {
|
||||||
STORE_SUMS_DOUBLE
|
STORE_SUMS_DOUBLE
|
||||||
dptr += dstStrideX;
|
dptr += dstStrideX;
|
||||||
@ -147,22 +136,15 @@ int box_blur_double(const SkPMColor** src, int srcStride, const SkIRect& srcBoun
|
|||||||
STORE_SUMS_DOUBLE
|
STORE_SUMS_DOUBLE
|
||||||
dptr += dstStrideX;
|
dptr += dstStrideX;
|
||||||
}
|
}
|
||||||
for (; x < decrementEnd; ++x) {
|
for (; x < width; ++x) {
|
||||||
STORE_SUMS_DOUBLE
|
STORE_SUMS_DOUBLE
|
||||||
dptr += dstStrideX;
|
dptr += dstStrideX;
|
||||||
DECREMENT_SUMS_DOUBLE(lptr);
|
DECREMENT_SUMS_DOUBLE(lptr);
|
||||||
lptr += srcStrideX;
|
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;
|
*src += srcStrideY * 2;
|
||||||
*dst += dstStrideY * 2;
|
*dst += dstStrideY * 2;
|
||||||
}
|
}
|
||||||
return top;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARGB -> 0A0R 0G0B
|
// ARGB -> 0A0R 0G0B
|
||||||
@ -184,9 +166,8 @@ static inline uint16x4_t expand(SkPMColor p) {
|
|||||||
|
|
||||||
#define DOUBLE_ROW_OPTIMIZATION \
|
#define DOUBLE_ROW_OPTIMIZATION \
|
||||||
if (1 < kernelSize && kernelSize < 128) { \
|
if (1 < kernelSize && kernelSize < 128) { \
|
||||||
top = box_blur_double<srcDirection, dstDirection>(&src, srcStride, srcBounds, &dst, \
|
box_blur_double<srcDirection, dstDirection>(&src, srcStride, &dst, kernelSize, \
|
||||||
kernelSize, leftOffset, rightOffset, \
|
leftOffset, rightOffset, width, &height); \
|
||||||
width, height); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // Neither NEON nor >=SSE2.
|
#else // Neither NEON nor >=SSE2.
|
||||||
@ -219,16 +200,11 @@ static inline uint16x4_t expand(SkPMColor p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<BlurDirection srcDirection, BlurDirection dstDirection>
|
template<BlurDirection srcDirection, BlurDirection dstDirection>
|
||||||
static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBounds, SkPMColor* dst,
|
static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSize,
|
||||||
int kernelSize, int leftOffset, int rightOffset, int width, int height) {
|
int leftOffset, int rightOffset, int width, int height) {
|
||||||
int left = srcBounds.left();
|
int incrementStart = SkMax32(-rightOffset - 1, -width);
|
||||||
int right = srcBounds.right();
|
int incrementEnd = SkMax32(width - rightOffset - 1, 0);
|
||||||
int top = srcBounds.top();
|
int decrementStart = SkMin32(leftOffset, width);
|
||||||
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 srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride;
|
||||||
int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height;
|
int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height;
|
||||||
int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
|
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_SCALE
|
||||||
INIT_HALF
|
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
|
DOUBLE_ROW_OPTIMIZATION
|
||||||
|
|
||||||
for (int y = top; y < bottom; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
INIT_SUMS
|
INIT_SUMS
|
||||||
const SkPMColor* lptr = src;
|
const SkPMColor* lptr = src;
|
||||||
const SkPMColor* rptr = src;
|
const SkPMColor* rptr = src;
|
||||||
@ -259,11 +225,6 @@ static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBoun
|
|||||||
rptr += srcStrideX;
|
rptr += srcStrideX;
|
||||||
PREFETCH_RPTR
|
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) {
|
for (; x < decrementStart && x < incrementEnd; ++x) {
|
||||||
STORE_SUMS
|
STORE_SUMS
|
||||||
dptr += dstStrideX;
|
dptr += dstStrideX;
|
||||||
@ -284,29 +245,15 @@ static void box_blur(const SkPMColor* src, int srcStride, const SkIRect& srcBoun
|
|||||||
STORE_SUMS
|
STORE_SUMS
|
||||||
dptr += dstStrideX;
|
dptr += dstStrideX;
|
||||||
}
|
}
|
||||||
for (; x < decrementEnd; ++x) {
|
for (; x < width; ++x) {
|
||||||
STORE_SUMS
|
STORE_SUMS
|
||||||
dptr += dstStrideX;
|
dptr += dstStrideX;
|
||||||
DECREMENT_SUMS(*lptr);
|
DECREMENT_SUMS(*lptr);
|
||||||
lptr += srcStrideX;
|
lptr += srcStrideX;
|
||||||
}
|
}
|
||||||
// Clear to zero when sampling to the right of our domain.
|
|
||||||
for (; x < width; ++x) {
|
|
||||||
*dptr = 0;
|
|
||||||
dptr += dstStrideX;
|
|
||||||
}
|
|
||||||
src += srcStrideY;
|
src += srcStrideY;
|
||||||
dst += dstStrideY;
|
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>,
|
static auto box_blur_xx = &box_blur<BlurDirection::kX, BlurDirection::kX>,
|
||||||
|
Loading…
Reference in New Issue
Block a user