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 |