Chromium Code Reviews| Index: src/effects/SkBlurMaskFilter.cpp |
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp |
| index 6f69aaf4ab02481e299e5deee7573bd08216fac4..51eaa2668d9bff98642a97650a2e8bc4efed8e7b 100644 |
| --- a/src/effects/SkBlurMaskFilter.cpp |
| +++ b/src/effects/SkBlurMaskFilter.cpp |
| @@ -257,6 +257,61 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) { |
| r.width() > v || r.height() > v; |
| } |
| +#include "SkMaskCache.h" |
| + |
| +static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) { |
| + const size_t size = data->size(); |
| +#ifdef SK_DEBUG |
| + const size_t computed_size = mask->computeTotalImageSize(); |
| + SkASSERT(computed_size <= size); |
|
mtklein
2014/10/23 18:18:10
Might just
SkASSERT(mask->computeTotalImageSize()
reed1
2014/10/23 19:22:51
Done.
|
| +#endif |
| + |
| + mask->fImage = SkMask::AllocImage(size); |
| + if (mask->fImage) { |
| + memcpy(mask->fImage, data->data(), size); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) { |
| + const size_t size = mask.computeTotalImageSize(); |
| + SkCachedData* data = SkResourceCache::NewCachedData(size); |
| + if (data) { |
| + memcpy(data->writable_data(), mask.fImage, size); |
| + return data; |
| + } |
| + return NULL; |
| +} |
| + |
| +static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style, |
| + SkBlurQuality quality, const SkRRect& rrect) { |
| + SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, quality, rrect, mask)); |
| + return data.get() && copy_cacheddata_to_mask(data, mask); |
| +} |
| + |
| +static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle style, |
| + SkBlurQuality quality, const SkRRect& rrect) { |
| + SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); |
| + if (data.get()) { |
| + SkMaskCache::Add(sigma, style, quality, rrect, mask, data); |
| + } |
| +} |
| + |
| +static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style, |
| + SkBlurQuality quality, const SkRect rects[], int count) { |
| + SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, quality, rects, count, mask)); |
| + return data.get() && copy_cacheddata_to_mask(data, mask); |
| +} |
| + |
| +static void add_cached_rects(const SkMask& mask, SkScalar sigma, SkBlurStyle style, |
| + SkBlurQuality quality, const SkRect rects[], int count) { |
| + SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); |
| + if (data.get()) { |
| + SkMaskCache::Add(sigma, style, quality, rects, count, mask, data); |
| + } |
| +} |
| + |
| #ifdef SK_IGNORE_FAST_RRECT_BLUR |
| SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", false, "Use the faster analytic blur approach for ninepatch rects" ); |
| #else |
| @@ -368,23 +423,27 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma |
| radii[SkRRect::kLowerLeft_Corner] = LL; |
| smallRR.setRectRadii(smallR, radii); |
| - bool analyticBlurWorked = false; |
| - if (c_analyticBlurRRect) { |
| - analyticBlurWorked = |
| - this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
| - SkMask::kComputeBoundsAndRenderImage_CreateMode); |
| - } |
| - |
| - if (!analyticBlurWorked) { |
| - if (!draw_rrect_into_mask(smallRR, &srcM)) { |
| - return kFalse_FilterReturn; |
| + const SkScalar sigma = this->computeXformedSigma(matrix); |
| + if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR)) { |
| + 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; |
| + } |
| } |
| + add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR); |
| } |
| patch->fMask.fBounds.offsetTo(0, 0); |
| @@ -494,21 +553,25 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| SkASSERT(!smallR[1].isEmpty()); |
| } |
| - if (count > 1 || !c_analyticBlurNinepatch) { |
| - if (!draw_rects_into_mask(smallR, count, &srcM)) { |
| - return kFalse_FilterReturn; |
| - } |
| - |
| - SkAutoMaskFreeImage amf(srcM.fImage); |
| - |
| - 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; |
| + const SkScalar sigma = this->computeXformedSigma(matrix); |
| + if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(), rects, count)) { |
| + if (count > 1 || !c_analyticBlurNinepatch) { |
| + if (!draw_rects_into_mask(smallR, count, &srcM)) { |
| + return kFalse_FilterReturn; |
| + } |
| + |
| + SkAutoMaskFreeImage amf(srcM.fImage); |
| + |
| + 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; |
| + } |
| } |
| + add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), rects, count); |
| } |
| patch->fMask.fBounds.offsetTo(0, 0); |
| patch->fOuterRect = dstM.fBounds; |