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

Unified Diff: src/effects/SkGpuBlurUtils.cpp

Issue 21224003: Optimize the blur convolution by only applying domain clamping where necessary. Split the blur con… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Win32 fixes: SkScalar correctness. Created 7 years, 5 months 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/SkGpuBlurUtils.cpp
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
index 28ccd4589b327712169647bb6933dc1217299db8..f45ba353d423b1aed872bf186a35e1ede5ef8722 100644
--- a/src/effects/SkGpuBlurUtils.cpp
+++ b/src/effects/SkGpuBlurUtils.cpp
@@ -40,36 +40,78 @@ static float adjust_sigma(float sigma, int *scaleFactor, int *radius) {
}
static void convolve_gaussian(GrContext* context,
- GrTexture* texture,
const SkRect& srcRect,
const SkRect& dstRect,
- bool cropToSrcRect,
- float sigma,
+ GrTexture* texture,
+ Gr1DKernelEffect::Direction direction,
int radius,
- Gr1DKernelEffect::Direction direction) {
+ float sigma,
+ bool useBounds,
+ float bounds[2]) {
GrPaint paint;
paint.reset();
- float bounds[2] = { 0.0f, 1.0f };
- if (cropToSrcRect) {
- if (direction == Gr1DKernelEffect::kX_Direction) {
- bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
- bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width();
- } else {
- bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height();
- bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height();
- }
- }
-
- SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture,
- direction,
- radius,
- sigma,
- cropToSrcRect,
- bounds));
+ SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(
+ texture, direction, radius, sigma, useBounds, bounds));
+ paint.reset();
paint.addColorEffect(conv);
context->drawRectToRect(paint, dstRect, srcRect);
}
+static void convolve_gaussian(GrContext* context,
+ const SkRect& srcRect,
+ const SkRect& dstRect,
+ GrTexture* texture,
+ Gr1DKernelEffect::Direction direction,
+ int radius,
+ float sigma,
+ bool cropToSrcRect) {
+ float bounds[2] = { 0.0f, 1.0f };
+ if (!cropToSrcRect) {
+ convolve_gaussian(context, srcRect, dstRect, texture,
+ direction, radius, sigma, false, bounds);
+ return;
+ }
+ SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
+ SkRect middleSrcRect = srcRect, middleDstRect = dstRect;
+ SkRect upperSrcRect = srcRect, upperDstRect = dstRect;
+ SkScalar size;
+ SkScalar rad = SkIntToScalar(radius);
+ if (direction == Gr1DKernelEffect::kX_Direction) {
+ bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
+ bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width();
+ size = srcRect.width();
+ lowerSrcRect.fRight = srcRect.left() + rad;
+ lowerDstRect.fRight = dstRect.left() + rad;
+ upperSrcRect.fLeft = srcRect.right() - rad;
+ upperDstRect.fLeft = dstRect.right() - rad;
+ middleSrcRect.inset(rad, 0);
+ middleDstRect.inset(rad, 0);
+ } else {
+ bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height();
+ bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height();
+ size = srcRect.height();
+ lowerSrcRect.fBottom = srcRect.top() + rad;
+ lowerDstRect.fBottom = dstRect.top() + rad;
+ upperSrcRect.fTop = srcRect.bottom() - rad;
+ upperDstRect.fTop = dstRect.bottom() - rad;
+ middleSrcRect.inset(0, rad);
+ middleDstRect.inset(0, rad);
+ }
+ if (radius >= size * SK_ScalarHalf) {
+ // Blur radius covers srcRect; use bounds over entire draw
+ convolve_gaussian(context, srcRect, dstRect, texture,
+ direction, radius, sigma, true, bounds);
+ } else {
+ // Draw upper and lower margins with bounds; middle without.
+ convolve_gaussian(context, lowerSrcRect, lowerDstRect, texture,
+ direction, radius, sigma, true, bounds);
+ convolve_gaussian(context, upperSrcRect, upperDstRect, texture,
+ direction, radius, sigma, true, bounds);
+ convolve_gaussian(context, middleSrcRect, middleDstRect, texture,
+ direction, radius, sigma, false, bounds);
+ }
+}
+
GrTexture* GaussianBlur(GrContext* context,
GrTexture* srcTexture,
bool canClobberSrc,
@@ -159,8 +201,8 @@ GrTexture* GaussianBlur(GrContext* context,
}
context->setRenderTarget(dstTexture->asRenderTarget());
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
- convolve_gaussian(context, srcTexture, srcRect, dstRect, cropToRect,
- sigmaX, radiusX, Gr1DKernelEffect::kX_Direction);
+ convolve_gaussian(context, srcRect, dstRect, srcTexture,
+ Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropToRect);
srcTexture = dstTexture;
srcRect = dstRect;
SkTSwap(dstTexture, tempTexture);
@@ -177,8 +219,8 @@ GrTexture* GaussianBlur(GrContext* context,
context->setRenderTarget(dstTexture->asRenderTarget());
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
- convolve_gaussian(context, srcTexture, srcRect, dstRect, cropToRect,
- sigmaY, radiusY, Gr1DKernelEffect::kY_Direction);
+ convolve_gaussian(context, srcRect, dstRect, srcTexture,
+ Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropToRect);
srcTexture = dstTexture;
srcRect = dstRect;
SkTSwap(dstTexture, tempTexture);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698