Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "GrEffect.h" | 24 #include "GrEffect.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 virtual bool filterMaskGPU(GrTexture* src, | 60 virtual bool filterMaskGPU(GrTexture* src, |
| 60 const SkMatrix& ctm, | 61 const SkMatrix& ctm, |
| 61 const SkRect& maskRect, | 62 const SkRect& maskRect, |
| 62 GrTexture** result, | 63 GrTexture** result, |
| 63 bool canOverwriteSrc) const SK_OVERRIDE; | 64 bool canOverwriteSrc) const SK_OVERRIDE; |
| 64 #endif | 65 #endif |
| 65 | 66 |
| 66 virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; | 67 virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; |
| 67 virtual bool asABlur(BlurRec*) const SK_OVERRIDE; | 68 virtual bool asABlur(BlurRec*) const SK_OVERRIDE; |
| 68 | 69 |
| 70 static bool getCachedBlurMask(SkScalar sigma, | |
| 71 unsigned rectCount, | |
| 72 const SkRect rects[], | |
| 73 SkCachedMask &mask); | |
| 74 static bool getCachedBlurMask(SkScalar sigma, | |
| 75 const SkRRect rrect, | |
| 76 SkCachedMask &mask); | |
| 77 | |
| 69 SK_TO_STRING_OVERRIDE() | 78 SK_TO_STRING_OVERRIDE() |
| 70 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) | 79 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) |
| 71 | 80 |
| 72 protected: | 81 protected: |
| 73 virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMa trix&, | 82 virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMa trix&, |
| 74 const SkIRect& clipBounds, | 83 const SkIRect& clipBounds, |
| 75 NinePatch*) const SK_OVERRIDE; | 84 NinePatch*) const SK_OVERRIDE; |
| 76 | 85 |
| 77 virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&, | 86 virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&, |
| 78 const SkIRect& clipBounds, | 87 const SkIRect& clipBounds, |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 108 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); | 117 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); |
| 109 } | 118 } |
| 110 | 119 |
| 111 friend class SkBlurMaskFilter; | 120 friend class SkBlurMaskFilter; |
| 112 | 121 |
| 113 typedef SkMaskFilter INHERITED; | 122 typedef SkMaskFilter INHERITED; |
| 114 }; | 123 }; |
| 115 | 124 |
| 116 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); | 125 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); |
| 117 | 126 |
| 127 bool SkBlurMaskFilterImpl::getCachedBlurMask(SkScalar sigma, | |
|
reed1
2014/08/25 11:58:42
Do we really need these helper methods? The caller
qiankun
2014/08/26 08:36:33
Done.
| |
| 128 const SkRRect rrect, | |
| 129 SkCachedMask &mask) { | |
|
reed1
2014/08/25 11:58:42
skia's convention is to only use reference-paramet
qiankun
2014/08/26 08:36:33
Done.
| |
| 130 SkMaskCache::ID* cacheId = SkMaskCache::FindAndLock(sigma, rrect, &mask.fMas k); | |
| 131 mask.fCacheId = cacheId; | |
|
reed1
2014/08/25 11:58:42
Skia's convention is to not set the result fields
qiankun
2014/08/26 08:36:33
Done.
| |
| 132 return cacheId ? true : false; | |
| 133 } | |
| 134 | |
| 135 bool SkBlurMaskFilterImpl::getCachedBlurMask(SkScalar sigma, | |
| 136 unsigned rectCount, | |
| 137 const SkRect rects[], | |
| 138 SkCachedMask &mask) { | |
| 139 SkMaskCache::ID* cacheId = SkMaskCache::FindAndLock(sigma, rectCount, rects, &mask.fMask); | |
| 140 mask.fCacheId = cacheId; | |
| 141 return cacheId ? true : false; | |
| 142 } | |
| 143 | |
| 118 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32 _t flags) { | 144 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32 _t flags) { |
| 119 if (!SkScalarIsFinite(sigma) || sigma <= 0) { | 145 if (!SkScalarIsFinite(sigma) || sigma <= 0) { |
| 120 return NULL; | 146 return NULL; |
| 121 } | 147 } |
| 122 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { | 148 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { |
| 123 return NULL; | 149 return NULL; |
| 124 } | 150 } |
| 125 if (flags > SkBlurMaskFilter::kAll_BlurFlag) { | 151 if (flags > SkBlurMaskFilter::kAll_BlurFlag) { |
| 126 return NULL; | 152 return NULL; |
| 127 } | 153 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); | 387 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); |
| 362 | 388 |
| 363 SkRRect smallRR; | 389 SkRRect smallRR; |
| 364 SkVector radii[4]; | 390 SkVector radii[4]; |
| 365 radii[SkRRect::kUpperLeft_Corner] = UL; | 391 radii[SkRRect::kUpperLeft_Corner] = UL; |
| 366 radii[SkRRect::kUpperRight_Corner] = UR; | 392 radii[SkRRect::kUpperRight_Corner] = UR; |
| 367 radii[SkRRect::kLowerRight_Corner] = LR; | 393 radii[SkRRect::kLowerRight_Corner] = LR; |
| 368 radii[SkRRect::kLowerLeft_Corner] = LL; | 394 radii[SkRRect::kLowerLeft_Corner] = LL; |
| 369 smallRR.setRectRadii(smallR, radii); | 395 smallRR.setRectRadii(smallR, radii); |
| 370 | 396 |
| 397 SkScalar sigma = this->computeXformedSigma(matrix); | |
| 398 SkCachedMask cachedBlurMask; | |
| 399 cachedBlurMask.fCacheId = NULL; | |
| 400 if (getCachedBlurMask(sigma, rrect, cachedBlurMask)) { | |
| 401 patch->fCachedMask = cachedBlurMask; | |
| 402 patch->fOuterRect = dstM.fBounds; | |
| 403 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | |
| 404 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | |
| 405 return kTrue_FilterReturn; | |
| 406 } | |
| 407 | |
| 371 bool analyticBlurWorked = false; | 408 bool analyticBlurWorked = false; |
| 372 if (c_analyticBlurRRect) { | 409 if (c_analyticBlurRRect) { |
| 373 analyticBlurWorked = | 410 analyticBlurWorked = |
| 374 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, | 411 this->filterRRectMask(&(patch->fCachedMask.fMask), smallRR, matrix, &margin, |
| 375 SkMask::kComputeBoundsAndRenderImage_CreateMod e); | 412 SkMask::kComputeBoundsAndRenderImage_CreateMod e); |
| 376 } | 413 } |
| 377 | 414 |
| 378 if (!analyticBlurWorked) { | 415 if (!analyticBlurWorked) { |
| 379 if (!draw_rrect_into_mask(smallRR, &srcM)) { | 416 if (!draw_rrect_into_mask(smallRR, &srcM)) { |
| 380 return kFalse_FilterReturn; | 417 return kFalse_FilterReturn; |
| 381 } | 418 } |
| 382 | 419 |
| 383 SkAutoMaskFreeImage amf(srcM.fImage); | 420 SkAutoMaskFreeImage amf(srcM.fImage); |
| 384 | 421 |
| 385 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 422 if (!this->filterMask(&(patch->fCachedMask.fMask), srcM, matrix, &margin )) { |
| 386 return kFalse_FilterReturn; | 423 return kFalse_FilterReturn; |
| 387 } | 424 } |
| 388 } | 425 } |
| 389 | 426 |
| 390 patch->fMask.fBounds.offsetTo(0, 0); | 427 patch->fCachedMask.fMask.fBounds.offsetTo(0, 0); |
| 391 patch->fOuterRect = dstM.fBounds; | 428 patch->fOuterRect = dstM.fBounds; |
| 392 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 429 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
| 393 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 430 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| 431 if (!cachedBlurMask.fCacheId) { | |
| 432 patch->fCachedMask.fCacheId = SkMaskCache::AddAndLock(sigma, rrect, | |
| 433 patch->fCachedMask .fMask); | |
| 434 } | |
| 435 | |
| 394 return kTrue_FilterReturn; | 436 return kTrue_FilterReturn; |
| 395 } | 437 } |
| 396 | 438 |
| 397 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); | 439 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); |
| 398 | 440 |
| 399 SkMaskFilter::FilterReturn | 441 SkMaskFilter::FilterReturn |
| 400 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, | 442 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| 401 const SkMatrix& matrix, | 443 const SkMatrix& matrix, |
| 402 const SkIRect& clipBounds, | 444 const SkIRect& clipBounds, |
| 403 NinePatch* patch) const { | 445 NinePatch* patch) const { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 463 if (1 == count) { | 505 if (1 == count) { |
| 464 innerIR = srcM.fBounds; | 506 innerIR = srcM.fBounds; |
| 465 center.set(smallW, smallH); | 507 center.set(smallW, smallH); |
| 466 } else { | 508 } else { |
| 467 SkASSERT(2 == count); | 509 SkASSERT(2 == count); |
| 468 rects[1].roundIn(&innerIR); | 510 rects[1].roundIn(&innerIR); |
| 469 center.set(smallW + (innerIR.left() - srcM.fBounds.left()), | 511 center.set(smallW + (innerIR.left() - srcM.fBounds.left()), |
| 470 smallH + (innerIR.top() - srcM.fBounds.top())); | 512 smallH + (innerIR.top() - srcM.fBounds.top())); |
| 471 } | 513 } |
| 472 | 514 |
| 515 SkScalar sigma = this->computeXformedSigma(matrix); | |
| 516 SkCachedMask cachedBlurMask; | |
| 517 cachedBlurMask.fCacheId = NULL; | |
| 518 if (getCachedBlurMask(sigma, count, rects, cachedBlurMask)) { | |
| 519 patch->fCachedMask = cachedBlurMask; | |
| 520 patch->fOuterRect = dstM.fBounds; | |
| 521 patch->fCenter = center; | |
| 522 return kTrue_FilterReturn; | |
| 523 } | |
| 524 | |
| 473 // +1 so we get a clean, stretchable, center row/col | 525 // +1 so we get a clean, stretchable, center row/col |
| 474 smallW += 1; | 526 smallW += 1; |
| 475 smallH += 1; | 527 smallH += 1; |
| 476 | 528 |
| 477 // we want the inset amounts to be integral, so we don't change any | 529 // we want the inset amounts to be integral, so we don't change any |
| 478 // fractional phase on the fRight or fBottom of our smallR. | 530 // fractional phase on the fRight or fBottom of our smallR. |
| 479 const SkScalar dx = SkIntToScalar(innerIR.width() - smallW); | 531 const SkScalar dx = SkIntToScalar(innerIR.width() - smallW); |
| 480 const SkScalar dy = SkIntToScalar(innerIR.height() - smallH); | 532 const SkScalar dy = SkIntToScalar(innerIR.height() - smallH); |
| 481 if (dx < 0 || dy < 0) { | 533 if (dx < 0 || dy < 0) { |
| 482 // we're too small, relative to our blur, to break into nine-patch, | 534 // we're too small, relative to our blur, to break into nine-patch, |
| 483 // so we ask to have our normal filterMask() be called. | 535 // so we ask to have our normal filterMask() be called. |
| 484 return kUnimplemented_FilterReturn; | 536 return kUnimplemented_FilterReturn; |
| 485 } | 537 } |
| 486 | 538 |
| 487 smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[ 0].bottom() - dy); | 539 smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[ 0].bottom() - dy); |
| 488 if (smallR[0].width() < 2 || smallR[0].height() < 2) { | 540 if (smallR[0].width() < 2 || smallR[0].height() < 2) { |
| 489 return kUnimplemented_FilterReturn; | 541 return kUnimplemented_FilterReturn; |
| 490 } | 542 } |
| 491 if (2 == count) { | 543 if (2 == count) { |
| 492 smallR[1].set(rects[1].left(), rects[1].top(), | 544 smallR[1].set(rects[1].left(), rects[1].top(), |
| 493 rects[1].right() - dx, rects[1].bottom() - dy); | 545 rects[1].right() - dx, rects[1].bottom() - dy); |
| 494 SkASSERT(!smallR[1].isEmpty()); | 546 SkASSERT(!smallR[1].isEmpty()); |
| 495 } | 547 } |
| 496 | 548 |
| 497 if (count > 1 || !c_analyticBlurNinepatch) { | 549 if (count > 1 || !c_analyticBlurNinepatch) { |
| 498 if (!draw_rects_into_mask(smallR, count, &srcM)) { | 550 if (!draw_rects_into_mask(smallR, count, &srcM)) { |
| 499 return kFalse_FilterReturn; | 551 return kFalse_FilterReturn; |
| 500 } | 552 } |
| 501 | |
| 502 SkAutoMaskFreeImage amf(srcM.fImage); | 553 SkAutoMaskFreeImage amf(srcM.fImage); |
| 503 | 554 |
| 504 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 555 if (!this->filterMask(&patch->fCachedMask.fMask, srcM, matrix, &margin)) { |
| 505 return kFalse_FilterReturn; | 556 return kFalse_FilterReturn; |
| 506 } | 557 } |
| 507 } else { | 558 } else { |
| 508 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | 559 if (!this->filterRectMask(&patch->fCachedMask.fMask, smallR[0], matrix, &margin, |
| 509 SkMask::kComputeBoundsAndRenderImage_CreateMod e)) { | 560 SkMask::kComputeBoundsAndRenderImage_CreateMod e)) { |
| 510 return kFalse_FilterReturn; | 561 return kFalse_FilterReturn; |
| 511 } | 562 } |
| 512 } | 563 } |
| 513 patch->fMask.fBounds.offsetTo(0, 0); | 564 patch->fCachedMask.fMask.fBounds.offsetTo(0, 0); |
| 514 patch->fOuterRect = dstM.fBounds; | 565 patch->fOuterRect = dstM.fBounds; |
| 515 patch->fCenter = center; | 566 patch->fCenter = center; |
| 567 if (!cachedBlurMask.fCacheId) { | |
| 568 patch->fCachedMask.fCacheId = SkMaskCache::AddAndLock(sigma, count, rect s, | |
| 569 patch->fCachedMask .fMask); | |
| 570 } | |
| 571 | |
| 516 return kTrue_FilterReturn; | 572 return kTrue_FilterReturn; |
| 517 } | 573 } |
| 518 | 574 |
| 519 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 575 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
| 520 SkRect* dst) const { | 576 SkRect* dst) const { |
| 521 SkScalar pad = 3.0f * fSigma; | 577 SkScalar pad = 3.0f * fSigma; |
| 522 | 578 |
| 523 dst->set(src.fLeft - pad, src.fTop - pad, | 579 dst->set(src.fLeft - pad, src.fTop - pad, |
| 524 src.fRight + pad, src.fBottom + pad); | 580 src.fRight + pad, src.fBottom + pad); |
| 525 } | 581 } |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1219 } else { | 1275 } else { |
| 1220 str->append("None"); | 1276 str->append("None"); |
| 1221 } | 1277 } |
| 1222 str->append("))"); | 1278 str->append("))"); |
| 1223 } | 1279 } |
| 1224 #endif | 1280 #endif |
| 1225 | 1281 |
| 1226 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1282 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 1227 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1283 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 1228 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1284 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |