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

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

Issue 1956023002: Revert of Simplify SkGpuBlurUtils::GaussianBlur method (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 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/SkGpuBlurUtils.h ('k') | src/gpu/GrContext.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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 direction, radius, sigma, true, bounds); 158 direction, radius, sigma, true, bounds);
159 convolve_gaussian_1d(drawContext, clip, rightRect, srcOffset, texture, 159 convolve_gaussian_1d(drawContext, clip, rightRect, srcOffset, texture,
160 direction, radius, sigma, true, bounds); 160 direction, radius, sigma, true, bounds);
161 convolve_gaussian_1d(drawContext, clip, midRect, srcOffset, texture, 161 convolve_gaussian_1d(drawContext, clip, midRect, srcOffset, texture,
162 direction, radius, sigma, false, bounds); 162 direction, radius, sigma, false, bounds);
163 } 163 }
164 } 164 }
165 165
166 GrTexture* GaussianBlur(GrContext* context, 166 GrTexture* GaussianBlur(GrContext* context,
167 GrTexture* srcTexture, 167 GrTexture* srcTexture,
168 bool canClobberSrc,
168 bool gammaCorrect, 169 bool gammaCorrect,
169 const SkRect& dstBounds, 170 const SkRect& dstBounds,
170 const SkRect* srcBounds, 171 const SkRect* srcBounds,
171 float sigmaX, 172 float sigmaX,
172 float sigmaY) { 173 float sigmaY) {
173 SkASSERT(context); 174 SkASSERT(context);
174 SkIRect clearRect; 175 SkIRect clearRect;
175 int scaleFactorX, radiusX; 176 int scaleFactorX, radiusX;
176 int scaleFactorY, radiusY; 177 int scaleFactorY, radiusY;
177 int maxTextureSize = context->caps()->maxTextureSize(); 178 int maxTextureSize = context->caps()->maxTextureSize();
(...skipping 19 matching lines...) Expand all
197 198
198 // setup new clip 199 // setup new clip
199 GrClip clip(localDstBounds); 200 GrClip clip(localDstBounds);
200 201
201 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || 202 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
202 kRGBA_8888_GrPixelConfig == srcTexture->config() || 203 kRGBA_8888_GrPixelConfig == srcTexture->config() ||
203 kSRGBA_8888_GrPixelConfig == srcTexture->config() || 204 kSRGBA_8888_GrPixelConfig == srcTexture->config() ||
204 kSBGRA_8888_GrPixelConfig == srcTexture->config() || 205 kSBGRA_8888_GrPixelConfig == srcTexture->config() ||
205 kAlpha_8_GrPixelConfig == srcTexture->config()); 206 kAlpha_8_GrPixelConfig == srcTexture->config());
206 207
207 const int width = SkScalarFloorToInt(dstBounds.width());
208 const int height = SkScalarFloorToInt(dstBounds.height());
209 const GrPixelConfig config = srcTexture->config();
210
211 const SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0,
212 SkSurfaceProps::kLegacyFontHost_InitType);
213
214 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just
215 // launch a single non separable kernel vs two launches
216 if (sigmaX > 0.0f && sigmaY > 0.0f &&
217 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
218 // We shouldn't be scaling because this is a small size blur
219 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
220
221 sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit ::kApprox,
222 width, heigh t, config,
223 0, kDefault_ GrSurfaceOrigin,
224 &props));
225 if (!dstDrawContext) {
226 return nullptr;
227 }
228 convolve_gaussian_2d(dstDrawContext.get(), clip, localDstBounds, srcOffs et,
229 srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBo unds);
230
231 return dstDrawContext->asTexture().release();
232 }
233
234 GrSurfaceDesc desc; 208 GrSurfaceDesc desc;
235 desc.fFlags = kRenderTarget_GrSurfaceFlag; 209 desc.fFlags = kRenderTarget_GrSurfaceFlag;
236 desc.fWidth = width; 210 desc.fWidth = SkScalarFloorToInt(dstBounds.width());
237 desc.fHeight = height; 211 desc.fHeight = SkScalarFloorToInt(dstBounds.height());
238 desc.fConfig = config; 212 desc.fConfig = srcTexture->config();
239 213
240 GrTexture* dstTexture; 214 GrTexture* dstTexture;
241 GrTexture* tempTexture; 215 GrTexture* tempTexture;
242 SkAutoTUnref<GrTexture> temp1, temp2; 216 SkAutoTUnref<GrTexture> temp1, temp2;
243 217
244 temp1.reset(context->textureProvider()->createApproxTexture(desc)); 218 temp1.reset(context->textureProvider()->createApproxTexture(desc));
245 dstTexture = temp1.get(); 219 dstTexture = temp1.get();
246 temp2.reset(context->textureProvider()->createApproxTexture(desc)); 220 if (canClobberSrc) {
247 tempTexture = temp2.get(); 221 tempTexture = srcTexture;
222 } else {
223 temp2.reset(context->textureProvider()->createApproxTexture(desc));
224 tempTexture = temp2.get();
225 }
248 226
249 if (!dstTexture || !tempTexture) { 227 if (nullptr == dstTexture || nullptr == tempTexture) {
250 return nullptr; 228 return nullptr;
251 } 229 }
252 230
253 sk_sp<GrDrawContext> srcDrawContext; 231 sk_sp<GrDrawContext> srcDrawContext;
254 232
255 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 233 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
256 GrPaint paint; 234 GrPaint paint;
257 paint.setGammaCorrect(gammaCorrect); 235 paint.setGammaCorrect(gammaCorrect);
258 SkMatrix matrix; 236 SkMatrix matrix;
259 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 237 matrix.setIDiv(srcTexture->width(), srcTexture->height());
260 SkRect dstRect(srcRect); 238 SkRect dstRect(srcRect);
261 if (srcBounds && i == 1) { 239 if (srcBounds && i == 1) {
262 SkRect domain; 240 SkRect domain;
263 matrix.mapRect(&domain, *srcBounds); 241 matrix.mapRect(&domain, *srcBounds);
264 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width( ) : 0.0f, 242 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width( ) : 0.0f,
265 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height () : 0.0f); 243 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height () : 0.0f);
266 sk_sp<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create( 244 SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Cr eate(
267 srcTexture, 245 srcTexture,
268 matrix, 246 matrix,
269 domain, 247 domain,
270 GrTextureDomain::kDecal_ Mode, 248 GrTextureDomain::kDecal_Mode,
271 GrTextureParams::kBilerp _FilterMode)); 249 GrTextureParams::kBilerp_FilterMode));
272 paint.addColorFragmentProcessor(fp.get()); 250 paint.addColorFragmentProcessor(fp);
273 srcRect.offset(-srcOffset); 251 srcRect.offset(-srcOffset);
274 srcOffset.set(0, 0); 252 srcOffset.set(0, 0);
275 } else { 253 } else {
276 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode); 254 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode);
277 paint.addColorTextureProcessor(srcTexture, matrix, params); 255 paint.addColorTextureProcessor(srcTexture, matrix, params);
278 } 256 }
279 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 257 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
280 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 258 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
281 i < scaleFactorY ? 0.5f : 1.0f); 259 i < scaleFactorY ? 0.5f : 1.0f);
282 260
283 sk_sp<GrDrawContext> dstDrawContext( 261 sk_sp<GrDrawContext> dstDrawContext(
284 context->drawContext(sk_ref_sp(dstTexture->as RenderTarget()))); 262 context->drawContext(sk_ref_sp(dstTexture->as RenderTarget())));
285 if (!dstDrawContext) { 263 if (!dstDrawContext) {
286 return nullptr; 264 return nullptr;
287 } 265 }
288 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR ect); 266 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR ect);
289 267
290 srcDrawContext.swap(dstDrawContext); 268 srcDrawContext.swap(dstDrawContext);
291 srcRect = dstRect; 269 srcRect = dstRect;
292 srcTexture = dstTexture; 270 srcTexture = dstTexture;
293 SkTSwap(dstTexture, tempTexture); 271 SkTSwap(dstTexture, tempTexture);
294 localSrcBounds = srcRect; 272 localSrcBounds = srcRect;
295 } 273 }
296 274
275 SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0,
276 SkSurfaceProps::kLegacyFontHost_InitType);
277
278 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just
279 // launch a single non separable kernel vs two launches
297 srcRect = localDstBounds; 280 srcRect = localDstBounds;
298 281 if (sigmaX > 0.0f && sigmaY > 0.0f &&
299 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 282 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
300 srcRect.roundOut(&srcRect); 283 // We shouldn't be scaling because this is a small size blur
301 SkIRect srcIRect = srcRect.roundOut(); 284 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
302 if (sigmaX > 0.0f) {
303 if (scaleFactorX > 1) {
304 // TODO: if we pass in the source draw context we don't need this he re
305 if (!srcDrawContext) {
306 srcDrawContext = context->drawContext(sk_ref_sp(srcTexture->asRe nderTarget()));
307 if (!srcDrawContext) {
308 return nullptr;
309 }
310 }
311
312 // Clear out a radius to the right of the srcRect to prevent the
313 // X convolution from reading garbage.
314 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
315 radiusX, srcIRect.height());
316 srcDrawContext->clear(&clearRect, 0x0, false);
317 }
318 285
319 sk_sp<GrDrawContext> dstDrawContext( 286 sk_sp<GrDrawContext> dstDrawContext(
320 context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &props )); 287 context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &props ));
321 if (!dstDrawContext) { 288 if (!dstDrawContext) {
322 return nullptr; 289 return nullptr;
323 } 290 }
324 convolve_gaussian(dstDrawContext.get(), clip, srcRect, 291 convolve_gaussian_2d(dstDrawContext.get(), clip, srcRect, srcOffset,
325 srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, s igmaX, 292 srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBo unds);
326 srcBounds, srcOffset); 293
327 srcDrawContext.swap(dstDrawContext); 294 srcDrawContext.swap(dstDrawContext);
295 srcRect.offsetTo(0, 0);
328 srcTexture = dstTexture; 296 srcTexture = dstTexture;
329 srcRect.offsetTo(0, 0);
330 SkTSwap(dstTexture, tempTexture); 297 SkTSwap(dstTexture, tempTexture);
331 localSrcBounds = srcRect;
332 srcOffset.set(0, 0);
333 }
334 298
335 if (sigmaY > 0.0f) { 299 } else {
336 if (scaleFactorY > 1 || sigmaX > 0.0f) { 300 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
337 // TODO: if we pass in the source draw context we don't need this he re 301 srcRect.roundOut(&srcRect);
338 if (!srcDrawContext) { 302 const SkIRect srcIRect = srcRect.roundOut();
339 srcDrawContext = context->drawContext(sk_ref_sp(srcTexture->asRe nderTarget())); 303 if (sigmaX > 0.0f) {
304 if (scaleFactorX > 1) {
305 // TODO: if we pass in the source draw context we don't need thi s here
340 if (!srcDrawContext) { 306 if (!srcDrawContext) {
341 return nullptr; 307 srcDrawContext = context->drawContext(sk_ref_sp(srcTexture-> asRenderTarget()));
308 if (!srcDrawContext) {
309 return nullptr;
310 }
342 } 311 }
312
313 // Clear out a radius to the right of the srcRect to prevent the
314 // X convolution from reading garbage.
315 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
316 radiusX, srcIRect.height());
317 srcDrawContext->clear(&clearRect, 0x0, false);
343 } 318 }
344 319
345 // Clear out a radius below the srcRect to prevent the Y 320 sk_sp<GrDrawContext> dstDrawContext(
346 // convolution from reading garbage. 321 context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &p rops));
347 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 322 if (!dstDrawContext) {
348 srcIRect.width(), radiusY); 323 return nullptr;
349 srcDrawContext->clear(&clearRect, 0x0, false); 324 }
325 convolve_gaussian(dstDrawContext.get(), clip, srcRect,
326 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX,
327 srcBounds, srcOffset);
328 srcDrawContext.swap(dstDrawContext);
329 srcTexture = dstTexture;
330 srcRect.offsetTo(0, 0);
331 SkTSwap(dstTexture, tempTexture);
332 localSrcBounds = srcRect;
333 srcOffset.set(0, 0);
350 } 334 }
351 335
352 sk_sp<GrDrawContext> dstDrawContext( 336 if (sigmaY > 0.0f) {
353 context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &props )); 337 if (scaleFactorY > 1 || sigmaX > 0.0f) {
354 if (!dstDrawContext) { 338 // TODO: if we pass in the source draw context we don't need thi s here
355 return nullptr; 339 if (!srcDrawContext) {
340 srcDrawContext = context->drawContext(sk_ref_sp(srcTexture-> asRenderTarget()));
341 if (!srcDrawContext) {
342 return nullptr;
343 }
344 }
345
346 // Clear out a radius below the srcRect to prevent the Y
347 // convolution from reading garbage.
348 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
349 srcIRect.width(), radiusY);
350 srcDrawContext->clear(&clearRect, 0x0, false);
351 }
352
353 sk_sp<GrDrawContext> dstDrawContext(
354 context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &p rops));
355 if (!dstDrawContext) {
356 return nullptr;
357 }
358 convolve_gaussian(dstDrawContext.get(), clip, srcRect,
359 srcTexture, Gr1DKernelEffect::kY_Direction, radius Y, sigmaY,
360 srcBounds, srcOffset);
361
362 srcDrawContext.swap(dstDrawContext);
363 srcTexture = dstTexture;
364 srcRect.offsetTo(0, 0);
365 SkTSwap(dstTexture, tempTexture);
356 } 366 }
357 convolve_gaussian(dstDrawContext.get(), clip, srcRect,
358 srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, s igmaY,
359 srcBounds, srcOffset);
360
361 srcDrawContext.swap(dstDrawContext);
362 srcTexture = dstTexture;
363 srcRect.offsetTo(0, 0);
364 SkTSwap(dstTexture, tempTexture);
365 } 367 }
366 368 const SkIRect srcIRect = srcRect.roundOut();
367 srcIRect = srcRect.roundOut();
368 369
369 if (scaleFactorX > 1 || scaleFactorY > 1) { 370 if (scaleFactorX > 1 || scaleFactorY > 1) {
370 SkASSERT(srcDrawContext); 371 SkASSERT(srcDrawContext);
371 372
372 // Clear one pixel to the right and below, to accommodate bilinear 373 // Clear one pixel to the right and below, to accommodate bilinear
373 // upsampling. 374 // upsampling.
374 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 375 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
375 srcIRect.width() + 1, 1); 376 srcIRect.width() + 1, 1);
376 srcDrawContext->clear(&clearRect, 0x0, false); 377 srcDrawContext->clear(&clearRect, 0x0, false);
377 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 378 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
(...skipping 23 matching lines...) Expand all
401 srcRect = dstRect; 402 srcRect = dstRect;
402 srcTexture = dstTexture; 403 srcTexture = dstTexture;
403 SkTSwap(dstTexture, tempTexture); 404 SkTSwap(dstTexture, tempTexture);
404 } 405 }
405 406
406 return SkRef(srcTexture); 407 return SkRef(srcTexture);
407 } 408 }
408 #endif 409 #endif
409 410
410 } 411 }
OLDNEW
« no previous file with comments | « src/effects/SkGpuBlurUtils.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698