| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBlurMaskFilter.h" | 8 #include "SkBlurMaskFilter.h" |
| 9 #include "SkBlurMask.h" | 9 #include "SkBlurMask.h" |
| 10 #include "SkGpuBlurUtils.h" | 10 #include "SkGpuBlurUtils.h" |
| 11 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
| 12 #include "SkWriteBuffer.h" | 12 #include "SkWriteBuffer.h" |
| 13 #include "SkMaskFilter.h" | 13 #include "SkMaskFilter.h" |
| 14 #include "SkRRect.h" | 14 #include "SkRRect.h" |
| 15 #include "SkStringUtils.h" | 15 #include "SkStringUtils.h" |
| 16 #include "SkStrokeRec.h" | 16 #include "SkStrokeRec.h" |
| 17 | 17 |
| 18 #if SK_SUPPORT_GPU | 18 #if SK_SUPPORT_GPU |
| 19 #include "GrCircleBlurFragmentProcessor.h" | 19 #include "GrCircleBlurFragmentProcessor.h" |
| 20 #include "GrContext.h" | 20 #include "GrContext.h" |
| 21 #include "GrDrawContext.h" | 21 #include "GrDrawContext.h" |
| 22 #include "GrTexture.h" | 22 #include "GrTexture.h" |
| 23 #include "GrFragmentProcessor.h" | 23 #include "GrFragmentProcessor.h" |
| 24 #include "GrInvariantOutput.h" | 24 #include "GrInvariantOutput.h" |
| 25 #include "SkDraw.h" | 25 #include "GrStyle.h" |
| 26 #include "effects/GrSimpleTextureEffect.h" | 26 #include "effects/GrSimpleTextureEffect.h" |
| 27 #include "glsl/GrGLSLFragmentProcessor.h" | 27 #include "glsl/GrGLSLFragmentProcessor.h" |
| 28 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 28 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
| 29 #include "glsl/GrGLSLProgramDataManager.h" | 29 #include "glsl/GrGLSLProgramDataManager.h" |
| 30 #include "glsl/GrGLSLSampler.h" | 30 #include "glsl/GrGLSLSampler.h" |
| 31 #include "glsl/GrGLSLUniformHandler.h" | 31 #include "glsl/GrGLSLUniformHandler.h" |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) { | 34 SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) { |
| 35 return SkBlurMask::ConvertRadiusToSigma(radius); | 35 return SkBlurMask::ConvertRadiusToSigma(radius); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 49 const SkIRect& clipBounds, | 49 const SkIRect& clipBounds, |
| 50 const SkMatrix& ctm, | 50 const SkMatrix& ctm, |
| 51 SkRect* maskRect) const override; | 51 SkRect* maskRect) const override; |
| 52 bool directFilterMaskGPU(GrTextureProvider* texProvider, | 52 bool directFilterMaskGPU(GrTextureProvider* texProvider, |
| 53 GrDrawContext* drawContext, | 53 GrDrawContext* drawContext, |
| 54 GrPaint* grp, | 54 GrPaint* grp, |
| 55 const GrClip&, | 55 const GrClip&, |
| 56 const SkMatrix& viewMatrix, | 56 const SkMatrix& viewMatrix, |
| 57 const SkStrokeRec& strokeRec, | 57 const SkStrokeRec& strokeRec, |
| 58 const SkPath& path) const override; | 58 const SkPath& path) const override; |
| 59 bool directFilterRRectMaskGPU(GrTextureProvider* texProvider, | 59 bool directFilterRRectMaskGPU(GrContext*, |
| 60 GrDrawContext* drawContext, | 60 GrDrawContext* drawContext, |
| 61 GrPaint* grp, | 61 GrPaint* grp, |
| 62 const GrClip&, | 62 const GrClip&, |
| 63 const SkMatrix& viewMatrix, | 63 const SkMatrix& viewMatrix, |
| 64 const SkStrokeRec& strokeRec, | 64 const SkStrokeRec& strokeRec, |
| 65 const SkRRect& rrect) const override; | 65 const SkRRect& rrect) const override; |
| 66 bool filterMaskGPU(GrTexture* src, | 66 bool filterMaskGPU(GrTexture* src, |
| 67 const SkMatrix& ctm, | 67 const SkMatrix& ctm, |
| 68 const SkIRect& maskRect, | 68 const SkIRect& maskRect, |
| 69 GrTexture** result) const override; | 69 GrTexture** result) const override; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 } | 129 } |
| 130 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { | 130 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { |
| 131 return nullptr; | 131 return nullptr; |
| 132 } | 132 } |
| 133 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); | 133 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); |
| 134 flags &= SkBlurMaskFilter::kAll_BlurFlag; | 134 flags &= SkBlurMaskFilter::kAll_BlurFlag; |
| 135 | 135 |
| 136 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, flags)); | 136 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, flags)); |
| 137 } | 137 } |
| 138 | 138 |
| 139 bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect, |
| 140 SkScalar sigma, |
| 141 SkRRect* rrectToDraw, |
| 142 SkISize* widthHeight, |
| 143 SkScalar xs[4], |
| 144 int* numXs, |
| 145 SkScalar ys[4], |
| 146 int* numYs) { |
| 147 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); |
| 148 |
| 149 const SkRect& orig = rrect.getBounds(); |
| 150 const SkVector& radiiUL = rrect.radii(SkRRect::kUpperLeft_Corner); |
| 151 const SkVector& radiiUR = rrect.radii(SkRRect::kUpperRight_Corner); |
| 152 const SkVector& radiiLR = rrect.radii(SkRRect::kLowerRight_Corner); |
| 153 const SkVector& radiiLL = rrect.radii(SkRRect::kLowerLeft_Corner); |
| 154 |
| 155 const int left = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUL.fX, radiiLL.fX)
); |
| 156 const int top = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUL.fY, radiiUR.fY)
); |
| 157 const int right = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUR.fX, radiiLR.fX)
); |
| 158 const int bot = SkScalarCeilToInt(SkTMax<SkScalar>(radiiLL.fY, radiiLR.fY)
); |
| 159 |
| 160 // This is a conservative check for nine-patchability |
| 161 if (orig.fLeft + left + blurRadius >= orig.fRight - right - blurRadius || |
| 162 orig.fTop + top + blurRadius >= orig.fBottom - bot - blurRadius) { |
| 163 return false; |
| 164 } |
| 165 |
| 166 int newRRWidth, newRRHeight; |
| 167 |
| 168 // 3x3 case |
| 169 newRRWidth = 2*blurRadius + left + right + 1; |
| 170 newRRHeight = 2*blurRadius + top + bot + 1; |
| 171 widthHeight->fWidth = newRRWidth + 2 * blurRadius; |
| 172 widthHeight->fHeight = newRRHeight + 2 * blurRadius; |
| 173 // TODO: need to return non-normalized indices |
| 174 xs[0] = 0.0f; |
| 175 xs[1] = (blurRadius + left) / (float) widthHeight->fWidth; |
| 176 xs[2] = (blurRadius + left + 1.0f) / widthHeight->fWidth; |
| 177 xs[3] = 1.0f; |
| 178 *numXs = 4; |
| 179 ys[0] = 0.0f; |
| 180 ys[1] = (blurRadius + top) / (float) widthHeight->fHeight; |
| 181 ys[2] = (blurRadius + top + 1.0f) / widthHeight->fHeight; |
| 182 ys[3] = 1.0f; |
| 183 *numYs = 4; |
| 184 |
| 185 const SkRect newRect = SkRect::MakeXYWH(SkIntToScalar(blurRadius), SkIntToSc
alar(blurRadius), |
| 186 SkIntToScalar(newRRWidth), SkIntToSc
alar(newRRHeight)); |
| 187 SkVector newRadii[4]; |
| 188 newRadii[0] = { SkScalarCeilToScalar(radiiUL.fX), SkScalarCeilToScalar(radii
UL.fY) }; |
| 189 newRadii[1] = { SkScalarCeilToScalar(radiiUR.fX), SkScalarCeilToScalar(radii
UR.fY) }; |
| 190 newRadii[2] = { SkScalarCeilToScalar(radiiLR.fX), SkScalarCeilToScalar(radii
LR.fY) }; |
| 191 newRadii[3] = { SkScalarCeilToScalar(radiiLL.fX), SkScalarCeilToScalar(radii
LL.fY) }; |
| 192 |
| 193 rrectToDraw->setRectRadii(newRect, newRadii); |
| 194 return true; |
| 195 } |
| 196 |
| 139 /////////////////////////////////////////////////////////////////////////////// | 197 /////////////////////////////////////////////////////////////////////////////// |
| 140 | 198 |
| 141 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui
nt32_t flags) | 199 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui
nt32_t flags) |
| 142 : fSigma(sigma) | 200 : fSigma(sigma) |
| 143 , fBlurStyle(style) | 201 , fBlurStyle(style) |
| 144 , fBlurFlags(flags) { | 202 , fBlurFlags(flags) { |
| 145 SkASSERT(fSigma > 0); | 203 SkASSERT(fSigma > 0); |
| 146 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle); | 204 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle); |
| 147 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); | 205 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); |
| 148 } | 206 } |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 } | 650 } |
| 593 return nullptr; | 651 return nullptr; |
| 594 } | 652 } |
| 595 | 653 |
| 596 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { | 654 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { |
| 597 buffer.writeScalar(fSigma); | 655 buffer.writeScalar(fSigma); |
| 598 buffer.writeUInt(fBlurStyle); | 656 buffer.writeUInt(fBlurStyle); |
| 599 buffer.writeUInt(fBlurFlags); | 657 buffer.writeUInt(fBlurFlags); |
| 600 } | 658 } |
| 601 | 659 |
| 660 |
| 602 #if SK_SUPPORT_GPU | 661 #if SK_SUPPORT_GPU |
| 603 | 662 |
| 604 class GrGLRectBlurEffect; | 663 class GrGLRectBlurEffect; |
| 605 | 664 |
| 606 class GrRectBlurEffect : public GrFragmentProcessor { | 665 class GrRectBlurEffect : public GrFragmentProcessor { |
| 607 public: | 666 public: |
| 608 ~GrRectBlurEffect() override { } | 667 ~GrRectBlurEffect() override { } |
| 609 | 668 |
| 610 const char* name() const override { return "RectBlur"; } | 669 const char* name() const override { return "RectBlur"; } |
| 611 | 670 |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 | 962 |
| 904 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), rect, invers
e); | 963 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), rect, invers
e); |
| 905 return true; | 964 return true; |
| 906 } | 965 } |
| 907 | 966 |
| 908 ////////////////////////////////////////////////////////////////////////////// | 967 ////////////////////////////////////////////////////////////////////////////// |
| 909 | 968 |
| 910 class GrRRectBlurEffect : public GrFragmentProcessor { | 969 class GrRRectBlurEffect : public GrFragmentProcessor { |
| 911 public: | 970 public: |
| 912 | 971 |
| 913 static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*, float sigma, cons
t SkRRect&); | 972 static sk_sp<GrFragmentProcessor> Make(GrContext*, float sigma, const SkRRec
t&); |
| 914 | 973 |
| 915 virtual ~GrRRectBlurEffect() {}; | 974 virtual ~GrRRectBlurEffect() {}; |
| 916 const char* name() const override { return "GrRRectBlur"; } | 975 const char* name() const override { return "GrRRectBlur"; } |
| 917 | 976 |
| 918 const SkRRect& getRRect() const { return fRRect; } | 977 const SkRRect& getRRect() const { return fRRect; } |
| 919 float getSigma() const { return fSigma; } | 978 float getSigma() const { return fSigma; } |
| 920 | 979 |
| 921 private: | 980 private: |
| 922 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; | 981 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; |
| 923 | 982 |
| 924 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); | 983 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); |
| 925 | 984 |
| 926 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 985 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
| 927 GrProcessorKeyBuilder* b) const override; | 986 GrProcessorKeyBuilder* b) const override; |
| 928 | 987 |
| 929 bool onIsEqual(const GrFragmentProcessor& other) const override; | 988 bool onIsEqual(const GrFragmentProcessor& other) const override; |
| 930 | 989 |
| 931 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 990 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
| 932 | 991 |
| 933 SkRRect fRRect; | 992 SkRRect fRRect; |
| 934 float fSigma; | 993 float fSigma; |
| 935 GrTextureAccess fNinePatchAccess; | 994 GrTextureAccess fNinePatchAccess; |
| 936 | 995 |
| 937 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 996 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 938 | 997 |
| 939 typedef GrFragmentProcessor INHERITED; | 998 typedef GrFragmentProcessor INHERITED; |
| 940 }; | 999 }; |
| 941 | 1000 |
| 1001 static sk_sp<GrTexture> make_rrect_blur_mask(GrContext* context, |
| 1002 const SkRRect& rrect, |
| 1003 float sigma, |
| 1004 bool doAA) { |
| 1005 SkRRect rrectToDraw; |
| 1006 SkISize size; |
| 1007 SkScalar xs[4], ys[4]; |
| 1008 int numXs, numYs; |
| 942 | 1009 |
| 943 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrTextureProvider* texProvide
r, float sigma, | 1010 SkBlurMaskFilter::ComputeBlurredRRectParams(rrect, sigma, &rrectToDraw, &siz
e, |
| 944 const SkRRect& rrect) { | 1011 xs, &numXs, ys, &numYs); |
| 945 if (rrect.isCircle()) { | 1012 |
| 946 return GrCircleBlurFragmentProcessor::Make(texProvider, rrect.rect(), si
gma); | 1013 // TODO: this could be approx but the texture coords will need to be updated |
| 1014 sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact, |
| 1015 size.fWidth, size.fHeight, |
| 1016 kAlpha_8_GrPixelConfig, nul
lptr)); |
| 1017 if (!dc) { |
| 1018 return nullptr; |
| 1019 } |
| 1020 |
| 1021 GrPaint grPaint; |
| 1022 grPaint.setAntiAlias(doAA); |
| 1023 |
| 1024 dc->clear(nullptr, 0x0, true); |
| 1025 dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::Simp
leFill()); |
| 1026 |
| 1027 sk_sp<GrTexture> tex(dc->asTexture()); |
| 1028 sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context, |
| 1029 tex.get(), |
| 1030 nullptr, |
| 1031 SkIRect::MakeWH(size.f
Width, |
| 1032 size.f
Height), |
| 1033 nullptr, |
| 1034 sigma, sigma, SkBackin
gFit::kExact)); |
| 1035 if (!dc2) { |
| 1036 return nullptr; |
| 947 } | 1037 } |
| 948 | 1038 |
| 1039 return dc2->asTexture(); |
| 1040 } |
| 1041 |
| 1042 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sig
ma, |
| 1043 const SkRRect& rrect) { |
| 1044 if (rrect.isCircle()) { |
| 1045 return GrCircleBlurFragmentProcessor::Make(context->textureProvider(), |
| 1046 rrect.rect(), sigma); |
| 1047 } |
| 1048 |
| 1049 // TODO: loosen this up |
| 949 if (!rrect.isSimpleCircular()) { | 1050 if (!rrect.isSimpleCircular()) { |
| 950 return nullptr; | 1051 return nullptr; |
| 951 } | 1052 } |
| 952 | 1053 |
| 953 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be | 1054 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be |
| 954 // sufficiently small relative to both the size of the corner radius and the | 1055 // sufficiently small relative to both the size of the corner radius and the |
| 955 // width (and height) of the rrect. | 1056 // width (and height) of the rrect. |
| 956 | 1057 |
| 957 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); | 1058 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); |
| 958 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); | 1059 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); |
| 959 if (cornerRadius + blurRadius > rrect.width()/2 || | 1060 if (cornerRadius + blurRadius > rrect.width()/2 || |
| 960 cornerRadius + blurRadius > rrect.height()/2) { | 1061 cornerRadius + blurRadius > rrect.height()/2) { |
| 961 return nullptr; | 1062 return nullptr; |
| 962 } | 1063 } |
| 963 | 1064 |
| 964 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 1065 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| 965 GrUniqueKey key; | 1066 GrUniqueKey key; |
| 966 GrUniqueKey::Builder builder(&key, kDomain, 2); | 1067 GrUniqueKey::Builder builder(&key, kDomain, 2); |
| 967 builder[0] = blurRadius; | 1068 builder[0] = blurRadius; |
| 968 builder[1] = cornerRadius; | 1069 builder[1] = cornerRadius; |
| 969 builder.finish(); | 1070 builder.finish(); |
| 970 | 1071 |
| 971 SkAutoTUnref<GrTexture> blurNinePatchTexture(texProvider->findAndRefTextureB
yUniqueKey(key)); | 1072 sk_sp<GrTexture> blurNinePatchTexture( |
| 1073 context->textureProvider()->findAndRefTextureByU
niqueKey(key)); |
| 972 | 1074 |
| 973 if (!blurNinePatchTexture) { | 1075 if (!blurNinePatchTexture) { |
| 974 SkMask mask; | 1076 blurNinePatchTexture = make_rrect_blur_mask(context, rrect, sigma, true)
; |
| 975 | |
| 976 unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1; | |
| 977 | |
| 978 mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide); | |
| 979 mask.fFormat = SkMask::kA8_Format; | |
| 980 mask.fRowBytes = mask.fBounds.width(); | |
| 981 mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize()); | |
| 982 SkAutoMaskFreeImage amfi(mask.fImage); | |
| 983 | |
| 984 memset(mask.fImage, 0, mask.computeTotalImageSize()); | |
| 985 | |
| 986 SkRect smallRect; | |
| 987 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid
e)); | |
| 988 | |
| 989 SkRRect smallRRect; | |
| 990 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal
ar(cornerRadius)); | |
| 991 | |
| 992 SkPath path; | |
| 993 path.addRRect(smallRRect); | |
| 994 | |
| 995 SkDraw::DrawToMask(path, &mask.fBounds, nullptr, nullptr, &mask, | |
| 996 SkMask::kJustRenderImage_CreateMode, SkStrokeRec::kFi
ll_InitStyle); | |
| 997 | |
| 998 SkMask blurredMask; | |
| 999 if (!SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle, | |
| 1000 kHigh_SkBlurQuality, nullptr, true)) { | |
| 1001 return nullptr; | |
| 1002 } | |
| 1003 | |
| 1004 unsigned int texSide = smallRectSide + 2*blurRadius; | |
| 1005 GrSurfaceDesc texDesc; | |
| 1006 texDesc.fWidth = texSide; | |
| 1007 texDesc.fHeight = texSide; | |
| 1008 texDesc.fConfig = kAlpha_8_GrPixelConfig; | |
| 1009 texDesc.fIsMipMapped = false; | |
| 1010 | |
| 1011 blurNinePatchTexture.reset( | |
| 1012 texProvider->createTexture(texDesc, SkBudgeted::kYes , blurredMask.f
Image, 0)); | |
| 1013 SkMask::FreeImage(blurredMask.fImage); | |
| 1014 if (!blurNinePatchTexture) { | 1077 if (!blurNinePatchTexture) { |
| 1015 return nullptr; | 1078 return nullptr; |
| 1016 } | 1079 } |
| 1017 texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture); | 1080 context->textureProvider()->assignUniqueKeyToTexture(key, blurNinePatchT
exture.get()); |
| 1018 } | 1081 } |
| 1019 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNi
nePatchTexture)); | 1082 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNi
nePatchTexture.get())); |
| 1020 } | 1083 } |
| 1021 | 1084 |
| 1022 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 1085 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
| 1023 inout->mulByUnknownSingleComponent(); | 1086 inout->mulByUnknownSingleComponent(); |
| 1024 } | 1087 } |
| 1025 | 1088 |
| 1026 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) | 1089 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) |
| 1027 : fRRect(rrect), | 1090 : fRRect(rrect), |
| 1028 fSigma(sigma), | 1091 fSigma(sigma), |
| 1029 fNinePatchAccess(ninePatchTexture) { | 1092 fNinePatchAccess(ninePatchTexture) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1043 | 1106 |
| 1044 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); | 1107 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); |
| 1045 | 1108 |
| 1046 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d)
{ | 1109 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d)
{ |
| 1047 SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f); | 1110 SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f); |
| 1048 SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f); | 1111 SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f); |
| 1049 SkScalar r = d->fRandom->nextRangeF(1.f, 9.f); | 1112 SkScalar r = d->fRandom->nextRangeF(1.f, 9.f); |
| 1050 SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f); | 1113 SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f); |
| 1051 SkRRect rrect; | 1114 SkRRect rrect; |
| 1052 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 1115 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
| 1053 return GrRRectBlurEffect::Make(d->fContext->textureProvider(), sigma, rrect)
; | 1116 return GrRRectBlurEffect::Make(d->fContext, sigma, rrect); |
| 1054 } | 1117 } |
| 1055 | 1118 |
| 1056 ////////////////////////////////////////////////////////////////////////////// | 1119 ////////////////////////////////////////////////////////////////////////////// |
| 1057 | 1120 |
| 1058 class GrGLRRectBlurEffect : public GrGLSLFragmentProcessor { | 1121 class GrGLRRectBlurEffect : public GrGLSLFragmentProcessor { |
| 1059 public: | 1122 public: |
| 1060 void emitCode(EmitArgs&) override; | 1123 void emitCode(EmitArgs&) override; |
| 1061 | 1124 |
| 1062 protected: | 1125 protected: |
| 1063 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; | 1126 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 | 1209 |
| 1147 void GrRRectBlurEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 1210 void GrRRectBlurEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
| 1148 GrProcessorKeyBuilder* b) const { | 1211 GrProcessorKeyBuilder* b) const { |
| 1149 GrGLRRectBlurEffect::GenKey(*this, caps, b); | 1212 GrGLRRectBlurEffect::GenKey(*this, caps, b); |
| 1150 } | 1213 } |
| 1151 | 1214 |
| 1152 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const { | 1215 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const { |
| 1153 return new GrGLRRectBlurEffect; | 1216 return new GrGLRRectBlurEffect; |
| 1154 } | 1217 } |
| 1155 | 1218 |
| 1156 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvid
er, | 1219 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, |
| 1157 GrDrawContext* drawContext, | 1220 GrDrawContext* drawContext, |
| 1158 GrPaint* grp, | 1221 GrPaint* grp, |
| 1159 const GrClip& clip, | 1222 const GrClip& clip, |
| 1160 const SkMatrix& viewMatrix, | 1223 const SkMatrix& viewMatrix, |
| 1161 const SkStrokeRec& strokeRec
, | 1224 const SkStrokeRec& strokeRec
, |
| 1162 const SkRRect& rrect) const
{ | 1225 const SkRRect& rrect) const
{ |
| 1163 SkASSERT(drawContext); | 1226 SkASSERT(drawContext); |
| 1164 | 1227 |
| 1165 if (fBlurStyle != kNormal_SkBlurStyle) { | 1228 if (fBlurStyle != kNormal_SkBlurStyle) { |
| 1166 return false; | 1229 return false; |
| 1167 } | 1230 } |
| 1168 | 1231 |
| 1169 if (!strokeRec.isFillStyle()) { | 1232 if (!strokeRec.isFillStyle()) { |
| 1170 return false; | 1233 return false; |
| 1171 } | 1234 } |
| 1172 | 1235 |
| 1173 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); | 1236 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); |
| 1174 | 1237 |
| 1175 sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSi
gma, rrect)); | 1238 sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma,
rrect)); |
| 1176 if (!fp) { | 1239 if (!fp) { |
| 1177 return false; | 1240 return false; |
| 1178 } | 1241 } |
| 1179 | 1242 |
| 1180 grp->addCoverageFragmentProcessor(std::move(fp)); | 1243 GrPaint newPaint(*grp); |
| 1244 newPaint.addCoverageFragmentProcessor(std::move(fp)); |
| 1245 newPaint.setAntiAlias(false); |
| 1181 | 1246 |
| 1182 SkMatrix inverse; | 1247 SkMatrix inverse; |
| 1183 if (!viewMatrix.invert(&inverse)) { | 1248 if (!viewMatrix.invert(&inverse)) { |
| 1184 return false; | 1249 return false; |
| 1185 } | 1250 } |
| 1186 | 1251 |
| 1187 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); | 1252 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); |
| 1188 | 1253 |
| 1189 SkRect proxyRect = rrect.rect(); | 1254 SkRect proxyRect = rrect.rect(); |
| 1190 proxyRect.outset(extra, extra); | 1255 proxyRect.outset(extra, extra); |
| 1191 | 1256 |
| 1192 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), proxyRect, i
nverse); | 1257 drawContext->fillRectWithLocalMatrix(clip, newPaint, SkMatrix::I(), proxyRec
t, inverse); |
| 1193 return true; | 1258 return true; |
| 1194 } | 1259 } |
| 1195 | 1260 |
| 1196 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect, | 1261 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect, |
| 1197 const SkIRect& clipBounds, | 1262 const SkIRect& clipBounds, |
| 1198 const SkMatrix& ctm, | 1263 const SkMatrix& ctm, |
| 1199 SkRect* maskRect) const { | 1264 SkRect* maskRect) const { |
| 1200 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1265 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
| 1201 if (xformedSigma <= 0) { | 1266 if (xformedSigma <= 0) { |
| 1202 return false; | 1267 return false; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 } else { | 1378 } else { |
| 1314 str->append("None"); | 1379 str->append("None"); |
| 1315 } | 1380 } |
| 1316 str->append("))"); | 1381 str->append("))"); |
| 1317 } | 1382 } |
| 1318 #endif | 1383 #endif |
| 1319 | 1384 |
| 1320 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1385 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 1321 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1386 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 1322 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1387 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |