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

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/SkMaskFilter.cpp ('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(GrTextureProvider* texProvider, 59 bool directFilterRRectMaskGPU(GrTextureProvider* texProvider,
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 16 matching lines...) Expand all
92 bool ignoreXform() const { 93 bool ignoreXform() const {
93 return SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag ); 94 return SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag );
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
103 // This flag should never escape from serialization
104 static const int kInternalFlag_HasOccluder = 0x08;
105
102 SkScalar fSigma; 106 SkScalar fSigma;
103 SkBlurStyle fBlurStyle; 107 SkBlurStyle fBlurStyle;
108 SkRect fOccluder;
104 uint32_t fBlurFlags; 109 uint32_t fBlurFlags;
105 110
106 SkBlurQuality getQuality() const { 111 SkBlurQuality getQuality() const {
107 return (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 112 return (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ?
108 kHigh_SkBlurQuality : kLow_SkBlurQuality; 113 kHigh_SkBlurQuality : kLow_SkBlurQuality;
109 } 114 }
110 115
111 SkBlurMaskFilterImpl(SkReadBuffer&); 116 SkBlurMaskFilterImpl(SkReadBuffer&);
112 void flatten(SkWriteBuffer&) const override; 117 void flatten(SkWriteBuffer&) const override;
113 118
114 SkScalar computeXformedSigma(const SkMatrix& ctm) const { 119 SkScalar computeXformedSigma(const SkMatrix& ctm) const {
115 SkScalar xformedSigma = this->ignoreXform() ? fSigma : ctm.mapRadius(fSi gma); 120 SkScalar xformedSigma = this->ignoreXform() ? fSigma : ctm.mapRadius(fSi gma);
116 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); 121 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA);
117 } 122 }
118 123
119 friend class SkBlurMaskFilter; 124 friend class SkBlurMaskFilter;
120 125
121 typedef SkMaskFilter INHERITED; 126 typedef SkMaskFilter INHERITED;
122 }; 127 };
123 128
124 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); 129 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128);
125 130
126 sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma, ui nt32_t flags) { 131 sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma,
132 const SkRect& occluder, uint32_t flag s) {
127 if (!SkScalarIsFinite(sigma) || sigma <= 0) { 133 if (!SkScalarIsFinite(sigma) || sigma <= 0) {
128 return nullptr; 134 return nullptr;
129 } 135 }
130 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { 136 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) {
131 return nullptr; 137 return nullptr;
132 } 138 }
133 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 139 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
134 flags &= SkBlurMaskFilter::kAll_BlurFlag; 140 flags &= SkBlurMaskFilter::kAll_BlurFlag;
135 141
136 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, flags)); 142 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, occluder, flags));
137 } 143 }
138 144
139 /////////////////////////////////////////////////////////////////////////////// 145 ///////////////////////////////////////////////////////////////////////////////
140 146
141 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui nt32_t flags) 147 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style,
148 const SkRect& occluder, uint32_t flag s)
142 : fSigma(sigma) 149 : fSigma(sigma)
143 , fBlurStyle(style) 150 , fBlurStyle(style)
151 , fOccluder(occluder)
144 , fBlurFlags(flags) { 152 , fBlurFlags(flags) {
145 SkASSERT(fSigma > 0); 153 SkASSERT(fSigma > 0);
146 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle); 154 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle);
155 fOccluder.sort();
reed1 2016/08/09 14:04:54 Lets do this (or reject it) in the factory, rather
robertphillips 2016/08/09 14:46:35 Done. If the user passes in an inverted rect it wi
147 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 156 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
148 } 157 }
149 158
150 SkMask::Format SkBlurMaskFilterImpl::getFormat() const { 159 SkMask::Format SkBlurMaskFilterImpl::getFormat() const {
151 return SkMask::kA8_Format; 160 return SkMask::kA8_Format;
152 } 161 }
153 162
154 bool SkBlurMaskFilterImpl::asABlur(BlurRec* rec) const { 163 bool SkBlurMaskFilterImpl::asABlur(BlurRec* rec) const {
155 if (this->ignoreXform()) { 164 if (this->ignoreXform()) {
156 return false; 165 return false;
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 SkScalar pad = 3.0f * fSigma; 589 SkScalar pad = 3.0f * fSigma;
581 590
582 dst->set(src.fLeft - pad, src.fTop - pad, 591 dst->set(src.fLeft - pad, src.fTop - pad,
583 src.fRight + pad, src.fBottom + pad); 592 src.fRight + pad, src.fBottom + pad);
584 } 593 }
585 594
586 sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { 595 sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
587 const SkScalar sigma = buffer.readScalar(); 596 const SkScalar sigma = buffer.readScalar();
588 const unsigned style = buffer.readUInt(); 597 const unsigned style = buffer.readUInt();
589 const unsigned flags = buffer.readUInt(); 598 const unsigned flags = buffer.readUInt();
599
600 SkRect occluder;
601 if (flags & kInternalFlag_HasOccluder) {
602 buffer.readRect(&occluder);
603 } else {
604 occluder.setEmpty();
605 }
606
590 if (style <= kLastEnum_SkBlurStyle) { 607 if (style <= kLastEnum_SkBlurStyle) {
591 return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, flags); 608 return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, occluder,
609 flags & ~kInternalFlag_HasOccluder);
592 } 610 }
593 return nullptr; 611 return nullptr;
594 } 612 }
595 613
596 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { 614 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
597 buffer.writeScalar(fSigma); 615 buffer.writeScalar(fSigma);
598 buffer.writeUInt(fBlurStyle); 616 buffer.writeUInt(fBlurStyle);
599 buffer.writeUInt(fBlurFlags); 617
618 SkASSERT(!(fBlurFlags & kInternalFlag_HasOccluder));
619 buffer.writeUInt(fBlurFlags | kInternalFlag_HasOccluder);
620
621 buffer.writeRect(fOccluder);
600 } 622 }
601 623
602 #if SK_SUPPORT_GPU 624 #if SK_SUPPORT_GPU
603 625
604 class GrGLRectBlurEffect; 626 class GrGLRectBlurEffect;
605 627
606 class GrRectBlurEffect : public GrFragmentProcessor { 628 class GrRectBlurEffect : public GrFragmentProcessor {
607 public: 629 public:
608 ~GrRectBlurEffect() override { } 630 ~GrRectBlurEffect() override { }
609 631
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 1168
1147 void GrRRectBlurEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, 1169 void GrRRectBlurEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
1148 GrProcessorKeyBuilder* b) const { 1170 GrProcessorKeyBuilder* b) const {
1149 GrGLRRectBlurEffect::GenKey(*this, caps, b); 1171 GrGLRRectBlurEffect::GenKey(*this, caps, b);
1150 } 1172 }
1151 1173
1152 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const { 1174 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const {
1153 return new GrGLRRectBlurEffect; 1175 return new GrGLRRectBlurEffect;
1154 } 1176 }
1155 1177
1178 static void to_points(const SkRect& r, SkPoint* points) {
bsalomon 2016/08/09 14:05:56 SkRect::toQuad?
robertphillips 2016/08/09 14:46:35 Done.
1179 points[0] = SkPoint::Make(r.fLeft, r.fTop);
1180 points[1] = SkPoint::Make(r.fRight, r.fTop);
1181 points[2] = SkPoint::Make(r.fRight, r.fBottom);
1182 points[3] = SkPoint::Make(r.fLeft, r.fBottom);
1183 }
1184
1156 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvid er, 1185 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvid er,
1157 GrDrawContext* drawContext, 1186 GrDrawContext* drawContext,
1158 GrPaint* grp, 1187 GrPaint* grp,
1159 const GrClip& clip, 1188 const GrClip& clip,
1160 const SkMatrix& viewMatrix, 1189 const SkMatrix& viewMatrix,
1161 const SkStrokeRec& strokeRec , 1190 const SkStrokeRec& strokeRec ,
1162 const SkRRect& rrect) const { 1191 const SkRRect& srcRRect,
1192 const SkRRect& devRRect) con st {
1163 SkASSERT(drawContext); 1193 SkASSERT(drawContext);
1164 1194
1165 if (fBlurStyle != kNormal_SkBlurStyle) { 1195 if (fBlurStyle != kNormal_SkBlurStyle) {
1166 return false; 1196 return false;
1167 } 1197 }
1168 1198
1169 if (!strokeRec.isFillStyle()) { 1199 if (!strokeRec.isFillStyle()) {
1170 return false; 1200 return false;
1171 } 1201 }
1172 1202
1173 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); 1203 SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
1174 1204
1175 sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSi gma, rrect)); 1205 sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSi gma, devRRect));
1176 if (!fp) { 1206 if (!fp) {
1177 return false; 1207 return false;
1178 } 1208 }
1179 1209
1180 grp->addCoverageFragmentProcessor(std::move(fp)); 1210 grp->addCoverageFragmentProcessor(std::move(fp));
1181 1211
1182 SkMatrix inverse; 1212 SkMatrix inverse;
1183 if (!viewMatrix.invert(&inverse)) { 1213 if (!viewMatrix.invert(&inverse)) {
1184 return false; 1214 return false;
1185 } 1215 }
1186 1216
1187 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); 1217 if (!this->ignoreXform()) {
1218 SkRect srcProxyRect = srcRRect.rect();
1219 srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
1188 1220
1189 SkRect proxyRect = rrect.rect(); 1221 SkPoint points[8];
1190 proxyRect.outset(extra, extra); 1222 uint16_t indices[24];
1223 int numPoints, numIndices;
1191 1224
1192 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), proxyRect, i nverse); 1225 SkRect temp = fOccluder;
1226
1227 if (!temp.isEmpty() && (srcProxyRect.contains(temp) || temp.intersect(sr cProxyRect))) {
1228 to_points(srcProxyRect, &points[0]);
1229 to_points(temp, &points[4]);
1230 numPoints = 8;
1231
1232 static const uint16_t ringI[24] = { 0, 1, 5, 5, 4, 0,
1233 1, 2, 6, 6, 5, 1,
1234 2, 3, 7, 7, 6, 2,
1235 3, 0, 4, 4, 7, 3 };
1236 memcpy(indices, ringI, sizeof(ringI));
1237 numIndices = 24;
1238 } else {
1239 // full rect case
1240 to_points(srcProxyRect, &points[0]);
1241 numPoints = 4;
1242
1243 static const uint16_t fullI[6] = { 0, 1, 2, 0, 2, 3 };
1244 memcpy(indices, fullI, sizeof(fullI));
1245 numIndices = 6;
1246 }
1247
1248 drawContext->drawVertices(clip, *grp, viewMatrix, kTriangles_GrPrimitive Type,
1249 numPoints, points, nullptr, nullptr, indices , numIndices);
1250
1251 } else {
1252 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
1253 SkRect proxyRect = devRRect.rect();
1254 proxyRect.outset(extra, extra);
1255
1256
1257 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), proxyRec t, inverse);
1258 }
1259
1193 return true; 1260 return true;
1194 } 1261 }
1195 1262
1196 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect, 1263 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
1197 const SkIRect& clipBounds, 1264 const SkIRect& clipBounds,
1198 const SkMatrix& ctm, 1265 const SkMatrix& ctm,
1199 SkRect* maskRect) const { 1266 SkRect* maskRect) const {
1200 SkScalar xformedSigma = this->computeXformedSigma(ctm); 1267 SkScalar xformedSigma = this->computeXformedSigma(ctm);
1201 if (xformedSigma <= 0) { 1268 if (xformedSigma <= 0) {
1202 return false; 1269 return false;
1203 } 1270 }
1204 1271
1205 // We always do circles on the GPU 1272 // We always do circles on the GPU
1206 if (!devRRect.isCircle()) { 1273 if (!devRRect.isCircle()) {
1207 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); 1274 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64);
1208 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); 1275 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32);
1209 1276
1210 if (devRRect.width() <= kMIN_GPU_BLUR_SIZE && 1277 if (!devRRect.allCornersCircular() &&
1278 devRRect.width() <= kMIN_GPU_BLUR_SIZE &&
1211 devRRect.height() <= kMIN_GPU_BLUR_SIZE && 1279 devRRect.height() <= kMIN_GPU_BLUR_SIZE &&
1212 xformedSigma <= kMIN_GPU_BLUR_SIGMA) { 1280 xformedSigma <= kMIN_GPU_BLUR_SIGMA) {
1213 // We prefer to blur small rects with small radii on the CPU. 1281 // We prefer to blur small rects with small radii on the CPU.
1214 return false; 1282 return false;
1215 } 1283 }
1216 } 1284 }
1217 1285
1218 if (nullptr == maskRect) { 1286 if (nullptr == maskRect) {
1219 // don't need to compute maskRect 1287 // don't need to compute maskRect
1220 return true; 1288 return true;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 str->append(" "); 1365 str->append(" ");
1298 1366
1299 static const char* gStyleName[kLastEnum_SkBlurStyle + 1] = { 1367 static const char* gStyleName[kLastEnum_SkBlurStyle + 1] = {
1300 "normal", "solid", "outer", "inner" 1368 "normal", "solid", "outer", "inner"
1301 }; 1369 };
1302 1370
1303 str->appendf("style: %s ", gStyleName[fBlurStyle]); 1371 str->appendf("style: %s ", gStyleName[fBlurStyle]);
1304 str->append("flags: ("); 1372 str->append("flags: (");
1305 if (fBlurFlags) { 1373 if (fBlurFlags) {
1306 bool needSeparator = false; 1374 bool needSeparator = false;
1307 SkAddFlagToString(str, 1375 SkAddFlagToString(str, this->ignoreXform(), "IgnoreXform", &needSeparato r);
1308 SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransfo rm_BlurFlag),
1309 "IgnoreXform", &needSeparator);
1310 SkAddFlagToString(str, 1376 SkAddFlagToString(str,
1311 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B lurFlag), 1377 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B lurFlag),
1312 "HighQuality", &needSeparator); 1378 "HighQuality", &needSeparator);
1313 } else { 1379 } else {
1314 str->append("None"); 1380 str->append("None");
1315 } 1381 }
1316 str->append("))"); 1382 str->append("))");
1317 } 1383 }
1318 #endif 1384 #endif
1319 1385
1320 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1386 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
1321 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1387 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
1322 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1388 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/core/SkMaskFilter.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698