OLD | NEW |
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" |
11 #include "SkGpuBlurUtils.h" | 11 #include "SkGpuBlurUtils.h" |
12 #include "SkFlattenableBuffers.h" | 12 #include "SkFlattenableBuffers.h" |
13 #include "SkMaskFilter.h" | 13 #include "SkMaskFilter.h" |
14 #include "SkRTConf.h" | 14 #include "SkRTConf.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 "GrContext.h" | 19 #include "GrContext.h" |
20 #include "GrTexture.h" | 20 #include "GrTexture.h" |
21 #include "effects/GrSimpleTextureEffect.h" | 21 #include "effects/GrSimpleTextureEffect.h" |
22 #include "SkGrPixelRef.h" | 22 #include "SkGrPixelRef.h" |
23 #endif | 23 #endif |
24 | 24 |
25 class SkBlurMaskFilterImpl : public SkMaskFilter { | 25 class SkBlurMaskFilterImpl : public SkMaskFilter { |
26 public: | 26 public: |
27 SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle, | 27 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurMaskFilter::BlurStyle, uint32_t f
lags); |
28 uint32_t flags); | |
29 | 28 |
30 // overrides from SkMaskFilter | 29 // overrides from SkMaskFilter |
31 virtual SkMask::Format getFormat() const SK_OVERRIDE; | 30 virtual SkMask::Format getFormat() const SK_OVERRIDE; |
32 virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, | 31 virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, |
33 SkIPoint* margin) const SK_OVERRIDE; | 32 SkIPoint* margin) const SK_OVERRIDE; |
34 | 33 |
35 #if SK_SUPPORT_GPU | 34 #if SK_SUPPORT_GPU |
36 virtual bool canFilterMaskGPU(const SkRect& devBounds, | 35 virtual bool canFilterMaskGPU(const SkRect& devBounds, |
37 const SkIRect& clipBounds, | 36 const SkIRect& clipBounds, |
38 const SkMatrix& ctm, | 37 const SkMatrix& ctm, |
(...skipping 14 matching lines...) Expand all Loading... |
53 const SkIRect& clipBounds, | 52 const SkIRect& clipBounds, |
54 NinePatch*) const SK_OVERRIDE; | 53 NinePatch*) const SK_OVERRIDE; |
55 | 54 |
56 bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, | 55 bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, |
57 SkIPoint* margin, SkMask::CreateMode createMode) const; | 56 SkIPoint* margin, SkMask::CreateMode createMode) const; |
58 | 57 |
59 private: | 58 private: |
60 // To avoid unseemly allocation requests (esp. for finite platforms like | 59 // To avoid unseemly allocation requests (esp. for finite platforms like |
61 // handset) we limit the radius so something manageable. (as opposed to | 60 // handset) we limit the radius so something manageable. (as opposed to |
62 // a request like 10,000) | 61 // a request like 10,000) |
63 static const SkScalar kMAX_BLUR_RADIUS; | 62 static const SkScalar kMAX_BLUR_SIGMA; |
64 // This constant approximates the scaling done in the software path's | |
65 // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). | |
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. | |
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 | |
70 // all the blur tests. | |
71 static const SkScalar kBLUR_SIGMA_SCALE; | |
72 | 63 |
73 SkScalar fRadius; | 64 SkScalar fSigma; |
74 SkBlurMaskFilter::BlurStyle fBlurStyle; | 65 SkBlurMaskFilter::BlurStyle fBlurStyle; |
75 uint32_t fBlurFlags; | 66 uint32_t fBlurFlags; |
76 | 67 |
77 SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); | 68 SkBlurMaskFilterImpl(SkFlattenableReadBuffer&); |
78 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; | 69 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
79 #if SK_SUPPORT_GPU | 70 |
80 SkScalar computeXformedRadius(const SkMatrix& ctm) const { | 71 SkScalar computeXformedSigma(const SkMatrix& ctm) const { |
81 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr
ansform_BlurFlag); | 72 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr
ansform_BlurFlag); |
82 | 73 |
83 SkScalar xformedRadius = ignoreTransform ? fRadius | 74 SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma)
; |
84 : ctm.mapRadius(fRadius); | 75 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); |
85 return SkMinScalar(xformedRadius, kMAX_BLUR_RADIUS); | |
86 } | 76 } |
87 #endif | |
88 | 77 |
89 typedef SkMaskFilter INHERITED; | 78 typedef SkMaskFilter INHERITED; |
90 }; | 79 }; |
91 | 80 |
92 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_RADIUS = SkIntToScalar(128); | 81 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); |
93 const SkScalar SkBlurMaskFilterImpl::kBLUR_SIGMA_SCALE = SkFloatToScalar(0.6f); | |
94 | 82 |
95 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, | 83 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, |
96 SkBlurMaskFilter::BlurStyle style, | 84 SkBlurMaskFilter::BlurStyle style, |
97 uint32_t flags) { | 85 uint32_t flags) { |
98 // use !(radius > 0) instead of radius <= 0 to reject NaN values | 86 // use !(radius > 0) instead of radius <= 0 to reject NaN values |
99 if (!(radius > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount | 87 if (!(radius > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount |
100 || flags > SkBlurMaskFilter::kAll_BlurFlag) { | 88 || flags > SkBlurMaskFilter::kAll_BlurFlag) { |
101 return NULL; | 89 return NULL; |
102 } | 90 } |
103 | 91 |
104 return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags)); | 92 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); |
| 93 |
| 94 return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); |
| 95 } |
| 96 |
| 97 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurMaskFilter::BlurStyle style, |
| 98 SkScalar sigma, |
| 99 uint32_t flags) { |
| 100 // use !(sigma > 0) instead of sigma <= 0 to reject NaN values |
| 101 if (!(sigma > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount |
| 102 || flags > SkBlurMaskFilter::kAll_BlurFlag) { |
| 103 return NULL; |
| 104 } |
| 105 |
| 106 return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); |
105 } | 107 } |
106 | 108 |
107 /////////////////////////////////////////////////////////////////////////////// | 109 /////////////////////////////////////////////////////////////////////////////// |
108 | 110 |
109 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, | 111 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, |
110 SkBlurMaskFilter::BlurStyle style, | 112 SkBlurMaskFilter::BlurStyle style, |
111 uint32_t flags) | 113 uint32_t flags) |
112 : fRadius(radius), fBlurStyle(style), fBlurFlags(flags) { | 114 : fSigma(sigma), fBlurStyle(style), fBlurFlags(flags) { |
113 #if 0 | 115 #if 0 |
114 fGamma = NULL; | 116 fGamma = NULL; |
115 if (gammaScale) { | 117 if (gammaScale) { |
116 fGamma = new U8[256]; | 118 fGamma = new U8[256]; |
117 if (gammaScale > 0) | 119 if (gammaScale > 0) |
118 SkBlurMask::BuildSqrGamma(fGamma, gammaScale); | 120 SkBlurMask::BuildSqrGamma(fGamma, gammaScale); |
119 else | 121 else |
120 SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); | 122 SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); |
121 } | 123 } |
122 #endif | 124 #endif |
123 SkASSERT(radius >= 0); | 125 SkASSERT(fSigma >= 0); |
124 SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); | 126 SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); |
125 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); | 127 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); |
126 } | 128 } |
127 | 129 |
128 SkMask::Format SkBlurMaskFilterImpl::getFormat() const { | 130 SkMask::Format SkBlurMaskFilterImpl::getFormat() const { |
129 return SkMask::kA8_Format; | 131 return SkMask::kA8_Format; |
130 } | 132 } |
131 | 133 |
132 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, | 134 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, |
133 const SkMatrix& matrix, | 135 const SkMatrix& matrix, |
134 SkIPoint* margin) const{ | 136 SkIPoint* margin) const{ |
135 SkScalar radius; | 137 SkScalar sigma = this->computeXformedSigma(matrix); |
136 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { | |
137 radius = fRadius; | |
138 } else { | |
139 radius = matrix.mapRadius(fRadius); | |
140 } | |
141 | 138 |
142 radius = SkMinScalar(radius, kMAX_BLUR_RADIUS); | |
143 SkBlurMask::Quality blurQuality = | 139 SkBlurMask::Quality blurQuality = |
144 (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? | 140 (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? |
145 SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; | 141 SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; |
146 | 142 |
147 return SkBlurMask::Blur(dst, src, radius, (SkBlurMask::Style)fBlurStyle, | 143 return SkBlurMask::BoxBlur(dst, src, sigma, (SkBlurMask::Style)fBlurStyle, |
148 blurQuality, margin); | 144 blurQuality, margin); |
149 } | 145 } |
150 | 146 |
151 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, | 147 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, |
152 const SkMatrix& matrix, | 148 const SkMatrix& matrix, |
153 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ | 149 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ |
154 SkScalar radius; | 150 SkScalar sigma = computeXformedSigma(matrix); |
155 if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { | |
156 radius = fRadius; | |
157 } else { | |
158 radius = matrix.mapRadius(fRadius); | |
159 } | |
160 | 151 |
161 radius = SkMinScalar(radius, kMAX_BLUR_RADIUS); | 152 return SkBlurMask::BlurRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, |
162 | |
163 return SkBlurMask::BlurRect(dst, r, radius, (SkBlurMask::Style)fBlurStyle, | |
164 margin, createMode); | 153 margin, createMode); |
165 } | 154 } |
166 | 155 |
167 #include "SkCanvas.h" | 156 #include "SkCanvas.h" |
168 | 157 |
169 static bool drawRectsIntoMask(const SkRect rects[], int count, SkMask* mask) { | 158 static bool drawRectsIntoMask(const SkRect rects[], int count, SkMask* mask) { |
170 rects[0].roundOut(&mask->fBounds); | 159 rects[0].roundOut(&mask->fBounds); |
171 mask->fRowBytes = SkAlign4(mask->fBounds.width()); | 160 mask->fRowBytes = SkAlign4(mask->fBounds.width()); |
172 mask->fFormat = SkMask::kA8_Format; | 161 mask->fFormat = SkMask::kA8_Format; |
173 size_t size = mask->computeImageSize(); | 162 size_t size = mask->computeImageSize(); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 } | 316 } |
328 } | 317 } |
329 patch->fMask.fBounds.offsetTo(0, 0); | 318 patch->fMask.fBounds.offsetTo(0, 0); |
330 patch->fOuterRect = dstM.fBounds; | 319 patch->fOuterRect = dstM.fBounds; |
331 patch->fCenter = center; | 320 patch->fCenter = center; |
332 return kTrue_FilterReturn; | 321 return kTrue_FilterReturn; |
333 } | 322 } |
334 | 323 |
335 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 324 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
336 SkRect* dst) const { | 325 SkRect* dst) const { |
337 SkScalar gpuPad, rasterPad; | 326 SkScalar pad = 3.0f * fSigma; |
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 | 327 |
356 dst->set(src.fLeft - pad, src.fTop - pad, | 328 dst->set(src.fLeft - pad, src.fTop - pad, |
357 src.fRight + pad, src.fBottom + pad); | 329 src.fRight + pad, src.fBottom + pad); |
358 } | 330 } |
359 | 331 |
360 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) | 332 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) |
361 : SkMaskFilter(buffer) { | 333 : SkMaskFilter(buffer) { |
362 fRadius = buffer.readScalar(); | 334 fSigma = buffer.readScalar(); |
| 335 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TO
O |
| 336 // Fixing this must be done in two stages. When the skps are recaptured in V
13, |
| 337 // remove the ConvertRadiusToSigma but retain the absolute value. |
| 338 // At the same time, switch the code in flatten to write a positive value. |
| 339 // When the skps are captured in V14 the absolute value can be removed. |
| 340 if (fSigma > 0) { |
| 341 fSigma = SkBlurMask::ConvertRadiusToSigma(fSigma); |
| 342 } else { |
| 343 fSigma = -fSigma; |
| 344 } |
| 345 #endif |
363 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readInt(); | 346 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readInt(); |
364 fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; | 347 fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; |
365 SkASSERT(fRadius >= 0); | 348 SkASSERT(fSigma >= 0); |
366 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); | 349 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); |
367 } | 350 } |
368 | 351 |
369 void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) const { | 352 void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer) const { |
370 this->INHERITED::flatten(buffer); | 353 this->INHERITED::flatten(buffer); |
371 buffer.writeScalar(fRadius); | 354 buffer.writeScalar(-fSigma); |
372 buffer.writeInt(fBlurStyle); | 355 buffer.writeInt(fBlurStyle); |
373 buffer.writeUInt(fBlurFlags); | 356 buffer.writeUInt(fBlurFlags); |
374 } | 357 } |
375 | 358 |
376 #if SK_SUPPORT_GPU | 359 #if SK_SUPPORT_GPU |
377 | 360 |
378 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, | 361 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, |
379 const SkIRect& clipBounds, | 362 const SkIRect& clipBounds, |
380 const SkMatrix& ctm, | 363 const SkMatrix& ctm, |
381 SkRect* maskRect) const { | 364 SkRect* maskRect) const { |
382 SkScalar xformedRadius = this->computeXformedRadius(ctm); | 365 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
383 if (xformedRadius <= 0) { | 366 if (xformedSigma <= 0) { |
384 return false; | 367 return false; |
385 } | 368 } |
386 | 369 |
387 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); | 370 static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); |
388 static const SkScalar kMIN_GPU_BLUR_RADIUS = SkIntToScalar(32); | 371 static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); |
389 | 372 |
390 if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && | 373 if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && |
391 srcBounds.height() <= kMIN_GPU_BLUR_SIZE && | 374 srcBounds.height() <= kMIN_GPU_BLUR_SIZE && |
392 xformedRadius <= kMIN_GPU_BLUR_RADIUS) { | 375 xformedSigma <= kMIN_GPU_BLUR_SIGMA) { |
393 // We prefer to blur small rect with small radius via CPU. | 376 // We prefer to blur small rect with small radius via CPU. |
394 return false; | 377 return false; |
395 } | 378 } |
396 | 379 |
397 if (NULL == maskRect) { | 380 if (NULL == maskRect) { |
398 // don't need to compute maskRect | 381 // don't need to compute maskRect |
399 return true; | 382 return true; |
400 } | 383 } |
401 | 384 |
402 float sigma3 = 3 * SkScalarToFloat(xformedRadius) * kBLUR_SIGMA_SCALE; | 385 float sigma3 = 3 * SkScalarToFloat(xformedSigma); |
403 | 386 |
404 SkRect clipRect = SkRect::MakeFromIRect(clipBounds); | 387 SkRect clipRect = SkRect::MakeFromIRect(clipBounds); |
405 SkRect srcRect(srcBounds); | 388 SkRect srcRect(srcBounds); |
406 | 389 |
407 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. | 390 // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. |
408 srcRect.outset(SkFloatToScalar(sigma3), SkFloatToScalar(sigma3)); | 391 srcRect.outset(SkFloatToScalar(sigma3), SkFloatToScalar(sigma3)); |
409 clipRect.outset(SkFloatToScalar(sigma3), SkFloatToScalar(sigma3)); | 392 clipRect.outset(SkFloatToScalar(sigma3), SkFloatToScalar(sigma3)); |
410 srcRect.intersect(clipRect); | 393 srcRect.intersect(clipRect); |
411 *maskRect = srcRect; | 394 *maskRect = srcRect; |
412 return true; | 395 return true; |
413 } | 396 } |
414 | 397 |
415 bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, | 398 bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, |
416 const SkRect& maskRect, | 399 const SkRect& maskRect, |
417 GrTexture** result, | 400 GrTexture** result, |
418 bool canOverwriteSrc) const { | 401 bool canOverwriteSrc) const { |
419 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); | 402 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); |
420 | 403 |
421 GrContext* context = src->getContext(); | 404 GrContext* context = src->getContext(); |
422 | 405 |
423 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); | 406 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); |
424 | 407 |
425 SkScalar xformedRadius = this->computeXformedRadius(context->getMatrix()); | 408 SkScalar xformedSigma = this->computeXformedSigma(context->getMatrix()); |
426 SkASSERT(xformedRadius > 0); | 409 SkASSERT(xformedSigma > 0); |
427 | |
428 float sigma = SkScalarToFloat(xformedRadius) * kBLUR_SIGMA_SCALE; | |
429 | 410 |
430 // If we're doing a normal blur, we can clobber the pathTexture in the | 411 // If we're doing a normal blur, we can clobber the pathTexture in the |
431 // gaussianBlur. Otherwise, we need to save it for later compositing. | 412 // gaussianBlur. Otherwise, we need to save it for later compositing. |
432 bool isNormalBlur = (SkBlurMaskFilter::kNormal_BlurStyle == fBlurStyle); | 413 bool isNormalBlur = (SkBlurMaskFilter::kNormal_BlurStyle == fBlurStyle); |
433 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, | 414 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, |
434 clipRect, false, sigma, sigma); | 415 clipRect, false, xformedSigma, xforme
dSigma); |
435 if (NULL == *result) { | 416 if (NULL == *result) { |
436 return false; | 417 return false; |
437 } | 418 } |
438 | 419 |
439 if (!isNormalBlur) { | 420 if (!isNormalBlur) { |
440 context->setIdentityMatrix(); | 421 context->setIdentityMatrix(); |
441 GrPaint paint; | 422 GrPaint paint; |
442 SkMatrix matrix; | 423 SkMatrix matrix; |
443 matrix.setIDiv(src->width(), src->height()); | 424 matrix.setIDiv(src->width(), src->height()); |
444 // Blend pathTexture over blurTexture. | 425 // Blend pathTexture over blurTexture. |
(...skipping 17 matching lines...) Expand all Loading... |
462 return true; | 443 return true; |
463 } | 444 } |
464 | 445 |
465 #endif // SK_SUPPORT_GPU | 446 #endif // SK_SUPPORT_GPU |
466 | 447 |
467 | 448 |
468 #ifdef SK_DEVELOPER | 449 #ifdef SK_DEVELOPER |
469 void SkBlurMaskFilterImpl::toString(SkString* str) const { | 450 void SkBlurMaskFilterImpl::toString(SkString* str) const { |
470 str->append("SkBlurMaskFilterImpl: ("); | 451 str->append("SkBlurMaskFilterImpl: ("); |
471 | 452 |
472 str->append("radius: "); | 453 str->append("sigma: "); |
473 str->appendScalar(fRadius); | 454 str->appendScalar(fSigma); |
474 str->append(" "); | 455 str->append(" "); |
475 | 456 |
476 static const char* gStyleName[SkBlurMaskFilter::kBlurStyleCount] = { | 457 static const char* gStyleName[SkBlurMaskFilter::kBlurStyleCount] = { |
477 "normal", "solid", "outer", "inner" | 458 "normal", "solid", "outer", "inner" |
478 }; | 459 }; |
479 | 460 |
480 str->appendf("style: %s ", gStyleName[fBlurStyle]); | 461 str->appendf("style: %s ", gStyleName[fBlurStyle]); |
481 str->append("flags: ("); | 462 str->append("flags: ("); |
482 if (fBlurFlags) { | 463 if (fBlurFlags) { |
483 bool needSeparator = false; | 464 bool needSeparator = false; |
484 SkAddFlagToString(str, | 465 SkAddFlagToString(str, |
485 SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransfo
rm_BlurFlag), | 466 SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransfo
rm_BlurFlag), |
486 "IgnoreXform", &needSeparator); | 467 "IgnoreXform", &needSeparator); |
487 SkAddFlagToString(str, | 468 SkAddFlagToString(str, |
488 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B
lurFlag), | 469 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B
lurFlag), |
489 "HighQuality", &needSeparator); | 470 "HighQuality", &needSeparator); |
490 } else { | 471 } else { |
491 str->append("None"); | 472 str->append("None"); |
492 } | 473 } |
493 str->append("))"); | 474 str->append("))"); |
494 } | 475 } |
495 #endif | 476 #endif |
496 | 477 |
497 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 478 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
498 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 479 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
499 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 480 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |