diff options
author | 2013-03-11 20:16:28 +0000 | |
---|---|---|
committer | 2013-03-11 20:16:28 +0000 | |
commit | 7c5d7b781385c47e5be9a343d60c5b7d33b5b8cd (patch) | |
tree | f37dcfa88e288ccd682879eedb597e8470934208 /src/effects/SkBlurMaskFilter.cpp | |
parent | ed268bfed3205347a90557c5029f37e90cc01956 (diff) |
Plumb fast rectangle blur code into the skia mask filter
Review URL: https://codereview.chromium.org/12387099
git-svn-id: http://skia.googlecode.com/svn/trunk@8074 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects/SkBlurMaskFilter.cpp')
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index c49a785024..3273325570 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -10,6 +10,9 @@ #include "SkBlurMask.h" #include "SkFlattenableBuffers.h" #include "SkMaskFilter.h" +#include "SkBounder.h" +#include "SkRasterClip.h" +#include "SkRTConf.h" class SkBlurMaskFilterImpl : public SkMaskFilter { public: @@ -20,6 +23,7 @@ public: virtual SkMask::Format getFormat() const SK_OVERRIDE; virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, SkIPoint* margin) const SK_OVERRIDE; + virtual BlurType asABlur(BlurInfo*) const SK_OVERRIDE; virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; @@ -29,6 +33,9 @@ protected: virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMatrix&, const SkIRect& clipBounds, NinePatch*) const SK_OVERRIDE; + + bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, + SkIPoint* margin, SkMask::CreateMode createMode) const; private: SkScalar fRadius; @@ -106,6 +113,26 @@ bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, #endif } +bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, + const SkMatrix& matrix, + SkIPoint* margin, SkMask::CreateMode createMode) const{ + SkScalar radius; + if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { + radius = fRadius; + } else { + radius = matrix.mapRadius(fRadius); + } + + // To avoid unseemly allocation requests (esp. for finite platforms like + // handset) we limit the radius so something manageable. (as opposed to + // a request like 10,000) + static const SkScalar MAX_RADIUS = SkIntToScalar(128); + radius = SkMinScalar(radius, MAX_RADIUS); + + return SkBlurMask::BlurRect(dst, r, radius, (SkBlurMask::Style)fBlurStyle, + margin, createMode); +} + #include "SkCanvas.h" static bool drawRectsIntoMask(const SkRect rects[], int count, SkMask* mask) { @@ -150,6 +177,14 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) { r.width() > v || r.height() > v; } +SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", +#ifdef SK_IGNORE_FAST_RECT_BLUR + false, +#else + true, +#endif + "Use the faster analytic blur approach for ninepatch rects" ); + SkMaskFilter::FilterReturn SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, const SkMatrix& matrix, @@ -177,7 +212,18 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, srcM.fImage = NULL; srcM.fFormat = SkMask::kA8_Format; srcM.fRowBytes = 0; - if (!this->filterMask(&dstM, srcM, matrix, &margin)) { + + bool filterResult = false; + if (count == 1 && c_analyticBlurNinepatch) { + // special case for fast rect blur + // don't actually do the blur the first time, just compute the correct size + filterResult = this->filterRectMask(&dstM, rects[0], matrix, &margin, + SkMask::kJustComputeBounds_CreateMode); + } else { + filterResult = this->filterMask(&dstM, srcM, matrix, &margin); + } + + if (!filterResult) { return kFalse_FilterReturn; } @@ -235,14 +281,21 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, SkASSERT(!smallR[1].isEmpty()); } - if (!drawRectsIntoMask(smallR, count, &srcM)) { - return kFalse_FilterReturn; - } + if (count > 1 || !c_analyticBlurNinepatch) { + if (!drawRectsIntoMask(smallR, count, &srcM)) { + return kFalse_FilterReturn; + } - SkAutoMaskFreeImage amf(srcM.fImage); + SkAutoMaskFreeImage amf(srcM.fImage); - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { - return kFalse_FilterReturn; + if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { + return kFalse_FilterReturn; + } + } else { + if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, + SkMask::kComputeBoundsAndRenderImage_CreateMode)) { + return kFalse_FilterReturn; + } } patch->fMask.fBounds.offsetTo(0, 0); patch->fOuterRect = dstM.fBounds; |