Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: src/effects/SkBlurMaskFilter.cpp

Issue 2201133002: Implement GPU occluded blur mask filter (Closed) Base URL: https://skia.googlesource.com/skia.git@occluded-blur
Patch Set: update to ToT Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkReadBuffer.h ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 19 matching lines...) Expand all
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);
36 } 36 }
37 37
38 class SkBlurMaskFilterImpl : public SkMaskFilter { 38 class SkBlurMaskFilterImpl : public SkMaskFilter {
39 public: 39 public:
40 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags); 40 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, const SkRect& occluder, ui nt32_t flags);
41 41
42 // overrides from SkMaskFilter 42 // overrides from SkMaskFilter
43 SkMask::Format getFormat() const override; 43 SkMask::Format getFormat() const override;
44 bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, 44 bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
45 SkIPoint* margin) const override; 45 SkIPoint* margin) const override;
46 46
47 #if SK_SUPPORT_GPU 47 #if SK_SUPPORT_GPU
48 bool canFilterMaskGPU(const SkRRect& devRRect, 48 bool canFilterMaskGPU(const SkRRect& devRRect,
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(GrContext*, 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,
66 const SkRRect& devRRect) const override;
66 bool filterMaskGPU(GrTexture* src, 67 bool filterMaskGPU(GrTexture* src,
67 const SkMatrix& ctm, 68 const SkMatrix& ctm,
68 const SkIRect& maskRect, 69 const SkIRect& maskRect,
69 GrTexture** result) const override; 70 GrTexture** result) const override;
70 #endif 71 #endif
71 72
72 void computeFastBounds(const SkRect&, SkRect*) const override; 73 void computeFastBounds(const SkRect&, SkRect*) const override;
73 bool asABlur(BlurRec*) const override; 74 bool asABlur(BlurRec*) const override;
74 75
75 SK_TO_STRING_OVERRIDE() 76 SK_TO_STRING_OVERRIDE()
(...skipping 18 matching lines...) Expand all
94 } 95 }
95 96
96 private: 97 private:
97 // To avoid unseemly allocation requests (esp. for finite platforms like 98 // To avoid unseemly allocation requests (esp. for finite platforms like
98 // handset) we limit the radius so something manageable. (as opposed to 99 // handset) we limit the radius so something manageable. (as opposed to
99 // a request like 10,000) 100 // a request like 10,000)
100 static const SkScalar kMAX_BLUR_SIGMA; 101 static const SkScalar kMAX_BLUR_SIGMA;
101 102
102 SkScalar fSigma; 103 SkScalar fSigma;
103 SkBlurStyle fBlurStyle; 104 SkBlurStyle fBlurStyle;
105 SkRect fOccluder;
104 uint32_t fBlurFlags; 106 uint32_t fBlurFlags;
105 107
106 SkBlurQuality getQuality() const { 108 SkBlurQuality getQuality() const {
107 return (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 109 return (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ?
108 kHigh_SkBlurQuality : kLow_SkBlurQuality; 110 kHigh_SkBlurQuality : kLow_SkBlurQuality;
109 } 111 }
110 112
111 SkBlurMaskFilterImpl(SkReadBuffer&); 113 SkBlurMaskFilterImpl(SkReadBuffer&);
112 void flatten(SkWriteBuffer&) const override; 114 void flatten(SkWriteBuffer&) const override;
113 115
114 SkScalar computeXformedSigma(const SkMatrix& ctm) const { 116 SkScalar computeXformedSigma(const SkMatrix& ctm) const {
115 SkScalar xformedSigma = this->ignoreXform() ? fSigma : ctm.mapRadius(fSi gma); 117 SkScalar xformedSigma = this->ignoreXform() ? fSigma : ctm.mapRadius(fSi gma);
116 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); 118 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA);
117 } 119 }
118 120
119 friend class SkBlurMaskFilter; 121 friend class SkBlurMaskFilter;
120 122
121 typedef SkMaskFilter INHERITED; 123 typedef SkMaskFilter INHERITED;
122 }; 124 };
123 125
124 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); 126 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128);
125 127
126 sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma, ui nt32_t flags) { 128 sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma,
129 const SkRect& occluder, uint32_t flag s) {
127 if (!SkScalarIsFinite(sigma) || sigma <= 0) { 130 if (!SkScalarIsFinite(sigma) || sigma <= 0) {
128 return nullptr; 131 return nullptr;
129 } 132 }
130 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { 133 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) {
131 return nullptr; 134 return nullptr;
132 } 135 }
133 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 136 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
134 flags &= SkBlurMaskFilter::kAll_BlurFlag; 137 flags &= SkBlurMaskFilter::kAll_BlurFlag;
135 138
136 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, flags)); 139 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, occluder, flags));
137 } 140 }
138 141
139 bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect, 142 bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect,
140 SkScalar sigma, 143 SkScalar sigma,
141 SkRRect* rrectToDraw, 144 SkRRect* rrectToDraw,
142 SkISize* widthHeight, 145 SkISize* widthHeight,
143 SkScalar xs[4], 146 SkScalar xs[4],
144 int* numXs, 147 int* numXs,
145 SkScalar ys[4], 148 SkScalar ys[4],
146 int* numYs) { 149 int* numYs) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 newRadii[1] = { SkScalarCeilToScalar(radiiUR.fX), SkScalarCeilToScalar(radii UR.fY) }; 192 newRadii[1] = { SkScalarCeilToScalar(radiiUR.fX), SkScalarCeilToScalar(radii UR.fY) };
190 newRadii[2] = { SkScalarCeilToScalar(radiiLR.fX), SkScalarCeilToScalar(radii LR.fY) }; 193 newRadii[2] = { SkScalarCeilToScalar(radiiLR.fX), SkScalarCeilToScalar(radii LR.fY) };
191 newRadii[3] = { SkScalarCeilToScalar(radiiLL.fX), SkScalarCeilToScalar(radii LL.fY) }; 194 newRadii[3] = { SkScalarCeilToScalar(radiiLL.fX), SkScalarCeilToScalar(radii LL.fY) };
192 195
193 rrectToDraw->setRectRadii(newRect, newRadii); 196 rrectToDraw->setRectRadii(newRect, newRadii);
194 return true; 197 return true;
195 } 198 }
196 199
197 /////////////////////////////////////////////////////////////////////////////// 200 ///////////////////////////////////////////////////////////////////////////////
198 201
199 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui nt32_t flags) 202 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style,
203 const SkRect& occluder, uint32_t flag s)
200 : fSigma(sigma) 204 : fSigma(sigma)
201 , fBlurStyle(style) 205 , fBlurStyle(style)
206 , fOccluder(occluder)
202 , fBlurFlags(flags) { 207 , fBlurFlags(flags) {
203 SkASSERT(fSigma > 0); 208 SkASSERT(fSigma > 0);
204 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle); 209 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle);
205 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 210 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
206 } 211 }
207 212
208 SkMask::Format SkBlurMaskFilterImpl::getFormat() const { 213 SkMask::Format SkBlurMaskFilterImpl::getFormat() const {
209 return SkMask::kA8_Format; 214 return SkMask::kA8_Format;
210 } 215 }
211 216
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 SkScalar pad = 3.0f * fSigma; 643 SkScalar pad = 3.0f * fSigma;
639 644
640 dst->set(src.fLeft - pad, src.fTop - pad, 645 dst->set(src.fLeft - pad, src.fTop - pad,
641 src.fRight + pad, src.fBottom + pad); 646 src.fRight + pad, src.fBottom + pad);
642 } 647 }
643 648
644 sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { 649 sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
645 const SkScalar sigma = buffer.readScalar(); 650 const SkScalar sigma = buffer.readScalar();
646 const unsigned style = buffer.readUInt(); 651 const unsigned style = buffer.readUInt();
647 const unsigned flags = buffer.readUInt(); 652 const unsigned flags = buffer.readUInt();
653
654 SkRect occluder;
655 if (buffer.isVersionLT(SkReadBuffer::kBlurMaskFilterWritesOccluder)) {
656 occluder.setEmpty();
657 } else {
658 buffer.readRect(&occluder);
659 }
660
648 if (style <= kLastEnum_SkBlurStyle) { 661 if (style <= kLastEnum_SkBlurStyle) {
649 return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, flags); 662 return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, occluder, flags );
650 } 663 }
651 return nullptr; 664 return nullptr;
652 } 665 }
653 666
654 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { 667 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
655 buffer.writeScalar(fSigma); 668 buffer.writeScalar(fSigma);
656 buffer.writeUInt(fBlurStyle); 669 buffer.writeUInt(fBlurStyle);
657 buffer.writeUInt(fBlurFlags); 670 buffer.writeUInt(fBlurFlags);
671 buffer.writeRect(fOccluder);
658 } 672 }
659 673
660 674
661 #if SK_SUPPORT_GPU 675 #if SK_SUPPORT_GPU
662 676
663 class GrGLRectBlurEffect; 677 class GrGLRectBlurEffect;
664 678
665 class GrRectBlurEffect : public GrFragmentProcessor { 679 class GrRectBlurEffect : public GrFragmentProcessor {
666 public: 680 public:
667 ~GrRectBlurEffect() override { } 681 ~GrRectBlurEffect() override { }
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const { 1229 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const {
1216 return new GrGLRRectBlurEffect; 1230 return new GrGLRRectBlurEffect;
1217 } 1231 }
1218 1232
1219 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, 1233 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
1220 GrDrawContext* drawContext, 1234 GrDrawContext* drawContext,
1221 GrPaint* grp, 1235 GrPaint* grp,
1222 const GrClip& clip, 1236 const GrClip& clip,
1223 const SkMatrix& viewMatrix, 1237 const SkMatrix& viewMatrix,
1224 const SkStrokeRec& strokeRec , 1238 const SkStrokeRec& strokeRec ,
1225 const SkRRect& rrect) const { 1239 const SkRRect& srcRRect,
1240 const SkRRect& devRRect) con st {
1226 SkASSERT(drawContext); 1241 SkASSERT(drawContext);
1227 1242
1228 if (fBlurStyle != kNormal_SkBlurStyle) { 1243 if (fBlurStyle != kNormal_SkBlurStyle) {
1229 return false; 1244 return false;
1230 } 1245 }
1231 1246
1232 if (!strokeRec.isFillStyle()) { 1247 if (!strokeRec.isFillStyle()) {
1233 return false; 1248 return false;
1234 } 1249 }
1235 1250
1236 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); 1251 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
1237 1252
1238 sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma, rrect)); 1253 sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma, devRRect));
1239 if (!fp) { 1254 if (!fp) {
1240 return false; 1255 return false;
1241 } 1256 }
1242 1257
1243 GrPaint newPaint(*grp); 1258 GrPaint newPaint(*grp);
1244 newPaint.addCoverageFragmentProcessor(std::move(fp)); 1259 newPaint.addCoverageFragmentProcessor(std::move(fp));
1245 newPaint.setAntiAlias(false); 1260 newPaint.setAntiAlias(false);
1246 1261
1247 SkMatrix inverse; 1262 if (!this->ignoreXform()) {
1248 if (!viewMatrix.invert(&inverse)) { 1263 SkRect srcProxyRect = srcRRect.rect();
1249 return false; 1264 srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
1265
1266 SkPoint points[8];
1267 uint16_t indices[24];
1268 int numPoints, numIndices;
1269
1270 SkRect temp = fOccluder;
1271
1272 if (!temp.isEmpty() && (srcProxyRect.contains(temp) || temp.intersect(sr cProxyRect))) {
1273 srcProxyRect.toQuad(points);
1274 temp.toQuad(&points[4]);
1275 numPoints = 8;
1276
1277 static const uint16_t ringI[24] = { 0, 1, 5, 5, 4, 0,
1278 1, 2, 6, 6, 5, 1,
1279 2, 3, 7, 7, 6, 2,
1280 3, 0, 4, 4, 7, 3 };
1281 memcpy(indices, ringI, sizeof(ringI));
1282 numIndices = 24;
1283 } else {
1284 // full rect case
1285 srcProxyRect.toQuad(points);
1286 numPoints = 4;
1287
1288 static const uint16_t fullI[6] = { 0, 1, 2, 0, 2, 3 };
1289 memcpy(indices, fullI, sizeof(fullI));
1290 numIndices = 6;
1291 }
1292
1293 drawContext->drawVertices(clip, newPaint, viewMatrix, kTriangles_GrPrimi tiveType,
1294 numPoints, points, nullptr, nullptr, indices, numIndices);
1295
1296 } else {
1297 SkMatrix inverse;
1298 if (!viewMatrix.invert(&inverse)) {
1299 return false;
1300 }
1301
1302 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
1303 SkRect proxyRect = devRRect.rect();
1304 proxyRect.outset(extra, extra);
1305
1306
1307 drawContext->fillRectWithLocalMatrix(clip, newPaint, SkMatrix::I(), prox yRect, inverse);
1250 } 1308 }
1251 1309
1252 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
1253
1254 SkRect proxyRect = rrect.rect();
1255 proxyRect.outset(extra, extra);
1256
1257 drawContext->fillRectWithLocalMatrix(clip, newPaint, SkMatrix::I(), proxyRec t, inverse);
1258 return true; 1310 return true;
1259 } 1311 }
1260 1312
1261 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect, 1313 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
1262 const SkIRect& clipBounds, 1314 const SkIRect& clipBounds,
1263 const SkMatrix& ctm, 1315 const SkMatrix& ctm,
1264 SkRect* maskRect) const { 1316 SkRect* maskRect) const {
1265 SkScalar xformedSigma = this->computeXformedSigma(ctm); 1317 SkScalar xformedSigma = this->computeXformedSigma(ctm);
1266 if (xformedSigma <= 0) { 1318 if (xformedSigma <= 0) {
1267 return false; 1319 return false;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 str->append(" "); 1414 str->append(" ");
1363 1415
1364 static const char* gStyleName[kLastEnum_SkBlurStyle + 1] = { 1416 static const char* gStyleName[kLastEnum_SkBlurStyle + 1] = {
1365 "normal", "solid", "outer", "inner" 1417 "normal", "solid", "outer", "inner"
1366 }; 1418 };
1367 1419
1368 str->appendf("style: %s ", gStyleName[fBlurStyle]); 1420 str->appendf("style: %s ", gStyleName[fBlurStyle]);
1369 str->append("flags: ("); 1421 str->append("flags: (");
1370 if (fBlurFlags) { 1422 if (fBlurFlags) {
1371 bool needSeparator = false; 1423 bool needSeparator = false;
1372 SkAddFlagToString(str, 1424 SkAddFlagToString(str, this->ignoreXform(), "IgnoreXform", &needSeparato r);
1373 SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransfo rm_BlurFlag),
1374 "IgnoreXform", &needSeparator);
1375 SkAddFlagToString(str, 1425 SkAddFlagToString(str,
1376 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B lurFlag), 1426 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B lurFlag),
1377 "HighQuality", &needSeparator); 1427 "HighQuality", &needSeparator);
1378 } else { 1428 } else {
1379 str->append("None"); 1429 str->append("None");
1380 } 1430 }
1381 str->append("))"); 1431 str->append("))");
1382 } 1432 }
1383 #endif 1433 #endif
1384 1434
1385 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1435 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
1386 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1436 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
1387 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1437 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/core/SkReadBuffer.h ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698