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" |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "GrEffect.h" | 23 #include "GrEffect.h" |
24 #include "gl/GrGLEffect.h" | 24 #include "gl/GrGLEffect.h" |
25 #include "effects/GrSimpleTextureEffect.h" | 25 #include "effects/GrSimpleTextureEffect.h" |
26 #include "GrTBackendEffectFactory.h" | 26 #include "GrTBackendEffectFactory.h" |
27 #include "SkGrPixelRef.h" | 27 #include "SkGrPixelRef.h" |
28 #include "SkDraw.h" | 28 #include "SkDraw.h" |
29 #endif | 29 #endif |
30 | 30 |
31 class SkBlurMaskFilterImpl : public SkMaskFilter { | 31 class SkBlurMaskFilterImpl : public SkMaskFilter { |
32 public: | 32 public: |
33 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurMaskFilter::BlurStyle, uint32_t f
lags); | 33 SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags); |
34 | 34 |
35 // overrides from SkMaskFilter | 35 // overrides from SkMaskFilter |
36 virtual SkMask::Format getFormat() const SK_OVERRIDE; | 36 virtual SkMask::Format getFormat() const SK_OVERRIDE; |
37 virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, | 37 virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, |
38 SkIPoint* margin) const SK_OVERRIDE; | 38 SkIPoint* margin) const SK_OVERRIDE; |
39 | 39 |
40 #if SK_SUPPORT_GPU | 40 #if SK_SUPPORT_GPU |
41 virtual bool canFilterMaskGPU(const SkRect& devBounds, | 41 virtual bool canFilterMaskGPU(const SkRect& devBounds, |
42 const SkIRect& clipBounds, | 42 const SkIRect& clipBounds, |
43 const SkMatrix& ctm, | 43 const SkMatrix& ctm, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 SkIPoint* margin, SkMask::CreateMode createMode) const; | 76 SkIPoint* margin, SkMask::CreateMode createMode) const; |
77 bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, | 77 bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, |
78 SkIPoint* margin, SkMask::CreateMode createMode) const; | 78 SkIPoint* margin, SkMask::CreateMode createMode) const; |
79 | 79 |
80 private: | 80 private: |
81 // To avoid unseemly allocation requests (esp. for finite platforms like | 81 // To avoid unseemly allocation requests (esp. for finite platforms like |
82 // handset) we limit the radius so something manageable. (as opposed to | 82 // handset) we limit the radius so something manageable. (as opposed to |
83 // a request like 10,000) | 83 // a request like 10,000) |
84 static const SkScalar kMAX_BLUR_SIGMA; | 84 static const SkScalar kMAX_BLUR_SIGMA; |
85 | 85 |
86 SkScalar fSigma; | 86 SkScalar fSigma; |
87 SkBlurMaskFilter::BlurStyle fBlurStyle; | 87 SkBlurStyle fBlurStyle; |
88 uint32_t fBlurFlags; | 88 uint32_t fBlurFlags; |
89 | 89 |
90 SkBlurMaskFilterImpl(SkReadBuffer&); | 90 SkBlurMaskFilterImpl(SkReadBuffer&); |
91 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; | 91 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; |
92 | 92 |
93 SkScalar computeXformedSigma(const SkMatrix& ctm) const { | 93 SkScalar computeXformedSigma(const SkMatrix& ctm) const { |
94 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr
ansform_BlurFlag); | 94 bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTr
ansform_BlurFlag); |
95 | 95 |
96 SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma)
; | 96 SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma)
; |
97 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); | 97 return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); |
98 } | 98 } |
99 | 99 |
100 typedef SkMaskFilter INHERITED; | 100 typedef SkMaskFilter INHERITED; |
101 }; | 101 }; |
102 | 102 |
103 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); | 103 const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); |
104 | 104 |
| 105 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32
_t flags) { |
| 106 if (!SkScalarIsFinite(sigma) || sigma <= 0) { |
| 107 return NULL; |
| 108 } |
| 109 if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { |
| 110 return NULL; |
| 111 } |
| 112 if (flags > SkBlurMaskFilter::kAll_BlurFlag) { |
| 113 return NULL; |
| 114 } |
| 115 return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); |
| 116 } |
| 117 |
| 118 #ifdef SK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE |
105 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, | 119 SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, |
106 SkBlurMaskFilter::BlurStyle style, | 120 SkBlurMaskFilter::BlurStyle style, |
107 uint32_t flags) { | 121 uint32_t flags) { |
108 // use !(radius > 0) instead of radius <= 0 to reject NaN values | |
109 if (!(radius > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount | |
110 || flags > SkBlurMaskFilter::kAll_BlurFlag) { | |
111 return NULL; | |
112 } | |
113 | |
114 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); | 122 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); |
115 | 123 return Create((SkBlurStyle)style, sigma, flags); |
116 return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); | |
117 } | 124 } |
118 | 125 |
119 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurMaskFilter::BlurStyle style, | 126 SkMaskFilter* SkBlurMaskFilter::Create(SkBlurMaskFilter::BlurStyle style, |
120 SkScalar sigma, | 127 SkScalar sigma, |
121 uint32_t flags) { | 128 uint32_t flags) { |
122 // use !(sigma > 0) instead of sigma <= 0 to reject NaN values | 129 return Create((SkBlurStyle)style, sigma, flags); |
123 if (!(sigma > 0) || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount | |
124 || flags > SkBlurMaskFilter::kAll_BlurFlag) { | |
125 return NULL; | |
126 } | |
127 | |
128 return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); | |
129 } | 130 } |
| 131 #endif |
130 | 132 |
131 /////////////////////////////////////////////////////////////////////////////// | 133 /////////////////////////////////////////////////////////////////////////////// |
132 | 134 |
133 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, | 135 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, ui
nt32_t flags) |
134 SkBlurMaskFilter::BlurStyle style, | 136 : fSigma(sigma) |
135 uint32_t flags) | 137 , fBlurStyle(style) |
136 : fSigma(sigma), fBlurStyle(style), fBlurFlags(flags) { | 138 , fBlurFlags(flags) { |
137 #if 0 | 139 SkASSERT(fSigma > 0); |
138 fGamma = NULL; | 140 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle); |
139 if (gammaScale) { | |
140 fGamma = new U8[256]; | |
141 if (gammaScale > 0) | |
142 SkBlurMask::BuildSqrGamma(fGamma, gammaScale); | |
143 else | |
144 SkBlurMask::BuildSqrtGamma(fGamma, -gammaScale); | |
145 } | |
146 #endif | |
147 SkASSERT(fSigma >= 0); | |
148 SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount); | |
149 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); | 141 SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); |
150 } | 142 } |
151 | 143 |
152 SkMask::Format SkBlurMaskFilterImpl::getFormat() const { | 144 SkMask::Format SkBlurMaskFilterImpl::getFormat() const { |
153 return SkMask::kA8_Format; | 145 return SkMask::kA8_Format; |
154 } | 146 } |
155 | 147 |
156 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, | 148 bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, |
157 const SkMatrix& matrix, | 149 const SkMatrix& matrix, |
158 SkIPoint* margin) const{ | 150 SkIPoint* margin) const{ |
159 SkScalar sigma = this->computeXformedSigma(matrix); | 151 SkScalar sigma = this->computeXformedSigma(matrix); |
160 | 152 |
161 SkBlurMask::Quality blurQuality = | 153 SkBlurQuality blurQuality = |
162 (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? | 154 (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? |
163 SkBlurMask::kHigh_Quality : SkBlurMask::kLow_Quality; | 155 kHigh_SkBlurQuality : kLow_SkBlurQuality; |
164 | 156 |
165 return SkBlurMask::BoxBlur(dst, src, sigma, (SkBlurMask::Style)fBlurStyle, | 157 return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, blurQuality, margin)
; |
166 blurQuality, margin); | |
167 } | 158 } |
168 | 159 |
169 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, | 160 bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, |
170 const SkMatrix& matrix, | 161 const SkMatrix& matrix, |
171 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ | 162 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ |
172 SkScalar sigma = computeXformedSigma(matrix); | 163 SkScalar sigma = computeXformedSigma(matrix); |
173 | 164 |
174 return SkBlurMask::BlurRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, | 165 return SkBlurMask::BlurRect(sigma, dst, r, fBlurStyle, |
175 margin, createMode); | 166 margin, createMode); |
176 } | 167 } |
177 | 168 |
178 bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, | 169 bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, |
179 const SkMatrix& matrix, | 170 const SkMatrix& matrix, |
180 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ | 171 SkIPoint* margin, SkMask::CreateMode c
reateMode) const{ |
181 SkScalar sigma = computeXformedSigma(matrix); | 172 SkScalar sigma = computeXformedSigma(matrix); |
182 | 173 |
183 return SkBlurMask::BlurRRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, | 174 return SkBlurMask::BlurRRect(sigma, dst, r, fBlurStyle, |
184 margin, createMode); | 175 margin, createMode); |
185 } | 176 } |
186 | 177 |
187 #include "SkCanvas.h" | 178 #include "SkCanvas.h" |
188 | 179 |
189 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { | 180 static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { |
190 SkASSERT(mask != NULL); | 181 SkASSERT(mask != NULL); |
191 | 182 |
192 bounds.roundOut(&mask->fBounds); | 183 bounds.roundOut(&mask->fBounds); |
193 mask->fRowBytes = SkAlign4(mask->fBounds.width()); | 184 mask->fRowBytes = SkAlign4(mask->fBounds.width()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 282 |
292 // These three can take advantage of this fast path. | 283 // These three can take advantage of this fast path. |
293 case SkRRect::kSimple_Type: | 284 case SkRRect::kSimple_Type: |
294 case SkRRect::kNinePatch_Type: | 285 case SkRRect::kNinePatch_Type: |
295 case SkRRect::kComplex_Type: | 286 case SkRRect::kComplex_Type: |
296 break; | 287 break; |
297 } | 288 } |
298 | 289 |
299 // TODO: report correct metrics for innerstyle, where we do not grow the | 290 // TODO: report correct metrics for innerstyle, where we do not grow the |
300 // total bounds, but we do need an inset the size of our blur-radius | 291 // total bounds, but we do need an inset the size of our blur-radius |
301 if (SkBlurMaskFilter::kInner_BlurStyle == fBlurStyle) { | 292 if (kInner_SkBlurStyle == fBlurStyle) { |
302 return kUnimplemented_FilterReturn; | 293 return kUnimplemented_FilterReturn; |
303 } | 294 } |
304 | 295 |
305 // TODO: take clipBounds into account to limit our coordinates up front | 296 // TODO: take clipBounds into account to limit our coordinates up front |
306 // for now, just skip too-large src rects (to take the old code path). | 297 // for now, just skip too-large src rects (to take the old code path). |
307 if (rect_exceeds(rrect.rect(), SkIntToScalar(32767))) { | 298 if (rect_exceeds(rrect.rect(), SkIntToScalar(32767))) { |
308 return kUnimplemented_FilterReturn; | 299 return kUnimplemented_FilterReturn; |
309 } | 300 } |
310 | 301 |
311 SkIPoint margin; | 302 SkIPoint margin; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, | 394 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
404 const SkMatrix& matrix, | 395 const SkMatrix& matrix, |
405 const SkIRect& clipBounds, | 396 const SkIRect& clipBounds, |
406 NinePatch* patch) const { | 397 NinePatch* patch) const { |
407 if (count < 1 || count > 2) { | 398 if (count < 1 || count > 2) { |
408 return kUnimplemented_FilterReturn; | 399 return kUnimplemented_FilterReturn; |
409 } | 400 } |
410 | 401 |
411 // TODO: report correct metrics for innerstyle, where we do not grow the | 402 // TODO: report correct metrics for innerstyle, where we do not grow the |
412 // total bounds, but we do need an inset the size of our blur-radius | 403 // total bounds, but we do need an inset the size of our blur-radius |
413 if (SkBlurMaskFilter::kInner_BlurStyle == fBlurStyle || | 404 if (kInner_SkBlurStyle == fBlurStyle || kOuter_SkBlurStyle == fBlurStyle) { |
414 SkBlurMaskFilter::kOuter_BlurStyle == fBlurStyle) { | |
415 return kUnimplemented_FilterReturn; | 405 return kUnimplemented_FilterReturn; |
416 } | 406 } |
417 | 407 |
418 // TODO: take clipBounds into account to limit our coordinates up front | 408 // TODO: take clipBounds into account to limit our coordinates up front |
419 // for now, just skip too-large src rects (to take the old code path). | 409 // for now, just skip too-large src rects (to take the old code path). |
420 if (rect_exceeds(rects[0], SkIntToScalar(32767))) { | 410 if (rect_exceeds(rects[0], SkIntToScalar(32767))) { |
421 return kUnimplemented_FilterReturn; | 411 return kUnimplemented_FilterReturn; |
422 } | 412 } |
423 | 413 |
424 SkIPoint margin; | 414 SkIPoint margin; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 SkRect* dst) const { | 514 SkRect* dst) const { |
525 SkScalar pad = 3.0f * fSigma; | 515 SkScalar pad = 3.0f * fSigma; |
526 | 516 |
527 dst->set(src.fLeft - pad, src.fTop - pad, | 517 dst->set(src.fLeft - pad, src.fTop - pad, |
528 src.fRight + pad, src.fBottom + pad); | 518 src.fRight + pad, src.fBottom + pad); |
529 } | 519 } |
530 | 520 |
531 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer) | 521 SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer) |
532 : SkMaskFilter(buffer) { | 522 : SkMaskFilter(buffer) { |
533 fSigma = buffer.readScalar(); | 523 fSigma = buffer.readScalar(); |
534 fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readInt(); | 524 fBlurStyle = (SkBlurStyle)buffer.readInt(); |
535 fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; | 525 fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; |
536 SkASSERT(fSigma >= 0); | 526 SkASSERT(fSigma > 0); |
537 SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount); | 527 SkASSERT((unsigned)fBlurStyle <= kLastEnum_SkBlurStyle); |
538 } | 528 } |
539 | 529 |
540 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { | 530 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { |
541 this->INHERITED::flatten(buffer); | 531 this->INHERITED::flatten(buffer); |
542 buffer.writeScalar(fSigma); | 532 buffer.writeScalar(fSigma); |
543 buffer.writeInt(fBlurStyle); | 533 buffer.writeInt(fBlurStyle); |
544 buffer.writeUInt(fBlurFlags); | 534 buffer.writeUInt(fBlurFlags); |
545 } | 535 } |
546 | 536 |
547 #if SK_SUPPORT_GPU | 537 #if SK_SUPPORT_GPU |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 float width = random->nextRangeF(200,300); | 768 float width = random->nextRangeF(200,300); |
779 float height = random->nextRangeF(200,300); | 769 float height = random->nextRangeF(200,300); |
780 return GrRectBlurEffect::Create(context, SkRect::MakeWH(width, height), sigm
a); | 770 return GrRectBlurEffect::Create(context, SkRect::MakeWH(width, height), sigm
a); |
781 } | 771 } |
782 | 772 |
783 | 773 |
784 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, | 774 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, |
785 GrPaint* grp, | 775 GrPaint* grp, |
786 const SkStrokeRec& strokeRec, | 776 const SkStrokeRec& strokeRec, |
787 const SkPath& path) const { | 777 const SkPath& path) const { |
788 if (fBlurStyle != SkBlurMaskFilter::kNormal_BlurStyle) { | 778 if (fBlurStyle != kNormal_SkBlurStyle) { |
789 return false; | 779 return false; |
790 } | 780 } |
791 | 781 |
792 SkRect rect; | 782 SkRect rect; |
793 if (!path.isRect(&rect)) { | 783 if (!path.isRect(&rect)) { |
794 return false; | 784 return false; |
795 } | 785 } |
796 | 786 |
797 if (!strokeRec.isFillStyle()) { | 787 if (!strokeRec.isFillStyle()) { |
798 return false; | 788 return false; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 GrTextureParams params; | 871 GrTextureParams params; |
882 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); | 872 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); |
883 | 873 |
884 unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1; | 874 unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1; |
885 unsigned int texSide = smallRectSide + 2*blurRadius; | 875 unsigned int texSide = smallRectSide + 2*blurRadius; |
886 GrTextureDesc texDesc; | 876 GrTextureDesc texDesc; |
887 texDesc.fWidth = texSide; | 877 texDesc.fWidth = texSide; |
888 texDesc.fHeight = texSide; | 878 texDesc.fHeight = texSide; |
889 texDesc.fConfig = kAlpha_8_GrPixelConfig; | 879 texDesc.fConfig = kAlpha_8_GrPixelConfig; |
890 | 880 |
891 GrTexture *blurNinePatchTexture = context->findAndRefTexture(texDesc, blurRR
ectNinePatchID, ¶ms); | 881 GrTexture *blurNinePatchTexture = context->findAndRefTexture(texDesc, blurRR
ectNinePatchID, |
| 882 ¶ms); |
892 | 883 |
893 if (NULL == blurNinePatchTexture) { | 884 if (NULL == blurNinePatchTexture) { |
894 SkMask mask; | 885 SkMask mask; |
895 | 886 |
896 mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide); | 887 mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide); |
897 mask.fFormat = SkMask::kA8_Format; | 888 mask.fFormat = SkMask::kA8_Format; |
898 mask.fRowBytes = mask.fBounds.width(); | 889 mask.fRowBytes = mask.fBounds.width(); |
899 mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize()); | 890 mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize()); |
900 SkAutoMaskFreeImage amfi(mask.fImage); | 891 SkAutoMaskFreeImage amfi(mask.fImage); |
901 | 892 |
902 memset(mask.fImage, 0, mask.computeTotalImageSize()); | 893 memset(mask.fImage, 0, mask.computeTotalImageSize()); |
903 | 894 |
904 SkRect smallRect; | 895 SkRect smallRect; |
905 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid
e)); | 896 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid
e)); |
906 | 897 |
907 SkRRect smallRRect; | 898 SkRRect smallRRect; |
908 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal
ar(cornerRadius)); | 899 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal
ar(cornerRadius)); |
909 | 900 |
910 SkPath path; | 901 SkPath path; |
911 path.addRRect( smallRRect ); | 902 path.addRRect( smallRRect ); |
912 | 903 |
913 SkDraw::DrawToMask(path, &mask.fBounds, NULL, NULL, &mask, SkMask::kJust
RenderImage_CreateMode, SkPaint::kFill_Style); | 904 SkDraw::DrawToMask(path, &mask.fBounds, NULL, NULL, &mask, |
| 905 SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_S
tyle); |
914 | 906 |
915 SkMask blurred_mask; | 907 SkMask blurred_mask; |
916 SkBlurMask::BoxBlur(&blurred_mask, mask, sigma, SkBlurMask::kNormal_Styl
e, SkBlurMask::kHigh_Quality, NULL, true ); | 908 SkBlurMask::BoxBlur(&blurred_mask, mask, sigma, kNormal_SkBlurStyle, |
| 909 kHigh_SkBlurQuality, NULL, true ); |
917 | 910 |
918 blurNinePatchTexture = context->createTexture(¶ms, texDesc, blurRRec
tNinePatchID, blurred_mask.fImage, 0); | 911 blurNinePatchTexture = context->createTexture(¶ms, texDesc, blurRRec
tNinePatchID, |
| 912 blurred_mask.fImage, 0); |
919 } | 913 } |
920 | 914 |
921 if (NULL == blurNinePatchTexture) { | 915 if (NULL == blurNinePatchTexture) { |
922 return NULL; | 916 return NULL; |
923 } | 917 } |
924 | 918 |
925 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrRRectBlurEffect, | 919 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrRRectBlurEffect, |
926 (sigma, rrect, blurNinePat
chTexture)))); | 920 (sigma, rrect, blurNinePat
chTexture)))); |
927 } | 921 } |
928 | 922 |
929 void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* val
idFlags) const { | 923 void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* val
idFlags) const { |
930 *validFlags = 0; | 924 *validFlags = 0; |
931 } | 925 } |
932 | 926 |
933 const GrBackendEffectFactory& GrRRectBlurEffect::getFactory() const { | 927 const GrBackendEffectFactory& GrRRectBlurEffect::getFactory() const { |
934 return GrTBackendEffectFactory<GrRRectBlurEffect>::getInstance(); | 928 return GrTBackendEffectFactory<GrRRectBlurEffect>::getInstance(); |
935 } | 929 } |
936 | 930 |
937 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) | 931 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) |
938 : fRRect(rrect), | 932 : fRRect(rrect) |
939 fSigma(sigma), | 933 , fSigma(sigma) |
940 fNinePatchAccess(ninePatchTexture) { | 934 , fNinePatchAccess(ninePatchTexture) |
| 935 { |
941 this->addTextureAccess(&fNinePatchAccess); | 936 this->addTextureAccess(&fNinePatchAccess); |
942 this->setWillReadFragmentPosition(); | 937 this->setWillReadFragmentPosition(); |
943 } | 938 } |
944 | 939 |
945 bool GrRRectBlurEffect::onIsEqual(const GrEffect& other) const { | 940 bool GrRRectBlurEffect::onIsEqual(const GrEffect& other) const { |
946 const GrRRectBlurEffect& rrbe = CastEffect<GrRRectBlurEffect>(other); | 941 const GrRRectBlurEffect& rrbe = CastEffect<GrRRectBlurEffect>(other); |
947 return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSig
ma == rrbe.fSigma; | 942 return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSig
ma == rrbe.fSigma; |
948 } | 943 } |
949 | 944 |
950 ////////////////////////////////////////////////////////////////////////////// | 945 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 SkASSERT(rrect.isSimpleCircular() || rrect.isRect()); | 1058 SkASSERT(rrect.isSimpleCircular() || rrect.isRect()); |
1064 radius = rrect.getSimpleRadii().fX; | 1059 radius = rrect.getSimpleRadii().fX; |
1065 uman.set1f(fCornerRadiusUniform, radius); | 1060 uman.set1f(fCornerRadiusUniform, radius); |
1066 } | 1061 } |
1067 | 1062 |
1068 | 1063 |
1069 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, | 1064 bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, |
1070 GrPaint* grp, | 1065 GrPaint* grp, |
1071 const SkStrokeRec& strokeRec
, | 1066 const SkStrokeRec& strokeRec
, |
1072 const SkRRect& rrect) const
{ | 1067 const SkRRect& rrect) const
{ |
1073 if (fBlurStyle != SkBlurMaskFilter::kNormal_BlurStyle) { | 1068 if (fBlurStyle != kNormal_SkBlurStyle) { |
1074 return false; | 1069 return false; |
1075 } | 1070 } |
1076 | 1071 |
1077 if (!strokeRec.isFillStyle()) { | 1072 if (!strokeRec.isFillStyle()) { |
1078 return false; | 1073 return false; |
1079 } | 1074 } |
1080 | 1075 |
1081 SkRect proxy_rect = rrect.rect(); | 1076 SkRect proxy_rect = rrect.rect(); |
1082 SkMatrix ctm = context->getMatrix(); | 1077 SkMatrix ctm = context->getMatrix(); |
1083 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1078 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 | 1142 |
1148 GrContext* context = src->getContext(); | 1143 GrContext* context = src->getContext(); |
1149 | 1144 |
1150 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); | 1145 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); |
1151 | 1146 |
1152 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1147 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
1153 SkASSERT(xformedSigma > 0); | 1148 SkASSERT(xformedSigma > 0); |
1154 | 1149 |
1155 // If we're doing a normal blur, we can clobber the pathTexture in the | 1150 // If we're doing a normal blur, we can clobber the pathTexture in the |
1156 // gaussianBlur. Otherwise, we need to save it for later compositing. | 1151 // gaussianBlur. Otherwise, we need to save it for later compositing. |
1157 bool isNormalBlur = (SkBlurMaskFilter::kNormal_BlurStyle == fBlurStyle); | 1152 bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); |
1158 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, | 1153 *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOver
writeSrc, |
1159 clipRect, false, xformedSigma, xforme
dSigma); | 1154 clipRect, false, xformedSigma, xforme
dSigma); |
1160 if (NULL == *result) { | 1155 if (NULL == *result) { |
1161 return false; | 1156 return false; |
1162 } | 1157 } |
1163 | 1158 |
1164 if (!isNormalBlur) { | 1159 if (!isNormalBlur) { |
1165 context->setIdentityMatrix(); | 1160 context->setIdentityMatrix(); |
1166 GrPaint paint; | 1161 GrPaint paint; |
1167 SkMatrix matrix; | 1162 SkMatrix matrix; |
1168 matrix.setIDiv(src->width(), src->height()); | 1163 matrix.setIDiv(src->width(), src->height()); |
1169 // Blend pathTexture over blurTexture. | 1164 // Blend pathTexture over blurTexture. |
1170 GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget()); | 1165 GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget()); |
1171 paint.addColorEffect(GrSimpleTextureEffect::Create(src, matrix))->unref(
); | 1166 paint.addColorEffect(GrSimpleTextureEffect::Create(src, matrix))->unref(
); |
1172 if (SkBlurMaskFilter::kInner_BlurStyle == fBlurStyle) { | 1167 if (kInner_SkBlurStyle == fBlurStyle) { |
1173 // inner: dst = dst * src | 1168 // inner: dst = dst * src |
1174 paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); | 1169 paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); |
1175 } else if (SkBlurMaskFilter::kSolid_BlurStyle == fBlurStyle) { | 1170 } else if (kSolid_SkBlurStyle == fBlurStyle) { |
1176 // solid: dst = src + dst - src * dst | 1171 // solid: dst = src + dst - src * dst |
1177 // = (1 - dst) * src + 1 * dst | 1172 // = (1 - dst) * src + 1 * dst |
1178 paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff); | 1173 paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff); |
1179 } else if (SkBlurMaskFilter::kOuter_BlurStyle == fBlurStyle) { | 1174 } else if (kOuter_SkBlurStyle == fBlurStyle) { |
1180 // outer: dst = dst * (1 - src) | 1175 // outer: dst = dst * (1 - src) |
1181 // = 0 * src + (1 - src) * dst | 1176 // = 0 * src + (1 - src) * dst |
1182 paint.setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff); | 1177 paint.setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff); |
1183 } | 1178 } |
1184 context->drawRect(paint, clipRect); | 1179 context->drawRect(paint, clipRect); |
1185 } | 1180 } |
1186 | 1181 |
1187 return true; | 1182 return true; |
1188 } | 1183 } |
1189 | 1184 |
1190 #endif // SK_SUPPORT_GPU | 1185 #endif // SK_SUPPORT_GPU |
1191 | 1186 |
1192 | 1187 |
1193 #ifndef SK_IGNORE_TO_STRING | 1188 #ifndef SK_IGNORE_TO_STRING |
1194 void SkBlurMaskFilterImpl::toString(SkString* str) const { | 1189 void SkBlurMaskFilterImpl::toString(SkString* str) const { |
1195 str->append("SkBlurMaskFilterImpl: ("); | 1190 str->append("SkBlurMaskFilterImpl: ("); |
1196 | 1191 |
1197 str->append("sigma: "); | 1192 str->append("sigma: "); |
1198 str->appendScalar(fSigma); | 1193 str->appendScalar(fSigma); |
1199 str->append(" "); | 1194 str->append(" "); |
1200 | 1195 |
1201 static const char* gStyleName[SkBlurMaskFilter::kBlurStyleCount] = { | 1196 static const char* gStyleName[kLastEnum_SkBlurStyle + 1] = { |
1202 "normal", "solid", "outer", "inner" | 1197 "normal", "solid", "outer", "inner" |
1203 }; | 1198 }; |
1204 | 1199 |
1205 str->appendf("style: %s ", gStyleName[fBlurStyle]); | 1200 str->appendf("style: %s ", gStyleName[fBlurStyle]); |
1206 str->append("flags: ("); | 1201 str->append("flags: ("); |
1207 if (fBlurFlags) { | 1202 if (fBlurFlags) { |
1208 bool needSeparator = false; | 1203 bool needSeparator = false; |
1209 SkAddFlagToString(str, | 1204 SkAddFlagToString(str, |
1210 SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransfo
rm_BlurFlag), | 1205 SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransfo
rm_BlurFlag), |
1211 "IgnoreXform", &needSeparator); | 1206 "IgnoreXform", &needSeparator); |
1212 SkAddFlagToString(str, | 1207 SkAddFlagToString(str, |
1213 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B
lurFlag), | 1208 SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_B
lurFlag), |
1214 "HighQuality", &needSeparator); | 1209 "HighQuality", &needSeparator); |
1215 } else { | 1210 } else { |
1216 str->append("None"); | 1211 str->append("None"); |
1217 } | 1212 } |
1218 str->append("))"); | 1213 str->append("))"); |
1219 } | 1214 } |
1220 #endif | 1215 #endif |
1221 | 1216 |
1222 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1217 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1223 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1218 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1224 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1219 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |