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

Unified Diff: src/effects/SkBlurMask.cpp

Issue 12387099: first attempt to plumb fast blur code into skia mask filter (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: revert bench changes Created 7 years, 9 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
« no previous file with comments | « src/effects/SkBlurMask.h ('k') | src/effects/SkBlurMaskFilter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/SkBlurMask.cpp
diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp
index 413e8c0690311238dbc17b02f6568b1a0c732c61..d63de8c8c288c4a3e61c204d4e3e06214626af48 100644
--- a/src/effects/SkBlurMask.cpp
+++ b/src/effects/SkBlurMask.cpp
@@ -1200,20 +1200,22 @@ static float gaussianIntegral(float x) {
static int compute_profile(SkScalar radius, unsigned int **profile_out) {
int size = SkScalarRoundToInt(radius * 3);
- int center = size >> 1;
-
- unsigned int *profile = SkNEW_ARRAY(unsigned int, size);
-
- float invr = 1.f/radius;
+
+ if (profile_out) {
+ int center = size >> 1;
+ unsigned int *profile = SkNEW_ARRAY(unsigned int, size);
+
+ float invr = 1.f/radius;
+
+ profile[0] = 255;
+ for (int x = 1 ; x < size ; ++x) {
+ float scaled_x = (center - x - .5f) * invr;
+ float gi = gaussianIntegral(scaled_x);
+ profile[x] = 255 - (uint8_t) (255.f * gi);
+ }
- profile[0] = 255;
- for (int x = 1 ; x < size ; ++x) {
- float scaled_x = (center - x - .5f) * invr;
- float gi = gaussianIntegral(scaled_x);
- profile[x] = 255 - (uint8_t) (255.f * gi);
+ *profile_out = profile;
}
-
- *profile_out = profile;
return size;
}
@@ -1236,16 +1238,16 @@ static inline unsigned int profile_lookup( unsigned int *profile, int loc, int b
bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src,
SkScalar provided_radius, Style style,
- SkIPoint *margin) {
+ SkIPoint *margin, bool perform_blur) {
int profile_size;
- unsigned int *profile;
+ unsigned int *profile = NULL;
float radius = SkScalarToFloat( SkScalarMul( provided_radius, kBlurRadiusFudgeFactor ) );
// adjust blur radius to match interpretation from boxfilter code
radius = (radius + .5f) *2.f;
bungeman-skia 2013/03/11 19:47:41 My eyes... need a space after *
- profile_size = compute_profile( radius, &profile );
+ profile_size = compute_profile( radius, perform_blur ? &profile : NULL );
bungeman-skia 2013/03/11 19:47:41 It feels awkward to have this check here and anoth
SkAutoTDeleteArray<unsigned int> ada(profile);
@@ -1259,89 +1261,96 @@ bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src,
int shadow_right = (int)(src.width()) + pad;
int shadow_bottom = (int)(src.height()) + pad;
- dst->fBounds.set(shadow_left, shadow_top, shadow_right, shadow_bottom);
+ dst->fBounds.set(shadow_left + src.fLeft, shadow_top + src.fTop, shadow_right + src.fRight, shadow_bottom + src.fBottom);
bungeman-skia 2013/03/11 19:47:41 Nit: This line got really long. A few more below.
dst->fRowBytes = dst->fBounds.width();
dst->fFormat = SkMask::kA8_Format;
dst->fImage = NULL;
-
- size_t dstSize = dst->computeImageSize();
- if (0 == dstSize) {
- return false; // too big to allocate, abort
- }
-
+
int sw = SkScalarFloorToInt(src.width());
int sh = SkScalarFloorToInt(src.height());
+
+ if (perform_blur) {
bungeman-skia 2013/03/11 19:47:41 Can we put the else clause under !perform_blur and
+ size_t dstSize = dst->computeImageSize();
+ if (0 == dstSize) {
+ return false; // too big to allocate, abort
+ }
- uint8_t* dp = SkMask::AllocImage(dstSize);
+ uint8_t* dp = SkMask::AllocImage(dstSize);
- dst->fImage = dp;
+ dst->fImage = dp;
- int dstHeight = dst->fBounds.height();
- int dstWidth = dst->fBounds.width();
+ int dstHeight = dst->fBounds.height();
+ int dstWidth = dst->fBounds.width();
- // nearest odd number less than the profile size represents the center
- // of the (2x scaled) profile
- int center = ( profile_size & ~1 ) - 1;
+ // nearest odd number less than the profile size represents the center
+ // of the (2x scaled) profile
+ int center = ( profile_size & ~1 ) - 1;
- int w = sw - center;
- int h = sh - center;
+ int w = sw - center;
+ int h = sh - center;
- uint8_t *outptr = dp;
+ uint8_t *outptr = dp;
- SkAutoTMalloc<uint8_t> horizontalScanline(dstWidth);
+ SkAutoTMalloc<uint8_t> horizontalScanline(dstWidth);
- for (int x = 0 ; x < dstWidth ; ++x) {
- if (profile_size <= sw) {
- horizontalScanline[x] = profile_lookup(profile, x, dstWidth, w);
- } else {
- float span = float(sw)/radius;
- float giX = 1.5f - (x+.5f)/radius;
- horizontalScanline[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span)));
+ for (int x = 0 ; x < dstWidth ; ++x) {
+ if (profile_size <= sw) {
+ horizontalScanline[x] = profile_lookup(profile, x, dstWidth, w);
+ } else {
+ float span = float(sw)/radius;
+ float giX = 1.5f - (x+.5f)/radius;
+ horizontalScanline[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span)));
+ }
}
- }
- for (int y = 0 ; y < dstHeight ; ++y) {
- unsigned int profile_y;
- if (profile_size <= sh) {
- profile_y = profile_lookup(profile, y, dstHeight, h);
- } else {
- float span = float(sh)/radius;
- float giY = 1.5f - (y+.5f)/radius;
- profile_y = (uint8_t) (255 * (gaussianIntegral(giY) - gaussianIntegral(giY + span)));
- }
+ for (int y = 0 ; y < dstHeight ; ++y) {
+ unsigned int profile_y;
+ if (profile_size <= sh) {
+ profile_y = profile_lookup(profile, y, dstHeight, h);
+ } else {
+ float span = float(sh)/radius;
+ float giY = 1.5f - (y+.5f)/radius;
+ profile_y = (uint8_t) (255 * (gaussianIntegral(giY) - gaussianIntegral(giY + span)));
+ }
- for (int x = 0 ; x < dstWidth ; x++) {
- unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], profile_y);
- *(outptr++) = maskval;
+ for (int x = 0 ; x < dstWidth ; x++) {
+ unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], profile_y);
+ *(outptr++) = maskval;
+ }
}
- }
- if (style == kInner_Style) {
- // now we allocate the "real" dst, mirror the size of src
- size_t srcSize = (size_t)(src.width() * src.height());
- if (0 == srcSize) {
- return false; // too big to allocate, abort
- }
- dst->fImage = SkMask::AllocImage(srcSize);
- 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 (style == kInner_Style) {
+ // now we allocate the "real" dst, mirror the size of src
+ size_t srcSize = (size_t)(src.width() * src.height());
+ if (0 == srcSize) {
+ return false; // too big to allocate, abort
+ }
+ dst->fImage = SkMask::AllocImage(srcSize);
+ 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);
- dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds
- dst->fRowBytes = sw;
+ dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds
+ dst->fRowBytes = sw;
- } else if (style == kOuter_Style) {
- for (int y = pad ; y < dstHeight-pad ; y++) {
- uint8_t *dst_scanline = dp + y*dstWidth + pad;
- memset(dst_scanline, 0, sw);
+ } else if (style == kOuter_Style) {
+ for (int y = pad ; y < dstHeight-pad ; y++) {
+ uint8_t *dst_scanline = dp + y*dstWidth + pad;
+ memset(dst_scanline, 0, sw);
+ }
+ }
+ // normal and solid styles are the same for analytic rect blurs, so don't
+ // need to handle solid specially.
+ } else {
+ if (style == kInner_Style) {
+ dst->fBounds.set(0, 0, sw, sh); // restore trimmed bounds
+ dst->fRowBytes = sw;
}
}
- // normal and solid styles are the same for analytic rect blurs, so don't
- // need to handle solid specially.
return true;
}
« no previous file with comments | « src/effects/SkBlurMask.h ('k') | src/effects/SkBlurMaskFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698