| 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" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 | 118 |
| 119 friend class SkBlurMaskFilter; | 119 friend class SkBlurMaskFilter; |
| 120 | 120 |
| 121 typedef SkMaskFilter INHERITED; | 121 typedef SkMaskFilter INHERITED; |
| 122 }; | 122 }; |
| 123 | 123 |
| 124 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); | 124 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); |
| 125 | 125 |
| 126 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32
_t flags) { | 126 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32
_t flags) { |
| 127 if (!SkScalarIsFinite(sigma) || sigma <= 0) { | 127 if (!SkScalarIsFinite(sigma) || sigma <= 0) { |
| 128 return NULL; | 128 return nullptr; |
| 129 } | 129 } |
| 130 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { | 130 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { |
| 131 return NULL; | 131 return nullptr; |
| 132 } | 132 } |
| 133 if (flags > SkBlurMaskFilter::kAll_BlurFlag) { | 133 if (flags > SkBlurMaskFilter::kAll_BlurFlag) { |
| 134 return NULL; | 134 return nullptr; |
| 135 } | 135 } |
| 136 return new SkBlurMaskFilterImpl(sigma, style, flags); | 136 return new SkBlurMaskFilterImpl(sigma, style, flags); |
| 137 } | 137 } |
| 138 | 138 |
| 139 /////////////////////////////////////////////////////////////////////////////// | 139 /////////////////////////////////////////////////////////////////////////////// |
| 140 | 140 |
| 141 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui
nt32_t flags) | 141 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui
nt32_t flags) |
| 142 : fSigma(sigma) | 142 : fSigma(sigma) |
| 143 , fBlurStyle(style) | 143 , fBlurStyle(style) |
| 144 , fBlurFlags(flags) { | 144 , fBlurFlags(flags) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ | 185 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ |
| 186 SkScalar sigma = computeXformedSigma(matrix); | 186 SkScalar sigma = computeXformedSigma(matrix); |
| 187 | 187 |
| 188 return SkBlurMask::BlurRRect(sigma, dst, r, fBlurStyle, | 188 return SkBlurMask::BlurRRect(sigma, dst, r, fBlurStyle, |
| 189 margin, createMode); | 189 margin, createMode); |
| 190 } | 190 } |
| 191 | 191 |
| 192 #include "SkCanvas.h" | 192 #include "SkCanvas.h" |
| 193 | 193 |
| 194 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { | 194 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { |
| 195 SkASSERT(mask != NULL); | 195 SkASSERT(mask != nullptr); |
| 196 | 196 |
| 197 mask->fBounds = bounds.roundOut(); | 197 mask->fBounds = bounds.roundOut(); |
| 198 mask->fRowBytes = SkAlign4(mask->fBounds.width()); | 198 mask->fRowBytes = SkAlign4(mask->fBounds.width()); |
| 199 mask->fFormat = SkMask::kA8_Format; | 199 mask->fFormat = SkMask::kA8_Format; |
| 200 const size_t size = mask->computeImageSize(); | 200 const size_t size = mask->computeImageSize(); |
| 201 mask->fImage = SkMask::AllocImage(size); | 201 mask->fImage = SkMask::AllocImage(size); |
| 202 if (NULL == mask->fImage) { | 202 if (nullptr == mask->fImage) { |
| 203 return false; | 203 return false; |
| 204 } | 204 } |
| 205 | 205 |
| 206 // FIXME: use sk_calloc in AllocImage? | 206 // FIXME: use sk_calloc in AllocImage? |
| 207 sk_bzero(mask->fImage, size); | 207 sk_bzero(mask->fImage, size); |
| 208 return true; | 208 return true; |
| 209 } | 209 } |
| 210 | 210 |
| 211 static bool draw_rrect_into_mask(const SkRRect rrect, SkMask* mask) { | 211 static bool draw_rrect_into_mask(const SkRRect rrect, SkMask* mask) { |
| 212 if (!prepare_to_draw_into_mask(rrect.rect(), mask)) { | 212 if (!prepare_to_draw_into_mask(rrect.rect(), mask)) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 #ifdef SK_IGNORE_FAST_RRECT_BLUR | 309 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
| 310 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, false, "Use the faster analytic blur approach for ninepatch rects" ); | 310 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, false, "Use the faster analytic blur approach for ninepatch rects" ); |
| 311 #else | 311 #else |
| 312 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, true, "Use the faster analytic blur approach for ninepatch round rects" ); | 312 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, true, "Use the faster analytic blur approach for ninepatch round rects" ); |
| 313 #endif | 313 #endif |
| 314 | 314 |
| 315 SkMaskFilter::FilterReturn | 315 SkMaskFilter::FilterReturn |
| 316 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, | 316 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, |
| 317 const SkIRect& clipBounds, | 317 const SkIRect& clipBounds, |
| 318 NinePatch* patch) const { | 318 NinePatch* patch) const { |
| 319 SkASSERT(patch != NULL); | 319 SkASSERT(patch != nullptr); |
| 320 switch (rrect.getType()) { | 320 switch (rrect.getType()) { |
| 321 case SkRRect::kEmpty_Type: | 321 case SkRRect::kEmpty_Type: |
| 322 // Nothing to draw. | 322 // Nothing to draw. |
| 323 return kFalse_FilterReturn; | 323 return kFalse_FilterReturn; |
| 324 | 324 |
| 325 case SkRRect::kRect_Type: | 325 case SkRRect::kRect_Type: |
| 326 // We should have caught this earlier. | 326 // We should have caught this earlier. |
| 327 SkASSERT(false); | 327 SkASSERT(false); |
| 328 // Fall through. | 328 // Fall through. |
| 329 case SkRRect::kOval_Type: | 329 case SkRRect::kOval_Type: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 346 | 346 |
| 347 // TODO: take clipBounds into account to limit our coordinates up front | 347 // TODO: take clipBounds into account to limit our coordinates up front |
| 348 // for now, just skip too-large src rects (to take the old code path). | 348 // for now, just skip too-large src rects (to take the old code path). |
| 349 if (rect_exceeds(rrect.rect(), SkIntToScalar(32767))) { | 349 if (rect_exceeds(rrect.rect(), SkIntToScalar(32767))) { |
| 350 return kUnimplemented_FilterReturn; | 350 return kUnimplemented_FilterReturn; |
| 351 } | 351 } |
| 352 | 352 |
| 353 SkIPoint margin; | 353 SkIPoint margin; |
| 354 SkMask srcM, dstM; | 354 SkMask srcM, dstM; |
| 355 srcM.fBounds = rrect.rect().roundOut(); | 355 srcM.fBounds = rrect.rect().roundOut(); |
| 356 srcM.fImage = NULL; | 356 srcM.fImage = nullptr; |
| 357 srcM.fFormat = SkMask::kA8_Format; | 357 srcM.fFormat = SkMask::kA8_Format; |
| 358 srcM.fRowBytes = 0; | 358 srcM.fRowBytes = 0; |
| 359 | 359 |
| 360 bool filterResult = false; | 360 bool filterResult = false; |
| 361 if (c_analyticBlurRRect) { | 361 if (c_analyticBlurRRect) { |
| 362 // special case for fast round rect blur | 362 // special case for fast round rect blur |
| 363 // don't actually do the blur the first time, just compute the correct s
ize | 363 // don't actually do the blur the first time, just compute the correct s
ize |
| 364 filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, | 364 filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, |
| 365 SkMask::kJustComputeBounds_CreateMod
e); | 365 SkMask::kJustComputeBounds_CreateMod
e); |
| 366 } | 366 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 return kFalse_FilterReturn; | 435 return kFalse_FilterReturn; |
| 436 } | 436 } |
| 437 } | 437 } |
| 438 cache = add_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQual
ity(), smallRR); | 438 cache = add_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQual
ity(), smallRR); |
| 439 } | 439 } |
| 440 | 440 |
| 441 patch->fMask.fBounds.offsetTo(0, 0); | 441 patch->fMask.fBounds.offsetTo(0, 0); |
| 442 patch->fOuterRect = dstM.fBounds; | 442 patch->fOuterRect = dstM.fBounds; |
| 443 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 443 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
| 444 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 444 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| 445 SkASSERT(NULL == patch->fCache); | 445 SkASSERT(nullptr == patch->fCache); |
| 446 patch->fCache = cache; // transfer ownership to patch | 446 patch->fCache = cache; // transfer ownership to patch |
| 447 return kTrue_FilterReturn; | 447 return kTrue_FilterReturn; |
| 448 } | 448 } |
| 449 | 449 |
| 450 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); | 450 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); |
| 451 | 451 |
| 452 SkMaskFilter::FilterReturn | 452 SkMaskFilter::FilterReturn |
| 453 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, | 453 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| 454 const SkMatrix& matrix, | 454 const SkMatrix& matrix, |
| 455 const SkIRect& clipBounds, | 455 const SkIRect& clipBounds, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 466 | 466 |
| 467 // TODO: take clipBounds into account to limit our coordinates up front | 467 // TODO: take clipBounds into account to limit our coordinates up front |
| 468 // for now, just skip too-large src rects (to take the old code path). | 468 // for now, just skip too-large src rects (to take the old code path). |
| 469 if (rect_exceeds(rects[0], SkIntToScalar(32767))) { | 469 if (rect_exceeds(rects[0], SkIntToScalar(32767))) { |
| 470 return kUnimplemented_FilterReturn; | 470 return kUnimplemented_FilterReturn; |
| 471 } | 471 } |
| 472 | 472 |
| 473 SkIPoint margin; | 473 SkIPoint margin; |
| 474 SkMask srcM, dstM; | 474 SkMask srcM, dstM; |
| 475 srcM.fBounds = rects[0].roundOut(); | 475 srcM.fBounds = rects[0].roundOut(); |
| 476 srcM.fImage = NULL; | 476 srcM.fImage = nullptr; |
| 477 srcM.fFormat = SkMask::kA8_Format; | 477 srcM.fFormat = SkMask::kA8_Format; |
| 478 srcM.fRowBytes = 0; | 478 srcM.fRowBytes = 0; |
| 479 | 479 |
| 480 bool filterResult = false; | 480 bool filterResult = false; |
| 481 if (count == 1 && c_analyticBlurNinepatch) { | 481 if (count == 1 && c_analyticBlurNinepatch) { |
| 482 // special case for fast rect blur | 482 // special case for fast rect blur |
| 483 // don't actually do the blur the first time, just compute the correct s
ize | 483 // don't actually do the blur the first time, just compute the correct s
ize |
| 484 filterResult = this->filterRectMask(&dstM, rects[0], matrix, &margin, | 484 filterResult = this->filterRectMask(&dstM, rects[0], matrix, &margin, |
| 485 SkMask::kJustComputeBounds_CreateMod
e); | 485 SkMask::kJustComputeBounds_CreateMod
e); |
| 486 } else { | 486 } else { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | 565 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, |
| 566 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { | 566 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { |
| 567 return kFalse_FilterReturn; | 567 return kFalse_FilterReturn; |
| 568 } | 568 } |
| 569 } | 569 } |
| 570 cache = add_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQual
ity(), smallR, count); | 570 cache = add_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQual
ity(), smallR, count); |
| 571 } | 571 } |
| 572 patch->fMask.fBounds.offsetTo(0, 0); | 572 patch->fMask.fBounds.offsetTo(0, 0); |
| 573 patch->fOuterRect = dstM.fBounds; | 573 patch->fOuterRect = dstM.fBounds; |
| 574 patch->fCenter = center; | 574 patch->fCenter = center; |
| 575 SkASSERT(NULL == patch->fCache); | 575 SkASSERT(nullptr == patch->fCache); |
| 576 patch->fCache = cache; // transfer ownership to patch | 576 patch->fCache = cache; // transfer ownership to patch |
| 577 return kTrue_FilterReturn; | 577 return kTrue_FilterReturn; |
| 578 } | 578 } |
| 579 | 579 |
| 580 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 580 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
| 581 SkRect* dst) const { | 581 SkRect* dst) const { |
| 582 SkScalar pad = 3.0f * fSigma; | 582 SkScalar pad = 3.0f * fSigma; |
| 583 | 583 |
| 584 dst->set(src.fLeft - pad, src.fTop - pad, | 584 dst->set(src.fLeft - pad, src.fTop - pad, |
| 585 src.fRight + pad, src.fBottom + pad); | 585 src.fRight + pad, src.fBottom + pad); |
| 586 } | 586 } |
| 587 | 587 |
| 588 SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { | 588 SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { |
| 589 const SkScalar sigma = buffer.readScalar(); | 589 const SkScalar sigma = buffer.readScalar(); |
| 590 const unsigned style = buffer.readUInt(); | 590 const unsigned style = buffer.readUInt(); |
| 591 const unsigned flags = buffer.readUInt(); | 591 const unsigned flags = buffer.readUInt(); |
| 592 if (style <= kLastEnum_SkBlurStyle) { | 592 if (style <= kLastEnum_SkBlurStyle) { |
| 593 return SkBlurMaskFilter::Create((SkBlurStyle)style, sigma, flags); | 593 return SkBlurMaskFilter::Create((SkBlurStyle)style, sigma, flags); |
| 594 } | 594 } |
| 595 return NULL; | 595 return nullptr; |
| 596 } | 596 } |
| 597 | 597 |
| 598 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { | 598 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { |
| 599 buffer.writeScalar(fSigma); | 599 buffer.writeScalar(fSigma); |
| 600 buffer.writeUInt(fBlurStyle); | 600 buffer.writeUInt(fBlurStyle); |
| 601 buffer.writeUInt(fBlurFlags); | 601 buffer.writeUInt(fBlurFlags); |
| 602 } | 602 } |
| 603 | 603 |
| 604 #if SK_SUPPORT_GPU | 604 #if SK_SUPPORT_GPU |
| 605 | 605 |
| 606 class GrGLRectBlurEffect; | 606 class GrGLRectBlurEffect; |
| 607 | 607 |
| 608 class GrRectBlurEffect : public GrFragmentProcessor { | 608 class GrRectBlurEffect : public GrFragmentProcessor { |
| 609 public: | 609 public: |
| 610 virtual ~GrRectBlurEffect(); | 610 virtual ~GrRectBlurEffect(); |
| 611 | 611 |
| 612 const char* name() const override { return "RectBlur"; } | 612 const char* name() const override { return "RectBlur"; } |
| 613 | 613 |
| 614 /** | 614 /** |
| 615 * Create a simple filter effect with custom bicubic coefficients. | 615 * Create a simple filter effect with custom bicubic coefficients. |
| 616 */ | 616 */ |
| 617 static GrFragmentProcessor* Create(GrTextureProvider *textureProvider, const
SkRect& rect, | 617 static GrFragmentProcessor* Create(GrTextureProvider *textureProvider, const
SkRect& rect, |
| 618 float sigma) { | 618 float sigma) { |
| 619 GrTexture *blurProfileTexture = NULL; | 619 GrTexture *blurProfileTexture = nullptr; |
| 620 int doubleProfileSize = SkScalarCeilToInt(12*sigma); | 620 int doubleProfileSize = SkScalarCeilToInt(12*sigma); |
| 621 | 621 |
| 622 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { | 622 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { |
| 623 // if the blur sigma is too large so the gaussian overlaps the whole | 623 // if the blur sigma is too large so the gaussian overlaps the whole |
| 624 // rect in either direction, fall back to CPU path for now. | 624 // rect in either direction, fall back to CPU path for now. |
| 625 | 625 |
| 626 return NULL; | 626 return nullptr; |
| 627 } | 627 } |
| 628 | 628 |
| 629 bool createdBlurProfileTexture = CreateBlurProfileTexture( | 629 bool createdBlurProfileTexture = CreateBlurProfileTexture( |
| 630 textureProvider, sigma, &blurProfileTexture); | 630 textureProvider, sigma, &blurProfileTexture); |
| 631 SkAutoTUnref<GrTexture> hunref(blurProfileTexture); | 631 SkAutoTUnref<GrTexture> hunref(blurProfileTexture); |
| 632 if (!createdBlurProfileTexture) { | 632 if (!createdBlurProfileTexture) { |
| 633 return NULL; | 633 return nullptr; |
| 634 } | 634 } |
| 635 return new GrRectBlurEffect(rect, sigma, blurProfileTexture); | 635 return new GrRectBlurEffect(rect, sigma, blurProfileTexture); |
| 636 } | 636 } |
| 637 | 637 |
| 638 const SkRect& getRect() const { return fRect; } | 638 const SkRect& getRect() const { return fRect; } |
| 639 float getSigma() const { return fSigma; } | 639 float getSigma() const { return fSigma; } |
| 640 | 640 |
| 641 private: | 641 private: |
| 642 GrGLFragmentProcessor* onCreateGLInstance() const override; | 642 GrGLFragmentProcessor* onCreateGLInstance() const override; |
| 643 | 643 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 texDesc.fWidth = profileSize; | 755 texDesc.fWidth = profileSize; |
| 756 texDesc.fHeight = 1; | 756 texDesc.fHeight = 1; |
| 757 texDesc.fConfig = kAlpha_8_GrPixelConfig; | 757 texDesc.fConfig = kAlpha_8_GrPixelConfig; |
| 758 | 758 |
| 759 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 759 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| 760 GrUniqueKey key; | 760 GrUniqueKey key; |
| 761 GrUniqueKey::Builder builder(&key, kDomain, 1); | 761 GrUniqueKey::Builder builder(&key, kDomain, 1); |
| 762 builder[0] = profileSize; | 762 builder[0] = profileSize; |
| 763 builder.finish(); | 763 builder.finish(); |
| 764 | 764 |
| 765 uint8_t *profile = NULL; | 765 uint8_t *profile = nullptr; |
| 766 SkAutoTDeleteArray<uint8_t> ada(NULL); | 766 SkAutoTDeleteArray<uint8_t> ada(nullptr); |
| 767 | 767 |
| 768 *blurProfileTexture = textureProvider->findAndRefTextureByUniqueKey(key); | 768 *blurProfileTexture = textureProvider->findAndRefTextureByUniqueKey(key); |
| 769 | 769 |
| 770 if (NULL == *blurProfileTexture) { | 770 if (nullptr == *blurProfileTexture) { |
| 771 | 771 |
| 772 SkBlurMask::ComputeBlurProfile(sigma, &profile); | 772 SkBlurMask::ComputeBlurProfile(sigma, &profile); |
| 773 ada.reset(profile); | 773 ada.reset(profile); |
| 774 | 774 |
| 775 *blurProfileTexture = textureProvider->createTexture(texDesc, true, prof
ile, 0); | 775 *blurProfileTexture = textureProvider->createTexture(texDesc, true, prof
ile, 0); |
| 776 | 776 |
| 777 if (NULL == *blurProfileTexture) { | 777 if (nullptr == *blurProfileTexture) { |
| 778 return false; | 778 return false; |
| 779 } | 779 } |
| 780 textureProvider->assignUniqueKeyToTexture(key, *blurProfileTexture); | 780 textureProvider->assignUniqueKeyToTexture(key, *blurProfileTexture); |
| 781 } | 781 } |
| 782 | 782 |
| 783 return true; | 783 return true; |
| 784 } | 784 } |
| 785 | 785 |
| 786 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, | 786 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, |
| 787 GrTexture *blur_profile) | 787 GrTexture *blur_profile) |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 | 899 |
| 900 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 900 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 901 | 901 |
| 902 typedef GrFragmentProcessor INHERITED; | 902 typedef GrFragmentProcessor INHERITED; |
| 903 }; | 903 }; |
| 904 | 904 |
| 905 | 905 |
| 906 GrFragmentProcessor* GrRRectBlurEffect::Create(GrTextureProvider* texProvider, f
loat sigma, | 906 GrFragmentProcessor* GrRRectBlurEffect::Create(GrTextureProvider* texProvider, f
loat sigma, |
| 907 const SkRRect& rrect) { | 907 const SkRRect& rrect) { |
| 908 if (!rrect.isSimpleCircular()) { | 908 if (!rrect.isSimpleCircular()) { |
| 909 return NULL; | 909 return nullptr; |
| 910 } | 910 } |
| 911 | 911 |
| 912 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be | 912 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be |
| 913 // sufficiently small relative to both the size of the corner radius and the | 913 // sufficiently small relative to both the size of the corner radius and the |
| 914 // width (and height) of the rrect. | 914 // width (and height) of the rrect. |
| 915 | 915 |
| 916 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); | 916 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); |
| 917 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); | 917 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); |
| 918 if (cornerRadius + blurRadius > rrect.width()/2 || | 918 if (cornerRadius + blurRadius > rrect.width()/2 || |
| 919 cornerRadius + blurRadius > rrect.height()/2) { | 919 cornerRadius + blurRadius > rrect.height()/2) { |
| 920 return NULL; | 920 return nullptr; |
| 921 } | 921 } |
| 922 | 922 |
| 923 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 923 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| 924 GrUniqueKey key; | 924 GrUniqueKey key; |
| 925 GrUniqueKey::Builder builder(&key, kDomain, 2); | 925 GrUniqueKey::Builder builder(&key, kDomain, 2); |
| 926 builder[0] = blurRadius; | 926 builder[0] = blurRadius; |
| 927 builder[1] = cornerRadius; | 927 builder[1] = cornerRadius; |
| 928 builder.finish(); | 928 builder.finish(); |
| 929 | 929 |
| 930 SkAutoTUnref<GrTexture> blurNinePatchTexture(texProvider->findAndRefTextureB
yUniqueKey(key)); | 930 SkAutoTUnref<GrTexture> blurNinePatchTexture(texProvider->findAndRefTextureB
yUniqueKey(key)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 944 | 944 |
| 945 SkRect smallRect; | 945 SkRect smallRect; |
| 946 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid
e)); | 946 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid
e)); |
| 947 | 947 |
| 948 SkRRect smallRRect; | 948 SkRRect smallRRect; |
| 949 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal
ar(cornerRadius)); | 949 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal
ar(cornerRadius)); |
| 950 | 950 |
| 951 SkPath path; | 951 SkPath path; |
| 952 path.addRRect( smallRRect ); | 952 path.addRRect( smallRRect ); |
| 953 | 953 |
| 954 SkDraw::DrawToMask(path, &mask.fBounds, NULL, NULL, &mask, | 954 SkDraw::DrawToMask(path, &mask.fBounds, nullptr, nullptr, &mask, |
| 955 SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_S
tyle); | 955 SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_S
tyle); |
| 956 | 956 |
| 957 SkMask blurredMask; | 957 SkMask blurredMask; |
| 958 SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle, kHig
h_SkBlurQuality, | 958 SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle, kHig
h_SkBlurQuality, |
| 959 NULL, true ); | 959 nullptr, true ); |
| 960 | 960 |
| 961 unsigned int texSide = smallRectSide + 2*blurRadius; | 961 unsigned int texSide = smallRectSide + 2*blurRadius; |
| 962 GrSurfaceDesc texDesc; | 962 GrSurfaceDesc texDesc; |
| 963 texDesc.fWidth = texSide; | 963 texDesc.fWidth = texSide; |
| 964 texDesc.fHeight = texSide; | 964 texDesc.fHeight = texSide; |
| 965 texDesc.fConfig = kAlpha_8_GrPixelConfig; | 965 texDesc.fConfig = kAlpha_8_GrPixelConfig; |
| 966 | 966 |
| 967 blurNinePatchTexture.reset( | 967 blurNinePatchTexture.reset( |
| 968 texProvider->createTexture(texDesc, true, blurredMask.fImage, 0)); | 968 texProvider->createTexture(texDesc, true, blurredMask.fImage, 0)); |
| 969 SkMask::FreeImage(blurredMask.fImage); | 969 SkMask::FreeImage(blurredMask.fImage); |
| 970 if (!blurNinePatchTexture) { | 970 if (!blurNinePatchTexture) { |
| 971 return NULL; | 971 return nullptr; |
| 972 } | 972 } |
| 973 texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture); | 973 texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture); |
| 974 } | 974 } |
| 975 return new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture); | 975 return new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture); |
| 976 } | 976 } |
| 977 | 977 |
| 978 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 978 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
| 979 inout->mulByUnknownSingleComponent(); | 979 inout->mulByUnknownSingleComponent(); |
| 980 } | 980 } |
| 981 | 981 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); | 1158 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); |
| 1159 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); | 1159 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); |
| 1160 | 1160 |
| 1161 if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && | 1161 if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && |
| 1162 srcBounds.height() <= kMIN_GPU_BLUR_SIZE && | 1162 srcBounds.height() <= kMIN_GPU_BLUR_SIZE && |
| 1163 xformedSigma <= kMIN_GPU_BLUR_SIGMA) { | 1163 xformedSigma <= kMIN_GPU_BLUR_SIGMA) { |
| 1164 // We prefer to blur small rect with small radius via CPU. | 1164 // We prefer to blur small rect with small radius via CPU. |
| 1165 return false; | 1165 return false; |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 if (NULL == maskRect) { | 1168 if (nullptr == maskRect) { |
| 1169 // don't need to compute maskRect | 1169 // don't need to compute maskRect |
| 1170 return true; | 1170 return true; |
| 1171 } | 1171 } |
| 1172 | 1172 |
| 1173 float sigma3 = 3 * SkScalarToFloat(xformedSigma); | 1173 float sigma3 = 3 * SkScalarToFloat(xformedSigma); |
| 1174 | 1174 |
| 1175 SkRect clipRect = SkRect::Make(clipBounds); | 1175 SkRect clipRect = SkRect::Make(clipBounds); |
| 1176 SkRect srcRect(srcBounds); | 1176 SkRect srcRect(srcBounds); |
| 1177 | 1177 |
| 1178 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. | 1178 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1195 GrContext* context = src->getContext(); | 1195 GrContext* context = src->getContext(); |
| 1196 | 1196 |
| 1197 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1197 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
| 1198 SkASSERT(xformedSigma > 0); | 1198 SkASSERT(xformedSigma > 0); |
| 1199 | 1199 |
| 1200 // If we're doing a normal blur, we can clobber the pathTexture in the | 1200 // If we're doing a normal blur, we can clobber the pathTexture in the |
| 1201 // gaussianBlur. Otherwise, we need to save it for later compositing. | 1201 // gaussianBlur. Otherwise, we need to save it for later compositing. |
| 1202 bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); | 1202 bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); |
| 1203 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, | 1203 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, |
| 1204 clipRect, false, xformedSigma, xforme
dSigma); | 1204 clipRect, false, xformedSigma, xforme
dSigma); |
| 1205 if (NULL == *result) { | 1205 if (nullptr == *result) { |
| 1206 return false; | 1206 return false; |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 if (!isNormalBlur) { | 1209 if (!isNormalBlur) { |
| 1210 GrPaint paint; | 1210 GrPaint paint; |
| 1211 SkMatrix matrix; | 1211 SkMatrix matrix; |
| 1212 matrix.setIDiv(src->width(), src->height()); | 1212 matrix.setIDiv(src->width(), src->height()); |
| 1213 // Blend pathTexture over blurTexture. | 1213 // Blend pathTexture over blurTexture. |
| 1214 paint.addCoverageFragmentProcessor( | 1214 paint.addCoverageFragmentProcessor( |
| 1215 GrSimpleTextureEffect::Create(paint.getProcessorDataManager(), src,
matrix))->unref(); | 1215 GrSimpleTextureEffect::Create(paint.getProcessorDataManager(), src,
matrix))->unref(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 } else { | 1266 } else { |
| 1267 str->append("None"); | 1267 str->append("None"); |
| 1268 } | 1268 } |
| 1269 str->append("))"); | 1269 str->append("))"); |
| 1270 } | 1270 } |
| 1271 #endif | 1271 #endif |
| 1272 | 1272 |
| 1273 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1273 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 1274 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1274 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 1275 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1275 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |