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 "GrRenderTargetContext.h" | 21 #include "GrRenderTargetContext.h" |
22 #include "GrTexture.h" | 22 #include "GrTexture.h" |
| 23 #include "GrTextureProxy.h" |
23 #include "GrFragmentProcessor.h" | 24 #include "GrFragmentProcessor.h" |
24 #include "GrInvariantOutput.h" | 25 #include "GrInvariantOutput.h" |
25 #include "GrStyle.h" | 26 #include "GrStyle.h" |
26 #include "effects/GrSimpleTextureEffect.h" | 27 #include "effects/GrSimpleTextureEffect.h" |
27 #include "glsl/GrGLSLFragmentProcessor.h" | 28 #include "glsl/GrGLSLFragmentProcessor.h" |
28 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 29 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
29 #include "glsl/GrGLSLProgramDataManager.h" | 30 #include "glsl/GrGLSLProgramDataManager.h" |
30 #include "glsl/GrGLSLSampler.h" | 31 #include "glsl/GrGLSLSampler.h" |
31 #include "glsl/GrGLSLUniformHandler.h" | 32 #include "glsl/GrGLSLUniformHandler.h" |
32 #endif | 33 #endif |
(...skipping 24 matching lines...) Expand all Loading... |
57 const SkStrokeRec& strokeRec, | 58 const SkStrokeRec& strokeRec, |
58 const SkPath& path) const override; | 59 const SkPath& path) const override; |
59 bool directFilterRRectMaskGPU(GrContext*, | 60 bool directFilterRRectMaskGPU(GrContext*, |
60 GrRenderTargetContext* renderTargetContext, | 61 GrRenderTargetContext* renderTargetContext, |
61 GrPaint* grp, | 62 GrPaint* grp, |
62 const GrClip&, | 63 const GrClip&, |
63 const SkMatrix& viewMatrix, | 64 const SkMatrix& viewMatrix, |
64 const SkStrokeRec& strokeRec, | 65 const SkStrokeRec& strokeRec, |
65 const SkRRect& rrect, | 66 const SkRRect& rrect, |
66 const SkRRect& devRRect) const override; | 67 const SkRRect& devRRect) const override; |
67 bool filterMaskGPU(GrTexture* src, | 68 bool filterMaskGPU(GrTextureProxy* src, |
68 const SkMatrix& ctm, | 69 const SkMatrix& ctm, |
69 const SkIRect& maskRect, | 70 const SkIRect& maskRect, |
70 GrTexture** result) const override; | 71 GrTextureProxy** result) const override; |
71 #endif | 72 #endif |
72 | 73 |
73 void computeFastBounds(const SkRect&, SkRect*) const override; | 74 void computeFastBounds(const SkRect&, SkRect*) const override; |
74 bool asABlur(BlurRec*) const override; | 75 bool asABlur(BlurRec*) const override; |
75 | 76 |
76 SK_TO_STRING_OVERRIDE() | 77 SK_TO_STRING_OVERRIDE() |
77 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) | 78 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) |
78 | 79 |
79 protected: | 80 protected: |
80 FilterReturn filterRectsToNine(const SkRect[], int count, const SkMatrix&, | 81 FilterReturn filterRectsToNine(const SkRect[], int count, const SkMatrix&, |
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 const char* name() const override { return "GrRRectBlur"; } | 1078 const char* name() const override { return "GrRRectBlur"; } |
1078 | 1079 |
1079 const SkRRect& getRRect() const { return fRRect; } | 1080 const SkRRect& getRRect() const { return fRRect; } |
1080 float getSigma() const { return fSigma; } | 1081 float getSigma() const { return fSigma; } |
1081 | 1082 |
1082 private: | 1083 private: |
1083 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; | 1084 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; |
1084 | 1085 |
1085 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); | 1086 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); |
1086 | 1087 |
| 1088 GrRRectBlurEffect(float sigma, const SkRRect&, GrTextureProxy* profileTextur
e); |
| 1089 |
1087 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 1090 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
1088 GrProcessorKeyBuilder* b) const override; | 1091 GrProcessorKeyBuilder* b) const override; |
1089 | 1092 |
1090 bool onIsEqual(const GrFragmentProcessor& other) const override; | 1093 bool onIsEqual(const GrFragmentProcessor& other) const override; |
1091 | 1094 |
1092 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 1095 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
1093 | 1096 |
1094 SkRRect fRRect; | 1097 SkRRect fRRect; |
1095 float fSigma; | 1098 float fSigma; |
1096 GrTextureAccess fNinePatchAccess; | 1099 GrTextureAccess fNinePatchAccess; |
1097 | 1100 |
1098 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 1101 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
1099 | 1102 |
1100 typedef GrFragmentProcessor INHERITED; | 1103 typedef GrFragmentProcessor INHERITED; |
1101 }; | 1104 }; |
1102 | 1105 |
1103 static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context, | 1106 static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context, |
1104 const SkRRect& rrectToDra
w, | 1107 const SkRRect& rrect
ToDraw, |
1105 const SkISize& size, | 1108 const SkISize& size, |
1106 float xformedSigma, | 1109 float xformedSigma, |
1107 bool doAA) { | 1110 bool doAA) { |
1108 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 1111 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
1109 GrUniqueKey key; | 1112 GrUniqueKey key; |
1110 GrUniqueKey::Builder builder(&key, kDomain, 9); | 1113 GrUniqueKey::Builder builder(&key, kDomain, 9); |
1111 builder[0] = SkScalarCeilToInt(xformedSigma-1/6.0f); | 1114 builder[0] = SkScalarCeilToInt(xformedSigma-1/6.0f); |
1112 | 1115 |
1113 int index = 1; | 1116 int index = 1; |
1114 for (auto c : { SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner, | 1117 for (auto c : { SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner, |
1115 SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner }) { | 1118 SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner }) { |
1116 SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) && SkScalarIsInt(rrectTo
Draw.radii(c).fY)); | 1119 SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) && SkScalarIsInt(rrectTo
Draw.radii(c).fY)); |
1117 builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX); | 1120 builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX); |
1118 builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY); | 1121 builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY); |
1119 } | 1122 } |
1120 builder.finish(); | 1123 builder.finish(); |
1121 | 1124 |
1122 sk_sp<GrTexture> mask(context->textureProvider()->findAndRefTextureByUniqueK
ey(key)); | 1125 sk_sp<GrTextureProxy> mask(context->textureProvider()->findAndRefTextureProx
yByUniqueKey(key)); |
1123 if (!mask) { | 1126 if (!mask) { |
1124 // TODO: this could be approx but the texture coords will need to be upd
ated | 1127 // TODO: this could be approx but the texture coords will need to be upd
ated |
1125 sk_sp<GrRenderTargetContext> rtc(context->makeRenderTargetContextWithFal
lback( | 1128 sk_sp<GrRenderTargetContext> rtc(context->makeRenderTargetContextWithFal
lback( |
1126 SkBackingFit::kExact, size.fWidth, size.fHeight, kAlpha_8_GrPixelCon
fig, nullptr)); | 1129 SkBackingFit::kExact, size.fWidth, size.fHeight, kAlpha_8_GrPixelCon
fig, nullptr)); |
1127 if (!rtc) { | 1130 if (!rtc) { |
1128 return nullptr; | 1131 return nullptr; |
1129 } | 1132 } |
1130 | 1133 |
1131 GrPaint grPaint; | 1134 GrPaint grPaint; |
1132 grPaint.setAntiAlias(doAA); | 1135 grPaint.setAntiAlias(doAA); |
1133 | 1136 |
1134 rtc->clear(nullptr, 0x0, true); | 1137 rtc->clear(nullptr, 0x0, true); |
1135 rtc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle:
:SimpleFill()); | 1138 rtc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle:
:SimpleFill()); |
1136 | 1139 |
1137 sk_sp<GrTexture> srcTexture(rtc->asTexture()); | 1140 sk_sp<GrTextureProxy> srcTexture(rtc->asDeferredTexture()); |
1138 sk_sp<GrRenderTargetContext> rtc2(SkGpuBlurUtils::GaussianBlur(context, | 1141 sk_sp<GrRenderTargetContext> rtc2(SkGpuBlurUtils::GaussianBlur(context, |
1139 srcTextur
e.get(), | 1142 srcTextur
e.get(), |
1140 nullptr, | 1143 nullptr, |
1141 SkIRect::
MakeWH( | 1144 SkIRect::
MakeWH( |
1142 size.
fWidth, | 1145 size.
fWidth, |
1143 size.
fHeight), | 1146 size.
fHeight), |
1144 nullptr, | 1147 nullptr, |
1145 xformedSi
gma, xformedSigma, | 1148 xformedSi
gma, xformedSigma, |
1146 SkBacking
Fit::kExact)); | 1149 SkBacking
Fit::kExact)); |
1147 if (!rtc2) { | 1150 if (!rtc2) { |
1148 return nullptr; | 1151 return nullptr; |
1149 } | 1152 } |
1150 | 1153 |
1151 mask = rtc2->asTexture(); | 1154 mask = rtc2->asDeferredTexture(); |
1152 SkASSERT(mask); | 1155 SkASSERT(mask); |
1153 context->textureProvider()->assignUniqueKeyToTexture(key, mask.get()); | 1156 context->textureProvider()->assignUniqueKeyToDeferredTexture(key, mask.g
et()); |
1154 } | 1157 } |
1155 | 1158 |
1156 return mask; | 1159 return mask; |
1157 } | 1160 } |
1158 | 1161 |
1159 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, | 1162 sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, |
1160 float sigma, float xformedSig
ma, | 1163 float sigma, float xformedSig
ma, |
1161 const SkRRect& srcRRect, cons
t SkRRect& devRRect) { | 1164 const SkRRect& srcRRect, cons
t SkRRect& devRRect) { |
1162 SkASSERT(!devRRect.isCircle() && !devRRect.isRect()); // Should've been caug
ht up-stream | 1165 SkASSERT(!devRRect.isCircle() && !devRRect.isRect()); // Should've been caug
ht up-stream |
1163 | 1166 |
(...skipping 16 matching lines...) Expand all Loading... |
1180 sigma, xfor
medSigma, | 1183 sigma, xfor
medSigma, |
1181 &rrectToDra
w, &size, | 1184 &rrectToDra
w, &size, |
1182 ignored, ig
nored, | 1185 ignored, ig
nored, |
1183 ignored, ig
nored, | 1186 ignored, ig
nored, |
1184 &ignoredSiz
e, &ignoredSize, | 1187 &ignoredSiz
e, &ignoredSize, |
1185 &ignored32)
; | 1188 &ignored32)
; |
1186 if (!ninePatchable) { | 1189 if (!ninePatchable) { |
1187 return nullptr; | 1190 return nullptr; |
1188 } | 1191 } |
1189 | 1192 |
1190 sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, s
ize, | 1193 sk_sp<GrTextureProxy> mask(find_or_create_rrect_blur_mask(context, rrectToDr
aw, size, |
1191 xformedSigma, true)); | 1194 xformedSigma, true)
); |
1192 if (!mask) { | 1195 if (!mask) { |
1193 return nullptr; | 1196 return nullptr; |
1194 } | 1197 } |
1195 | 1198 |
1196 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, | 1199 return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, |
1197 devRRect, | 1200 devRRect, |
1198 mask.get())); | 1201 mask.get())); |
1199 } | 1202 } |
1200 | 1203 |
1201 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 1204 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. | 1484 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. |
1482 srcRect.outset(sigma3, sigma3); | 1485 srcRect.outset(sigma3, sigma3); |
1483 clipRect.outset(sigma3, sigma3); | 1486 clipRect.outset(sigma3, sigma3); |
1484 if (!srcRect.intersect(clipRect)) { | 1487 if (!srcRect.intersect(clipRect)) { |
1485 srcRect.setEmpty(); | 1488 srcRect.setEmpty(); |
1486 } | 1489 } |
1487 *maskRect = srcRect; | 1490 *maskRect = srcRect; |
1488 return true; | 1491 return true; |
1489 } | 1492 } |
1490 | 1493 |
1491 bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, | 1494 bool SkBlurMaskFilterImpl::filterMaskGPU(GrTextureProxy* src, |
1492 const SkMatrix& ctm, | 1495 const SkMatrix& ctm, |
1493 const SkIRect& maskRect, | 1496 const SkIRect& maskRect, |
1494 GrTexture** result) const { | 1497 GrTextureProxy** result) const { |
1495 // 'maskRect' isn't snapped to the UL corner but the mask in 'src' is. | 1498 // 'maskRect' isn't snapped to the UL corner but the mask in 'src' is. |
1496 const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height()
); | 1499 const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height()
); |
1497 | 1500 |
1498 GrContext* context = src->getContext(); | 1501 GrContext* context = src->getContext(); |
1499 | 1502 |
1500 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1503 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
1501 SkASSERT(xformedSigma > 0); | 1504 SkASSERT(xformedSigma > 0); |
1502 | 1505 |
1503 // If we're doing a normal blur, we can clobber the pathTexture in the | 1506 // If we're doing a normal blur, we can clobber the pathTexture in the |
1504 // gaussianBlur. Otherwise, we need to save it for later compositing. | 1507 // gaussianBlur. Otherwise, we need to save it for later compositing. |
(...skipping 24 matching lines...) Expand all Loading... |
1529 // outer: dst = dst * (1 - src) | 1532 // outer: dst = dst * (1 - src) |
1530 // = 0 * src + (1 - src) * dst | 1533 // = 0 * src + (1 - src) * dst |
1531 paint.setCoverageSetOpXPFactory(SkRegion::kDifference_Op); | 1534 paint.setCoverageSetOpXPFactory(SkRegion::kDifference_Op); |
1532 } else { | 1535 } else { |
1533 paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); | 1536 paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); |
1534 } | 1537 } |
1535 | 1538 |
1536 renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::
Make(clipRect)); | 1539 renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::
Make(clipRect)); |
1537 } | 1540 } |
1538 | 1541 |
1539 *result = renderTargetContext->asTexture().release(); | 1542 *result = renderTargetContext->asDeferredTexture().release(); |
1540 return true; | 1543 return true; |
1541 } | 1544 } |
1542 | 1545 |
1543 #endif // SK_SUPPORT_GPU | 1546 #endif // SK_SUPPORT_GPU |
1544 | 1547 |
1545 | 1548 |
1546 #ifndef SK_IGNORE_TO_STRING | 1549 #ifndef SK_IGNORE_TO_STRING |
1547 void SkBlurMaskFilterImpl::toString(SkString* str) const { | 1550 void SkBlurMaskFilterImpl::toString(SkString* str) const { |
1548 str->append("SkBlurMaskFilterImpl: ("); | 1551 str->append("SkBlurMaskFilterImpl: ("); |
1549 | 1552 |
(...skipping 16 matching lines...) Expand all Loading... |
1566 } else { | 1569 } else { |
1567 str->append("None"); | 1570 str->append("None"); |
1568 } | 1571 } |
1569 str->append("))"); | 1572 str->append("))"); |
1570 } | 1573 } |
1571 #endif | 1574 #endif |
1572 | 1575 |
1573 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1576 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1574 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1577 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1575 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1578 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |