Chromium Code Reviews| 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; |
| } |