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

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

Issue 1430593006: Simplify SkGpuBlurUtils. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: More cleanup Created 5 years, 1 month 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
« 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 29 matching lines...) Expand all
40 sigma = MAX_BLUR_SIGMA; 40 sigma = MAX_BLUR_SIGMA;
41 } 41 }
42 } 42 }
43 *radius = static_cast<int>(ceilf(sigma * 3.0f)); 43 *radius = static_cast<int>(ceilf(sigma * 3.0f));
44 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); 44 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius);
45 return sigma; 45 return sigma;
46 } 46 }
47 47
48 static void convolve_gaussian_1d(GrDrawContext* drawContext, 48 static void convolve_gaussian_1d(GrDrawContext* drawContext,
49 const GrClip& clip, 49 const GrClip& clip,
50 const SkRect& srcRect,
51 const SkRect& dstRect, 50 const SkRect& dstRect,
51 const SkPoint& srcOffset,
52 GrTexture* texture, 52 GrTexture* texture,
53 Gr1DKernelEffect::Direction direction, 53 Gr1DKernelEffect::Direction direction,
54 int radius, 54 int radius,
55 float sigma, 55 float sigma,
56 bool useBounds, 56 bool useBounds,
57 float bounds[2]) { 57 float bounds[2]) {
58 GrPaint paint; 58 GrPaint paint;
59 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( 59 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
60 texture, direction, radius, sigma, useBounds, bounds)); 60 texture, direction, radius, sigma, useBounds, bounds));
61 paint.addColorFragmentProcessor(conv); 61 paint.addColorFragmentProcessor(conv);
62 drawContext->drawNonAARectToRect(clip, paint, SkMatrix::I(), dstRect, srcRec t); 62 SkMatrix localMatrix = SkMatrix::MakeTrans(srcOffset.x(), srcOffset.y());
63 drawContext->drawNonAARectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRec t, localMatrix);
63 } 64 }
64 65
65 static void convolve_gaussian_2d(GrDrawContext* drawContext, 66 static void convolve_gaussian_2d(GrDrawContext* drawContext,
66 const GrClip& clip, 67 const GrClip& clip,
67 const SkRect& srcRect, 68 const SkRect& srcRect,
68 const SkRect& dstRect,
69 GrTexture* texture, 69 GrTexture* texture,
70 int radiusX, 70 int radiusX,
71 int radiusY, 71 int radiusY,
72 SkScalar sigmaX, 72 SkScalar sigmaX,
73 SkScalar sigmaY, 73 SkScalar sigmaY,
74 bool useBounds, 74 bool useBounds,
75 SkIRect bounds) { 75 SkIRect bounds) {
76 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
77 SkMatrix localMatrix = SkMatrix::MakeTrans(srcRect.x(), srcRect.y());
76 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); 78 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
77 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); 79 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
78 GrPaint paint; 80 GrPaint paint;
79 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian( 81 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian(
80 texture, bounds, size, 1.0, 0.0, kernelOffset, 82 texture, bounds, size, 1.0, 0.0, kernelOffset,
81 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode, 83 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode,
82 true, sigmaX, sigmaY)); 84 true, sigmaX, sigmaY));
83 paint.addColorFragmentProcessor(conv); 85 paint.addColorFragmentProcessor(conv);
84 drawContext->drawNonAARectToRect(clip, paint, SkMatrix::I(), dstRect, srcRec t); 86 drawContext->drawNonAARectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRec t, localMatrix);
85 } 87 }
86 88
87 static void convolve_gaussian(GrDrawContext* drawContext, 89 static void convolve_gaussian(GrDrawContext* drawContext,
88 const GrClip& clip, 90 const GrClip& clip,
89 const SkRect& srcRect, 91 const SkRect& srcRect,
90 const SkRect& dstRect,
91 GrTexture* texture, 92 GrTexture* texture,
92 Gr1DKernelEffect::Direction direction, 93 Gr1DKernelEffect::Direction direction,
93 int radius, 94 int radius,
94 float sigma, 95 float sigma,
95 bool cropToSrcRect) { 96 bool cropToSrcRect) {
96 float bounds[2] = { 0.0f, 1.0f }; 97 float bounds[2] = { 0.0f, 1.0f };
98 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
99 SkPoint srcOffset = SkPoint::Make(srcRect.x(), srcRect.y());
97 if (!cropToSrcRect) { 100 if (!cropToSrcRect) {
98 convolve_gaussian_1d(drawContext, clip, srcRect, dstRect, texture, 101 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture,
99 direction, radius, sigma, false, bounds); 102 direction, radius, sigma, false, bounds);
100 return; 103 return;
101 } 104 }
102 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 105 SkRect lowerDstRect = dstRect;
103 SkRect middleSrcRect = srcRect, middleDstRect = dstRect; 106 SkRect middleDstRect = dstRect;
104 SkRect upperSrcRect = srcRect, upperDstRect = dstRect; 107 SkRect upperDstRect = dstRect;
105 SkScalar size; 108 SkScalar size;
106 SkScalar rad = SkIntToScalar(radius); 109 SkScalar rad = SkIntToScalar(radius);
107 if (direction == Gr1DKernelEffect::kX_Direction) { 110 if (direction == Gr1DKernelEffect::kX_Direction) {
108 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); 111 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
109 bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width(); 112 bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width();
110 size = srcRect.width(); 113 size = dstRect.width();
111 lowerSrcRect.fRight = srcRect.left() + rad;
112 lowerDstRect.fRight = dstRect.left() + rad; 114 lowerDstRect.fRight = dstRect.left() + rad;
113 upperSrcRect.fLeft = srcRect.right() - rad;
114 upperDstRect.fLeft = dstRect.right() - rad; 115 upperDstRect.fLeft = dstRect.right() - rad;
115 middleSrcRect.inset(rad, 0);
116 middleDstRect.inset(rad, 0); 116 middleDstRect.inset(rad, 0);
117 } else { 117 } else {
118 bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height(); 118 bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height();
119 bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height(); 119 bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height();
120 size = srcRect.height(); 120 size = dstRect.height();
121 lowerSrcRect.fBottom = srcRect.top() + rad;
122 lowerDstRect.fBottom = dstRect.top() + rad; 121 lowerDstRect.fBottom = dstRect.top() + rad;
123 upperSrcRect.fTop = srcRect.bottom() - rad;
124 upperDstRect.fTop = dstRect.bottom() - rad; 122 upperDstRect.fTop = dstRect.bottom() - rad;
125 middleSrcRect.inset(0, rad);
126 middleDstRect.inset(0, rad); 123 middleDstRect.inset(0, rad);
127 } 124 }
128 if (radius >= size * SK_ScalarHalf) { 125 if (radius >= size * SK_ScalarHalf) {
129 // Blur radius covers srcRect; use bounds over entire draw 126 // Blur radius covers srcRect; use bounds over entire draw
130 convolve_gaussian_1d(drawContext, clip, srcRect, dstRect, texture, 127 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture,
131 direction, radius, sigma, true, bounds); 128 direction, radius, sigma, true, bounds);
132 } else { 129 } else {
133 // Draw upper and lower margins with bounds; middle without. 130 // Draw upper and lower margins with bounds; middle without.
134 convolve_gaussian_1d(drawContext, clip, lowerSrcRect, lowerDstRect, text ure, 131 convolve_gaussian_1d(drawContext, clip, lowerDstRect, srcOffset, texture ,
135 direction, radius, sigma, true, bounds); 132 direction, radius, sigma, true, bounds);
136 convolve_gaussian_1d(drawContext, clip, upperSrcRect, upperDstRect, text ure, 133 convolve_gaussian_1d(drawContext, clip, upperDstRect, srcOffset, texture ,
137 direction, radius, sigma, true, bounds); 134 direction, radius, sigma, true, bounds);
138 convolve_gaussian_1d(drawContext, clip, middleSrcRect, middleDstRect, te xture, 135 convolve_gaussian_1d(drawContext, clip, middleDstRect, srcOffset, textur e,
139 direction, radius, sigma, false, bounds); 136 direction, radius, sigma, false, bounds);
140 } 137 }
141 } 138 }
142 139
143 GrTexture* GaussianBlur(GrContext* context, 140 GrTexture* GaussianBlur(GrContext* context,
144 GrTexture* srcTexture, 141 GrTexture* srcTexture,
145 bool canClobberSrc, 142 bool canClobberSrc,
146 const SkRect& rect, 143 const SkRect& rect,
147 bool cropToRect, 144 bool cropToRect,
148 float sigmaX, 145 float sigmaX,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 231 }
235 232
236 const SkIRect srcIRect = srcRect.roundOut(); 233 const SkIRect srcIRect = srcRect.roundOut();
237 234
238 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just 235 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just
239 // launch a single non separable kernel vs two launches 236 // launch a single non separable kernel vs two launches
240 if (sigmaX > 0.0f && sigmaY > 0.0f && 237 if (sigmaX > 0.0f && sigmaY > 0.0f &&
241 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { 238 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
242 // We shouldn't be scaling because this is a small size blur 239 // We shouldn't be scaling because this is a small size blur
243 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); 240 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
244 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
245 241
246 SkAutoTUnref<GrDrawContext> dstDrawContext( 242 SkAutoTUnref<GrDrawContext> dstDrawContext(
247 context->drawContext(dstTexture->as RenderTarget())); 243 context->drawContext(dstTexture->as RenderTarget()));
248 if (!dstDrawContext) { 244 if (!dstDrawContext) {
249 return nullptr; 245 return nullptr;
250 } 246 }
251 convolve_gaussian_2d(dstDrawContext, clip, srcRect, dstRect, 247 convolve_gaussian_2d(dstDrawContext, clip, srcRect,
252 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT oRect, srcIRect); 248 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT oRect, srcIRect);
253 249
254 srcDrawContext.swap(dstDrawContext); 250 srcDrawContext.swap(dstDrawContext);
255 srcRect = dstRect; 251 srcRect.offsetTo(0, 0);
256 srcTexture = dstTexture; 252 srcTexture = dstTexture;
257 SkTSwap(dstTexture, tempTexture); 253 SkTSwap(dstTexture, tempTexture);
258 254
259 } else { 255 } else {
260 if (sigmaX > 0.0f) { 256 if (sigmaX > 0.0f) {
261 if (scaleFactorX > 1) { 257 if (scaleFactorX > 1) {
262 // TODO: if we pass in the source draw context we don't need thi s here 258 // TODO: if we pass in the source draw context we don't need thi s here
263 if (!srcDrawContext) { 259 if (!srcDrawContext) {
264 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget())); 260 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget()));
265 if (!srcDrawContext) { 261 if (!srcDrawContext) {
266 return nullptr; 262 return nullptr;
267 } 263 }
268 } 264 }
269 265
270 // Clear out a radius to the right of the srcRect to prevent the 266 // Clear out a radius to the right of the srcRect to prevent the
271 // X convolution from reading garbage. 267 // X convolution from reading garbage.
272 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 268 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
273 radiusX, srcIRect.height()); 269 radiusX, srcIRect.height());
274 srcDrawContext->clear(&clearRect, 0x0, false); 270 srcDrawContext->clear(&clearRect, 0x0, false);
275 } 271 }
276 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
277 272
278 SkAutoTUnref<GrDrawContext> dstDrawContext( 273 SkAutoTUnref<GrDrawContext> dstDrawContext(
279 context->drawContext(dstTexture->as RenderTarget())); 274 context->drawContext(dstTexture->as RenderTarget()));
280 if (!dstDrawContext) { 275 if (!dstDrawContext) {
281 return nullptr; 276 return nullptr;
282 } 277 }
283 convolve_gaussian(dstDrawContext, clip, srcRect, dstRect, 278 convolve_gaussian(dstDrawContext, clip, srcRect,
284 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX, 279 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX,
285 cropToRect); 280 cropToRect);
286 281
287 srcDrawContext.swap(dstDrawContext); 282 srcDrawContext.swap(dstDrawContext);
288 srcTexture = dstTexture; 283 srcTexture = dstTexture;
289 srcRect = dstRect; 284 srcRect.offsetTo(0, 0);
290 SkTSwap(dstTexture, tempTexture); 285 SkTSwap(dstTexture, tempTexture);
291 } 286 }
292 287
293 if (sigmaY > 0.0f) { 288 if (sigmaY > 0.0f) {
294 if (scaleFactorY > 1 || sigmaX > 0.0f) { 289 if (scaleFactorY > 1 || sigmaX > 0.0f) {
295 // TODO: if we pass in the source draw context we don't need thi s here 290 // TODO: if we pass in the source draw context we don't need thi s here
296 if (!srcDrawContext) { 291 if (!srcDrawContext) {
297 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget())); 292 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget()));
298 if (!srcDrawContext) { 293 if (!srcDrawContext) {
299 return nullptr; 294 return nullptr;
300 } 295 }
301 } 296 }
302 297
303 // Clear out a radius below the srcRect to prevent the Y 298 // Clear out a radius below the srcRect to prevent the Y
304 // convolution from reading garbage. 299 // convolution from reading garbage.
305 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 300 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
306 srcIRect.width(), radiusY); 301 srcIRect.width(), radiusY);
307 srcDrawContext->clear(&clearRect, 0x0, false); 302 srcDrawContext->clear(&clearRect, 0x0, false);
308 } 303 }
309 304
310 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
311
312 SkAutoTUnref<GrDrawContext> dstDrawContext( 305 SkAutoTUnref<GrDrawContext> dstDrawContext(
313 context->drawContext(dstTexture-> asRenderTarget())); 306 context->drawContext(dstTexture-> asRenderTarget()));
314 if (!dstDrawContext) { 307 if (!dstDrawContext) {
315 return nullptr; 308 return nullptr;
316 } 309 }
317 convolve_gaussian(dstDrawContext, clip, srcRect, 310 convolve_gaussian(dstDrawContext, clip, srcRect,
318 dstRect, srcTexture, Gr1DKernelEffect::kY_Directio n, radiusY, sigmaY, 311 srcTexture, Gr1DKernelEffect::kY_Direction, radius Y, sigmaY,
319 cropToRect); 312 cropToRect);
320 313
321 srcDrawContext.swap(dstDrawContext); 314 srcDrawContext.swap(dstDrawContext);
322 srcTexture = dstTexture; 315 srcTexture = dstTexture;
323 srcRect = dstRect; 316 srcRect.offsetTo(0, 0);
324 SkTSwap(dstTexture, tempTexture); 317 SkTSwap(dstTexture, tempTexture);
325 } 318 }
326 } 319 }
327 320
328 if (scaleFactorX > 1 || scaleFactorY > 1) { 321 if (scaleFactorX > 1 || scaleFactorY > 1) {
329 SkASSERT(srcDrawContext); 322 SkASSERT(srcDrawContext);
330 323
331 // Clear one pixel to the right and below, to accommodate bilinear 324 // Clear one pixel to the right and below, to accommodate bilinear
332 // upsampling. 325 // upsampling.
333 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 326 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
(...skipping 24 matching lines...) Expand all
358 srcRect = dstRect; 351 srcRect = dstRect;
359 srcTexture = dstTexture; 352 srcTexture = dstTexture;
360 SkTSwap(dstTexture, tempTexture); 353 SkTSwap(dstTexture, tempTexture);
361 } 354 }
362 355
363 return SkRef(srcTexture); 356 return SkRef(srcTexture);
364 } 357 }
365 #endif 358 #endif
366 359
367 } 360 }
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