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

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

Issue 1404823005: GrDrawContext now holds GrRenderTarget pointer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix overlength line Created 5 years, 2 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
« no previous file with comments | « src/effects/SkDisplacementMapEffect.cpp ('k') | src/effects/SkLightingImageFilter.cpp » ('j') | 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 28 matching lines...) Expand all
39 *scaleFactor = maxTextureSize; 39 *scaleFactor = maxTextureSize;
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 GrRenderTarget* rt,
50 const GrClip& clip, 49 const GrClip& clip,
51 const SkRect& srcRect, 50 const SkRect& srcRect,
52 const SkRect& dstRect, 51 const SkRect& dstRect,
53 GrTexture* texture, 52 GrTexture* texture,
54 Gr1DKernelEffect::Direction direction, 53 Gr1DKernelEffect::Direction direction,
55 int radius, 54 int radius,
56 float sigma, 55 float sigma,
57 bool useBounds, 56 bool useBounds,
58 float bounds[2]) { 57 float bounds[2]) {
59 GrPaint paint; 58 GrPaint paint;
60 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( 59 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
61 texture, direction, radius, sigma, useBounds, bounds)); 60 texture, direction, radius, sigma, useBounds, bounds));
62 paint.addColorFragmentProcessor(conv); 61 paint.addColorFragmentProcessor(conv);
63 drawContext->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, sr cRect); 62 drawContext->drawNonAARectToRect(clip, paint, SkMatrix::I(), dstRect, srcRec t);
64 } 63 }
65 64
66 static void convolve_gaussian_2d(GrDrawContext* drawContext, 65 static void convolve_gaussian_2d(GrDrawContext* drawContext,
67 GrRenderTarget* rt,
68 const GrClip& clip, 66 const GrClip& clip,
69 const SkRect& srcRect, 67 const SkRect& srcRect,
70 const SkRect& dstRect, 68 const SkRect& dstRect,
71 GrTexture* texture, 69 GrTexture* texture,
72 int radiusX, 70 int radiusX,
73 int radiusY, 71 int radiusY,
74 SkScalar sigmaX, 72 SkScalar sigmaX,
75 SkScalar sigmaY, 73 SkScalar sigmaY,
76 bool useBounds, 74 bool useBounds,
77 SkIRect bounds) { 75 SkIRect bounds) {
78 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); 76 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
79 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); 77 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
80 GrPaint paint; 78 GrPaint paint;
81 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian( 79 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian(
82 texture, bounds, size, 1.0, 0.0, kernelOffset, 80 texture, bounds, size, 1.0, 0.0, kernelOffset,
83 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode, 81 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode,
84 true, sigmaX, sigmaY)); 82 true, sigmaX, sigmaY));
85 paint.addColorFragmentProcessor(conv); 83 paint.addColorFragmentProcessor(conv);
86 drawContext->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, sr cRect); 84 drawContext->drawNonAARectToRect(clip, paint, SkMatrix::I(), dstRect, srcRec t);
87 } 85 }
88 86
89 static void convolve_gaussian(GrDrawContext* drawContext, 87 static void convolve_gaussian(GrDrawContext* drawContext,
90 GrRenderTarget* rt,
91 const GrClip& clip, 88 const GrClip& clip,
92 const SkRect& srcRect, 89 const SkRect& srcRect,
93 const SkRect& dstRect, 90 const SkRect& dstRect,
94 GrTexture* texture, 91 GrTexture* texture,
95 Gr1DKernelEffect::Direction direction, 92 Gr1DKernelEffect::Direction direction,
96 int radius, 93 int radius,
97 float sigma, 94 float sigma,
98 bool cropToSrcRect) { 95 bool cropToSrcRect) {
99 float bounds[2] = { 0.0f, 1.0f }; 96 float bounds[2] = { 0.0f, 1.0f };
100 if (!cropToSrcRect) { 97 if (!cropToSrcRect) {
101 convolve_gaussian_1d(drawContext, rt, clip, srcRect, dstRect, texture, 98 convolve_gaussian_1d(drawContext, clip, srcRect, dstRect, texture,
102 direction, radius, sigma, false, bounds); 99 direction, radius, sigma, false, bounds);
103 return; 100 return;
104 } 101 }
105 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 102 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
106 SkRect middleSrcRect = srcRect, middleDstRect = dstRect; 103 SkRect middleSrcRect = srcRect, middleDstRect = dstRect;
107 SkRect upperSrcRect = srcRect, upperDstRect = dstRect; 104 SkRect upperSrcRect = srcRect, upperDstRect = dstRect;
108 SkScalar size; 105 SkScalar size;
109 SkScalar rad = SkIntToScalar(radius); 106 SkScalar rad = SkIntToScalar(radius);
110 if (direction == Gr1DKernelEffect::kX_Direction) { 107 if (direction == Gr1DKernelEffect::kX_Direction) {
111 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); 108 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
(...skipping 11 matching lines...) Expand all
123 size = srcRect.height(); 120 size = srcRect.height();
124 lowerSrcRect.fBottom = srcRect.top() + rad; 121 lowerSrcRect.fBottom = srcRect.top() + rad;
125 lowerDstRect.fBottom = dstRect.top() + rad; 122 lowerDstRect.fBottom = dstRect.top() + rad;
126 upperSrcRect.fTop = srcRect.bottom() - rad; 123 upperSrcRect.fTop = srcRect.bottom() - rad;
127 upperDstRect.fTop = dstRect.bottom() - rad; 124 upperDstRect.fTop = dstRect.bottom() - rad;
128 middleSrcRect.inset(0, rad); 125 middleSrcRect.inset(0, rad);
129 middleDstRect.inset(0, rad); 126 middleDstRect.inset(0, rad);
130 } 127 }
131 if (radius >= size * SK_ScalarHalf) { 128 if (radius >= size * SK_ScalarHalf) {
132 // Blur radius covers srcRect; use bounds over entire draw 129 // Blur radius covers srcRect; use bounds over entire draw
133 convolve_gaussian_1d(drawContext, rt, clip, srcRect, dstRect, texture, 130 convolve_gaussian_1d(drawContext, clip, srcRect, dstRect, texture,
134 direction, radius, sigma, true, bounds); 131 direction, radius, sigma, true, bounds);
135 } else { 132 } else {
136 // Draw upper and lower margins with bounds; middle without. 133 // Draw upper and lower margins with bounds; middle without.
137 convolve_gaussian_1d(drawContext, rt, clip, lowerSrcRect, lowerDstRect, texture, 134 convolve_gaussian_1d(drawContext, clip, lowerSrcRect, lowerDstRect, text ure,
138 direction, radius, sigma, true, bounds); 135 direction, radius, sigma, true, bounds);
139 convolve_gaussian_1d(drawContext, rt, clip, upperSrcRect, upperDstRect, texture, 136 convolve_gaussian_1d(drawContext, clip, upperSrcRect, upperDstRect, text ure,
140 direction, radius, sigma, true, bounds); 137 direction, radius, sigma, true, bounds);
141 convolve_gaussian_1d(drawContext, rt, clip, middleSrcRect, middleDstRect , texture, 138 convolve_gaussian_1d(drawContext, clip, middleSrcRect, middleDstRect, te xture,
142 direction, radius, sigma, false, bounds); 139 direction, radius, sigma, false, bounds);
143 } 140 }
144 } 141 }
145 142
146 GrTexture* GaussianBlur(GrContext* context, 143 GrTexture* GaussianBlur(GrContext* context,
147 GrTexture* srcTexture, 144 GrTexture* srcTexture,
148 bool canClobberSrc, 145 bool canClobberSrc,
149 const SkRect& rect, 146 const SkRect& rect,
150 bool cropToRect, 147 bool cropToRect,
151 float sigmaX, 148 float sigmaX,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 GrTextureDomain::kDecal_Mode, 212 GrTextureDomain::kDecal_Mode,
216 GrTextureParams::kBilerp_FilterMode)); 213 GrTextureParams::kBilerp_FilterMode));
217 paint.addColorFragmentProcessor(fp); 214 paint.addColorFragmentProcessor(fp);
218 } else { 215 } else {
219 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode); 216 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode);
220 paint.addColorTextureProcessor(srcTexture, matrix, params); 217 paint.addColorTextureProcessor(srcTexture, matrix, params);
221 } 218 }
222 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 219 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
223 i < scaleFactorY ? 0.5f : 1.0f); 220 i < scaleFactorY ? 0.5f : 1.0f);
224 221
225 SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext()); 222 SkAutoTUnref<GrDrawContext> dstDrawContext(
223 context->drawContext(dstTexture->as RenderTarget()));
226 if (!dstDrawContext) { 224 if (!dstDrawContext) {
227 return nullptr; 225 return nullptr;
228 } 226 }
229 dstDrawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, 227 dstDrawContext->drawNonAARectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
230 SkMatrix::I(), dstRect, srcRect);
231 228
232 srcDrawContext.swap(dstDrawContext); 229 srcDrawContext.swap(dstDrawContext);
233 srcRect = dstRect; 230 srcRect = dstRect;
234 srcTexture = dstTexture; 231 srcTexture = dstTexture;
235 SkTSwap(dstTexture, tempTexture); 232 SkTSwap(dstTexture, tempTexture);
236 } 233 }
237 234
238 const SkIRect srcIRect = srcRect.roundOut(); 235 const SkIRect srcIRect = srcRect.roundOut();
239 236
240 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just 237 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just
241 // launch a single non separable kernel vs two launches 238 // launch a single non separable kernel vs two launches
242 if (sigmaX > 0.0f && sigmaY > 0.0f && 239 if (sigmaX > 0.0f && sigmaY > 0.0f &&
243 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { 240 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
244 // We shouldn't be scaling because this is a small size blur 241 // We shouldn't be scaling because this is a small size blur
245 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); 242 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
246 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 243 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
247 244
248 SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext()); 245 SkAutoTUnref<GrDrawContext> dstDrawContext(
246 context->drawContext(dstTexture->as RenderTarget()));
249 if (!dstDrawContext) { 247 if (!dstDrawContext) {
250 return nullptr; 248 return nullptr;
251 } 249 }
252 convolve_gaussian_2d(dstDrawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect, 250 convolve_gaussian_2d(dstDrawContext, clip, srcRect, dstRect,
253 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT oRect, srcIRect); 251 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT oRect, srcIRect);
254 252
255 srcDrawContext.swap(dstDrawContext); 253 srcDrawContext.swap(dstDrawContext);
256 srcRect = dstRect; 254 srcRect = dstRect;
257 srcTexture = dstTexture; 255 srcTexture = dstTexture;
258 SkTSwap(dstTexture, tempTexture); 256 SkTSwap(dstTexture, tempTexture);
259 257
260 } else { 258 } else {
261 if (sigmaX > 0.0f) { 259 if (sigmaX > 0.0f) {
262 if (scaleFactorX > 1) { 260 if (scaleFactorX > 1) {
263 // TODO: if we pass in the source draw context we don't need thi s here 261 // TODO: if we pass in the source draw context we don't need thi s here
264 if (!srcDrawContext) { 262 if (!srcDrawContext) {
265 srcDrawContext.reset(context->drawContext()); 263 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget()));
266 if (!srcDrawContext) { 264 if (!srcDrawContext) {
267 return nullptr; 265 return nullptr;
268 } 266 }
269 } 267 }
270 268
271 // Clear out a radius to the right of the srcRect to prevent the 269 // Clear out a radius to the right of the srcRect to prevent the
272 // X convolution from reading garbage. 270 // X convolution from reading garbage.
273 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 271 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
274 radiusX, srcIRect.height()); 272 radiusX, srcIRect.height());
275 srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false); 273 srcDrawContext->clear(&clearRect, 0x0, false);
276 } 274 }
277 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 275 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
278 276
279 SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext()); 277 SkAutoTUnref<GrDrawContext> dstDrawContext(
278 context->drawContext(dstTexture->asR enderTarget()));
280 if (!dstDrawContext) { 279 if (!dstDrawContext) {
281 return nullptr; 280 return nullptr;
282 } 281 }
283 convolve_gaussian(dstDrawContext, dstTexture->asRenderTarget(), clip , srcRect, dstRect, 282 convolve_gaussian(dstDrawContext, clip, srcRect, dstRect,
284 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX, 283 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX,
285 cropToRect); 284 cropToRect);
286 285
287 srcDrawContext.swap(dstDrawContext); 286 srcDrawContext.swap(dstDrawContext);
288 srcTexture = dstTexture; 287 srcTexture = dstTexture;
289 srcRect = dstRect; 288 srcRect = dstRect;
290 SkTSwap(dstTexture, tempTexture); 289 SkTSwap(dstTexture, tempTexture);
291 } 290 }
292 291
293 if (sigmaY > 0.0f) { 292 if (sigmaY > 0.0f) {
294 if (scaleFactorY > 1 || sigmaX > 0.0f) { 293 if (scaleFactorY > 1 || sigmaX > 0.0f) {
295 // TODO: if we pass in the source draw context we don't need thi s here 294 // TODO: if we pass in the source draw context we don't need thi s here
296 if (!srcDrawContext) { 295 if (!srcDrawContext) {
297 srcDrawContext.reset(context->drawContext()); 296 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget()));
298 if (!srcDrawContext) { 297 if (!srcDrawContext) {
299 return nullptr; 298 return nullptr;
300 } 299 }
301 } 300 }
302 301
303 // Clear out a radius below the srcRect to prevent the Y 302 // Clear out a radius below the srcRect to prevent the Y
304 // convolution from reading garbage. 303 // convolution from reading garbage.
305 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 304 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
306 srcIRect.width(), radiusY); 305 srcIRect.width(), radiusY);
307 srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false); 306 srcDrawContext->clear(&clearRect, 0x0, false);
308 } 307 }
309 308
310 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 309 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
311 310
312 SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext()); 311 SkAutoTUnref<GrDrawContext> dstDrawContext(
312 context->drawContext(dstTexture->as RenderTarget()));
313 if (!dstDrawContext) { 313 if (!dstDrawContext) {
314 return nullptr; 314 return nullptr;
315 } 315 }
316 convolve_gaussian(dstDrawContext, dstTexture->asRenderTarget(), clip , srcRect, 316 convolve_gaussian(dstDrawContext, clip, srcRect,
317 dstRect, srcTexture, Gr1DKernelEffect::kY_Directio n, radiusY, sigmaY, 317 dstRect, srcTexture, Gr1DKernelEffect::kY_Directio n, radiusY, sigmaY,
318 cropToRect); 318 cropToRect);
319 319
320 srcDrawContext.swap(dstDrawContext); 320 srcDrawContext.swap(dstDrawContext);
321 srcTexture = dstTexture; 321 srcTexture = dstTexture;
322 srcRect = dstRect; 322 srcRect = dstRect;
323 SkTSwap(dstTexture, tempTexture); 323 SkTSwap(dstTexture, tempTexture);
324 } 324 }
325 } 325 }
326 326
327 if (scaleFactorX > 1 || scaleFactorY > 1) { 327 if (scaleFactorX > 1 || scaleFactorY > 1) {
328 SkASSERT(srcDrawContext); 328 SkASSERT(srcDrawContext);
329 329
330 // Clear one pixel to the right and below, to accommodate bilinear 330 // Clear one pixel to the right and below, to accommodate bilinear
331 // upsampling. 331 // upsampling.
332 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 332 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
333 srcIRect.width() + 1, 1); 333 srcIRect.width() + 1, 1);
334 srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, fal se); 334 srcDrawContext->clear(&clearRect, 0x0, false);
335 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 335 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
336 1, srcIRect.height()); 336 1, srcIRect.height());
337 srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, fal se); 337 srcDrawContext->clear(&clearRect, 0x0, false);
338 SkMatrix matrix; 338 SkMatrix matrix;
339 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 339 matrix.setIDiv(srcTexture->width(), srcTexture->height());
340 340
341 GrPaint paint; 341 GrPaint paint;
342 // FIXME: this should be mitchell, not bilinear. 342 // FIXME: this should be mitchell, not bilinear.
343 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode); 343 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode);
344 paint.addColorTextureProcessor(srcTexture, matrix, params); 344 paint.addColorTextureProcessor(srcTexture, matrix, params);
345 345
346 SkRect dstRect(srcRect); 346 SkRect dstRect(srcRect);
347 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 347 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
348 348
349 SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext()); 349 SkAutoTUnref<GrDrawContext> dstDrawContext(
350 context->drawContext(dstTexture->asR enderTarget()));
350 if (!dstDrawContext) { 351 if (!dstDrawContext) {
351 return nullptr; 352 return nullptr;
352 } 353 }
353 dstDrawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, 354 dstDrawContext->drawNonAARectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
354 SkMatrix::I(), dstRect, srcRect);
355 355
356 srcDrawContext.swap(dstDrawContext); 356 srcDrawContext.swap(dstDrawContext);
357 srcRect = dstRect; 357 srcRect = dstRect;
358 srcTexture = dstTexture; 358 srcTexture = dstTexture;
359 SkTSwap(dstTexture, tempTexture); 359 SkTSwap(dstTexture, tempTexture);
360 } 360 }
361 361
362 return SkRef(srcTexture); 362 return SkRef(srcTexture);
363 } 363 }
364 #endif 364 #endif
365 365
366 } 366 }
OLDNEW
« no previous file with comments | « src/effects/SkDisplacementMapEffect.cpp ('k') | src/effects/SkLightingImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698