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

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

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

Powered by Google App Engine
This is Rietveld 408576698