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] = SkScalarCeilToInt(xformedSigma-1/6.0f); |
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); |
| 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, | 1071 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, |
1057 float xformedSigma, | 1072 float xformedSigma, |
1058 const SkRRect& devRRect) { | 1073 const SkRRect& devRRect) { |
1059 SkASSERT(!devRRect.isCircle()); // Should've been caught up-stream | 1074 SkASSERT(!devRRect.isCircle()); // Should've been caught up-stream |
1060 | 1075 |
1061 // TODO: loosen this up | 1076 // TODO: loosen this up |
1062 if (!devRRect.isSimpleCircular()) { | 1077 if (!devRRect.isSimpleCircular()) { |
1063 return nullptr; | 1078 return nullptr; |
1064 } | 1079 } |
1065 | 1080 |
1066 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be | 1081 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be |
1067 // sufficiently small relative to both the size of the corner radius and the | 1082 // sufficiently small relative to both the size of the corner radius and the |
1068 // width (and height) of the rrect. | 1083 // width (and height) of the rrect. |
| 1084 SkRRect rrectToDraw; |
| 1085 SkISize size; |
| 1086 SkScalar ignored[4]; |
| 1087 int ignoredSize; |
1069 | 1088 |
1070 unsigned int blurRadius = 3*SkScalarCeilToInt(xformedSigma-1/6.0f); | 1089 bool ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(devRRect, x
formedSigma, |
1071 unsigned int cornerRadius = SkScalarCeilToInt(devRRect.getSimpleRadii().x())
; | 1090 &rrectToDra
w, &size, |
1072 if (cornerRadius + blurRadius > devRRect.width()/2 || | 1091 ignored, &i
gnoredSize, |
1073 cornerRadius + blurRadius > devRRect.height()/2) { | 1092 ignored, &i
gnoredSize); |
| 1093 if (!ninePatchable) { |
1074 return nullptr; | 1094 return nullptr; |
1075 } | 1095 } |
1076 | 1096 |
1077 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 1097 sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, s
ize, |
1078 GrUniqueKey key; | 1098 xformedSigma, true)); |
1079 GrUniqueKey::Builder builder(&key, kDomain, 2); | 1099 if (!mask) { |
1080 builder[0] = blurRadius; | 1100 return nullptr; |
1081 builder[1] = cornerRadius; | 1101 } |
1082 builder.finish(); | |
1083 | 1102 |
1084 sk_sp<GrTexture> blurNinePatchTexture( | 1103 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, |
1085 context->textureProvider()->findAndRefTextureByU
niqueKey(key)); | 1104 devRRect, |
1086 | 1105 mask.get())); |
1087 if (!blurNinePatchTexture) { | |
1088 blurNinePatchTexture = make_rrect_blur_mask(context, devRRect, xformedSi
gma, true); | |
1089 if (!blurNinePatchTexture) { | |
1090 return nullptr; | |
1091 } | |
1092 context->textureProvider()->assignUniqueKeyToTexture(key, blurNinePatchT
exture.get()); | |
1093 } | |
1094 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, devRRe
ct, | |
1095 blurNinePatchTexture
.get())); | |
1096 } | 1106 } |
1097 | 1107 |
1098 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 1108 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
1099 inout->mulByUnknownSingleComponent(); | 1109 inout->mulByUnknownSingleComponent(); |
1100 } | 1110 } |
1101 | 1111 |
1102 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) | 1112 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) |
1103 : fRRect(rrect), | 1113 : fRRect(rrect), |
1104 fSigma(sigma), | 1114 fSigma(sigma), |
1105 fNinePatchAccess(ninePatchTexture) { | 1115 fNinePatchAccess(ninePatchTexture) { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 } else { | 1457 } else { |
1448 str->append("None"); | 1458 str->append("None"); |
1449 } | 1459 } |
1450 str->append("))"); | 1460 str->append("))"); |
1451 } | 1461 } |
1452 #endif | 1462 #endif |
1453 | 1463 |
1454 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1464 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1455 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1465 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1456 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1466 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |