Chromium Code Reviews| Index: src/effects/SkBlurMask.cpp |
| diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp |
| index bf50845ab6cb1d308562ea44fa279133bcafd46f..a04383359bd24f40db331b0d12f4966823c44939 100644 |
| --- a/src/effects/SkBlurMask.cpp |
| +++ b/src/effects/SkBlurMask.cpp |
| @@ -8,7 +8,9 @@ |
| #include "SkBlurMask.h" |
| +#include "SkCachedData.h" |
| #include "SkMath.h" |
| +#include "SkResourceCache.h" |
| #include "SkTemplates.h" |
| #include "SkEndian.h" |
| @@ -479,7 +481,7 @@ void SkMask_FreeImage(uint8_t* image) { |
| SkMask::FreeImage(image); |
| } |
| -bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, |
| +bool SkBlurMask::BoxBlur(SkMask* dst, SkCachedData** data, const SkMask& src, |
| SkScalar sigma, SkBlurStyle style, SkBlurQuality quality, |
| SkIPoint* margin, bool force_quality) { |
| @@ -541,8 +543,14 @@ bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, |
| int sw = src.fBounds.width(); |
| int sh = src.fBounds.height(); |
| const uint8_t* sp = src.fImage; |
| - uint8_t* dp = SkMask::AllocImage(dstSize); |
| - SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp); |
| + uint8_t* dp = NULL; |
| + SkCachedData* tmpData = NULL; |
| + if (NULL == data) { |
|
reed1
2014/10/21 21:32:55
we have to repeat this pattern pretty often. This
|
| + dp = SkMask::AllocImage(dstSize); |
| + } else { |
| + tmpData = SkResourceCache::NewCachedData(dstSize); |
| + dp = (uint8_t*)(tmpData->data()); |
| + } |
| // build the blurry destination |
| SkAutoTMalloc<uint8_t> tmpBuffer(dstSize); |
| @@ -582,25 +590,45 @@ bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, |
| } |
| dst->fImage = dp; |
| + if (data) { |
| + *data = tmpData; |
| + (*data)->ref(); |
| + } |
| // if need be, alloc the "real" dst (same size as src) and copy/merge |
| // the blur into it (applying the src) |
| if (style == kInner_SkBlurStyle) { |
| // now we allocate the "real" dst, mirror the size of src |
| size_t srcSize = src.computeImageSize(); |
| if (0 == srcSize) { |
| + if (NULL == data) { |
| + SkMask::FreeImage(dp); |
| + } else { |
| + tmpData->unref(); |
| + (*data)->unref(); |
| + } |
| return false; // too big to allocate, abort |
| } |
| - dst->fImage = SkMask::AllocImage(srcSize); |
| + if (NULL == data) { |
| + dst->fImage = SkMask::AllocImage(srcSize); |
| + } else { |
| + (*data)->unref(); |
| + (*data) = SkResourceCache::NewCachedData(srcSize); |
| + dst->fImage = (uint8_t*)((*data)->data()); |
| + } |
| merge_src_with_blur(dst->fImage, src.fRowBytes, |
| sp, src.fRowBytes, |
| dp + passCount * (rx + ry * dst->fRowBytes), |
| dst->fRowBytes, sw, sh); |
| - SkMask::FreeImage(dp); |
| + if (NULL == data) { |
| + SkMask::FreeImage(dp); |
|
reed1
2014/10/21 21:32:55
We don't have the if/else pattern here. How is thi
|
| + } |
| } else if (style != kNormal_SkBlurStyle) { |
| clamp_with_orig(dp + passCount * (rx + ry * dst->fRowBytes), |
| dst->fRowBytes, sp, src.fRowBytes, sw, sh, style); |
| } |
| - (void)autoCall.detach(); |
| + if (data) { |
| + tmpData->unref(); |
| + } |
| } |
| if (style == kInner_SkBlurStyle) { |
| @@ -737,7 +765,7 @@ void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile, |
| } |
| } |
| -bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, |
| +bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, SkCachedData** data, |
| const SkRect &src, SkBlurStyle style, |
| SkIPoint *margin, SkMask::CreateMode createMode) { |
| int profile_size = SkScalarCeilToInt(6*sigma); |
| @@ -779,9 +807,20 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, |
| return false; // too big to allocate, abort |
| } |
| - uint8_t* dp = SkMask::AllocImage(dstSize); |
| + uint8_t* dp = NULL; |
| + SkCachedData* tmpData = NULL; |
| + if (NULL == data) { |
| + dp = SkMask::AllocImage(dstSize); |
| + } else { |
| + tmpData = SkResourceCache::NewCachedData(dstSize); |
| + dp = (uint8_t*)(tmpData->data()); |
| + } |
| dst->fImage = dp; |
| + if (data) { |
| + *data = tmpData; |
| + (*data)->ref(); |
| + } |
| int dstHeight = dst->fBounds.height(); |
| int dstWidth = dst->fBounds.width(); |
| @@ -805,15 +844,29 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, |
| // now we allocate the "real" dst, mirror the size of src |
| size_t srcSize = (size_t)(src.width() * src.height()); |
| if (0 == srcSize) { |
| + if (NULL == data) { |
| + SkMask::FreeImage(dp); |
| + } else { |
| + tmpData->unref(); |
| + (*data)->unref(); |
| + } |
| return false; // too big to allocate, abort |
| } |
| - dst->fImage = SkMask::AllocImage(srcSize); |
| + if (NULL == data) { |
| + dst->fImage = SkMask::AllocImage(srcSize); |
| + } else { |
| + (*data)->unref(); |
| + (*data) = SkResourceCache::NewCachedData(srcSize); |
| + dst->fImage = (uint8_t*)((*data)->data()); |
| + } |
| for (int y = 0 ; y < sh ; y++) { |
| uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad; |
| uint8_t *inner_scanline = dst->fImage + y*sw; |
| memcpy(inner_scanline, blur_scanline, sw); |
| } |
| - SkMask::FreeImage(dp); |
| + if (NULL == data) { |
| + SkMask::FreeImage(dp); |
| + } |
| dst->fBounds.set(SkScalarRoundToInt(src.fLeft), |
| SkScalarRoundToInt(src.fTop), |
| @@ -832,13 +885,16 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, |
| memset(dst_scanline, 0xff, sw); |
| } |
| } |
| + if (data) { |
| + tmpData->unref(); |
| + } |
| // normal and solid styles are the same for analytic rect blurs, so don't |
| // need to handle solid specially. |
| return true; |
| } |
| -bool SkBlurMask::BlurRRect(SkScalar sigma, SkMask *dst, |
| +bool SkBlurMask::BlurRRect(SkScalar sigma, SkMask *dst, SkCachedData** data, |
| const SkRRect &src, SkBlurStyle style, |
| SkIPoint *margin, SkMask::CreateMode createMode) { |
| // Temporary for now -- always fail, should cause caller to fall back |