| Index: src/effects/SkBlurMaskFilter.cpp
|
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
|
| index 4e469bca9b32f3a80c00c963b201fc9e9a7949a5..aaac57ccc9b287d0e875960da7ca1d44470d61c5 100644
|
| --- a/src/effects/SkBlurMaskFilter.cpp
|
| +++ b/src/effects/SkBlurMaskFilter.cpp
|
| @@ -6,6 +6,7 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| +#include "SkBitmapCache.h"
|
| #include "SkBlurMaskFilter.h"
|
| #include "SkBlurMask.h"
|
| #include "SkGpuBlurUtils.h"
|
| @@ -66,6 +67,14 @@ public:
|
| virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
|
| virtual bool asABlur(BlurRec*) const SK_OVERRIDE;
|
|
|
| + static bool getCachedBlurMask(SkScalar sigma,
|
| + unsigned rectCount,
|
| + const SkRect rects[],
|
| + SkCachedMask &mask);
|
| + static bool getCachedBlurMask(SkScalar sigma,
|
| + const SkRRect rrect,
|
| + SkCachedMask &mask);
|
| +
|
| SK_TO_STRING_OVERRIDE()
|
| SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl)
|
|
|
| @@ -115,6 +124,45 @@ private:
|
|
|
| const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128);
|
|
|
| +bool SkBlurMaskFilterImpl::getCachedBlurMask(SkScalar sigma,
|
| + const SkRRect rrect,
|
| + SkCachedMask &mask) {
|
| + SkBitmap bitmap;
|
| + SkBitmapCache::ID* cacheId = SkBitmapCache::FindAndLock(sigma, rrect, &bitmap);
|
| + if (cacheId) {
|
| + SkAutoLockPixels autoLockPixels(bitmap);
|
| + if (bitmap.getPixels()) {
|
| + mask.fMask.fBounds.set(0, 0, bitmap.width(), bitmap.height());
|
| + mask.fMask.fRowBytes = mask.fMask.fBounds.width();
|
| + mask.fMask.fFormat = SkMask::kA8_Format;
|
| + mask.fMask.fImage = static_cast<uint8_t*>(bitmap.getPixels());
|
| + mask.fCacheId = cacheId;
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool SkBlurMaskFilterImpl::getCachedBlurMask(SkScalar sigma,
|
| + unsigned rectCount,
|
| + const SkRect rects[],
|
| + SkCachedMask &mask) {
|
| + SkBitmap bitmap;
|
| + SkBitmapCache::ID* cacheId = SkBitmapCache::FindAndLock(sigma, rectCount, rects, &bitmap);
|
| + if (cacheId) {
|
| + SkAutoLockPixels autoLockPixels(bitmap);
|
| + if (bitmap.getPixels()) {
|
| + mask.fMask.fBounds.set(0, 0, bitmap.width(), bitmap.height());
|
| + mask.fMask.fRowBytes = mask.fMask.fBounds.width();
|
| + mask.fMask.fFormat = SkMask::kA8_Format;
|
| + mask.fMask.fImage = static_cast<uint8_t*>(bitmap.getPixels());
|
| + mask.fCacheId = cacheId;
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| SkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32_t flags) {
|
| if (!SkScalarIsFinite(sigma) || sigma <= 0) {
|
| return NULL;
|
| @@ -368,10 +416,21 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
|
| radii[SkRRect::kLowerLeft_Corner] = LL;
|
| smallRR.setRectRadii(smallR, radii);
|
|
|
| + SkScalar sigma = this->computeXformedSigma(matrix);
|
| + SkCachedMask cachedBlurMask;
|
| + cachedBlurMask.fCacheId = NULL;
|
| + if (getCachedBlurMask(sigma, rrect, cachedBlurMask)) {
|
| + patch->fCachedMask = cachedBlurMask;
|
| + patch->fOuterRect = dstM.fBounds;
|
| + patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1;
|
| + patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1;
|
| + return kTrue_FilterReturn;
|
| + }
|
| +
|
| bool analyticBlurWorked = false;
|
| if (c_analyticBlurRRect) {
|
| analyticBlurWorked =
|
| - this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin,
|
| + this->filterRRectMask(&(patch->fCachedMask.fMask), smallRR, matrix, &margin,
|
| SkMask::kComputeBoundsAndRenderImage_CreateMode);
|
| }
|
|
|
| @@ -382,15 +441,21 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
|
|
|
| SkAutoMaskFreeImage amf(srcM.fImage);
|
|
|
| - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
|
| + if (!this->filterMask(&(patch->fCachedMask.fMask), srcM, matrix, &margin)) {
|
| return kFalse_FilterReturn;
|
| }
|
| }
|
|
|
| - patch->fMask.fBounds.offsetTo(0, 0);
|
| + patch->fCachedMask.fMask.fBounds.offsetTo(0, 0);
|
| patch->fOuterRect = dstM.fBounds;
|
| patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1;
|
| patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1;
|
| + if (!cachedBlurMask.fCacheId) {
|
| + SkBitmap bitmap;
|
| + bitmap.installMaskPixels(patch->fCachedMask.fMask);
|
| + patch->fCachedMask.fCacheId = SkBitmapCache::AddAndLock(sigma, rrect, bitmap);
|
| + }
|
| +
|
| return kTrue_FilterReturn;
|
| }
|
|
|
| @@ -470,6 +535,16 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count,
|
| smallH + (innerIR.top() - srcM.fBounds.top()));
|
| }
|
|
|
| + SkScalar sigma = this->computeXformedSigma(matrix);
|
| + SkCachedMask cachedBlurMask;
|
| + cachedBlurMask.fCacheId = NULL;
|
| + if (getCachedBlurMask(sigma, count, rects, cachedBlurMask)) {
|
| + patch->fCachedMask = cachedBlurMask;
|
| + patch->fOuterRect = dstM.fBounds;
|
| + patch->fCenter = center;
|
| + return kTrue_FilterReturn;
|
| + }
|
| +
|
| // +1 so we get a clean, stretchable, center row/col
|
| smallW += 1;
|
| smallH += 1;
|
| @@ -498,21 +573,26 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count,
|
| if (!draw_rects_into_mask(smallR, count, &srcM)) {
|
| return kFalse_FilterReturn;
|
| }
|
| -
|
| SkAutoMaskFreeImage amf(srcM.fImage);
|
|
|
| - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
|
| + if (!this->filterMask(&patch->fCachedMask.fMask, srcM, matrix, &margin)) {
|
| return kFalse_FilterReturn;
|
| }
|
| } else {
|
| - if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin,
|
| + if (!this->filterRectMask(&patch->fCachedMask.fMask, smallR[0], matrix, &margin,
|
| SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
|
| return kFalse_FilterReturn;
|
| }
|
| }
|
| - patch->fMask.fBounds.offsetTo(0, 0);
|
| + patch->fCachedMask.fMask.fBounds.offsetTo(0, 0);
|
| patch->fOuterRect = dstM.fBounds;
|
| patch->fCenter = center;
|
| + if (!cachedBlurMask.fCacheId) {
|
| + SkBitmap bitmap;
|
| + bitmap.installMaskPixels(patch->fCachedMask.fMask);
|
| + patch->fCachedMask.fCacheId = SkBitmapCache::AddAndLock(sigma, count, rects, bitmap);
|
| + }
|
| +
|
| return kTrue_FilterReturn;
|
| }
|
|
|
|
|