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

Side by Side 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, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkGpuBlurUtils.h" 8 #include "SkGpuBlurUtils.h"
9 9
10 #include "SkRect.h" 10 #include "SkRect.h"
(...skipping 22 matching lines...) Expand all
33 while (sigma > MAX_BLUR_SIGMA) { 33 while (sigma > MAX_BLUR_SIGMA) {
34 *scaleFactor *= 2; 34 *scaleFactor *= 2;
35 sigma *= 0.5f; 35 sigma *= 0.5f;
36 } 36 }
37 *radius = static_cast<int>(ceilf(sigma * 3.0f)); 37 *radius = static_cast<int>(ceilf(sigma * 3.0f));
38 GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius); 38 GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius);
39 return sigma; 39 return sigma;
40 } 40 }
41 41
42 static void convolve_gaussian(GrContext* context, 42 static void convolve_gaussian(GrContext* context,
43 GrTexture* texture,
44 const SkRect& srcRect, 43 const SkRect& srcRect,
45 const SkRect& dstRect, 44 const SkRect& dstRect,
46 bool cropToSrcRect, 45 GrTexture* texture,
46 Gr1DKernelEffect::Direction direction,
47 int radius,
47 float sigma, 48 float sigma,
48 int radius, 49 bool useBounds,
49 Gr1DKernelEffect::Direction direction) { 50 float bounds[2]) {
50 GrPaint paint; 51 GrPaint paint;
51 paint.reset(); 52 paint.reset();
52 float bounds[2] = { 0.0f, 1.0f }; 53 SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(
53 if (cropToSrcRect) { 54 texture, direction, radius, sigma, useBounds, bounds));
54 if (direction == Gr1DKernelEffect::kX_Direction) { 55 paint.reset();
55 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
56 bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width();
57 } else {
58 bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height();
59 bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height();
60 }
61 }
62
63 SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture,
64 direction ,
65 radius,
66 sigma,
67 cropToSrc Rect,
68 bounds));
69 paint.addColorEffect(conv); 56 paint.addColorEffect(conv);
70 context->drawRectToRect(paint, dstRect, srcRect); 57 context->drawRectToRect(paint, dstRect, srcRect);
71 } 58 }
72 59
60 static void convolve_gaussian(GrContext* context,
61 const SkRect& srcRect,
62 const SkRect& dstRect,
63 GrTexture* texture,
64 Gr1DKernelEffect::Direction direction,
65 int radius,
66 float sigma,
67 bool cropToSrcRect) {
68 float bounds[2] = { 0.0f, 1.0f };
69 if (!cropToSrcRect) {
70 convolve_gaussian(context, srcRect, dstRect, texture,
71 direction, radius, sigma, false, bounds);
72 return;
73 }
74 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
75 SkRect middleSrcRect = srcRect, middleDstRect = dstRect;
76 SkRect upperSrcRect = srcRect, upperDstRect = dstRect;
77 SkScalar size;
78 SkScalar rad = SkIntToScalar(radius);
79 if (direction == Gr1DKernelEffect::kX_Direction) {
80 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
81 bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width();
82 size = srcRect.width();
83 lowerSrcRect.fRight = srcRect.left() + rad;
84 lowerDstRect.fRight = dstRect.left() + rad;
85 upperSrcRect.fLeft = srcRect.right() - rad;
86 upperDstRect.fLeft = dstRect.right() - rad;
87 middleSrcRect.inset(rad, 0);
88 middleDstRect.inset(rad, 0);
89 } else {
90 bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height();
91 bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height();
92 size = srcRect.height();
93 lowerSrcRect.fBottom = srcRect.top() + rad;
94 lowerDstRect.fBottom = dstRect.top() + rad;
95 upperSrcRect.fTop = srcRect.bottom() - rad;
96 upperDstRect.fTop = dstRect.bottom() - rad;
97 middleSrcRect.inset(0, rad);
98 middleDstRect.inset(0, rad);
99 }
100 if (radius >= size * SK_ScalarHalf) {
101 // Blur radius covers srcRect; use bounds over entire draw
102 convolve_gaussian(context, srcRect, dstRect, texture,
103 direction, radius, sigma, true, bounds);
104 } else {
105 // Draw upper and lower margins with bounds; middle without.
106 convolve_gaussian(context, lowerSrcRect, lowerDstRect, texture,
107 direction, radius, sigma, true, bounds);
108 convolve_gaussian(context, upperSrcRect, upperDstRect, texture,
109 direction, radius, sigma, true, bounds);
110 convolve_gaussian(context, middleSrcRect, middleDstRect, texture,
111 direction, radius, sigma, false, bounds);
112 }
113 }
114
73 GrTexture* GaussianBlur(GrContext* context, 115 GrTexture* GaussianBlur(GrContext* context,
74 GrTexture* srcTexture, 116 GrTexture* srcTexture,
75 bool canClobberSrc, 117 bool canClobberSrc,
76 const SkRect& rect, 118 const SkRect& rect,
77 bool cropToRect, 119 bool cropToRect,
78 float sigmaX, 120 float sigmaX,
79 float sigmaY) { 121 float sigmaY) {
80 GrAssert(NULL != context); 122 GrAssert(NULL != context);
81 123
82 GrContext::AutoRenderTarget art(context); 124 GrContext::AutoRenderTarget art(context);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 if (sigmaX > 0.0f) { 194 if (sigmaX > 0.0f) {
153 if (scaleFactorX > 1) { 195 if (scaleFactorX > 1) {
154 // Clear out a radius to the right of the srcRect to prevent the 196 // Clear out a radius to the right of the srcRect to prevent the
155 // X convolution from reading garbage. 197 // X convolution from reading garbage.
156 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 198 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
157 radiusX, srcIRect.height()); 199 radiusX, srcIRect.height());
158 context->clear(&clearRect, 0x0); 200 context->clear(&clearRect, 0x0);
159 } 201 }
160 context->setRenderTarget(dstTexture->asRenderTarget()); 202 context->setRenderTarget(dstTexture->asRenderTarget());
161 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 203 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
162 convolve_gaussian(context, srcTexture, srcRect, dstRect, cropToRect, 204 convolve_gaussian(context, srcRect, dstRect, srcTexture,
163 sigmaX, radiusX, Gr1DKernelEffect::kX_Direction); 205 Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropT oRect);
164 srcTexture = dstTexture; 206 srcTexture = dstTexture;
165 srcRect = dstRect; 207 srcRect = dstRect;
166 SkTSwap(dstTexture, tempTexture); 208 SkTSwap(dstTexture, tempTexture);
167 } 209 }
168 210
169 if (sigmaY > 0.0f) { 211 if (sigmaY > 0.0f) {
170 if (scaleFactorY > 1 || sigmaX > 0.0f) { 212 if (scaleFactorY > 1 || sigmaX > 0.0f) {
171 // Clear out a radius below the srcRect to prevent the Y 213 // Clear out a radius below the srcRect to prevent the Y
172 // convolution from reading garbage. 214 // convolution from reading garbage.
173 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 215 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
174 srcIRect.width(), radiusY); 216 srcIRect.width(), radiusY);
175 context->clear(&clearRect, 0x0); 217 context->clear(&clearRect, 0x0);
176 } 218 }
177 219
178 context->setRenderTarget(dstTexture->asRenderTarget()); 220 context->setRenderTarget(dstTexture->asRenderTarget());
179 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 221 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
180 convolve_gaussian(context, srcTexture, srcRect, dstRect, cropToRect, 222 convolve_gaussian(context, srcRect, dstRect, srcTexture,
181 sigmaY, radiusY, Gr1DKernelEffect::kY_Direction); 223 Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropT oRect);
182 srcTexture = dstTexture; 224 srcTexture = dstTexture;
183 srcRect = dstRect; 225 srcRect = dstRect;
184 SkTSwap(dstTexture, tempTexture); 226 SkTSwap(dstTexture, tempTexture);
185 } 227 }
186 228
187 if (scaleFactorX > 1 || scaleFactorY > 1) { 229 if (scaleFactorX > 1 || scaleFactorY > 1) {
188 // Clear one pixel to the right and below, to accommodate bilinear 230 // Clear one pixel to the right and below, to accommodate bilinear
189 // upsampling. 231 // upsampling.
190 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 232 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
191 srcIRect.width() + 1, 1); 233 srcIRect.width() + 1, 1);
(...skipping 22 matching lines...) Expand all
214 } else if (srcTexture == temp2.texture()) { 256 } else if (srcTexture == temp2.texture()) {
215 return temp2.detach(); 257 return temp2.detach();
216 } else { 258 } else {
217 srcTexture->ref(); 259 srcTexture->ref();
218 return srcTexture; 260 return srcTexture;
219 } 261 }
220 } 262 }
221 #endif 263 #endif
222 264
223 } 265 }
OLDNEW
« 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