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" |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1005 | 1005 |
1006 SkRRect fRRect; | 1006 SkRRect fRRect; |
1007 float fSigma; | 1007 float fSigma; |
1008 GrTextureAccess fNinePatchAccess; | 1008 GrTextureAccess fNinePatchAccess; |
1009 | 1009 |
1010 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 1010 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
1011 | 1011 |
1012 typedef GrFragmentProcessor INHERITED; | 1012 typedef GrFragmentProcessor INHERITED; |
1013 }; | 1013 }; |
1014 | 1014 |
1015 static sk_sp<GrTexture> make_rrect_blur_mask(GrContext* context, | 1015 static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context, |
1016 const SkRRect& rrect, | 1016 const SkRRect& rrectToDra w, |
1017 float sigma, | 1017 const SkISize& size, |
1018 bool doAA) { | 1018 float xformedSigma, |
1019 SkRRect rrectToDraw; | 1019 bool doAA) { |
1020 SkISize size; | 1020 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
1021 SkScalar xs[4], ys[4]; | 1021 GrUniqueKey key; |
1022 int numXs, numYs; | 1022 GrUniqueKey::Builder builder(&key, kDomain, 9); |
1023 builder[0] = 3*SkScalarCeilToInt(xformedSigma-1/6.0f); | |
bsalomon
2016/08/15 13:55:23
Why 3*?
robertphillips
2016/08/15 17:41:37
We/SVG requires that we include 3*sigma of the sha
bsalomon
2016/08/15 17:57:56
Right but does it matter for the key?
robertphillips
2016/08/15 18:30:38
Nope - removed.
| |
1023 | 1024 |
1024 SkBlurMaskFilter::ComputeBlurredRRectParams(rrect, sigma, &rrectToDraw, &siz e, | 1025 int index = 1; |
1025 xs, &numXs, ys, &numYs); | 1026 for (auto c : { SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner, |
1027 SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner }) { | |
1028 SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) && SkScalarIsInt(rrectTo Draw.radii(c).fY)); | |
1029 builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX); | |
bsalomon
2016/08/15 13:55:23
Is the idea to handle non-circular? Right now I th
robertphillips
2016/08/15 17:41:37
The code will soon be able to handle non-simple-ci
| |
1030 builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY); | |
1031 } | |
1032 builder.finish(); | |
1026 | 1033 |
1027 // TODO: this could be approx but the texture coords will need to be updated | 1034 sk_sp<GrTexture> mask(context->textureProvider()->findAndRefTextureByUniqueK ey(key)); |
1028 sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact, | 1035 if (!mask) { |
1029 size.fWidth, size.fHeight, | 1036 // TODO: this could be approx but the texture coords will need to be upd ated |
1030 kAlpha_8_GrPixelConfig, nul lptr)); | 1037 sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact, |
1031 if (!dc) { | 1038 size.fWidth, size.fHeig ht, |
1032 return nullptr; | 1039 kAlpha_8_GrPixelConfig, nullptr)); |
1033 } | 1040 if (!dc) { |
1041 return nullptr; | |
1042 } | |
1034 | 1043 |
1035 GrPaint grPaint; | 1044 GrPaint grPaint; |
1036 grPaint.setAntiAlias(doAA); | 1045 grPaint.setAntiAlias(doAA); |
1037 | 1046 |
1038 dc->clear(nullptr, 0x0, true); | 1047 dc->clear(nullptr, 0x0, true); |
1039 dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::Simp leFill()); | 1048 dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle:: SimpleFill()); |
1040 | 1049 |
1041 sk_sp<GrTexture> tex(dc->asTexture()); | 1050 sk_sp<GrTexture> srcTexture(dc->asTexture()); |
1042 sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context, | 1051 sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context, |
1043 tex.get(), | 1052 srcTexture.get(), |
1044 nullptr, | 1053 nullptr, |
1045 SkIRect::MakeWH(size.f Width, | 1054 SkIRect::MakeWH(si ze.fWidth, |
1046 size.f Height), | 1055 si ze.fHeight), |
1047 nullptr, | 1056 nullptr, |
1048 sigma, sigma, SkBackin gFit::kExact)); | 1057 xformedSigma, xfor medSigma, |
1049 if (!dc2) { | 1058 SkBackingFit::kExa ct)); |
1050 return nullptr; | 1059 if (!dc2) { |
1060 return nullptr; | |
1061 } | |
1062 | |
1063 mask = dc2->asTexture(); | |
1064 SkASSERT(mask); | |
1065 context->textureProvider()->assignUniqueKeyToTexture(key, mask.get()); | |
1051 } | 1066 } |
1052 | 1067 |
1053 return dc2->asTexture(); | 1068 return mask; |
1054 } | 1069 } |
1055 | 1070 |
1056 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sig ma, | 1071 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, |
1057 const SkRRect& rrect) { | 1072 float xformedSigma, |
1058 if (rrect.isCircle()) { | 1073 const SkRRect& devRRect) { |
1074 if (devRRect.isCircle()) { | |
1059 return GrCircleBlurFragmentProcessor::Make(context->textureProvider(), | 1075 return GrCircleBlurFragmentProcessor::Make(context->textureProvider(), |
1060 rrect.rect(), sigma); | 1076 devRRect.rect(), xformedSigma ); |
1061 } | 1077 } |
1062 | 1078 |
1063 // TODO: loosen this up | 1079 // TODO: loosen this up |
1064 if (!rrect.isSimpleCircular()) { | 1080 if (!devRRect.isSimpleCircular()) { |
1065 return nullptr; | 1081 return nullptr; |
1066 } | 1082 } |
1067 | 1083 |
1068 // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be | 1084 // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be |
1069 // sufficiently small relative to both the size of the corner radius and the | 1085 // sufficiently small relative to both the size of the corner radius and the |
1070 // width (and height) of the rrect. | 1086 // width (and height) of the rrect. |
1087 SkRRect rrectToDraw; | |
1088 SkISize size; | |
1089 SkScalar ignored[4]; | |
1090 int ignoredSize; | |
1071 | 1091 |
1072 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); | 1092 bool ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(devRRect, x formedSigma, |
1073 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); | 1093 &rrectToDra w, &size, |
1074 if (cornerRadius + blurRadius > rrect.width()/2 || | 1094 ignored, &i gnoredSize, |
1075 cornerRadius + blurRadius > rrect.height()/2) { | 1095 ignored, &i gnoredSize); |
1096 if (!ninePatchable) { | |
1076 return nullptr; | 1097 return nullptr; |
1077 } | 1098 } |
1078 | 1099 |
1079 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 1100 sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, s ize, |
1080 GrUniqueKey key; | 1101 xformedSigma, true)); |
1081 GrUniqueKey::Builder builder(&key, kDomain, 2); | 1102 if (!mask) { |
1082 builder[0] = blurRadius; | 1103 return nullptr; |
1083 builder[1] = cornerRadius; | 1104 } |
1084 builder.finish(); | |
1085 | 1105 |
1086 sk_sp<GrTexture> blurNinePatchTexture( | 1106 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, |
1087 context->textureProvider()->findAndRefTextureByU niqueKey(key)); | 1107 devRRect, |
1088 | 1108 mask.get())); |
1089 if (!blurNinePatchTexture) { | |
1090 blurNinePatchTexture = make_rrect_blur_mask(context, rrect, sigma, true) ; | |
1091 if (!blurNinePatchTexture) { | |
1092 return nullptr; | |
1093 } | |
1094 context->textureProvider()->assignUniqueKeyToTexture(key, blurNinePatchT exture.get()); | |
1095 } | |
1096 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNi nePatchTexture.get())); | |
1097 } | 1109 } |
1098 | 1110 |
1099 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { | 1111 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
1100 inout->mulByUnknownSingleComponent(); | 1112 inout->mulByUnknownSingleComponent(); |
1101 } | 1113 } |
1102 | 1114 |
1103 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur e *ninePatchTexture) | 1115 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur e *ninePatchTexture) |
1104 : fRRect(rrect), | 1116 : fRRect(rrect), |
1105 fSigma(sigma), | 1117 fSigma(sigma), |
1106 fNinePatchAccess(ninePatchTexture) { | 1118 fNinePatchAccess(ninePatchTexture) { |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1428 } else { | 1440 } else { |
1429 str->append("None"); | 1441 str->append("None"); |
1430 } | 1442 } |
1431 str->append("))"); | 1443 str->append("))"); |
1432 } | 1444 } |
1433 #endif | 1445 #endif |
1434 | 1446 |
1435 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1447 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1436 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1448 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1437 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1449 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |