| Index: src/effects/SkBlurMaskFilter.cpp
|
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
|
| index c49a785024da8e20e8b713f2bd7ddbf0a7626bb9..327332557093d0285ab58fc02747cf3a4e56b8d1 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;
|
|
|