Chromium Code Reviews| Index: src/effects/SkBlurMaskFilter.cpp |
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp |
| index 79cf7e64949f21346990ba07560ba74961308029..8370a86cf0623d8c105d0fcddc68dc5105a321f0 100644 |
| --- a/src/effects/SkBlurMaskFilter.cpp |
| +++ b/src/effects/SkBlurMaskFilter.cpp |
| @@ -11,6 +11,7 @@ |
| #include "SkGpuBlurUtils.h" |
| #include "SkReadBuffer.h" |
| #include "SkWriteBuffer.h" |
| +#include "SkMaskCache.h" |
| #include "SkMaskFilter.h" |
| #include "SkRRect.h" |
| #include "SkRTConf.h" |
| @@ -40,7 +41,7 @@ public: |
| // overrides from SkMaskFilter |
| virtual SkMask::Format getFormat() const SK_OVERRIDE; |
| virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, |
| - SkIPoint* margin) const SK_OVERRIDE; |
| + SkIPoint* margin, SkCachedData** data) const SK_OVERRIDE; |
| #if SK_SUPPORT_GPU |
| virtual bool canFilterMaskGPU(const SkRect& devBounds, |
| @@ -79,9 +80,9 @@ protected: |
| NinePatch*) const SK_OVERRIDE; |
| bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, |
| - SkIPoint* margin, SkMask::CreateMode createMode) const; |
| + SkIPoint* margin, SkMask::CreateMode createMode, SkCachedData** data) const; |
| bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, |
| - SkIPoint* margin, SkMask::CreateMode createMode) const; |
| + SkIPoint* margin, SkMask::CreateMode createMode, SkCachedData** data) const; |
| private: |
| // To avoid unseemly allocation requests (esp. for finite platforms like |
| @@ -158,26 +159,26 @@ bool SkBlurMaskFilterImpl::asABlur(BlurRec* rec) const { |
| bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, |
| const SkMatrix& matrix, |
| - SkIPoint* margin) const{ |
| + SkIPoint* margin, SkCachedData** data) const{ |
| SkScalar sigma = this->computeXformedSigma(matrix); |
| - return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, this->getQuality(), margin); |
| + return SkBlurMask::BoxBlur(dst, data, src, sigma, fBlurStyle, this->getQuality(), margin); |
| } |
| bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, |
| const SkMatrix& matrix, |
| - SkIPoint* margin, SkMask::CreateMode createMode) const{ |
| + SkIPoint* margin, SkMask::CreateMode createMode, SkCachedData** data) const{ |
| SkScalar sigma = computeXformedSigma(matrix); |
| - return SkBlurMask::BlurRect(sigma, dst, r, fBlurStyle, |
| + return SkBlurMask::BlurRect(sigma, dst, data, r, fBlurStyle, |
| margin, createMode); |
| } |
| bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, |
| const SkMatrix& matrix, |
| - SkIPoint* margin, SkMask::CreateMode createMode) const{ |
| + SkIPoint* margin, SkMask::CreateMode createMode, SkCachedData** data) const{ |
| SkScalar sigma = computeXformedSigma(matrix); |
| - return SkBlurMask::BlurRRect(sigma, dst, r, fBlurStyle, |
| + return SkBlurMask::BlurRRect(sigma, dst, data, r, fBlurStyle, |
| margin, createMode); |
| } |
| @@ -317,11 +318,11 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
| // 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); |
| + SkMask::kJustComputeBounds_CreateMode, &patch->fData); |
|
reed1
2014/10/21 21:29:49
If we are just computing bounds, shouldn't we pass
|
| } |
| if (!filterResult) { |
| - filterResult = this->filterMask(&dstM, srcM, matrix, &margin); |
| + filterResult = this->filterMask(&dstM, srcM, matrix, &margin, &patch->fData); |
| } |
| if (!filterResult) { |
| @@ -368,11 +369,19 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
| radii[SkRRect::kLowerLeft_Corner] = LL; |
| smallRR.setRectRadii(smallR, radii); |
| + SkScalar sigma = this->computeXformedSigma(matrix); |
| + if ((patch->fData = SkMaskCache::FindAndRef(sigma, rrect, &patch->fMask))) { |
| + patch->fOuterRect = dstM.fBounds; |
| + patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
|
reed1
2014/10/21 21:29:49
Can we set these fields of the patch once, before
|
| + patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| + return kTrue_FilterReturn; |
| + } |
| + |
| bool analyticBlurWorked = false; |
| if (c_analyticBlurRRect) { |
| analyticBlurWorked = |
| this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
| - SkMask::kComputeBoundsAndRenderImage_CreateMode); |
| + SkMask::kComputeBoundsAndRenderImage_CreateMode, &patch->fData); |
| } |
| if (!analyticBlurWorked) { |
| @@ -382,7 +391,7 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
| SkAutoMaskFreeImage amf(srcM.fImage); |
| - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
| + if (!this->filterMask(&patch->fMask, srcM, matrix, &margin, &patch->fData)) { |
| return kFalse_FilterReturn; |
| } |
| } |
| @@ -391,6 +400,8 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
| patch->fOuterRect = dstM.fBounds; |
| patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
| patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| + SkMaskCache::Add(sigma, rrect, patch->fMask, patch->fData); |
| + |
| return kTrue_FilterReturn; |
| } |
| @@ -429,9 +440,9 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| // 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); |
| + SkMask::kJustComputeBounds_CreateMode, &patch->fData); |
|
reed1
2014/10/21 21:29:49
again, can/should we pass NULL for the last parame
|
| } else { |
| - filterResult = this->filterMask(&dstM, srcM, matrix, &margin); |
| + filterResult = this->filterMask(&dstM, srcM, matrix, &margin, &patch->fData); |
| } |
| if (!filterResult) { |
| @@ -470,6 +481,14 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| smallH + (innerIR.top() - srcM.fBounds.top())); |
| } |
| + SkScalar sigma = this->computeXformedSigma(matrix); |
| + if ((patch->fData = SkMaskCache::FindAndRef(sigma, count, rects, &patch->fMask))) { |
| + patch->fOuterRect = dstM.fBounds; |
|
reed1
2014/10/21 21:29:49
again, can we share setup code for patch between h
|
| + patch->fCenter = center; |
| + |
| + return kTrue_FilterReturn; |
| + } |
| + |
| // +1 so we get a clean, stretchable, center row/col |
| smallW += 1; |
| smallH += 1; |
| @@ -501,18 +520,20 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| SkAutoMaskFreeImage amf(srcM.fImage); |
| - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
| + if (!this->filterMask(&patch->fMask, srcM, matrix, &margin, &patch->fData)) { |
| return kFalse_FilterReturn; |
| } |
| } else { |
| if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, |
| - SkMask::kComputeBoundsAndRenderImage_CreateMode)) { |
| + SkMask::kComputeBoundsAndRenderImage_CreateMode, &patch->fData)) { |
| return kFalse_FilterReturn; |
| } |
| } |
| patch->fMask.fBounds.offsetTo(0, 0); |
| patch->fOuterRect = dstM.fBounds; |
| patch->fCenter = center; |
| + SkMaskCache::Add(sigma, count, rects, patch->fMask, patch->fData); |
| + |
| return kTrue_FilterReturn; |
| } |
| @@ -915,7 +936,7 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma, |
| SkDraw::DrawToMask(path, &mask.fBounds, NULL, NULL, &mask, SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_Style); |
| SkMask blurred_mask; |
| - SkBlurMask::BoxBlur(&blurred_mask, mask, sigma, kNormal_SkBlurStyle, kHigh_SkBlurQuality, NULL, true ); |
| + SkBlurMask::BoxBlur(&blurred_mask, NULL, mask, sigma, kNormal_SkBlurStyle, kHigh_SkBlurQuality, NULL, true ); |
| blurNinePatchTexture = context->createTexture(¶ms, texDesc, blurRRectNinePatchID, blurred_mask.fImage, 0); |
| SkMask::FreeImage(blurred_mask.fImage); |