| 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 |