Index: src/effects/SkBlurMaskFilter.cpp |
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp |
index 7a202951564f8456267a3b2b11ec5243bdf71d7d..54d4a1b91ce8d980c29118300a68222aeef3611f 100644 |
--- a/src/effects/SkBlurMaskFilter.cpp |
+++ b/src/effects/SkBlurMaskFilter.cpp |
@@ -69,6 +69,8 @@ protected: |
bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, |
SkIPoint* margin, SkMask::CreateMode createMode) const; |
+ bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, |
+ SkIPoint* margin, SkMask::CreateMode createMode) const; |
private: |
// To avoid unseemly allocation requests (esp. for finite platforms like |
@@ -168,6 +170,15 @@ bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, |
margin, createMode); |
} |
+bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, |
+ const SkMatrix& matrix, |
+ SkIPoint* margin, SkMask::CreateMode createMode) const{ |
+ SkScalar sigma = computeXformedSigma(matrix); |
+ |
+ return SkBlurMask::BlurRRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, |
+ margin, createMode); |
+} |
+ |
#include "SkCanvas.h" |
static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { |
@@ -244,6 +255,12 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) { |
r.width() > v || r.height() > v; |
} |
+#ifdef SK_IGNORE_FAST_RRECT_BLUR |
+SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", false, "Use the faster analytic blur approach for ninepatch rects" ); |
+#else |
+SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", true, "Use the faster analytic blur approach for ninepatch round rects" ); |
+#endif |
+ |
SkMaskFilter::FilterReturn |
SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& matrix, |
const SkIRect& clipBounds, |
@@ -293,7 +310,19 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
srcM.fFormat = SkMask::kA8_Format; |
srcM.fRowBytes = 0; |
- if (!this->filterMask(&dstM, srcM, matrix, &margin)) { |
+ bool filterResult = false; |
+ if (c_analyticBlurRRect) { |
+ // special case for fast round rect blur |
+ // don't actually do the blur the first time, just compute the correct size |
+ filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, |
+ SkMask::kJustComputeBounds_CreateMode); |
+ } |
+ |
+ if (!filterResult) { |
+ filterResult = this->filterMask(&dstM, srcM, matrix, &margin); |
+ } |
+ |
+ if (!filterResult) { |
return kFalse_FilterReturn; |
} |
@@ -337,14 +366,23 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
radii[SkRRect::kLowerLeft_Corner] = LL; |
smallRR.setRectRadii(smallR, radii); |
- if (!draw_rrect_into_mask(smallRR, &srcM)) { |
- return kFalse_FilterReturn; |
+ bool analyticBlurWorked = false; |
+ if (c_analyticBlurRRect) { |
+ analyticBlurWorked = |
+ this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
+ SkMask::kComputeBoundsAndRenderImage_CreateMode); |
} |
- SkAutoMaskFreeImage amf(srcM.fImage); |
+ if (!analyticBlurWorked) { |
+ if (!draw_rrect_into_mask(smallRR, &srcM)) { |
+ return kFalse_FilterReturn; |
+ } |
- if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
- return kFalse_FilterReturn; |
+ SkAutoMaskFreeImage amf(srcM.fImage); |
+ |
+ if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
+ return kFalse_FilterReturn; |
+ } |
} |
patch->fMask.fBounds.offsetTo(0, 0); |