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

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

Issue 17035007: Fix quickReject computation for blurs (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: updated Created 7 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 | Annotate | Revision Log
« no previous file with comments | « 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 "SkBlurMaskFilter.h" 9 #include "SkBlurMaskFilter.h"
10 #include "SkBlurMask.h" 10 #include "SkBlurMask.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 const SkIRect& clipBounds, 53 const SkIRect& clipBounds,
54 NinePatch*) const SK_OVERRIDE; 54 NinePatch*) const SK_OVERRIDE;
55 55
56 bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, 56 bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix,
57 SkIPoint* margin, SkMask::CreateMode createMode) const; 57 SkIPoint* margin, SkMask::CreateMode createMode) const;
58 58
59 private: 59 private:
60 // To avoid unseemly allocation requests (esp. for finite platforms like 60 // To avoid unseemly allocation requests (esp. for finite platforms like
61 // handset) we limit the radius so something manageable. (as opposed to 61 // handset) we limit the radius so something manageable. (as opposed to
62 // a request like 10,000) 62 // a request like 10,000)
63 static const SkScalar kMAX_RADIUS; 63 static const SkScalar kMAX_BLUR_RADIUS;
64 // This constant approximates the scaling done in the software path's 64 // This constant approximates the scaling done in the software path's
65 // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). 65 // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)).
66 // IMHO, it actually should be 1: we blur "less" than we should do 66 // IMHO, it actually should be 1: we blur "less" than we should do
67 // according to the CSS and canvas specs, simply because Safari does the sam e. 67 // according to the CSS and canvas specs, simply because Safari does the sam e.
68 // Firefox used to do the same too, until 4.0 where they fixed it. So at so me 68 // Firefox used to do the same too, until 4.0 where they fixed it. So at so me
69 // point we should probably get rid of these scaling constants and rebaselin e 69 // point we should probably get rid of these scaling constants and rebaselin e
70 // all the blur tests. 70 // all the blur tests.
71 static const SkScalar kBLUR_SIGMA_SCALE; 71 static const SkScalar kBLUR_SIGMA_SCALE;
72 72
73 SkScalar fRadius; 73 SkScalar fRadius;
74 SkBlurMaskFilter::BlurStyle fBlurStyle; 74 SkBlurMaskFilter::BlurStyle fBlurStyle;
75 uint32_t fBlurFlags; 75 uint32_t fBlurFlags;
76 76
77 SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); 77 SkBlurMaskFilterImpl(SkFlattenableReadBuffer&);
78 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; 78 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
79 #if SK_SUPPORT_GPU 79 #if SK_SUPPORT_GPU
80 SkScalar computeXformedRadius(const SkMatrix& ctm) const { 80 SkScalar computeXformedRadius(const SkMatrix& ctm) const {
81 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr ansform_BlurFlag); 81 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr ansform_BlurFlag);
82 82
83 SkScalar xformedRadius = ignoreTransform ? fRadius 83 SkScalar xformedRadius = ignoreTransform ? fRadius
84 : ctm.mapRadius(fRadius); 84 : ctm.mapRadius(fRadius);
85 return SkMinScalar(xformedRadius, kMAX_RADIUS); 85 return SkMinScalar(xformedRadius, kMAX_BLUR_RADIUS);
86 } 86 }
87 #endif 87 #endif
88 88
89 typedef SkMaskFilter INHERITED; 89 typedef SkMaskFilter INHERITED;
90 }; 90 };
91 91
92 const SkScalar SkBlurMaskFilterImpl::kMAX_RADIUS = SkIntToScalar(128); 92 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_RADIUS = SkIntToScalar(128);
93 const SkScalar SkBlurMaskFilterImpl::kBLUR_SIGMA_SCALE = 0.6f; 93 const SkScalar SkBlurMaskFilterImpl::kBLUR_SIGMA_SCALE = SkFloatToScalar(0.6f);
94 94
95 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, 95 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius,
96 SkBlurMaskFilter::BlurStyle style, 96 SkBlurMaskFilter::BlurStyle style,
97 uint32_t flags) { 97 uint32_t flags) {
98 // use !(radius > 0) instead of radius <= 0 to reject NaN values 98 // use !(radius > 0) instead of radius <= 0 to reject NaN values
99 if (!(radius > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount 99 if (!(radius > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount
100 || flags > SkBlurMaskFilter::kAll_BlurFlag) { 100 || flags > SkBlurMaskFilter::kAll_BlurFlag) {
101 return NULL; 101 return NULL;
102 } 102 }
103 103
(...skipping 28 matching lines...) Expand all
132 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, 132 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
133 const SkMatrix& matrix, 133 const SkMatrix& matrix,
134 SkIPoint* margin) const{ 134 SkIPoint* margin) const{
135 SkScalar radius; 135 SkScalar radius;
136 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { 136 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) {
137 radius = fRadius; 137 radius = fRadius;
138 } else { 138 } else {
139 radius = matrix.mapRadius(fRadius); 139 radius = matrix.mapRadius(fRadius);
140 } 140 }
141 141
142 radius = SkMinScalar(radius, kMAX_RADIUS); 142 radius = SkMinScalar(radius, kMAX_BLUR_RADIUS);
143 SkBlurMask::Quality blurQuality = 143 SkBlurMask::Quality blurQuality =
144 (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 144 (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ?
145 SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; 145 SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality;
146 146
147 return SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, 147 return SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle,
148 blurQuality, margin); 148 blurQuality, margin);
149 } 149 }
150 150
151 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, 151 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r,
152 const SkMatrix& matrix, 152 const SkMatrix& matrix,
153 SkIPoint* margin, SkMask::CreateMode c reateMode) const{ 153 SkIPoint* margin, SkMask::CreateMode c reateMode) const{
154 SkScalar radius; 154 SkScalar radius;
155 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { 155 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) {
156 radius = fRadius; 156 radius = fRadius;
157 } else { 157 } else {
158 radius = matrix.mapRadius(fRadius); 158 radius = matrix.mapRadius(fRadius);
159 } 159 }
160 160
161 radius = SkMinScalar(radius, kMAX_RADIUS); 161 radius = SkMinScalar(radius, kMAX_BLUR_RADIUS);
162 162
163 return SkBlurMask::BlurRect(dst, r, radius, (SkBlurMask::Style)fBlurStyle, 163 return SkBlurMask::BlurRect(dst, r, radius, (SkBlurMask::Style)fBlurStyle,
164 margin, createMode); 164 margin, createMode);
165 } 165 }
166 166
167 #include "SkCanvas.h" 167 #include "SkCanvas.h"
168 168
169 static bool drawRectsIntoMask(const SkRect rects[], int count, SkMask* mask) { 169 static bool drawRectsIntoMask(const SkRect rects[], int count, SkMask* mask) {
170 rects[0].roundOut(&mask->fBounds); 170 rects[0].roundOut(&mask->fBounds);
171 mask->fRowBytes = SkAlign4(mask->fBounds.width()); 171 mask->fRowBytes = SkAlign4(mask->fBounds.width());
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 } 327 }
328 } 328 }
329 patch->fMask.fBounds.offsetTo(0, 0); 329 patch->fMask.fBounds.offsetTo(0, 0);
330 patch->fOuterRect = dstM.fBounds; 330 patch->fOuterRect = dstM.fBounds;
331 patch->fCenter = center; 331 patch->fCenter = center;
332 return kTrue_FilterReturn; 332 return kTrue_FilterReturn;
333 } 333 }
334 334
335 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, 335 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src,
336 SkRect* dst) const { 336 SkRect* dst) const {
337 dst->set(src.fLeft - fRadius, src.fTop - fRadius, 337 SkScalar gpuPad, rasterPad;
338 src.fRight + fRadius, src.fBottom + fRadius); 338
339 {
340 // GPU path
341 SkScalar sigma = SkScalarMul(fRadius, kBLUR_SIGMA_SCALE);
342 gpuPad = sigma * 3.0f;
343 }
344
345 {
346 // raster path
347 SkScalar radius = SkScalarMul(fRadius, SkBlurMask::kBlurRadiusFudgeFacto r);
348
349 radius = (radius + .5f) * 2.f;
350
351 rasterPad = SkIntToScalar(SkScalarRoundToInt(radius * 3)/2);
352 }
353
354 SkScalar pad = SkMaxScalar(gpuPad, rasterPad);
355
356 dst->set(src.fLeft - pad, src.fTop - pad,
357 src.fRight + pad, src.fBottom + pad);
339 } 358 }
340 359
341 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) 360 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer)
342 : SkMaskFilter(buffer) { 361 : SkMaskFilter(buffer) {
343 fRadius = buffer.readScalar(); 362 fRadius = buffer.readScalar();
344 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readInt(); 363 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readInt();
345 fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; 364 fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag;
346 SkASSERT(fRadius >= 0); 365 SkASSERT(fRadius >= 0);
347 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); 366 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount);
348 } 367 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } else { 490 } else {
472 str->append("None"); 491 str->append("None");
473 } 492 }
474 str->append("))"); 493 str->append("))");
475 } 494 }
476 #endif 495 #endif
477 496
478 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 497 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
479 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 498 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
480 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 499 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/effects/SkBlurMask.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698