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

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

Issue 939623005: Pass Rendertarget into context (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: sampleapp Created 5 years, 10 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/SkMorphologyImageFilter.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 26 matching lines...) Expand all
37 *scaleFactor = maxTextureSize; 37 *scaleFactor = maxTextureSize;
38 sigma = MAX_BLUR_SIGMA; 38 sigma = MAX_BLUR_SIGMA;
39 } 39 }
40 } 40 }
41 *radius = static_cast<int>(ceilf(sigma * 3.0f)); 41 *radius = static_cast<int>(ceilf(sigma * 3.0f));
42 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); 42 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius);
43 return sigma; 43 return sigma;
44 } 44 }
45 45
46 static void convolve_gaussian_1d(GrContext* context, 46 static void convolve_gaussian_1d(GrContext* context,
47 GrRenderTarget* rt,
47 const SkRect& srcRect, 48 const SkRect& srcRect,
48 const SkRect& dstRect, 49 const SkRect& dstRect,
49 GrTexture* texture, 50 GrTexture* texture,
50 Gr1DKernelEffect::Direction direction, 51 Gr1DKernelEffect::Direction direction,
51 int radius, 52 int radius,
52 float sigma, 53 float sigma,
53 bool useBounds, 54 bool useBounds,
54 float bounds[2]) { 55 float bounds[2]) {
55 GrPaint paint; 56 GrPaint paint;
56 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( 57 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
57 texture, direction, radius, sigma, useBounds, bounds)); 58 texture, direction, radius, sigma, useBounds, bounds));
58 paint.addColorProcessor(conv); 59 paint.addColorProcessor(conv);
59 context->drawNonAARectToRect(paint, SkMatrix::I(), dstRect, srcRect); 60 context->drawNonAARectToRect(rt, paint, SkMatrix::I(), dstRect, srcRect);
60 } 61 }
61 62
62 static void convolve_gaussian_2d(GrContext* context, 63 static void convolve_gaussian_2d(GrContext* context,
64 GrRenderTarget* rt,
63 const SkRect& srcRect, 65 const SkRect& srcRect,
64 const SkRect& dstRect, 66 const SkRect& dstRect,
65 GrTexture* texture, 67 GrTexture* texture,
66 int radiusX, 68 int radiusX,
67 int radiusY, 69 int radiusY,
68 SkScalar sigmaX, 70 SkScalar sigmaX,
69 SkScalar sigmaY, 71 SkScalar sigmaY,
70 bool useBounds, 72 bool useBounds,
71 SkIRect bounds) { 73 SkIRect bounds) {
72 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); 74 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
73 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); 75 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
74 GrPaint paint; 76 GrPaint paint;
75 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian( 77 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian(
76 texture, bounds, size, 1.0, 0.0, kernelOffset, 78 texture, bounds, size, 1.0, 0.0, kernelOffset,
77 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode, 79 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode,
78 true, sigmaX, sigmaY)); 80 true, sigmaX, sigmaY));
79 paint.addColorProcessor(conv); 81 paint.addColorProcessor(conv);
80 context->drawNonAARectToRect(paint, SkMatrix::I(), dstRect, srcRect); 82 context->drawNonAARectToRect(rt, paint, SkMatrix::I(), dstRect, srcRect);
81 } 83 }
82 84
83 static void convolve_gaussian(GrContext* context, 85 static void convolve_gaussian(GrContext* context,
86 GrRenderTarget* rt,
84 const SkRect& srcRect, 87 const SkRect& srcRect,
85 const SkRect& dstRect, 88 const SkRect& dstRect,
86 GrTexture* texture, 89 GrTexture* texture,
87 Gr1DKernelEffect::Direction direction, 90 Gr1DKernelEffect::Direction direction,
88 int radius, 91 int radius,
89 float sigma, 92 float sigma,
90 bool cropToSrcRect) { 93 bool cropToSrcRect) {
91 float bounds[2] = { 0.0f, 1.0f }; 94 float bounds[2] = { 0.0f, 1.0f };
92 if (!cropToSrcRect) { 95 if (!cropToSrcRect) {
93 convolve_gaussian_1d(context, srcRect, dstRect, texture, 96 convolve_gaussian_1d(context, rt, srcRect, dstRect, texture,
94 direction, radius, sigma, false, bounds); 97 direction, radius, sigma, false, bounds);
95 return; 98 return;
96 } 99 }
97 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 100 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
98 SkRect middleSrcRect = srcRect, middleDstRect = dstRect; 101 SkRect middleSrcRect = srcRect, middleDstRect = dstRect;
99 SkRect upperSrcRect = srcRect, upperDstRect = dstRect; 102 SkRect upperSrcRect = srcRect, upperDstRect = dstRect;
100 SkScalar size; 103 SkScalar size;
101 SkScalar rad = SkIntToScalar(radius); 104 SkScalar rad = SkIntToScalar(radius);
102 if (direction == Gr1DKernelEffect::kX_Direction) { 105 if (direction == Gr1DKernelEffect::kX_Direction) {
103 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); 106 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
(...skipping 11 matching lines...) Expand all
115 size = srcRect.height(); 118 size = srcRect.height();
116 lowerSrcRect.fBottom = srcRect.top() + rad; 119 lowerSrcRect.fBottom = srcRect.top() + rad;
117 lowerDstRect.fBottom = dstRect.top() + rad; 120 lowerDstRect.fBottom = dstRect.top() + rad;
118 upperSrcRect.fTop = srcRect.bottom() - rad; 121 upperSrcRect.fTop = srcRect.bottom() - rad;
119 upperDstRect.fTop = dstRect.bottom() - rad; 122 upperDstRect.fTop = dstRect.bottom() - rad;
120 middleSrcRect.inset(0, rad); 123 middleSrcRect.inset(0, rad);
121 middleDstRect.inset(0, rad); 124 middleDstRect.inset(0, rad);
122 } 125 }
123 if (radius >= size * SK_ScalarHalf) { 126 if (radius >= size * SK_ScalarHalf) {
124 // Blur radius covers srcRect; use bounds over entire draw 127 // Blur radius covers srcRect; use bounds over entire draw
125 convolve_gaussian_1d(context, srcRect, dstRect, texture, 128 convolve_gaussian_1d(context, rt, srcRect, dstRect, texture,
126 direction, radius, sigma, true, bounds); 129 direction, radius, sigma, true, bounds);
127 } else { 130 } else {
128 // Draw upper and lower margins with bounds; middle without. 131 // Draw upper and lower margins with bounds; middle without.
129 convolve_gaussian_1d(context, lowerSrcRect, lowerDstRect, texture, 132 convolve_gaussian_1d(context, rt, lowerSrcRect, lowerDstRect, texture,
130 direction, radius, sigma, true, bounds); 133 direction, radius, sigma, true, bounds);
131 convolve_gaussian_1d(context, upperSrcRect, upperDstRect, texture, 134 convolve_gaussian_1d(context, rt, upperSrcRect, upperDstRect, texture,
132 direction, radius, sigma, true, bounds); 135 direction, radius, sigma, true, bounds);
133 convolve_gaussian_1d(context, middleSrcRect, middleDstRect, texture, 136 convolve_gaussian_1d(context, rt, middleSrcRect, middleDstRect, texture,
134 direction, radius, sigma, false, bounds); 137 direction, radius, sigma, false, bounds);
135 } 138 }
136 } 139 }
137 140
138 GrTexture* GaussianBlur(GrContext* context, 141 GrTexture* GaussianBlur(GrContext* context,
139 GrTexture* srcTexture, 142 GrTexture* srcTexture,
140 bool canClobberSrc, 143 bool canClobberSrc,
141 const SkRect& rect, 144 const SkRect& rect,
142 bool cropToRect, 145 bool cropToRect,
143 float sigmaX, 146 float sigmaX,
144 float sigmaY) { 147 float sigmaY) {
145 SkASSERT(context); 148 SkASSERT(context);
146 149
147 GrContext::AutoRenderTarget art(context);
148
149 SkIRect clearRect; 150 SkIRect clearRect;
150 int scaleFactorX, radiusX; 151 int scaleFactorX, radiusX;
151 int scaleFactorY, radiusY; 152 int scaleFactorY, radiusY;
152 int maxTextureSize = context->getMaxTextureSize(); 153 int maxTextureSize = context->getMaxTextureSize();
153 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); 154 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX);
154 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); 155 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY);
155 156
156 SkRect srcRect(rect); 157 SkRect srcRect(rect);
157 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 158 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
158 srcRect.roundOut(&srcRect); 159 srcRect.roundOut(&srcRect);
(...skipping 26 matching lines...) Expand all
185 } 186 }
186 187
187 if (NULL == dstTexture || NULL == tempTexture) { 188 if (NULL == dstTexture || NULL == tempTexture) {
188 return NULL; 189 return NULL;
189 } 190 }
190 191
191 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 192 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
192 GrPaint paint; 193 GrPaint paint;
193 SkMatrix matrix; 194 SkMatrix matrix;
194 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 195 matrix.setIDiv(srcTexture->width(), srcTexture->height());
195 context->setRenderTarget(dstTexture->asRenderTarget());
196 SkRect dstRect(srcRect); 196 SkRect dstRect(srcRect);
197 if (cropToRect && i == 1) { 197 if (cropToRect && i == 1) {
198 dstRect.offset(-dstRect.fLeft, -dstRect.fTop); 198 dstRect.offset(-dstRect.fLeft, -dstRect.fTop);
199 SkRect domain; 199 SkRect domain;
200 matrix.mapRect(&domain, rect); 200 matrix.mapRect(&domain, rect);
201 domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f, 201 domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f,
202 i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f); 202 i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f);
203 SkAutoTUnref<GrFragmentProcessor> fp( GrTextureDomainEffect::Creat e( 203 SkAutoTUnref<GrFragmentProcessor> fp( GrTextureDomainEffect::Creat e(
204 srcTexture, 204 srcTexture,
205 matrix, 205 matrix,
206 domain, 206 domain,
207 GrTextureDomain::kDecal_Mode, 207 GrTextureDomain::kDecal_Mode,
208 GrTextureParams::kBilerp_FilterMode)); 208 GrTextureParams::kBilerp_FilterMode));
209 paint.addColorProcessor(fp); 209 paint.addColorProcessor(fp);
210 } else { 210 } else {
211 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode); 211 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode);
212 paint.addColorTextureProcessor(srcTexture, matrix, params); 212 paint.addColorTextureProcessor(srcTexture, matrix, params);
213 } 213 }
214 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 214 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
215 i < scaleFactorY ? 0.5f : 1.0f); 215 i < scaleFactorY ? 0.5f : 1.0f);
216 context->drawNonAARectToRect(paint, SkMatrix::I(), dstRect, srcRect); 216 context->drawNonAARectToRect(dstTexture->asRenderTarget(), paint, SkMatr ix::I(), dstRect,
217 srcRect);
217 srcRect = dstRect; 218 srcRect = dstRect;
218 srcTexture = dstTexture; 219 srcTexture = dstTexture;
219 SkTSwap(dstTexture, tempTexture); 220 SkTSwap(dstTexture, tempTexture);
220 } 221 }
221 222
222 const SkIRect srcIRect = srcRect.roundOut(); 223 const SkIRect srcIRect = srcRect.roundOut();
223 224
224 // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is faster to just 225 // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is faster to just
225 // launch a single non separable kernel vs two launches 226 // launch a single non separable kernel vs two launches
226 if (sigmaX > 0.0f && sigmaY > 0 && 227 if (sigmaX > 0.0f && sigmaY > 0 &&
227 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { 228 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
228 // We shouldn't be scaling because this is a small size blur 229 // We shouldn't be scaling because this is a small size blur
229 SkASSERT((scaleFactorX == scaleFactorY) == 1); 230 SkASSERT((scaleFactorX == scaleFactorY) == 1);
230 context->setRenderTarget(dstTexture->asRenderTarget());
231 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 231 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
232 convolve_gaussian_2d(context, srcRect, dstRect, srcTexture, 232 convolve_gaussian_2d(context, dstTexture->asRenderTarget(), srcRect, dst Rect, srcTexture,
233 radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect); 233 radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIR ect);
234 srcTexture = dstTexture; 234 srcTexture = dstTexture;
235 srcRect = dstRect; 235 srcRect = dstRect;
236 SkTSwap(dstTexture, tempTexture); 236 SkTSwap(dstTexture, tempTexture);
237 237
238 } else { 238 } else {
239 if (sigmaX > 0.0f) { 239 if (sigmaX > 0.0f) {
240 if (scaleFactorX > 1) { 240 if (scaleFactorX > 1) {
241 // Clear out a radius to the right of the srcRect to prevent the 241 // Clear out a radius to the right of the srcRect to prevent the
242 // X convolution from reading garbage. 242 // X convolution from reading garbage.
243 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 243 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
244 radiusX, srcIRect.height()); 244 radiusX, srcIRect.height());
245 context->clear(&clearRect, 0x0, false, context->getRenderTarget( )); 245 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge t());
246 } 246 }
247 context->setRenderTarget(dstTexture->asRenderTarget());
248 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 247 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
249 convolve_gaussian(context, srcRect, dstRect, srcTexture, 248 convolve_gaussian(context, dstTexture->asRenderTarget(), srcRect, ds tRect, srcTexture,
250 Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, c ropToRect); 249 Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, c ropToRect);
251 srcTexture = dstTexture; 250 srcTexture = dstTexture;
252 srcRect = dstRect; 251 srcRect = dstRect;
253 SkTSwap(dstTexture, tempTexture); 252 SkTSwap(dstTexture, tempTexture);
254 } 253 }
255 254
256 if (sigmaY > 0.0f) { 255 if (sigmaY > 0.0f) {
257 if (scaleFactorY > 1 || sigmaX > 0.0f) { 256 if (scaleFactorY > 1 || sigmaX > 0.0f) {
258 // Clear out a radius below the srcRect to prevent the Y 257 // Clear out a radius below the srcRect to prevent the Y
259 // convolution from reading garbage. 258 // convolution from reading garbage.
260 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 259 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
261 srcIRect.width(), radiusY); 260 srcIRect.width(), radiusY);
262 context->clear(&clearRect, 0x0, false, context->getRenderTarget( )); 261 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge t());
263 } 262 }
264 263
265 context->setRenderTarget(dstTexture->asRenderTarget());
266 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 264 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
267 convolve_gaussian(context, srcRect, dstRect, srcTexture, 265 convolve_gaussian(context, dstTexture->asRenderTarget(), srcRect, ds tRect, srcTexture,
268 Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, c ropToRect); 266 Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, c ropToRect);
269 srcTexture = dstTexture; 267 srcTexture = dstTexture;
270 srcRect = dstRect; 268 srcRect = dstRect;
271 SkTSwap(dstTexture, tempTexture); 269 SkTSwap(dstTexture, tempTexture);
272 } 270 }
273 } 271 }
274 272
275 if (scaleFactorX > 1 || scaleFactorY > 1) { 273 if (scaleFactorX > 1 || scaleFactorY > 1) {
276 // Clear one pixel to the right and below, to accommodate bilinear 274 // Clear one pixel to the right and below, to accommodate bilinear
277 // upsampling. 275 // upsampling.
278 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 276 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
279 srcIRect.width() + 1, 1); 277 srcIRect.width() + 1, 1);
280 context->clear(&clearRect, 0x0, false, context->getRenderTarget()); 278 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget());
281 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 279 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
282 1, srcIRect.height()); 280 1, srcIRect.height());
283 context->clear(&clearRect, 0x0, false, context->getRenderTarget()); 281 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget());
284 SkMatrix matrix; 282 SkMatrix matrix;
285 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 283 matrix.setIDiv(srcTexture->width(), srcTexture->height());
286 context->setRenderTarget(dstTexture->asRenderTarget());
287 284
288 GrPaint paint; 285 GrPaint paint;
289 // FIXME: this should be mitchell, not bilinear. 286 // FIXME: this should be mitchell, not bilinear.
290 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode); 287 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode);
291 paint.addColorTextureProcessor(srcTexture, matrix, params); 288 paint.addColorTextureProcessor(srcTexture, matrix, params);
292 289
293 SkRect dstRect(srcRect); 290 SkRect dstRect(srcRect);
294 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 291 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
295 context->drawNonAARectToRect(paint, SkMatrix::I(), dstRect, srcRect); 292 context->drawNonAARectToRect(dstTexture->asRenderTarget(), paint, SkMatr ix::I(), dstRect,
293 srcRect);
296 srcRect = dstRect; 294 srcRect = dstRect;
297 srcTexture = dstTexture; 295 srcTexture = dstTexture;
298 SkTSwap(dstTexture, tempTexture); 296 SkTSwap(dstTexture, tempTexture);
299 } 297 }
300 return SkRef(srcTexture); 298 return SkRef(srcTexture);
301 } 299 }
302 #endif 300 #endif
303 301
304 } 302 }
OLDNEW
« no previous file with comments | « src/effects/SkDisplacementMapEffect.cpp ('k') | src/effects/SkMorphologyImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698