Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: src/effects/SkBlurMask.cpp

Issue 471473002: Optimize CSS box-shadow performance (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: store SkMask and SkCachedData in cache Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698