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

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

Issue 729463002: Cache blur mask for rects which can not break into nine-patch (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix edge artifacts Created 6 years 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
« src/core/SkMaskFilter.cpp ('K') | « src/core/SkMaskFilter.cpp ('k') | no next file » | 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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkBlurMaskFilter.h" 9 #include "SkBlurMaskFilter.h"
10 #include "SkBlurMask.h" 10 #include "SkBlurMask.h"
11 #include "SkGpuBlurUtils.h" 11 #include "SkGpuBlurUtils.h"
12 #include "SkReadBuffer.h" 12 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
14 #include "SkMaskCache.h"
14 #include "SkMaskFilter.h" 15 #include "SkMaskFilter.h"
15 #include "SkRRect.h" 16 #include "SkRRect.h"
16 #include "SkRTConf.h" 17 #include "SkRTConf.h"
17 #include "SkStringUtils.h" 18 #include "SkStringUtils.h"
18 #include "SkStrokeRec.h" 19 #include "SkStrokeRec.h"
19 20
20 #if SK_SUPPORT_GPU 21 #if SK_SUPPORT_GPU
21 #include "GrContext.h" 22 #include "GrContext.h"
22 #include "GrTexture.h" 23 #include "GrTexture.h"
23 #include "GrFragmentProcessor.h" 24 #include "GrFragmentProcessor.h"
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 canvas.drawPath(path, paint); 252 canvas.drawPath(path, paint);
252 } 253 }
253 return true; 254 return true;
254 } 255 }
255 256
256 static bool rect_exceeds(const SkRect& r, SkScalar v) { 257 static bool rect_exceeds(const SkRect& r, SkScalar v) {
257 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || 258 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v ||
258 r.width() > v || r.height() > v; 259 r.width() > v || r.height() > v;
259 } 260 }
260 261
261 #include "SkMaskCache.h"
262
263 static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) {
264 const size_t size = data->size();
265 SkASSERT(mask->computeTotalImageSize() <= size);
266
267 mask->fImage = SkMask::AllocImage(size);
268 if (mask->fImage) {
269 memcpy(mask->fImage, data->data(), size);
270 return true;
271 }
272 return false;
273 }
274
275 static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) {
276 const size_t size = mask.computeTotalImageSize();
277 SkCachedData* data = SkResourceCache::NewCachedData(size);
278 if (data) {
279 memcpy(data->writable_data(), mask.fImage, size);
280 return data;
281 }
282 return NULL;
283 }
284
285 static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style,
286 SkBlurQuality quality, const SkRRect& rrect) {
287 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit y, rrect, mask));
288 return data.get() && copy_cacheddata_to_mask(data, mask);
289 }
290
291 static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle sty le,
292 SkBlurQuality quality, const SkRRect& rrect) {
293 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask));
294 if (data.get()) {
295 SkMaskCache::Add(sigma, style, quality, rrect, mask, data);
296 }
297 }
298
299 static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style,
300 SkBlurQuality quality, const SkRect rects[], int c ount) {
301 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit y, rects, count, mask));
302 return data.get() && copy_cacheddata_to_mask(data, mask);
303 }
304
305 static void add_cached_rects(const SkMask& mask, SkScalar sigma, SkBlurStyle sty le,
306 SkBlurQuality quality, const SkRect rects[], int co unt) {
307 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask));
308 if (data.get()) {
309 SkMaskCache::Add(sigma, style, quality, rects, count, mask, data);
310 }
311 }
312
313 #ifdef SK_IGNORE_FAST_RRECT_BLUR 262 #ifdef SK_IGNORE_FAST_RRECT_BLUR
314 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" ); 263 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" );
315 #else 264 #else
316 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" ); 265 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" );
317 #endif 266 #endif
318 267
319 SkMaskFilter::FilterReturn 268 SkMaskFilter::FilterReturn
320 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix, 269 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix,
321 const SkIRect& clipBounds, 270 const SkIRect& clipBounds,
322 NinePatch* patch) const { 271 NinePatch* patch) const {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 364
416 SkRRect smallRR; 365 SkRRect smallRR;
417 SkVector radii[4]; 366 SkVector radii[4];
418 radii[SkRRect::kUpperLeft_Corner] = UL; 367 radii[SkRRect::kUpperLeft_Corner] = UL;
419 radii[SkRRect::kUpperRight_Corner] = UR; 368 radii[SkRRect::kUpperRight_Corner] = UR;
420 radii[SkRRect::kLowerRight_Corner] = LR; 369 radii[SkRRect::kLowerRight_Corner] = LR;
421 radii[SkRRect::kLowerLeft_Corner] = LL; 370 radii[SkRRect::kLowerLeft_Corner] = LL;
422 smallRR.setRectRadii(smallR, radii); 371 smallRR.setRectRadii(smallR, radii);
423 372
424 const SkScalar sigma = this->computeXformedSigma(matrix); 373 const SkScalar sigma = this->computeXformedSigma(matrix);
425 if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR)) { 374 if (!SkMaskCache::FindCachedRRect(&patch->fMask, sigma, fBlurStyle, this->ge tQuality(), smallRR)) {
426 bool analyticBlurWorked = false; 375 bool analyticBlurWorked = false;
427 if (c_analyticBlurRRect) { 376 if (c_analyticBlurRRect) {
428 analyticBlurWorked = 377 analyticBlurWorked =
429 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, 378 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin,
430 SkMask::kComputeBoundsAndRenderImage_Creat eMode); 379 SkMask::kComputeBoundsAndRenderImage_Creat eMode);
431 } 380 }
432 381
433 if (!analyticBlurWorked) { 382 if (!analyticBlurWorked) {
434 if (!draw_rrect_into_mask(smallRR, &srcM)) { 383 if (!draw_rrect_into_mask(smallRR, &srcM)) {
435 return kFalse_FilterReturn; 384 return kFalse_FilterReturn;
436 } 385 }
437 386
438 SkAutoMaskFreeImage amf(srcM.fImage); 387 SkAutoMaskFreeImage amf(srcM.fImage);
439 388
440 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 389 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
441 return kFalse_FilterReturn; 390 return kFalse_FilterReturn;
442 } 391 }
443 } 392 }
444 add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm allRR); 393 SkMaskCache::AddCachedRRect(patch->fMask, sigma, fBlurStyle, this->getQu ality(), smallRR);
445 } 394 }
446 395
447 patch->fMask.fBounds.offsetTo(0, 0); 396 patch->fMask.fBounds.offsetTo(0, 0);
448 patch->fOuterRect = dstM.fBounds; 397 patch->fOuterRect = dstM.fBounds;
449 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; 398 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1;
450 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; 399 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1;
451 return kTrue_FilterReturn; 400 return kTrue_FilterReturn;
452 } 401 }
453 402
454 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); 403 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" );
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 if (smallR[0].width() < 2 || smallR[0].height() < 2) { 494 if (smallR[0].width() < 2 || smallR[0].height() < 2) {
546 return kUnimplemented_FilterReturn; 495 return kUnimplemented_FilterReturn;
547 } 496 }
548 if (2 == count) { 497 if (2 == count) {
549 smallR[1].set(rects[1].left(), rects[1].top(), 498 smallR[1].set(rects[1].left(), rects[1].top(),
550 rects[1].right() - dx, rects[1].bottom() - dy); 499 rects[1].right() - dx, rects[1].bottom() - dy);
551 SkASSERT(!smallR[1].isEmpty()); 500 SkASSERT(!smallR[1].isEmpty());
552 } 501 }
553 502
554 const SkScalar sigma = this->computeXformedSigma(matrix); 503 const SkScalar sigma = this->computeXformedSigma(matrix);
555 if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallR, count)) { 504 if (!SkMaskCache::FindCachedRects(&patch->fMask, sigma, fBlurStyle, this->ge tQuality(), smallR, count)) {
556 if (count > 1 || !c_analyticBlurNinepatch) { 505 if (count > 1 || !c_analyticBlurNinepatch) {
557 if (!draw_rects_into_mask(smallR, count, &srcM)) { 506 if (!draw_rects_into_mask(smallR, count, &srcM)) {
558 return kFalse_FilterReturn; 507 return kFalse_FilterReturn;
559 } 508 }
560 509
561 SkAutoMaskFreeImage amf(srcM.fImage); 510 SkAutoMaskFreeImage amf(srcM.fImage);
562 511
563 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 512 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
564 return kFalse_FilterReturn; 513 return kFalse_FilterReturn;
565 } 514 }
566 } else { 515 } else {
567 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, 516 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin,
568 SkMask::kComputeBoundsAndRenderImage_Creat eMode)) { 517 SkMask::kComputeBoundsAndRenderImage_Creat eMode)) {
569 return kFalse_FilterReturn; 518 return kFalse_FilterReturn;
570 } 519 }
571 } 520 }
572 add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm allR, count); 521 SkMaskCache::AddCachedRects(patch->fMask, sigma, fBlurStyle, this->getQu ality(), smallR, count);
573 } 522 }
574 patch->fMask.fBounds.offsetTo(0, 0); 523 patch->fMask.fBounds.offsetTo(0, 0);
575 patch->fOuterRect = dstM.fBounds; 524 patch->fOuterRect = dstM.fBounds;
576 patch->fCenter = center; 525 patch->fCenter = center;
577 return kTrue_FilterReturn; 526 return kTrue_FilterReturn;
578 } 527 }
579 528
580 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, 529 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src,
581 SkRect* dst) const { 530 SkRect* dst) const {
582 SkScalar pad = 3.0f * fSigma; 531 SkScalar pad = 3.0f * fSigma;
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 } else { 1217 } else {
1269 str->append("None"); 1218 str->append("None");
1270 } 1219 }
1271 str->append("))"); 1220 str->append("))");
1272 } 1221 }
1273 #endif 1222 #endif
1274 1223
1275 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1224 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
1276 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1225 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
1277 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1226 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« src/core/SkMaskFilter.cpp ('K') | « src/core/SkMaskFilter.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698