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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 ~GrRectBlurEffect() override { } | 610 ~GrRectBlurEffect() override { } |
611 | 611 |
612 const char* name() const override { return "RectBlur"; } | 612 const char* name() const override { return "RectBlur"; } |
613 | 613 |
614 static GrFragmentProcessor* Create(GrTextureProvider *textureProvider, | 614 static GrFragmentProcessor* Create(GrTextureProvider *textureProvider, |
615 const SkRect& rect, float sigma) { | 615 const SkRect& rect, float sigma, GrRender
Target* dst) { |
616 int doubleProfileSize = SkScalarCeilToInt(12*sigma); | 616 int doubleProfileSize = SkScalarCeilToInt(12*sigma); |
617 | 617 |
618 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { | 618 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { |
619 // if the blur sigma is too large so the gaussian overlaps the whole | 619 // if the blur sigma is too large so the gaussian overlaps the whole |
620 // rect in either direction, fall back to CPU path for now. | 620 // rect in either direction, fall back to CPU path for now. |
621 return nullptr; | 621 return nullptr; |
622 } | 622 } |
623 | 623 |
624 SkAutoTUnref<GrTexture> blurProfile(CreateBlurProfileTexture(textureProv
ider, sigma)); | 624 SkAutoTUnref<GrTexture> blurProfile(CreateBlurProfileTexture(textureProv
ider, sigma)); |
625 if (!blurProfile) { | 625 if (!blurProfile) { |
(...skipping 12 matching lines...) Expand all Loading... |
638 SkScalarAbs(rect.left()) > kMAX_BLUR_COORD || | 638 SkScalarAbs(rect.left()) > kMAX_BLUR_COORD || |
639 SkScalarAbs(rect.bottom()) > kMAX_BLUR_COORD || | 639 SkScalarAbs(rect.bottom()) > kMAX_BLUR_COORD || |
640 SkScalarAbs(rect.right()) > kMAX_BLUR_COORD || | 640 SkScalarAbs(rect.right()) > kMAX_BLUR_COORD || |
641 SkScalarAbs(rect.width()) > kMAX_BLUR_COORD || | 641 SkScalarAbs(rect.width()) > kMAX_BLUR_COORD || |
642 SkScalarAbs(rect.height()) > kMAX_BLUR_COORD) { | 642 SkScalarAbs(rect.height()) > kMAX_BLUR_COORD) { |
643 precision = kHigh_GrSLPrecision; | 643 precision = kHigh_GrSLPrecision; |
644 } | 644 } |
645 else { | 645 else { |
646 precision = kDefault_GrSLPrecision; | 646 precision = kDefault_GrSLPrecision; |
647 } | 647 } |
648 return new GrRectBlurEffect(rect, sigma, blurProfile, precision); | 648 return new GrRectBlurEffect(rect, sigma, blurProfile, precision, dst); |
649 } | 649 } |
650 | 650 |
651 const SkRect& getRect() const { return fRect; } | 651 const SkRect& getRect() const { return fRect; } |
652 float getSigma() const { return fSigma; } | 652 float getSigma() const { return fSigma; } |
653 | 653 |
654 private: | 654 private: |
655 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile, | 655 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile, |
656 GrSLPrecision fPrecision); | 656 GrSLPrecision fPrecision, GrRenderTarget* dstRT); |
657 | 657 |
658 GrGLFragmentProcessor* onCreateGLInstance() const override; | 658 GrGLFragmentProcessor* onCreateGLInstance() const override; |
659 | 659 |
660 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; | 660 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; |
661 | 661 |
662 bool onIsEqual(const GrFragmentProcessor&) const override; | 662 bool onIsEqual(const GrFragmentProcessor&) const override; |
663 | 663 |
664 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 664 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
665 | 665 |
666 static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma); | 666 static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 | 793 |
794 GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key); | 794 GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key); |
795 | 795 |
796 if (!blurProfile) { | 796 if (!blurProfile) { |
797 SkAutoTDeleteArray<uint8_t> profile(SkBlurMask::ComputeBlurProfile(sigma
)); | 797 SkAutoTDeleteArray<uint8_t> profile(SkBlurMask::ComputeBlurProfile(sigma
)); |
798 | 798 |
799 blurProfile = textureProvider->createTexture(texDesc, true, profile.get(
), 0); | 799 blurProfile = textureProvider->createTexture(texDesc, true, profile.get(
), 0); |
800 if (blurProfile) { | 800 if (blurProfile) { |
801 textureProvider->assignUniqueKeyToTexture(key, blurProfile); | 801 textureProvider->assignUniqueKeyToTexture(key, blurProfile); |
802 } | 802 } |
| 803 blurProfile->setFromRawPixels(true); |
803 } | 804 } |
804 | 805 |
805 return blurProfile; | 806 return blurProfile; |
806 } | 807 } |
807 | 808 |
808 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *b
lurProfile, | 809 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *b
lurProfile, |
809 GrSLPrecision precision) | 810 GrSLPrecision precision, GrRenderTarget* dst) |
810 : fRect(rect) | 811 : fRect(rect) |
811 , fSigma(sigma) | 812 , fSigma(sigma) |
812 , fBlurProfileAccess(blurProfile) | 813 , fBlurProfileAccess(blurProfile, GrTextureParams::kNone_FilterMode,SkShader
::kClamp_TileMode, dst) |
813 , fPrecision(precision) { | 814 , fPrecision(precision) { |
814 this->initClassID<GrRectBlurEffect>(); | 815 this->initClassID<GrRectBlurEffect>(); |
815 this->addTextureAccess(&fBlurProfileAccess); | 816 this->addTextureAccess(&fBlurProfileAccess); |
816 this->setWillReadFragmentPosition(); | 817 this->setWillReadFragmentPosition(); |
817 } | 818 } |
818 | 819 |
819 void GrRectBlurEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 820 void GrRectBlurEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, |
820 GrProcessorKeyBuilder* b) const { | 821 GrProcessorKeyBuilder* b) const { |
821 GrGLRectBlurEffect::GenKey(fPrecision, b); | 822 GrGLRectBlurEffect::GenKey(fPrecision, b); |
822 } | 823 } |
(...skipping 11 matching lines...) Expand all Loading... |
834 inout->mulByUnknownSingleComponent(); | 835 inout->mulByUnknownSingleComponent(); |
835 } | 836 } |
836 | 837 |
837 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect); | 838 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect); |
838 | 839 |
839 const GrFragmentProcessor* GrRectBlurEffect::TestCreate(GrProcessorTestData* d)
{ | 840 const GrFragmentProcessor* GrRectBlurEffect::TestCreate(GrProcessorTestData* d)
{ |
840 float sigma = d->fRandom->nextRangeF(3,8); | 841 float sigma = d->fRandom->nextRangeF(3,8); |
841 float width = d->fRandom->nextRangeF(200,300); | 842 float width = d->fRandom->nextRangeF(200,300); |
842 float height = d->fRandom->nextRangeF(200,300); | 843 float height = d->fRandom->nextRangeF(200,300); |
843 return GrRectBlurEffect::Create(d->fContext->textureProvider(), SkRect::Make
WH(width, height), | 844 return GrRectBlurEffect::Create(d->fContext->textureProvider(), SkRect::Make
WH(width, height), |
844 sigma); | 845 sigma, NULL); |
845 } | 846 } |
846 | 847 |
847 | 848 |
848 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texProvider, | 849 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texProvider, |
849 GrDrawContext* drawContext, | 850 GrDrawContext* drawContext, |
850 GrPaint* grp, | 851 GrPaint* grp, |
851 const GrClip& clip, | 852 const GrClip& clip, |
852 const SkMatrix& viewMatrix, | 853 const SkMatrix& viewMatrix, |
853 const SkStrokeRec& strokeRec, | 854 const SkStrokeRec& strokeRec, |
854 const SkPath& path) const { | 855 const SkPath& path) const { |
(...skipping 10 matching lines...) Expand all Loading... |
865 | 866 |
866 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); | 867 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); |
867 | 868 |
868 SkAutoTUnref<const GrFragmentProcessor> fp; | 869 SkAutoTUnref<const GrFragmentProcessor> fp; |
869 | 870 |
870 SkRect rect; | 871 SkRect rect; |
871 if (path.isRect(&rect)) { | 872 if (path.isRect(&rect)) { |
872 int pad = SkScalarCeilToInt(6*xformedSigma)/2; | 873 int pad = SkScalarCeilToInt(6*xformedSigma)/2; |
873 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); | 874 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); |
874 | 875 |
875 fp.reset(GrRectBlurEffect::Create(texProvider, rect, xformedSigma)); | 876 fp.reset(GrRectBlurEffect::Create(texProvider, rect, xformedSigma, drawC
ontext->rt_remove_me())); |
876 } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.heig
ht())) { | 877 } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.heig
ht())) { |
877 fp.reset(GrCircleBlurFragmentProcessor::Create(texProvider, rect, xforme
dSigma)); | 878 fp.reset(GrCircleBlurFragmentProcessor::Create(texProvider, rect, xforme
dSigma, drawContext->rt_remove_me())); |
878 | 879 |
879 // expand the rect for the coverage geometry | 880 // expand the rect for the coverage geometry |
880 int pad = SkScalarCeilToInt(6*xformedSigma)/2; | 881 int pad = SkScalarCeilToInt(6*xformedSigma)/2; |
881 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); | 882 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); |
882 } else { | 883 } else { |
883 return false; | 884 return false; |
884 } | 885 } |
885 | 886 |
886 if (!fp) { | 887 if (!fp) { |
887 return false; | 888 return false; |
888 } | 889 } |
889 | 890 |
890 grp->addCoverageFragmentProcessor(fp); | 891 grp->addCoverageFragmentProcessor(fp); |
891 | 892 |
892 SkMatrix inverse; | 893 SkMatrix inverse; |
893 if (!viewMatrix.invert(&inverse)) { | 894 if (!viewMatrix.invert(&inverse)) { |
894 return false; | 895 return false; |
895 } | 896 } |
896 | 897 |
897 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), rect, invers
e); | 898 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), rect, invers
e); |
898 return true; | 899 return true; |
899 } | 900 } |
900 | 901 |
901 ////////////////////////////////////////////////////////////////////////////// | 902 ////////////////////////////////////////////////////////////////////////////// |
902 | 903 |
903 class GrRRectBlurEffect : public GrFragmentProcessor { | 904 class GrRRectBlurEffect : public GrFragmentProcessor { |
904 public: | 905 public: |
905 | 906 |
906 static const GrFragmentProcessor* Create(GrTextureProvider*, float sigma, co
nst SkRRect&); | 907 static const GrFragmentProcessor* Create(GrTextureProvider*, float sigma, co
nst SkRRect&, GrRenderTarget* dst); |
907 | 908 |
908 virtual ~GrRRectBlurEffect() {}; | 909 virtual ~GrRRectBlurEffect() {}; |
909 const char* name() const override { return "GrRRectBlur"; } | 910 const char* name() const override { return "GrRRectBlur"; } |
910 | 911 |
911 const SkRRect& getRRect() const { return fRRect; } | 912 const SkRRect& getRRect() const { return fRRect; } |
912 float getSigma() const { return fSigma; } | 913 float getSigma() const { return fSigma; } |
913 | 914 |
914 private: | 915 private: |
915 GrGLFragmentProcessor* onCreateGLInstance() const override; | 916 GrGLFragmentProcessor* onCreateGLInstance() const override; |
916 | 917 |
917 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); | 918 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture, Gr
RenderTarget* dst); |
918 | 919 |
919 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, | 920 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, |
920 GrProcessorKeyBuilder* b) const override; | 921 GrProcessorKeyBuilder* b) const override; |
921 | 922 |
922 bool onIsEqual(const GrFragmentProcessor& other) const override; | 923 bool onIsEqual(const GrFragmentProcessor& other) const override; |
923 | 924 |
924 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 925 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
925 | 926 |
926 SkRRect fRRect; | 927 SkRRect fRRect; |
927 float fSigma; | 928 float fSigma; |
928 GrTextureAccess fNinePatchAccess; | 929 GrTextureAccess fNinePatchAccess; |
929 | 930 |
930 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 931 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
931 | 932 |
932 typedef GrFragmentProcessor INHERITED; | 933 typedef GrFragmentProcessor INHERITED; |
933 }; | 934 }; |
934 | 935 |
935 | 936 |
936 const GrFragmentProcessor* GrRRectBlurEffect::Create(GrTextureProvider* texProvi
der, float sigma, | 937 const GrFragmentProcessor* GrRRectBlurEffect::Create(GrTextureProvider* texProvi
der, float sigma, |
937 const SkRRect& rrect) { | 938 const SkRRect& rrect, GrRen
derTarget* dst) { |
938 if (rrect.isCircle()) { | 939 if (rrect.isCircle()) { |
939 return GrCircleBlurFragmentProcessor::Create(texProvider, rrect.rect(),
sigma); | 940 return GrCircleBlurFragmentProcessor::Create(texProvider, rrect.rect(),
sigma, dst); |
940 } | 941 } |
941 | 942 |
942 if (!rrect.isSimpleCircular()) { | 943 if (!rrect.isSimpleCircular()) { |
943 return nullptr; | 944 return nullptr; |
944 } | 945 } |
945 | 946 |
946 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be | 947 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be |
947 // sufficiently small relative to both the size of the corner radius and the | 948 // sufficiently small relative to both the size of the corner radius and the |
948 // width (and height) of the rrect. | 949 // width (and height) of the rrect. |
949 | 950 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 texDesc.fHeight = texSide; | 999 texDesc.fHeight = texSide; |
999 texDesc.fConfig = kAlpha_8_GrPixelConfig; | 1000 texDesc.fConfig = kAlpha_8_GrPixelConfig; |
1000 | 1001 |
1001 blurNinePatchTexture.reset( | 1002 blurNinePatchTexture.reset( |
1002 texProvider->createTexture(texDesc, true, blurredMask.fImage, 0)); | 1003 texProvider->createTexture(texDesc, true, blurredMask.fImage, 0)); |
1003 SkMask::FreeImage(blurredMask.fImage); | 1004 SkMask::FreeImage(blurredMask.fImage); |
1004 if (!blurNinePatchTexture) { | 1005 if (!blurNinePatchTexture) { |
1005 return nullptr; | 1006 return nullptr; |
1006 } | 1007 } |
1007 texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture); | 1008 texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture); |
| 1009 blurNinePatchTexture->setFromRawPixels(true); |
1008 } | 1010 } |
1009 return new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture); | 1011 return new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture, dst); |
1010 } | 1012 } |
1011 | 1013 |
1012 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 1014 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
1013 inout->mulByUnknownSingleComponent(); | 1015 inout->mulByUnknownSingleComponent(); |
1014 } | 1016 } |
1015 | 1017 |
1016 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) | 1018 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture, GrRenderTarget* dst) |
1017 : fRRect(rrect), | 1019 : fRRect(rrect), |
1018 fSigma(sigma), | 1020 fSigma(sigma), |
1019 fNinePatchAccess(ninePatchTexture) { | 1021 fNinePatchAccess(ninePatchTexture, GrTextureParams::kNone_FilterMode,SkSha
der::kClamp_TileMode, dst) { |
1020 this->initClassID<GrRRectBlurEffect>(); | 1022 this->initClassID<GrRRectBlurEffect>(); |
1021 this->addTextureAccess(&fNinePatchAccess); | 1023 this->addTextureAccess(&fNinePatchAccess); |
1022 this->setWillReadFragmentPosition(); | 1024 this->setWillReadFragmentPosition(); |
1023 } | 1025 } |
1024 | 1026 |
1025 bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const { | 1027 bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const { |
1026 const GrRRectBlurEffect& rrbe = other.cast<GrRRectBlurEffect>(); | 1028 const GrRRectBlurEffect& rrbe = other.cast<GrRRectBlurEffect>(); |
1027 return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSig
ma == rrbe.fSigma; | 1029 return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSig
ma == rrbe.fSigma; |
1028 } | 1030 } |
1029 | 1031 |
1030 ////////////////////////////////////////////////////////////////////////////// | 1032 ////////////////////////////////////////////////////////////////////////////// |
1031 | 1033 |
1032 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); | 1034 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); |
1033 | 1035 |
1034 const GrFragmentProcessor* GrRRectBlurEffect::TestCreate(GrProcessorTestData* d)
{ | 1036 const GrFragmentProcessor* GrRRectBlurEffect::TestCreate(GrProcessorTestData* d)
{ |
1035 SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f); | 1037 SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f); |
1036 SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f); | 1038 SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f); |
1037 SkScalar r = d->fRandom->nextRangeF(1.f, 9.f); | 1039 SkScalar r = d->fRandom->nextRangeF(1.f, 9.f); |
1038 SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f); | 1040 SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f); |
1039 SkRRect rrect; | 1041 SkRRect rrect; |
1040 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 1042 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
1041 return GrRRectBlurEffect::Create(d->fContext->textureProvider(), sigma, rrec
t); | 1043 return GrRRectBlurEffect::Create(d->fContext->textureProvider(), sigma, rrec
t, NULL); |
1042 } | 1044 } |
1043 | 1045 |
1044 ////////////////////////////////////////////////////////////////////////////// | 1046 ////////////////////////////////////////////////////////////////////////////// |
1045 | 1047 |
1046 class GrGLRRectBlurEffect : public GrGLFragmentProcessor { | 1048 class GrGLRRectBlurEffect : public GrGLFragmentProcessor { |
1047 public: | 1049 public: |
1048 GrGLRRectBlurEffect(const GrProcessor&) {} | 1050 GrGLRRectBlurEffect(const GrProcessor&) {} |
1049 | 1051 |
1050 virtual void emitCode(EmitArgs&) override; | 1052 virtual void emitCode(EmitArgs&) override; |
1051 | 1053 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 return false; | 1158 return false; |
1157 } | 1159 } |
1158 | 1160 |
1159 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); | 1161 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); |
1160 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); | 1162 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); |
1161 | 1163 |
1162 SkRect proxyRect = rrect.rect(); | 1164 SkRect proxyRect = rrect.rect(); |
1163 proxyRect.outset(extra, extra); | 1165 proxyRect.outset(extra, extra); |
1164 | 1166 |
1165 SkAutoTUnref<const GrFragmentProcessor> fp(GrRRectBlurEffect::Create(texProv
ider, | 1167 SkAutoTUnref<const GrFragmentProcessor> fp(GrRRectBlurEffect::Create(texProv
ider, |
1166 xformed
Sigma, rrect)); | 1168 xformed
Sigma, rrect, drawContext->rt_remove_me())); |
1167 if (!fp) { | 1169 if (!fp) { |
1168 return false; | 1170 return false; |
1169 } | 1171 } |
1170 | 1172 |
1171 grp->addCoverageFragmentProcessor(fp); | 1173 grp->addCoverageFragmentProcessor(fp); |
1172 | 1174 |
1173 SkMatrix inverse; | 1175 SkMatrix inverse; |
1174 if (!viewMatrix.invert(&inverse)) { | 1176 if (!viewMatrix.invert(&inverse)) { |
1175 return false; | 1177 return false; |
1176 } | 1178 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. | 1216 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. |
1215 srcRect.outset(sigma3, sigma3); | 1217 srcRect.outset(sigma3, sigma3); |
1216 clipRect.outset(sigma3, sigma3); | 1218 clipRect.outset(sigma3, sigma3); |
1217 if (!srcRect.intersect(clipRect)) { | 1219 if (!srcRect.intersect(clipRect)) { |
1218 srcRect.setEmpty(); | 1220 srcRect.setEmpty(); |
1219 } | 1221 } |
1220 *maskRect = srcRect; | 1222 *maskRect = srcRect; |
1221 return true; | 1223 return true; |
1222 } | 1224 } |
1223 | 1225 |
| 1226 #include "GrDrawTarget.h" |
| 1227 |
1224 bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, | 1228 bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, |
1225 const SkMatrix& ctm, | 1229 const SkMatrix& ctm, |
1226 const SkRect& maskRect, | 1230 const SkRect& maskRect, |
1227 GrTexture** result, | 1231 GrTexture** result, |
1228 bool canOverwriteSrc) const { | 1232 bool canOverwriteSrc) const { |
1229 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); | 1233 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); |
1230 | 1234 |
1231 GrContext* context = src->getContext(); | 1235 GrContext* context = src->getContext(); |
1232 | 1236 |
1233 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1237 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
1234 SkASSERT(xformedSigma > 0); | 1238 SkASSERT(xformedSigma > 0); |
1235 | 1239 |
1236 // If we're doing a normal blur, we can clobber the pathTexture in the | 1240 // If we're doing a normal blur, we can clobber the pathTexture in the |
1237 // gaussianBlur. Otherwise, we need to save it for later compositing. | 1241 // gaussianBlur. Otherwise, we need to save it for later compositing. |
1238 bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); | 1242 bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); |
1239 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, | 1243 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, |
1240 clipRect, nullptr, xformedSigma, xfor
medSigma, | 1244 clipRect, nullptr, xformedSigma, xfor
medSigma, |
1241 GrTextureProvider::kApprox_SizeConstr
aint); | 1245 GrTextureProvider::kApprox_SizeConstr
aint); |
1242 if (nullptr == *result) { | 1246 if (nullptr == *result) { |
1243 return false; | 1247 return false; |
1244 } | 1248 } |
1245 | 1249 |
1246 if (!isNormalBlur) { | 1250 if (!isNormalBlur) { |
1247 GrPaint paint; | 1251 GrPaint paint; |
1248 SkMatrix matrix; | 1252 SkMatrix matrix; |
1249 matrix.setIDiv(src->width(), src->height()); | 1253 matrix.setIDiv(src->width(), src->height()); |
1250 // Blend pathTexture over blurTexture. | 1254 // Blend pathTexture over blurTexture. |
1251 paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(src, ma
trix))->unref(); | 1255 paint.addCoverageFragmentProcessor( |
| 1256 GrSimpleTextureEffect::Create(src, matrix, kLocal_GrCoordSet, |
| 1257 (*result)->asRenderTarget()))->unref()
; |
| 1258 |
1252 if (kInner_SkBlurStyle == fBlurStyle) { | 1259 if (kInner_SkBlurStyle == fBlurStyle) { |
1253 // inner: dst = dst * src | 1260 // inner: dst = dst * src |
1254 paint.setCoverageSetOpXPFactory(SkRegion::kIntersect_Op); | 1261 paint.setCoverageSetOpXPFactory(SkRegion::kIntersect_Op); |
1255 } else if (kSolid_SkBlurStyle == fBlurStyle) { | 1262 } else if (kSolid_SkBlurStyle == fBlurStyle) { |
1256 // solid: dst = src + dst - src * dst | 1263 // solid: dst = src + dst - src * dst |
1257 // = src + (1 - src) * dst | 1264 // = src + (1 - src) * dst |
1258 paint.setCoverageSetOpXPFactory(SkRegion::kUnion_Op); | 1265 paint.setCoverageSetOpXPFactory(SkRegion::kUnion_Op); |
1259 } else if (kOuter_SkBlurStyle == fBlurStyle) { | 1266 } else if (kOuter_SkBlurStyle == fBlurStyle) { |
1260 // outer: dst = dst * (1 - src) | 1267 // outer: dst = dst * (1 - src) |
1261 // = 0 * src + (1 - src) * dst | 1268 // = 0 * src + (1 - src) * dst |
1262 paint.setCoverageSetOpXPFactory(SkRegion::kDifference_Op); | 1269 paint.setCoverageSetOpXPFactory(SkRegion::kDifference_Op); |
1263 } | 1270 } |
1264 | 1271 |
| 1272 GrRenderTarget* rt = (*result)->asRenderTarget(); |
| 1273 SkASSERT(rt); |
| 1274 GrDrawTarget* dt = rt->getLastDrawTarget(); |
| 1275 SkASSERT(dt); |
| 1276 SkASSERT(!dt->isClosed()); |
| 1277 |
1265 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext((*result)->
asRenderTarget())); | 1278 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext((*result)->
asRenderTarget())); |
1266 if (!drawContext) { | 1279 if (!drawContext) { |
1267 return false; | 1280 return false; |
1268 } | 1281 } |
1269 | 1282 |
1270 drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), clipRect
); | 1283 drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), clipRect
); |
1271 } | 1284 } |
1272 | 1285 |
1273 return true; | 1286 return true; |
1274 } | 1287 } |
(...skipping 26 matching lines...) Expand all Loading... |
1301 } else { | 1314 } else { |
1302 str->append("None"); | 1315 str->append("None"); |
1303 } | 1316 } |
1304 str->append("))"); | 1317 str->append("))"); |
1305 } | 1318 } |
1306 #endif | 1319 #endif |
1307 | 1320 |
1308 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1321 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1309 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1322 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1310 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1323 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |