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

Side by Side Diff: src/effects/SkGpuBlurUtils.cpp

Issue 418223009: 2D kernel initial wiring for Guassian (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: feedback inc Created 6 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 unified diff | Download patch
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"
11 11
12 #if SK_SUPPORT_GPU 12 #if SK_SUPPORT_GPU
13 #include "effects/GrConvolutionEffect.h" 13 #include "effects/GrConvolutionEffect.h"
14 #include "effects/GrMatrixConvolutionEffect.h"
14 #include "effects/GrTextureDomain.h" 15 #include "effects/GrTextureDomain.h"
15 #include "GrContext.h" 16 #include "GrContext.h"
16 #endif 17 #endif
17 18
18 namespace SkGpuBlurUtils { 19 namespace SkGpuBlurUtils {
19 20
20 #if SK_SUPPORT_GPU 21 #if SK_SUPPORT_GPU
21 22
22 #define MAX_BLUR_SIGMA 4.0f 23 #define MAX_BLUR_SIGMA 4.0f
23 24
(...skipping 30 matching lines...) Expand all
54 float bounds[2]) { 55 float bounds[2]) {
55 GrPaint paint; 56 GrPaint paint;
56 paint.reset(); 57 paint.reset();
57 SkAutoTUnref<GrEffect> conv(GrConvolutionEffect::CreateGaussian( 58 SkAutoTUnref<GrEffect> conv(GrConvolutionEffect::CreateGaussian(
58 texture, direction, radius, sigma, useBounds, bounds)); 59 texture, direction, radius, sigma, useBounds, bounds));
59 paint.reset(); 60 paint.reset();
60 paint.addColorEffect(conv); 61 paint.addColorEffect(conv);
61 context->drawRectToRect(paint, dstRect, srcRect); 62 context->drawRectToRect(paint, dstRect, srcRect);
62 } 63 }
63 64
65 // a 2d gaussian convolution pass
bsalomon 2014/07/28 15:20:41 Maybe we should give both these functions symmetri
66 static void convolve_gaussian_pass(GrContext* context,
67 const SkRect& srcRect,
68 const SkRect& dstRect,
69 GrTexture* texture,
70 int radiusX,
71 int radiusY,
72 SkScalar sigmaX,
73 SkScalar sigmaY,
74 bool useBounds,
75 SkIRect bounds) {
76 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
77 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
78 GrPaint paint;
79 paint.reset();
80 SkAutoTUnref<GrEffect> conv(GrMatrixConvolutionEffect::CreateGaussian(
81 texture, bounds, size, 1.0, 0.0, kernelOffset, GrMatrixConvolutionEffect ::kClamp_TileMode,
82 true, useBounds, sigmaX, sigmaY));
83 paint.reset();
84 paint.addColorEffect(conv);
85 context->drawRectToRect(paint, dstRect, srcRect);
86 }
87
64 static void convolve_gaussian(GrContext* context, 88 static void convolve_gaussian(GrContext* context,
65 const SkRect& srcRect, 89 const SkRect& srcRect,
66 const SkRect& dstRect, 90 const SkRect& dstRect,
67 GrTexture* texture, 91 GrTexture* texture,
68 Gr1DKernelEffect::Direction direction, 92 Gr1DKernelEffect::Direction direction,
69 int radius, 93 int radius,
70 float sigma, 94 float sigma,
71 bool cropToSrcRect) { 95 bool cropToSrcRect) {
72 float bounds[2] = { 0.0f, 1.0f }; 96 float bounds[2] = { 0.0f, 1.0f };
73 if (!cropToSrcRect) { 97 if (!cropToSrcRect) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 i < scaleFactorY ? 0.5f : 1.0f); 213 i < scaleFactorY ? 0.5f : 1.0f);
190 context->drawRectToRect(paint, dstRect, srcRect); 214 context->drawRectToRect(paint, dstRect, srcRect);
191 srcRect = dstRect; 215 srcRect = dstRect;
192 srcTexture = dstTexture; 216 srcTexture = dstTexture;
193 SkTSwap(dstTexture, tempTexture); 217 SkTSwap(dstTexture, tempTexture);
194 } 218 }
195 219
196 SkIRect srcIRect; 220 SkIRect srcIRect;
197 srcRect.roundOut(&srcIRect); 221 srcRect.roundOut(&srcIRect);
198 222
199 if (sigmaX > 0.0f) { 223 // if square, and small than do one pass instead of 2, actually small rectan gular blocks
224 // are okay too but for simplicity only handle the square case for now
bsalomon 2014/07/28 15:20:41 is the squareness enforced here?
225 if (sigmaX > 0.0f && sigmaY > 0 &&
226 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
200 if (scaleFactorX > 1) { 227 if (scaleFactorX > 1) {
201 // Clear out a radius to the right of the srcRect to prevent the 228 // Clear out a radius to the right of the srcRect to prevent the
202 // X convolution from reading garbage. 229 // X convolution from reading garbage.
203 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 230 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
204 radiusX, srcIRect.height()); 231 radiusX, srcIRect.height());
205 context->clear(&clearRect, 0x0, false); 232 context->clear(&clearRect, 0x0, false);
206 } 233 }
207 context->setRenderTarget(dstTexture->asRenderTarget()); 234 if (scaleFactorY > 1) {
bsalomon 2014/07/28 15:20:41 Can we get here with scaleFactorY > 1? I thought t
208 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
209 convolve_gaussian(context, srcRect, dstRect, srcTexture,
210 Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropT oRect);
211 srcTexture = dstTexture;
212 srcRect = dstRect;
213 SkTSwap(dstTexture, tempTexture);
214 }
215
216 if (sigmaY > 0.0f) {
217 if (scaleFactorY > 1 || sigmaX > 0.0f) {
218 // Clear out a radius below the srcRect to prevent the Y 235 // Clear out a radius below the srcRect to prevent the Y
219 // convolution from reading garbage. 236 // convolution from reading garbage.
220 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 237 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
221 srcIRect.width(), radiusY); 238 srcIRect.width(), radiusY);
222 context->clear(&clearRect, 0x0, false); 239 context->clear(&clearRect, 0x0, false);
223 } 240 }
224
225 context->setRenderTarget(dstTexture->asRenderTarget()); 241 context->setRenderTarget(dstTexture->asRenderTarget());
226 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 242 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
227 convolve_gaussian(context, srcRect, dstRect, srcTexture, 243 // TODO we have a ton of perf verification to do here, but its an open q uestion if we should
228 Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropT oRect); 244 // do 4 draw calls with bounds then 1 without, or 1 with bounds, or just fall back to
245 // separable when we have to crop to src rect
246 convolve_gaussian_pass(context, srcRect, dstRect, srcTexture,
247 radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect );
229 srcTexture = dstTexture; 248 srcTexture = dstTexture;
230 srcRect = dstRect; 249 srcRect = dstRect;
231 SkTSwap(dstTexture, tempTexture); 250 SkTSwap(dstTexture, tempTexture);
232 } 251 }
252 else {
bsalomon 2014/07/28 15:20:41 style nit, else goes with }
253 if (sigmaX > 0.0f) {
254 if (scaleFactorX > 1) {
255 // Clear out a radius to the right of the srcRect to prevent the
256 // X convolution from reading garbage.
257 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
258 radiusX, srcIRect.height());
259 context->clear(&clearRect, 0x0, false);
260 }
261 context->setRenderTarget(dstTexture->asRenderTarget());
262 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
263 convolve_gaussian(context, srcRect, dstRect, srcTexture,
264 Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, c ropToRect);
265 srcTexture = dstTexture;
266 srcRect = dstRect;
267 SkTSwap(dstTexture, tempTexture);
268 }
269
270 if (sigmaY > 0.0f) {
271 if (scaleFactorY > 1 || sigmaX > 0.0f) {
272 // Clear out a radius below the srcRect to prevent the Y
273 // convolution from reading garbage.
274 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
275 srcIRect.width(), radiusY);
276 context->clear(&clearRect, 0x0, false);
277 }
278
279 context->setRenderTarget(dstTexture->asRenderTarget());
280 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
281 convolve_gaussian(context, srcRect, dstRect, srcTexture,
282 Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, c ropToRect);
283 srcTexture = dstTexture;
284 srcRect = dstRect;
285 SkTSwap(dstTexture, tempTexture);
286 }
287 }
233 288
234 if (scaleFactorX > 1 || scaleFactorY > 1) { 289 if (scaleFactorX > 1 || scaleFactorY > 1) {
235 // Clear one pixel to the right and below, to accommodate bilinear 290 // Clear one pixel to the right and below, to accommodate bilinear
236 // upsampling. 291 // upsampling.
237 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 292 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
238 srcIRect.width() + 1, 1); 293 srcIRect.width() + 1, 1);
239 context->clear(&clearRect, 0x0, false); 294 context->clear(&clearRect, 0x0, false);
240 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 295 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
241 1, srcIRect.height()); 296 1, srcIRect.height());
242 context->clear(&clearRect, 0x0, false); 297 context->clear(&clearRect, 0x0, false);
(...skipping 18 matching lines...) Expand all
261 } else if (srcTexture == temp2.texture()) { 316 } else if (srcTexture == temp2.texture()) {
262 return temp2.detach(); 317 return temp2.detach();
263 } else { 318 } else {
264 srcTexture->ref(); 319 srcTexture->ref();
265 return srcTexture; 320 return srcTexture;
266 } 321 }
267 } 322 }
268 #endif 323 #endif
269 324
270 } 325 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698