Fix gaussian blur for small sigma.
I broke this in https://skia.googlesource.com/skia/+/c57e0ded7d535523cfc6bf07c78e5f3479bb8c42. That change added support for cropping during blur, but did not do the correct thing for the small-sigma 2D matrix convolution optimization when blurring from small-to-large textures. The fix is pass the correct dstRect and srcOffset to convolve_gaussian_2d. I also changed convolve_gaussian_1d() and convolve_gaussian_2d() to take the original (non-negated) srcOffset, and to negate them when constructing the local matrix. Test: added a new (blur 0.3 0.3) column to imagefilterscropexpand, so that GM will have to be rebaselined. BUG=skia:4719,569883 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1529313003 Review URL: https://codereview.chromium.org/1529313003
This commit is contained in:
parent
70509762c8
commit
c834ab178e
@ -35,7 +35,7 @@ protected:
|
||||
return SkString("imagefilterscropexpand");
|
||||
}
|
||||
|
||||
SkISize onISize() override { return SkISize::Make(570, 650); }
|
||||
SkISize onISize() override { return SkISize::Make(650, 650); }
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkAutoTUnref<SkColorFilter> cf(
|
||||
@ -77,6 +77,9 @@ protected:
|
||||
Draw(canvas, checkerboard, rect, SkColorFilterImageFilter::Create(
|
||||
cfAlphaTrans, noopCropped.get(), &big_rect));
|
||||
|
||||
Draw(canvas, checkerboard, rect, SkBlurImageFilter::Create(
|
||||
0.3f, 0.3f, noopCropped.get(), &big_rect));
|
||||
|
||||
Draw(canvas, checkerboard, rect, SkBlurImageFilter::Create(
|
||||
8.0f, 8.0f, noopCropped.get(), &big_rect));
|
||||
|
||||
|
@ -60,21 +60,21 @@ static void convolve_gaussian_1d(GrDrawContext* drawContext,
|
||||
texture, direction, radius, sigma, useBounds, bounds));
|
||||
paint.addColorFragmentProcessor(conv);
|
||||
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
||||
SkMatrix localMatrix = SkMatrix::MakeTrans(srcOffset.x(), srcOffset.y());
|
||||
SkMatrix localMatrix = SkMatrix::MakeTrans(-srcOffset.x(), -srcOffset.y());
|
||||
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix);
|
||||
}
|
||||
|
||||
static void convolve_gaussian_2d(GrDrawContext* drawContext,
|
||||
const GrClip& clip,
|
||||
const SkRect& srcRect,
|
||||
const SkRect& dstRect,
|
||||
const SkPoint& srcOffset,
|
||||
GrTexture* texture,
|
||||
int radiusX,
|
||||
int radiusY,
|
||||
SkScalar sigmaX,
|
||||
SkScalar sigmaY,
|
||||
const SkRect* srcBounds) {
|
||||
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
|
||||
SkMatrix localMatrix = SkMatrix::MakeTrans(srcRect.x(), srcRect.y());
|
||||
SkMatrix localMatrix = SkMatrix::MakeTrans(-srcOffset.x(), -srcOffset.y());
|
||||
SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
|
||||
SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
|
||||
GrPaint paint;
|
||||
@ -148,15 +148,15 @@ static void convolve_gaussian(GrDrawContext* drawContext,
|
||||
}
|
||||
if (midRect.isEmpty()) {
|
||||
// Blur radius covers srcBounds; use bounds over entire draw
|
||||
convolve_gaussian_1d(drawContext, clip, dstRect, -srcOffset, texture,
|
||||
convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture,
|
||||
direction, radius, sigma, true, bounds);
|
||||
} else {
|
||||
// Draw right and left margins with bounds; middle without.
|
||||
convolve_gaussian_1d(drawContext, clip, leftRect, -srcOffset, texture,
|
||||
convolve_gaussian_1d(drawContext, clip, leftRect, srcOffset, texture,
|
||||
direction, radius, sigma, true, bounds);
|
||||
convolve_gaussian_1d(drawContext, clip, rightRect, -srcOffset, texture,
|
||||
convolve_gaussian_1d(drawContext, clip, rightRect, srcOffset, texture,
|
||||
direction, radius, sigma, true, bounds);
|
||||
convolve_gaussian_1d(drawContext, clip, midRect, -srcOffset, texture,
|
||||
convolve_gaussian_1d(drawContext, clip, midRect, srcOffset, texture,
|
||||
direction, radius, sigma, false, bounds);
|
||||
}
|
||||
}
|
||||
@ -269,6 +269,7 @@ GrTexture* GaussianBlur(GrContext* context,
|
||||
|
||||
// For really small blurs (certainly no wider than 5x5 on desktop gpus) it is faster to just
|
||||
// launch a single non separable kernel vs two launches
|
||||
srcRect = localDstBounds;
|
||||
if (sigmaX > 0.0f && sigmaY > 0.0f &&
|
||||
(2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
|
||||
// We shouldn't be scaling because this is a small size blur
|
||||
@ -279,7 +280,7 @@ GrTexture* GaussianBlur(GrContext* context,
|
||||
if (!dstDrawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
convolve_gaussian_2d(dstDrawContext, clip, srcRect,
|
||||
convolve_gaussian_2d(dstDrawContext, clip, srcRect, srcOffset,
|
||||
srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBounds);
|
||||
|
||||
srcDrawContext.swap(dstDrawContext);
|
||||
@ -288,7 +289,6 @@ GrTexture* GaussianBlur(GrContext* context,
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
|
||||
} else {
|
||||
srcRect = localDstBounds;
|
||||
scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
|
||||
srcRect.roundOut(&srcRect);
|
||||
const SkIRect srcIRect = srcRect.roundOut();
|
||||
|
Loading…
Reference in New Issue
Block a user