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

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

Issue 1311583005: Add special case circle blur for Ganesh (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix no-GPU build Created 5 years, 3 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/SkBlurMask.cpp ('k') | src/gpu/GrBlurUtils.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 /* 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 "SkMaskFilter.h" 14 #include "SkMaskFilter.h"
15 #include "SkRRect.h" 15 #include "SkRRect.h"
16 #include "SkRTConf.h" 16 #include "SkRTConf.h"
17 #include "SkStringUtils.h" 17 #include "SkStringUtils.h"
18 #include "SkStrokeRec.h" 18 #include "SkStrokeRec.h"
19 19
20 #if SK_SUPPORT_GPU 20 #if SK_SUPPORT_GPU
21 #include "GrCircleBlurFragmentProcessor.h"
21 #include "GrContext.h" 22 #include "GrContext.h"
22 #include "GrDrawContext.h" 23 #include "GrDrawContext.h"
23 #include "GrTexture.h" 24 #include "GrTexture.h"
24 #include "GrFragmentProcessor.h" 25 #include "GrFragmentProcessor.h"
25 #include "GrInvariantOutput.h" 26 #include "GrInvariantOutput.h"
26 #include "SkGrPixelRef.h" 27 #include "SkGrPixelRef.h"
27 #include "SkDraw.h" 28 #include "SkDraw.h"
28 #include "effects/GrSimpleTextureEffect.h" 29 #include "effects/GrSimpleTextureEffect.h"
29 #include "gl/GrGLFragmentProcessor.h" 30 #include "gl/GrGLFragmentProcessor.h"
30 #include "gl/builders/GrGLProgramBuilder.h" 31 #include "gl/builders/GrGLProgramBuilder.h"
31 #endif 32 #endif
32 33
33 SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) { 34 SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) {
34 return SkBlurMask::ConvertRadiusToSigma(radius); 35 return SkBlurMask::ConvertRadiusToSigma(radius);
35 } 36 }
36 37
37 class SkBlurMaskFilterImpl : public SkMaskFilter { 38 class SkBlurMaskFilterImpl : public SkMaskFilter {
38 public: 39 public:
39 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags); 40 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags);
40 41
41 // overrides from SkMaskFilter 42 // overrides from SkMaskFilter
42 SkMask::Format getFormat() const override; 43 SkMask::Format getFormat() const override;
43 bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, 44 bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
44 SkIPoint* margin) const override; 45 SkIPoint* margin) const override;
45 46
46 #if SK_SUPPORT_GPU 47 #if SK_SUPPORT_GPU
47 bool canFilterMaskGPU(const SkRect& devBounds, 48 bool canFilterMaskGPU(const SkRRect& devRRect,
48 const SkIRect& clipBounds, 49 const SkIRect& clipBounds,
49 const SkMatrix& ctm, 50 const SkMatrix& ctm,
50 SkRect* maskRect) const override; 51 SkRect* maskRect) const override;
51 bool directFilterMaskGPU(GrTextureProvider* texProvider, 52 bool directFilterMaskGPU(GrTextureProvider* texProvider,
52 GrDrawContext* drawContext, 53 GrDrawContext* drawContext,
53 GrRenderTarget* rt, 54 GrRenderTarget* rt,
54 GrPaint* grp, 55 GrPaint* grp,
55 const GrClip&, 56 const GrClip&,
56 const SkMatrix& viewMatrix, 57 const SkMatrix& viewMatrix,
57 const SkStrokeRec& strokeRec, 58 const SkStrokeRec& strokeRec,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 if (rec) { 160 if (rec) {
160 rec->fSigma = fSigma; 161 rec->fSigma = fSigma;
161 rec->fStyle = fBlurStyle; 162 rec->fStyle = fBlurStyle;
162 rec->fQuality = this->getQuality(); 163 rec->fQuality = this->getQuality();
163 } 164 }
164 return true; 165 return true;
165 } 166 }
166 167
167 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, 168 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
168 const SkMatrix& matrix, 169 const SkMatrix& matrix,
169 SkIPoint* margin) const{ 170 SkIPoint* margin) const {
170 SkScalar sigma = this->computeXformedSigma(matrix); 171 SkScalar sigma = this->computeXformedSigma(matrix);
171 return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, this->getQuality(), margin); 172 return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, this->getQuality(), margin);
172 } 173 }
173 174
174 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, 175 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r,
175 const SkMatrix& matrix, 176 const SkMatrix& matrix,
176 SkIPoint* margin, SkMask::CreateMode c reateMode) const{ 177 SkIPoint* margin, SkMask::CreateMode c reateMode) const {
177 SkScalar sigma = computeXformedSigma(matrix); 178 SkScalar sigma = computeXformedSigma(matrix);
178 179
179 return SkBlurMask::BlurRect(sigma, dst, r, fBlurStyle, 180 return SkBlurMask::BlurRect(sigma, dst, r, fBlurStyle, margin, createMode);
180 margin, createMode);
181 } 181 }
182 182
183 bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, 183 bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r,
184 const SkMatrix& matrix, 184 const SkMatrix& matrix,
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, margin, createMode);
189 margin, createMode);
190 } 189 }
191 190
192 #include "SkCanvas.h" 191 #include "SkCanvas.h"
193 192
194 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { 193 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) {
195 SkASSERT(mask != nullptr); 194 SkASSERT(mask != nullptr);
196 195
197 mask->fBounds = bounds.roundOut(); 196 mask->fBounds = bounds.roundOut();
198 mask->fRowBytes = SkAlign4(mask->fBounds.width()); 197 mask->fRowBytes = SkAlign4(mask->fBounds.width());
199 mask->fFormat = SkMask::kA8_Format; 198 mask->fFormat = SkMask::kA8_Format;
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 buffer.writeUInt(fBlurStyle); 599 buffer.writeUInt(fBlurStyle);
601 buffer.writeUInt(fBlurFlags); 600 buffer.writeUInt(fBlurFlags);
602 } 601 }
603 602
604 #if SK_SUPPORT_GPU 603 #if SK_SUPPORT_GPU
605 604
606 class GrGLRectBlurEffect; 605 class GrGLRectBlurEffect;
607 606
608 class GrRectBlurEffect : public GrFragmentProcessor { 607 class GrRectBlurEffect : public GrFragmentProcessor {
609 public: 608 public:
610 virtual ~GrRectBlurEffect(); 609 ~GrRectBlurEffect() override { }
611 610
612 const char* name() const override { return "RectBlur"; } 611 const char* name() const override { return "RectBlur"; }
613 612
614 /** 613 static GrFragmentProcessor* Create(GrTextureProvider *textureProvider,
615 * Create a simple filter effect with custom bicubic coefficients. 614 const SkRect& rect, float sigma) {
616 */
617 static GrFragmentProcessor* Create(GrTextureProvider *textureProvider, const SkRect& rect,
618 float sigma) {
619 GrTexture *blurProfileTexture = nullptr;
620 int doubleProfileSize = SkScalarCeilToInt(12*sigma); 615 int doubleProfileSize = SkScalarCeilToInt(12*sigma);
621 616
622 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh t()) { 617 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh t()) {
623 // if the blur sigma is too large so the gaussian overlaps the whole 618 // 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. 619 // rect in either direction, fall back to CPU path for now.
625
626 return nullptr; 620 return nullptr;
627 } 621 }
628 622
629 bool createdBlurProfileTexture = CreateBlurProfileTexture( 623 SkAutoTUnref<GrTexture> blurProfile(CreateBlurProfileTexture(textureProv ider, sigma));
630 textureProvider, sigma, &blurProfileTexture); 624 if (!blurProfile) {
631 SkAutoTUnref<GrTexture> hunref(blurProfileTexture);
632 if (!createdBlurProfileTexture) {
633 return nullptr; 625 return nullptr;
634 } 626 }
635 return new GrRectBlurEffect(rect, sigma, blurProfileTexture); 627 return new GrRectBlurEffect(rect, sigma, blurProfile);
636 } 628 }
637 629
638 const SkRect& getRect() const { return fRect; } 630 const SkRect& getRect() const { return fRect; }
639 float getSigma() const { return fSigma; } 631 float getSigma() const { return fSigma; }
640 632
641 private: 633 private:
634 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile);
635
642 GrGLFragmentProcessor* onCreateGLInstance() const override; 636 GrGLFragmentProcessor* onCreateGLInstance() const override;
643 637
644 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile); 638 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
645
646 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
647 GrProcessorKeyBuilder* b) const override;
648 639
649 bool onIsEqual(const GrFragmentProcessor&) const override; 640 bool onIsEqual(const GrFragmentProcessor&) const override;
650 641
651 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; 642 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
652 643
653 static bool CreateBlurProfileTexture(GrTextureProvider*, float sigma, 644 static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma);
654 GrTexture **blurProfileTexture);
655 645
656 SkRect fRect; 646 SkRect fRect;
657 float fSigma; 647 float fSigma;
658 GrTextureAccess fBlurProfileAccess; 648 GrTextureAccess fBlurProfileAccess;
659 649
660 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 650 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
661 651
662 typedef GrFragmentProcessor INHERITED; 652 typedef GrFragmentProcessor INHERITED;
663 }; 653 };
664 654
665 class GrGLRectBlurEffect : public GrGLFragmentProcessor { 655 class GrGLRectBlurEffect : public GrGLFragmentProcessor {
666 public: 656 public:
667 GrGLRectBlurEffect(const GrProcessor&) {} 657 GrGLRectBlurEffect(const GrProcessor&) {}
668 virtual void emitCode(EmitArgs&) override; 658 void emitCode(EmitArgs&) override;
669 659
670 protected: 660 protected:
671 void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override; 661 void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
672 662
673 private: 663 private:
674 typedef GrGLProgramDataManager::UniformHandle UniformHandle; 664 typedef GrGLProgramDataManager::UniformHandle UniformHandle;
675 665
676 UniformHandle fProxyRectUniform; 666 UniformHandle fProxyRectUniform;
677 UniformHandle fProfileSizeUniform; 667 UniformHandle fProfileSizeUniform;
678 668
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "horiz_lookup", pr ofileSizeName, 721 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "horiz_lookup", pr ofileSizeName,
732 "translatedPos.x", "width", "wh.x"); 722 "translatedPos.x", "width", "wh.x");
733 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "vert_lookup", pro fileSizeName, 723 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "vert_lookup", pro fileSizeName,
734 "translatedPos.y", "height", "wh.y"); 724 "translatedPos.y", "height", "wh.y");
735 725
736 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); 726 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n");
737 fsBuilder->codeAppendf("\t%s = src * final;\n", args.fOutputColor ); 727 fsBuilder->codeAppendf("\t%s = src * final;\n", args.fOutputColor );
738 } 728 }
739 729
740 void GrGLRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman, 730 void GrGLRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman,
741 const GrProcessor& proc) { 731 const GrProcessor& proc) {
742 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); 732 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
743 SkRect rect = rbe.getRect(); 733 SkRect rect = rbe.getRect();
744 734
745 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot tom); 735 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot tom);
746 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); 736 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
747 } 737 }
748 738
749 bool GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* textureProvid er, float sigma, 739 GrTexture* GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* texture Provider,
750 GrTexture **blurProfileTexture) { 740 float sigma) {
751 GrSurfaceDesc texDesc; 741 GrSurfaceDesc texDesc;
752 742
753 unsigned int profileSize = SkScalarCeilToInt(6*sigma); 743 unsigned int profileSize = SkScalarCeilToInt(6*sigma);
754 744
755 texDesc.fWidth = profileSize; 745 texDesc.fWidth = profileSize;
756 texDesc.fHeight = 1; 746 texDesc.fHeight = 1;
757 texDesc.fConfig = kAlpha_8_GrPixelConfig; 747 texDesc.fConfig = kAlpha_8_GrPixelConfig;
758 748
759 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 749 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
760 GrUniqueKey key; 750 GrUniqueKey key;
761 GrUniqueKey::Builder builder(&key, kDomain, 1); 751 GrUniqueKey::Builder builder(&key, kDomain, 1);
762 builder[0] = profileSize; 752 builder[0] = profileSize;
763 builder.finish(); 753 builder.finish();
764 754
765 uint8_t *profile = nullptr; 755 GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key);
766 SkAutoTDeleteArray<uint8_t> ada(nullptr);
767 756
768 *blurProfileTexture = textureProvider->findAndRefTextureByUniqueKey(key); 757 if (!blurProfile) {
758 SkAutoTDeleteArray<uint8_t> profile(SkBlurMask::ComputeBlurProfile(sigma ));
769 759
770 if (nullptr == *blurProfileTexture) { 760 blurProfile = textureProvider->createTexture(texDesc, true, profile.get( ), 0);
771 761 if (blurProfile) {
772 SkBlurMask::ComputeBlurProfile(sigma, &profile); 762 textureProvider->assignUniqueKeyToTexture(key, blurProfile);
773 ada.reset(profile);
774
775 *blurProfileTexture = textureProvider->createTexture(texDesc, true, prof ile, 0);
776
777 if (nullptr == *blurProfileTexture) {
778 return false;
779 } 763 }
780 textureProvider->assignUniqueKeyToTexture(key, *blurProfileTexture);
781 } 764 }
782 765
783 return true; 766 return blurProfile;
784 } 767 }
785 768
786 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, 769 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *b lurProfile)
787 GrTexture *blur_profile) 770 : fRect(rect)
788 : fRect(rect), 771 , fSigma(sigma)
789 fSigma(sigma), 772 , fBlurProfileAccess(blurProfile) {
790 fBlurProfileAccess(blur_profile) {
791 this->initClassID<GrRectBlurEffect>(); 773 this->initClassID<GrRectBlurEffect>();
792 this->addTextureAccess(&fBlurProfileAccess); 774 this->addTextureAccess(&fBlurProfileAccess);
793 this->setWillReadFragmentPosition(); 775 this->setWillReadFragmentPosition();
794 } 776 }
795 777
796 GrRectBlurEffect::~GrRectBlurEffect() {
797 }
798
799 void GrRectBlurEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, 778 void GrRectBlurEffect::onGetGLProcessorKey(const GrGLSLCaps& caps,
800 GrProcessorKeyBuilder* b) const { 779 GrProcessorKeyBuilder* b) const {
801 GrGLRectBlurEffect::GenKey(*this, caps, b); 780 GrGLRectBlurEffect::GenKey(*this, caps, b);
802 } 781 }
803 782
804 GrGLFragmentProcessor* GrRectBlurEffect::onCreateGLInstance() const { 783 GrGLFragmentProcessor* GrRectBlurEffect::onCreateGLInstance() const {
805 return new GrGLRectBlurEffect(*this); 784 return new GrGLRectBlurEffect(*this);
806 } 785 }
807 786
808 bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 787 bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
(...skipping 23 matching lines...) Expand all
832 const GrClip& clip, 811 const GrClip& clip,
833 const SkMatrix& viewMatrix, 812 const SkMatrix& viewMatrix,
834 const SkStrokeRec& strokeRec, 813 const SkStrokeRec& strokeRec,
835 const SkPath& path) const { 814 const SkPath& path) const {
836 SkASSERT(drawContext); 815 SkASSERT(drawContext);
837 816
838 if (fBlurStyle != kNormal_SkBlurStyle) { 817 if (fBlurStyle != kNormal_SkBlurStyle) {
839 return false; 818 return false;
840 } 819 }
841 820
842 SkRect rect; 821 // TODO: we could handle blurred stroked circles
843 if (!path.isRect(&rect)) {
844 return false;
845 }
846
847 if (!strokeRec.isFillStyle()) { 822 if (!strokeRec.isFillStyle()) {
848 return false; 823 return false;
849 } 824 }
850 825
851 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); 826 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
852 827
853 int pad = SkScalarCeilToInt(6*xformedSigma)/2; 828 SkAutoTUnref<const GrFragmentProcessor> fp;
854 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad));
855 829
856 SkAutoTUnref<GrFragmentProcessor> fp(GrRectBlurEffect::Create( 830 SkRect rect;
857 texProvider, rec t, xformedSigma)); 831 if (path.isRect(&rect)) {
832 int pad = SkScalarCeilToInt(6*xformedSigma)/2;
833 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad));
834
835 fp.reset(GrRectBlurEffect::Create(texProvider, rect, xformedSigma));
836 } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.heig ht())) {
837 fp.reset(GrCircleBlurFragmentProcessor::Create(texProvider, rect, xforme dSigma));
838
839 // expand the rect for the coverage geometry
840 int pad = SkScalarCeilToInt(6*xformedSigma)/2;
841 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad));
842 } else {
843 return false;
844 }
845
858 if (!fp) { 846 if (!fp) {
859 return false; 847 return false;
860 } 848 }
861 849
862 grp->addCoverageFragmentProcessor(fp); 850 grp->addCoverageFragmentProcessor(fp);
863 851
864 SkMatrix inverse; 852 SkMatrix inverse;
865 if (!viewMatrix.invert(&inverse)) { 853 if (!viewMatrix.invert(&inverse)) {
866 return false; 854 return false;
867 } 855 }
868 856
869 drawContext->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), rec t, inverse); 857 drawContext->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), rec t, inverse);
870 return true; 858 return true;
871 } 859 }
872 860
861 //////////////////////////////////////////////////////////////////////////////
862
873 class GrRRectBlurEffect : public GrFragmentProcessor { 863 class GrRRectBlurEffect : public GrFragmentProcessor {
874 public: 864 public:
875 865
876 static GrFragmentProcessor* Create(GrTextureProvider*, float sigma, const Sk RRect&); 866 static const GrFragmentProcessor* Create(GrTextureProvider*, float sigma, co nst SkRRect&);
877 867
878 virtual ~GrRRectBlurEffect() {}; 868 virtual ~GrRRectBlurEffect() {};
879 const char* name() const override { return "GrRRectBlur"; } 869 const char* name() const override { return "GrRRectBlur"; }
880 870
881 const SkRRect& getRRect() const { return fRRect; } 871 const SkRRect& getRRect() const { return fRRect; }
882 float getSigma() const { return fSigma; } 872 float getSigma() const { return fSigma; }
883 873
884 private: 874 private:
885 GrGLFragmentProcessor* onCreateGLInstance() const override; 875 GrGLFragmentProcessor* onCreateGLInstance() const override;
886 876
887 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); 877 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture);
888 878
889 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, 879 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
890 GrProcessorKeyBuilder* b) const override; 880 GrProcessorKeyBuilder* b) const override;
891 881
892 bool onIsEqual(const GrFragmentProcessor& other) const override; 882 bool onIsEqual(const GrFragmentProcessor& other) const override;
893 883
894 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; 884 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
895 885
896 SkRRect fRRect; 886 SkRRect fRRect;
897 float fSigma; 887 float fSigma;
898 GrTextureAccess fNinePatchAccess; 888 GrTextureAccess fNinePatchAccess;
899 889
900 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 890 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
901 891
902 typedef GrFragmentProcessor INHERITED; 892 typedef GrFragmentProcessor INHERITED;
903 }; 893 };
904 894
905 895
906 GrFragmentProcessor* GrRRectBlurEffect::Create(GrTextureProvider* texProvider, f loat sigma, 896 const GrFragmentProcessor* GrRRectBlurEffect::Create(GrTextureProvider* texProvi der, float sigma,
907 const SkRRect& rrect) { 897 const SkRRect& rrect) {
898 if (rrect.isCircle()) {
899 return GrCircleBlurFragmentProcessor::Create(texProvider, rrect.rect(), sigma);
900 }
901
908 if (!rrect.isSimpleCircular()) { 902 if (!rrect.isSimpleCircular()) {
909 return nullptr; 903 return nullptr;
910 } 904 }
911 905
912 // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be 906 // 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 907 // sufficiently small relative to both the size of the corner radius and the
914 // width (and height) of the rrect. 908 // width (and height) of the rrect.
915 909
916 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); 910 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f);
917 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); 911 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x());
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 if (!strokeRec.isFillStyle()) { 1116 if (!strokeRec.isFillStyle()) {
1123 return false; 1117 return false;
1124 } 1118 }
1125 1119
1126 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); 1120 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
1127 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); 1121 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
1128 1122
1129 SkRect proxyRect = rrect.rect(); 1123 SkRect proxyRect = rrect.rect();
1130 proxyRect.outset(extra, extra); 1124 proxyRect.outset(extra, extra);
1131 1125
1132 SkAutoTUnref<GrFragmentProcessor> fp(GrRRectBlurEffect::Create(texProvider, 1126 SkAutoTUnref<const GrFragmentProcessor> fp(GrRRectBlurEffect::Create(texProv ider,
1133 xformedSigma, rrect)); 1127 xformed Sigma, rrect));
1134 if (!fp) { 1128 if (!fp) {
1135 return false; 1129 return false;
1136 } 1130 }
1137 1131
1138 grp->addCoverageFragmentProcessor(fp); 1132 grp->addCoverageFragmentProcessor(fp);
1139 1133
1140 SkMatrix inverse; 1134 SkMatrix inverse;
1141 if (!viewMatrix.invert(&inverse)) { 1135 if (!viewMatrix.invert(&inverse)) {
1142 return false; 1136 return false;
1143 } 1137 }
1144 1138
1145 drawContext->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), pro xyRect, inverse); 1139 drawContext->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), pro xyRect, inverse);
1146 return true; 1140 return true;
1147 } 1141 }
1148 1142
1149 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, 1143 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
1150 const SkIRect& clipBounds, 1144 const SkIRect& clipBounds,
1151 const SkMatrix& ctm, 1145 const SkMatrix& ctm,
1152 SkRect* maskRect) const { 1146 SkRect* maskRect) const {
1153 SkScalar xformedSigma = this->computeXformedSigma(ctm); 1147 SkScalar xformedSigma = this->computeXformedSigma(ctm);
1154 if (xformedSigma <= 0) { 1148 if (xformedSigma <= 0) {
1155 return false; 1149 return false;
1156 } 1150 }
1157 1151
1158 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); 1152 // We always do circles on the GPU
1159 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); 1153 if (!devRRect.isCircle()) {
1154 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64);
1155 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32);
1160 1156
1161 if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && 1157 if (devRRect.width() <= kMIN_GPU_BLUR_SIZE &&
1162 srcBounds.height() <= kMIN_GPU_BLUR_SIZE && 1158 devRRect.height() <= kMIN_GPU_BLUR_SIZE &&
1163 xformedSigma <= kMIN_GPU_BLUR_SIGMA) { 1159 xformedSigma <= kMIN_GPU_BLUR_SIGMA) {
1164 // We prefer to blur small rect with small radius via CPU. 1160 // We prefer to blur small rects with small radii on the CPU.
1165 return false; 1161 return false;
1162 }
1166 } 1163 }
1167 1164
1168 if (nullptr == maskRect) { 1165 if (nullptr == maskRect) {
1169 // don't need to compute maskRect 1166 // don't need to compute maskRect
1170 return true; 1167 return true;
1171 } 1168 }
1172 1169
1173 float sigma3 = 3 * SkScalarToFloat(xformedSigma); 1170 float sigma3 = 3 * SkScalarToFloat(xformedSigma);
1174 1171
1175 SkRect clipRect = SkRect::Make(clipBounds); 1172 SkRect clipRect = SkRect::Make(clipBounds);
1176 SkRect srcRect(srcBounds); 1173 SkRect srcRect(devRRect.rect());
1177 1174
1178 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. 1175 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area.
1179 srcRect.outset(sigma3, sigma3); 1176 srcRect.outset(sigma3, sigma3);
1180 clipRect.outset(sigma3, sigma3); 1177 clipRect.outset(sigma3, sigma3);
1181 if (!srcRect.intersect(clipRect)) { 1178 if (!srcRect.intersect(clipRect)) {
1182 srcRect.setEmpty(); 1179 srcRect.setEmpty();
1183 } 1180 }
1184 *maskRect = srcRect; 1181 *maskRect = srcRect;
1185 return true; 1182 return true;
1186 } 1183 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 } else { 1263 } else {
1267 str->append("None"); 1264 str->append("None");
1268 } 1265 }
1269 str->append("))"); 1266 str->append("))");
1270 } 1267 }
1271 #endif 1268 #endif
1272 1269
1273 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1270 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
1274 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1271 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
1275 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1272 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/effects/SkBlurMask.cpp ('k') | src/gpu/GrBlurUtils.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698