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

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

Issue 286273002: Optimize CSS box-shadow performance by caching the SkMask of the blur effect. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: add mutex for thread-safe and use SkDiscardableMemory Created 6 years, 7 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 | Annotate | Revision Log
« src/core/SkMaskFilter.cpp ('K') | « src/effects/SkBlurMask.cpp ('k') | no next file » | 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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include <list>
10
9 #include "SkBlurMaskFilter.h" 11 #include "SkBlurMaskFilter.h"
10 #include "SkBlurMask.h" 12 #include "SkBlurMask.h"
11 #include "SkGpuBlurUtils.h" 13 #include "SkGpuBlurUtils.h"
12 #include "SkReadBuffer.h" 14 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h" 15 #include "SkWriteBuffer.h"
14 #include "SkMaskFilter.h" 16 #include "SkMaskFilter.h"
15 #include "SkRRect.h" 17 #include "SkRRect.h"
16 #include "SkRTConf.h" 18 #include "SkRTConf.h"
17 #include "SkStringUtils.h" 19 #include "SkStringUtils.h"
18 #include "SkStrokeRec.h" 20 #include "SkStrokeRec.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 virtual bool filterMaskGPU(GrTexture* src, 60 virtual bool filterMaskGPU(GrTexture* src,
59 const SkMatrix& ctm, 61 const SkMatrix& ctm,
60 const SkRect& maskRect, 62 const SkRect& maskRect,
61 GrTexture** result, 63 GrTexture** result,
62 bool canOverwriteSrc) const SK_OVERRIDE; 64 bool canOverwriteSrc) const SK_OVERRIDE;
63 #endif 65 #endif
64 66
65 virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; 67 virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
66 virtual bool asABlur(BlurRec*) const SK_OVERRIDE; 68 virtual bool asABlur(BlurRec*) const SK_OVERRIDE;
67 69
70 class BlurMaskRecord {
71 public:
72 BlurMaskRecord(): fSigma(0),
73 fRectCount(0),
74 fRects(NULL),
75 fMask(NULL) {}
76
77 BlurMaskRecord(SkScalar sigma, unsigned rectCount, SkRect** rects, SkMas k* mask)
78 : fSigma(sigma),
79 fRectCount(rectCount),
80 fRects(rects),
81 fMask(mask) {}
82
83 ~BlurMaskRecord() {
84 if (fMask) {
85 if (fMask->fUseDiscardableMemory && fMask->fDiscardableMemory) {
86 fMask->fDiscardableMemory->unlock();
87 SkDELETE(fMask->fDiscardableMemory);
88 fMask->fDiscardableMemory = NULL;
89 } else if (fMask->fImage) {
90 SkMask::FreeImage(fMask->fImage);
91 }
92 delete fMask;
93 }
94 if (fRects) {
95 for(int i = 0; i < fRectCount; i++) {
96 if (fRects[i])
97 delete fRects[i];
98 }
99 delete []fRects;
100 }
101 }
102
103 SkScalar fSigma;
104 unsigned fRectCount;
105 SkRect** fRects;
106 SkMask* fMask;
107 };
108
109 static bool getBlurMaskRecord(SkScalar sigma,
110 unsigned rectCount,
111 const SkRect rects[],
112 SkMask** mask);
113 static bool addBlurMaskRecord(BlurMaskRecord* blurMaskRecord);
114 static void clearBlurMaskRecordList();
115 static unsigned getBlurMaskRecordsMemoryUsage();
116 static void setBlurMaskRecordsLimit(unsigned, unsigned);
117
68 SK_TO_STRING_OVERRIDE() 118 SK_TO_STRING_OVERRIDE()
69 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) 119 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl)
70 120
71 protected: 121 protected:
72 virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMa trix&, 122 virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMa trix&,
73 const SkIRect& clipBounds, 123 const SkIRect& clipBounds,
74 NinePatch*) const SK_OVERRIDE; 124 NinePatch*) const SK_OVERRIDE;
75 125
76 virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&, 126 virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&,
77 const SkIRect& clipBounds, 127 const SkIRect& clipBounds,
(...skipping 22 matching lines...) Expand all
100 SkBlurMaskFilterImpl(SkReadBuffer&); 150 SkBlurMaskFilterImpl(SkReadBuffer&);
101 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 151 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
102 152
103 SkScalar computeXformedSigma(const SkMatrix& ctm) const { 153 SkScalar computeXformedSigma(const SkMatrix& ctm) const {
104 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr ansform_BlurFlag); 154 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr ansform_BlurFlag);
105 155
106 SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma) ; 156 SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma) ;
107 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); 157 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA);
108 } 158 }
109 159
160 typedef std::list<BlurMaskRecord*> BlurMaskRecordList;
reveman 2014/05/23 02:31:29 Probably need a hash to make sure this scales well
161 static BlurMaskRecordList fCachedBlurMaskRecordList;
162 static unsigned fCachedBlurMaskImageMemorySize;
163 static unsigned fMaxBlurMaskListSize;
164 static unsigned fMaxImageMemorySize;
165
110 typedef SkMaskFilter INHERITED; 166 typedef SkMaskFilter INHERITED;
111 }; 167 };
112 168
113 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); 169 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128);
114 170
171 SkBlurMaskFilterImpl::BlurMaskRecordList SkBlurMaskFilterImpl::fCachedBlurMaskRe cordList;
172 unsigned SkBlurMaskFilterImpl::fCachedBlurMaskImageMemorySize = 0;
173 unsigned SkBlurMaskFilterImpl::fMaxBlurMaskListSize = 50;
reveman 2014/05/23 02:31:29 This limit could be much higher when using SkDisca
174 unsigned SkBlurMaskFilterImpl::fMaxImageMemorySize = 2 * 1024 * 1024;
reveman 2014/05/23 02:31:29 We don't want this limit when using SkDiscardableM
175 SK_DECLARE_STATIC_MUTEX(gMutex);
176
177 bool SkBlurMaskFilterImpl::getBlurMaskRecord(SkScalar sigma,
178 unsigned rectCount,
179 const SkRect rects[],
180 SkMask** mask) {
181 SkAutoMutexAcquire am(gMutex);
182 if (!fCachedBlurMaskRecordList.empty()) {
183 for (BlurMaskRecordList::reverse_iterator it = fCachedBlurMaskRecordList .rbegin();
184 it != fCachedBlurMaskRecordList.rend(); ++it) {
185 BlurMaskRecord* cachedBlurMaskRecord = *it;
186 if (cachedBlurMaskRecord->fSigma == sigma
187 && cachedBlurMaskRecord->fRectCount == rectCount) {
188 bool found = true;
189 SkRect* tempRects[2] = {NULL, NULL};
190 for (int i = 0; i < rectCount; i++) {
191 tempRects[i] = *(cachedBlurMaskRecord->fRects + i);
192 if (tempRects[i]->width() != rects[i].width() ||
193 tempRects[i]->height() != rects[i].height()) {
194 found = false;
195 break;
196 }
197 }
198 if (found && rectCount == 2) {
199 if ((tempRects[0]->x() - rects[0].x()) != (tempRects[1]->x() - rects[1].x()) ||
200 (tempRects[0]->y() - rects[0].y()) != (tempRects[1]->y() - rects[1].y()))
201 found = false;
202 }
203 if (found) {
204 *mask = cachedBlurMaskRecord->fMask;
205 return true;
206 }
207 }
208 }
209 }
210 return false;
211 }
212
213 bool SkBlurMaskFilterImpl::addBlurMaskRecord(BlurMaskRecord* blurMaskRecord) {
214 SkAutoMutexAcquire am(gMutex);
215 while (fCachedBlurMaskRecordList.size() >= fMaxBlurMaskListSize
216 || fCachedBlurMaskImageMemorySize >= fMaxImageMemorySize) {
217 BlurMaskRecord* cachedBlurMaskRecord = fCachedBlurMaskRecordList.front() ;
218 fCachedBlurMaskRecordList.pop_front();
219 if (cachedBlurMaskRecord) {
220 fCachedBlurMaskImageMemorySize -= cachedBlurMaskRecord->fMask->compu teImageSize();
221 delete cachedBlurMaskRecord;
222 cachedBlurMaskRecord = NULL;
223 }
224 }
225 fCachedBlurMaskRecordList.push_back(blurMaskRecord);
226 fCachedBlurMaskImageMemorySize += blurMaskRecord->fMask->computeImageSize();
227 return true;
228 }
229
230 void SkBlurMaskFilterImpl::clearBlurMaskRecordList() {
231 SkAutoMutexAcquire am(gMutex);
232 while (!fCachedBlurMaskRecordList.empty()) {
233 BlurMaskRecord* cachedBlurMaskRecord = fCachedBlurMaskRecordList.front() ;
234 fCachedBlurMaskRecordList.pop_front();
235 if (cachedBlurMaskRecord) {
236 delete cachedBlurMaskRecord;
237 cachedBlurMaskRecord = NULL;
238 }
239 }
240 fCachedBlurMaskImageMemorySize = 0;
241 }
242
243 unsigned SkBlurMaskFilterImpl::getBlurMaskRecordsMemoryUsage() {
244 SkAutoMutexAcquire am(gMutex);
245 return fCachedBlurMaskImageMemorySize;
246 }
247
248 void SkBlurMaskFilterImpl::setBlurMaskRecordsLimit(unsigned listSize, unsigned m emSize) {
249 SkAutoMutexAcquire am(gMutex);
250 fMaxBlurMaskListSize = listSize;
251 fMaxImageMemorySize = memSize;
252 }
253
115 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32 _t flags) { 254 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32 _t flags) {
116 if (!SkScalarIsFinite(sigma) || sigma <= 0) { 255 if (!SkScalarIsFinite(sigma) || sigma <= 0) {
117 return NULL; 256 return NULL;
118 } 257 }
119 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { 258 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) {
120 return NULL; 259 return NULL;
121 } 260 }
122 if (flags > SkBlurMaskFilter::kAll_BlurFlag) { 261 if (flags > SkBlurMaskFilter::kAll_BlurFlag) {
123 return NULL; 262 return NULL;
124 } 263 }
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); 512 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight);
374 513
375 SkRRect smallRR; 514 SkRRect smallRR;
376 SkVector radii[4]; 515 SkVector radii[4];
377 radii[SkRRect::kUpperLeft_Corner] = UL; 516 radii[SkRRect::kUpperLeft_Corner] = UL;
378 radii[SkRRect::kUpperRight_Corner] = UR; 517 radii[SkRRect::kUpperRight_Corner] = UR;
379 radii[SkRRect::kLowerRight_Corner] = LR; 518 radii[SkRRect::kLowerRight_Corner] = LR;
380 radii[SkRRect::kLowerLeft_Corner] = LL; 519 radii[SkRRect::kLowerLeft_Corner] = LL;
381 smallRR.setRectRadii(smallR, radii); 520 smallRR.setRectRadii(smallR, radii);
382 521
522 SkScalar sigma = this->computeXformedSigma(matrix);
523 SkMask* cachedBlurMask = NULL;
524 SkRect rects[1];
525 rects[0] = rrect.rect();
526 if (getBlurMaskRecord(sigma, 1, rects, &cachedBlurMask)) {
527 patch->fMask = *cachedBlurMask;
528 patch->fOuterRect = dstM.fBounds;
529 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1;
530 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1;
531 return kTrue_FilterReturn;
532 }
533
383 bool analyticBlurWorked = false; 534 bool analyticBlurWorked = false;
384 if (c_analyticBlurRRect) { 535 if (c_analyticBlurRRect) {
385 analyticBlurWorked = 536 analyticBlurWorked =
386 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, 537 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin,
387 SkMask::kComputeBoundsAndRenderImage_CreateMod e); 538 SkMask::kComputeBoundsAndRenderImage_CreateMod e);
388 } 539 }
389 540
390 if (!analyticBlurWorked) { 541 if (!analyticBlurWorked) {
391 if (!draw_rrect_into_mask(smallRR, &srcM)) { 542 if (!draw_rrect_into_mask(smallRR, &srcM)) {
392 return kFalse_FilterReturn; 543 return kFalse_FilterReturn;
393 } 544 }
394 545
395 SkAutoMaskFreeImage amf(srcM.fImage); 546 SkAutoMaskFreeImage amf(srcM.fImage);
396 547
548 patch->fMask.fUseDiscardableMemory = true;
397 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 549 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
398 return kFalse_FilterReturn; 550 return kFalse_FilterReturn;
399 } 551 }
400 } 552 }
401 553
402 patch->fMask.fBounds.offsetTo(0, 0); 554 patch->fMask.fBounds.offsetTo(0, 0);
403 patch->fOuterRect = dstM.fBounds; 555 patch->fOuterRect = dstM.fBounds;
404 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; 556 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1;
405 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; 557 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1;
558 if (!cachedBlurMask) {
559 SkMask* tempMask = new SkMask;
560 *tempMask = patch->fMask;
561 SkRect** tempRects = new SkRect* [1];
562 tempRects[0] = new SkRect;
563 *(tempRects[0]) = rrect.rect();
564 BlurMaskRecord * blurMaskRecord = new BlurMaskRecord(sigma, 1, tempRects , tempMask);
565 if (blurMaskRecord)
566 addBlurMaskRecord(blurMaskRecord);
567 }
568
406 return kTrue_FilterReturn; 569 return kTrue_FilterReturn;
407 } 570 }
408 571
409 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); 572 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" );
410 573
411 SkMaskFilter::FilterReturn 574 SkMaskFilter::FilterReturn
412 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, 575 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count,
413 const SkMatrix& matrix, 576 const SkMatrix& matrix,
414 const SkIRect& clipBounds, 577 const SkIRect& clipBounds,
415 NinePatch* patch) const { 578 NinePatch* patch) const {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 if (1 == count) { 638 if (1 == count) {
476 innerIR = srcM.fBounds; 639 innerIR = srcM.fBounds;
477 center.set(smallW, smallH); 640 center.set(smallW, smallH);
478 } else { 641 } else {
479 SkASSERT(2 == count); 642 SkASSERT(2 == count);
480 rects[1].roundIn(&innerIR); 643 rects[1].roundIn(&innerIR);
481 center.set(smallW + (innerIR.left() - srcM.fBounds.left()), 644 center.set(smallW + (innerIR.left() - srcM.fBounds.left()),
482 smallH + (innerIR.top() - srcM.fBounds.top())); 645 smallH + (innerIR.top() - srcM.fBounds.top()));
483 } 646 }
484 647
648 SkScalar sigma = this->computeXformedSigma(matrix);
649 SkMask* cachedBlurMask = NULL;
650 if (getBlurMaskRecord(sigma, count, rects, &cachedBlurMask)) {
651 patch->fMask = *cachedBlurMask;
652 patch->fOuterRect = dstM.fBounds;
653 patch->fCenter = center;
654 return kTrue_FilterReturn;
655 }
656
485 // +1 so we get a clean, stretchable, center row/col 657 // +1 so we get a clean, stretchable, center row/col
486 smallW += 1; 658 smallW += 1;
487 smallH += 1; 659 smallH += 1;
488 660
489 // we want the inset amounts to be integral, so we don't change any 661 // we want the inset amounts to be integral, so we don't change any
490 // fractional phase on the fRight or fBottom of our smallR. 662 // fractional phase on the fRight or fBottom of our smallR.
491 const SkScalar dx = SkIntToScalar(innerIR.width() - smallW); 663 const SkScalar dx = SkIntToScalar(innerIR.width() - smallW);
492 const SkScalar dy = SkIntToScalar(innerIR.height() - smallH); 664 const SkScalar dy = SkIntToScalar(innerIR.height() - smallH);
493 if (dx < 0 || dy < 0) { 665 if (dx < 0 || dy < 0) {
494 // we're too small, relative to our blur, to break into nine-patch, 666 // we're too small, relative to our blur, to break into nine-patch,
495 // so we ask to have our normal filterMask() be called. 667 // so we ask to have our normal filterMask() be called.
496 return kUnimplemented_FilterReturn; 668 return kUnimplemented_FilterReturn;
497 } 669 }
498 670
499 smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[ 0].bottom() - dy); 671 smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[ 0].bottom() - dy);
500 if (smallR[0].width() < 2 || smallR[0].height() < 2) { 672 if (smallR[0].width() < 2 || smallR[0].height() < 2) {
501 return kUnimplemented_FilterReturn; 673 return kUnimplemented_FilterReturn;
502 } 674 }
503 if (2 == count) { 675 if (2 == count) {
504 smallR[1].set(rects[1].left(), rects[1].top(), 676 smallR[1].set(rects[1].left(), rects[1].top(),
505 rects[1].right() - dx, rects[1].bottom() - dy); 677 rects[1].right() - dx, rects[1].bottom() - dy);
506 SkASSERT(!smallR[1].isEmpty()); 678 SkASSERT(!smallR[1].isEmpty());
507 } 679 }
508 680
509 if (count > 1 || !c_analyticBlurNinepatch) { 681 if (count > 1 || !c_analyticBlurNinepatch) {
510 if (!draw_rects_into_mask(smallR, count, &srcM)) { 682 if (!draw_rects_into_mask(smallR, count, &srcM)) {
511 return kFalse_FilterReturn; 683 return kFalse_FilterReturn;
512 } 684 }
513
514 SkAutoMaskFreeImage amf(srcM.fImage); 685 SkAutoMaskFreeImage amf(srcM.fImage);
515 686
687 patch->fMask.fUseDiscardableMemory = true;
516 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 688 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
517 return kFalse_FilterReturn; 689 return kFalse_FilterReturn;
518 } 690 }
519 } else { 691 } else {
520 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, 692 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin,
521 SkMask::kComputeBoundsAndRenderImage_CreateMod e)) { 693 SkMask::kComputeBoundsAndRenderImage_CreateMod e)) {
522 return kFalse_FilterReturn; 694 return kFalse_FilterReturn;
523 } 695 }
524 } 696 }
525 patch->fMask.fBounds.offsetTo(0, 0); 697 patch->fMask.fBounds.offsetTo(0, 0);
526 patch->fOuterRect = dstM.fBounds; 698 patch->fOuterRect = dstM.fBounds;
527 patch->fCenter = center; 699 patch->fCenter = center;
700
701 if (!cachedBlurMask) {
702 SkMask* tempMask = new SkMask;
703 *tempMask = patch->fMask;
704 SkRect** tempRects = new SkRect* [count];
705 for (int i = 0; i < count; i++) {
706 tempRects[i] = new SkRect;
707 *(tempRects[i]) = rects[i];
708 }
709 BlurMaskRecord * blurMaskRecord = new BlurMaskRecord(sigma, count, tempR ects, tempMask);
710 if (blurMaskRecord)
711 addBlurMaskRecord(blurMaskRecord);
712 }
713
528 return kTrue_FilterReturn; 714 return kTrue_FilterReturn;
529 } 715 }
530 716
531 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, 717 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src,
532 SkRect* dst) const { 718 SkRect* dst) const {
533 SkScalar pad = 3.0f * fSigma; 719 SkScalar pad = 3.0f * fSigma;
534 720
535 dst->set(src.fLeft - pad, src.fTop - pad, 721 dst->set(src.fLeft - pad, src.fTop - pad,
536 src.fRight + pad, src.fBottom + pad); 722 src.fRight + pad, src.fBottom + pad);
537 } 723 }
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 } else { 1410 } else {
1225 str->append("None"); 1411 str->append("None");
1226 } 1412 }
1227 str->append("))"); 1413 str->append("))");
1228 } 1414 }
1229 #endif 1415 #endif
1230 1416
1231 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1417 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
1232 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1418 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
1233 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1419 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« src/core/SkMaskFilter.cpp ('K') | « src/effects/SkBlurMask.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698