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

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

Issue 956083002: Revert of Pass clip to context (Closed) Base URL: https://skia.googlesource.com/skia.git@pass_down_rendertarget
Patch Set: Created 5 years, 9 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 27 matching lines...) Expand all
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 GrRenderTarget* rt,
48 const GrClip& clip,
49 const SkRect& srcRect, 48 const SkRect& srcRect,
50 const SkRect& dstRect, 49 const SkRect& dstRect,
51 GrTexture* texture, 50 GrTexture* texture,
52 Gr1DKernelEffect::Direction direction, 51 Gr1DKernelEffect::Direction direction,
53 int radius, 52 int radius,
54 float sigma, 53 float sigma,
55 bool useBounds, 54 bool useBounds,
56 float bounds[2]) { 55 float bounds[2]) {
57 GrPaint paint; 56 GrPaint paint;
58 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( 57 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
59 texture, direction, radius, sigma, useBounds, bounds)); 58 texture, direction, radius, sigma, useBounds, bounds));
60 paint.addColorProcessor(conv); 59 paint.addColorProcessor(conv);
61 context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRec t); 60 context->drawNonAARectToRect(rt, paint, SkMatrix::I(), dstRect, srcRect);
62 } 61 }
63 62
64 static void convolve_gaussian_2d(GrContext* context, 63 static void convolve_gaussian_2d(GrContext* context,
65 GrRenderTarget* rt, 64 GrRenderTarget* rt,
66 const GrClip& clip,
67 const SkRect& srcRect, 65 const SkRect& srcRect,
68 const SkRect& dstRect, 66 const SkRect& dstRect,
69 GrTexture* texture, 67 GrTexture* texture,
70 int radiusX, 68 int radiusX,
71 int radiusY, 69 int radiusY,
72 SkScalar sigmaX, 70 SkScalar sigmaX,
73 SkScalar sigmaY, 71 SkScalar sigmaY,
74 bool useBounds, 72 bool useBounds,
75 SkIRect bounds) { 73 SkIRect bounds) {
76 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); 74 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
77 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); 75 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
78 GrPaint paint; 76 GrPaint paint;
79 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian( 77 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian(
80 texture, bounds, size, 1.0, 0.0, kernelOffset, 78 texture, bounds, size, 1.0, 0.0, kernelOffset,
81 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode, 79 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode,
82 true, sigmaX, sigmaY)); 80 true, sigmaX, sigmaY));
83 paint.addColorProcessor(conv); 81 paint.addColorProcessor(conv);
84 context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRec t); 82 context->drawNonAARectToRect(rt, paint, SkMatrix::I(), dstRect, srcRect);
85 } 83 }
86 84
87 static void convolve_gaussian(GrContext* context, 85 static void convolve_gaussian(GrContext* context,
88 GrRenderTarget* rt, 86 GrRenderTarget* rt,
89 const GrClip& clip,
90 const SkRect& srcRect, 87 const SkRect& srcRect,
91 const SkRect& dstRect, 88 const SkRect& dstRect,
92 GrTexture* texture, 89 GrTexture* texture,
93 Gr1DKernelEffect::Direction direction, 90 Gr1DKernelEffect::Direction direction,
94 int radius, 91 int radius,
95 float sigma, 92 float sigma,
96 bool cropToSrcRect) { 93 bool cropToSrcRect) {
97 float bounds[2] = { 0.0f, 1.0f }; 94 float bounds[2] = { 0.0f, 1.0f };
98 if (!cropToSrcRect) { 95 if (!cropToSrcRect) {
99 convolve_gaussian_1d(context, rt, clip, srcRect, dstRect, texture, 96 convolve_gaussian_1d(context, rt, srcRect, dstRect, texture,
100 direction, radius, sigma, false, bounds); 97 direction, radius, sigma, false, bounds);
101 return; 98 return;
102 } 99 }
103 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 100 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
104 SkRect middleSrcRect = srcRect, middleDstRect = dstRect; 101 SkRect middleSrcRect = srcRect, middleDstRect = dstRect;
105 SkRect upperSrcRect = srcRect, upperDstRect = dstRect; 102 SkRect upperSrcRect = srcRect, upperDstRect = dstRect;
106 SkScalar size; 103 SkScalar size;
107 SkScalar rad = SkIntToScalar(radius); 104 SkScalar rad = SkIntToScalar(radius);
108 if (direction == Gr1DKernelEffect::kX_Direction) { 105 if (direction == Gr1DKernelEffect::kX_Direction) {
109 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); 106 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width();
(...skipping 11 matching lines...) Expand all
121 size = srcRect.height(); 118 size = srcRect.height();
122 lowerSrcRect.fBottom = srcRect.top() + rad; 119 lowerSrcRect.fBottom = srcRect.top() + rad;
123 lowerDstRect.fBottom = dstRect.top() + rad; 120 lowerDstRect.fBottom = dstRect.top() + rad;
124 upperSrcRect.fTop = srcRect.bottom() - rad; 121 upperSrcRect.fTop = srcRect.bottom() - rad;
125 upperDstRect.fTop = dstRect.bottom() - rad; 122 upperDstRect.fTop = dstRect.bottom() - rad;
126 middleSrcRect.inset(0, rad); 123 middleSrcRect.inset(0, rad);
127 middleDstRect.inset(0, rad); 124 middleDstRect.inset(0, rad);
128 } 125 }
129 if (radius >= size * SK_ScalarHalf) { 126 if (radius >= size * SK_ScalarHalf) {
130 // Blur radius covers srcRect; use bounds over entire draw 127 // Blur radius covers srcRect; use bounds over entire draw
131 convolve_gaussian_1d(context, rt, clip, srcRect, dstRect, texture, 128 convolve_gaussian_1d(context, rt, srcRect, dstRect, texture,
132 direction, radius, sigma, true, bounds); 129 direction, radius, sigma, true, bounds);
133 } else { 130 } else {
134 // Draw upper and lower margins with bounds; middle without. 131 // Draw upper and lower margins with bounds; middle without.
135 convolve_gaussian_1d(context, rt, clip, lowerSrcRect, lowerDstRect, text ure, 132 convolve_gaussian_1d(context, rt, lowerSrcRect, lowerDstRect, texture,
136 direction, radius, sigma, true, bounds); 133 direction, radius, sigma, true, bounds);
137 convolve_gaussian_1d(context, rt, clip, upperSrcRect, upperDstRect, text ure, 134 convolve_gaussian_1d(context, rt, upperSrcRect, upperDstRect, texture,
138 direction, radius, sigma, true, bounds); 135 direction, radius, sigma, true, bounds);
139 convolve_gaussian_1d(context, rt, clip, middleSrcRect, middleDstRect, te xture, 136 convolve_gaussian_1d(context, rt, middleSrcRect, middleDstRect, texture,
140 direction, radius, sigma, false, bounds); 137 direction, radius, sigma, false, bounds);
141 } 138 }
142 } 139 }
143 140
144 GrTexture* GaussianBlur(GrContext* context, 141 GrTexture* GaussianBlur(GrContext* context,
145 GrTexture* srcTexture, 142 GrTexture* srcTexture,
146 bool canClobberSrc, 143 bool canClobberSrc,
147 const SkRect& rect, 144 const SkRect& rect,
148 bool cropToRect, 145 bool cropToRect,
149 float sigmaX, 146 float sigmaX,
150 float sigmaY) { 147 float sigmaY) {
151 SkASSERT(context); 148 SkASSERT(context);
152 149
153 SkIRect clearRect; 150 SkIRect clearRect;
154 int scaleFactorX, radiusX; 151 int scaleFactorX, radiusX;
155 int scaleFactorY, radiusY; 152 int scaleFactorY, radiusY;
156 int maxTextureSize = context->getMaxTextureSize(); 153 int maxTextureSize = context->getMaxTextureSize();
157 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); 154 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX);
158 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); 155 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY);
159 156
160 SkRect srcRect(rect); 157 SkRect srcRect(rect);
161 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 158 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
162 srcRect.roundOut(&srcRect); 159 srcRect.roundOut(&srcRect);
163 scale_rect(&srcRect, static_cast<float>(scaleFactorX), 160 scale_rect(&srcRect, static_cast<float>(scaleFactorX),
164 static_cast<float>(scaleFactorY)); 161 static_cast<float>(scaleFactorY));
165 162
166 // setup new clip 163 GrContext::AutoClip acs(context, SkRect::MakeWH(srcRect.width(), srcRect.hei ght()));
167 GrClip clip(SkRect::MakeWH(srcRect.width(), srcRect.height()));
168 164
169 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || 165 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
170 kRGBA_8888_GrPixelConfig == srcTexture->config() || 166 kRGBA_8888_GrPixelConfig == srcTexture->config() ||
171 kAlpha_8_GrPixelConfig == srcTexture->config()); 167 kAlpha_8_GrPixelConfig == srcTexture->config());
172 168
173 GrSurfaceDesc desc; 169 GrSurfaceDesc desc;
174 desc.fFlags = kRenderTarget_GrSurfaceFlag; 170 desc.fFlags = kRenderTarget_GrSurfaceFlag;
175 desc.fWidth = SkScalarFloorToInt(srcRect.width()); 171 desc.fWidth = SkScalarFloorToInt(srcRect.width());
176 desc.fHeight = SkScalarFloorToInt(srcRect.height()); 172 desc.fHeight = SkScalarFloorToInt(srcRect.height());
177 desc.fConfig = srcTexture->config(); 173 desc.fConfig = srcTexture->config();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 domain, 206 domain,
211 GrTextureDomain::kDecal_Mode, 207 GrTextureDomain::kDecal_Mode,
212 GrTextureParams::kBilerp_FilterMode)); 208 GrTextureParams::kBilerp_FilterMode));
213 paint.addColorProcessor(fp); 209 paint.addColorProcessor(fp);
214 } else { 210 } else {
215 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode); 211 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode);
216 paint.addColorTextureProcessor(srcTexture, matrix, params); 212 paint.addColorTextureProcessor(srcTexture, matrix, params);
217 } 213 }
218 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 214 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
219 i < scaleFactorY ? 0.5f : 1.0f); 215 i < scaleFactorY ? 0.5f : 1.0f);
220 context->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, SkMatrix::I(), 216 context->drawNonAARectToRect(dstTexture->asRenderTarget(), paint, SkMatr ix::I(), dstRect,
221 dstRect, srcRect); 217 srcRect);
222 srcRect = dstRect; 218 srcRect = dstRect;
223 srcTexture = dstTexture; 219 srcTexture = dstTexture;
224 SkTSwap(dstTexture, tempTexture); 220 SkTSwap(dstTexture, tempTexture);
225 } 221 }
226 222
227 const SkIRect srcIRect = srcRect.roundOut(); 223 const SkIRect srcIRect = srcRect.roundOut();
228 224
229 // 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
230 // launch a single non separable kernel vs two launches 226 // launch a single non separable kernel vs two launches
231 if (sigmaX > 0.0f && sigmaY > 0 && 227 if (sigmaX > 0.0f && sigmaY > 0 &&
232 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { 228 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
233 // 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
234 SkASSERT((scaleFactorX == scaleFactorY) == 1); 230 SkASSERT((scaleFactorX == scaleFactorY) == 1);
235 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 231 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
236 convolve_gaussian_2d(context, dstTexture->asRenderTarget(), clip, srcRec t, dstRect, 232 convolve_gaussian_2d(context, dstTexture->asRenderTarget(), srcRect, dst Rect, srcTexture,
237 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT oRect, srcIRect); 233 radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIR ect);
238 srcTexture = dstTexture; 234 srcTexture = dstTexture;
239 srcRect = dstRect; 235 srcRect = dstRect;
240 SkTSwap(dstTexture, tempTexture); 236 SkTSwap(dstTexture, tempTexture);
241 237
242 } else { 238 } else {
243 if (sigmaX > 0.0f) { 239 if (sigmaX > 0.0f) {
244 if (scaleFactorX > 1) { 240 if (scaleFactorX > 1) {
245 // 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
246 // X convolution from reading garbage. 242 // X convolution from reading garbage.
247 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 243 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
248 radiusX, srcIRect.height()); 244 radiusX, srcIRect.height());
249 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge t()); 245 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge t());
250 } 246 }
251 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 247 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
252 convolve_gaussian(context, dstTexture->asRenderTarget(), clip, srcRe ct, dstRect, 248 convolve_gaussian(context, dstTexture->asRenderTarget(), srcRect, ds tRect, srcTexture,
253 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX, 249 Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, c ropToRect);
254 cropToRect);
255 srcTexture = dstTexture; 250 srcTexture = dstTexture;
256 srcRect = dstRect; 251 srcRect = dstRect;
257 SkTSwap(dstTexture, tempTexture); 252 SkTSwap(dstTexture, tempTexture);
258 } 253 }
259 254
260 if (sigmaY > 0.0f) { 255 if (sigmaY > 0.0f) {
261 if (scaleFactorY > 1 || sigmaX > 0.0f) { 256 if (scaleFactorY > 1 || sigmaX > 0.0f) {
262 // Clear out a radius below the srcRect to prevent the Y 257 // Clear out a radius below the srcRect to prevent the Y
263 // convolution from reading garbage. 258 // convolution from reading garbage.
264 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 259 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
265 srcIRect.width(), radiusY); 260 srcIRect.width(), radiusY);
266 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge t()); 261 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge t());
267 } 262 }
268 263
269 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 264 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
270 convolve_gaussian(context, dstTexture->asRenderTarget(), clip, srcRe ct, 265 convolve_gaussian(context, dstTexture->asRenderTarget(), srcRect, ds tRect, srcTexture,
271 dstRect, srcTexture, Gr1DKernelEffect::kY_Directio n, radiusY, sigmaY, 266 Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, c ropToRect);
272 cropToRect);
273 srcTexture = dstTexture; 267 srcTexture = dstTexture;
274 srcRect = dstRect; 268 srcRect = dstRect;
275 SkTSwap(dstTexture, tempTexture); 269 SkTSwap(dstTexture, tempTexture);
276 } 270 }
277 } 271 }
278 272
279 if (scaleFactorX > 1 || scaleFactorY > 1) { 273 if (scaleFactorX > 1 || scaleFactorY > 1) {
280 // Clear one pixel to the right and below, to accommodate bilinear 274 // Clear one pixel to the right and below, to accommodate bilinear
281 // upsampling. 275 // upsampling.
282 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 276 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
283 srcIRect.width() + 1, 1); 277 srcIRect.width() + 1, 1);
284 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget()); 278 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget());
285 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 279 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
286 1, srcIRect.height()); 280 1, srcIRect.height());
287 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget()); 281 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget());
288 SkMatrix matrix; 282 SkMatrix matrix;
289 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 283 matrix.setIDiv(srcTexture->width(), srcTexture->height());
290 284
291 GrPaint paint; 285 GrPaint paint;
292 // FIXME: this should be mitchell, not bilinear. 286 // FIXME: this should be mitchell, not bilinear.
293 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode); 287 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode);
294 paint.addColorTextureProcessor(srcTexture, matrix, params); 288 paint.addColorTextureProcessor(srcTexture, matrix, params);
295 289
296 SkRect dstRect(srcRect); 290 SkRect dstRect(srcRect);
297 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 291 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
298 context->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, 292 context->drawNonAARectToRect(dstTexture->asRenderTarget(), paint, SkMatr ix::I(), dstRect,
299 SkMatrix::I(), dstRect, srcRect); 293 srcRect);
300 srcRect = dstRect; 294 srcRect = dstRect;
301 srcTexture = dstTexture; 295 srcTexture = dstTexture;
302 SkTSwap(dstTexture, tempTexture); 296 SkTSwap(dstTexture, tempTexture);
303 } 297 }
304 return SkRef(srcTexture); 298 return SkRef(srcTexture);
305 } 299 }
306 #endif 300 #endif
307 301
308 } 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