| Index: src/effects/SkBlurMask.cpp
|
| diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp
|
| index 32a3d20d31f33f9dbb4d5ab3b622689ae6e83367..f61536e65affe2b79de5cdc17241fa73f3ee533a 100644
|
| --- a/src/effects/SkBlurMask.cpp
|
| +++ b/src/effects/SkBlurMask.cpp
|
| @@ -671,7 +671,7 @@ static float gaussianIntegral(float x) {
|
| return 0.4375f + (-x3 / 6.0f - 3.0f * x2 * 0.25f - 1.125f * x);
|
| }
|
|
|
| -/* compute_profile allocates and fills in an array of floating
|
| +/* ComputeBlurProfile allocates and fills in an array of floating
|
| point values between 0 and 255 for the profile signature of
|
| a blurred half-plane with the given blur radius. Since we're
|
| going to be doing screened multiplications (i.e., 1 - (1-x)(1-y))
|
| @@ -682,11 +682,11 @@ static float gaussianIntegral(float x) {
|
| memory returned in profile_out.
|
| */
|
|
|
| -static void compute_profile(SkScalar sigma, unsigned int **profile_out) {
|
| +void SkBlurMask::ComputeBlurProfile(SkScalar sigma, uint8_t **profile_out) {
|
| int size = SkScalarCeilToInt(6*sigma);
|
|
|
| int center = size >> 1;
|
| - unsigned int *profile = SkNEW_ARRAY(unsigned int, size);
|
| + uint8_t *profile = SkNEW_ARRAY(uint8_t, size);
|
|
|
| float invr = 1.f/(2*sigma);
|
|
|
| @@ -707,7 +707,7 @@ static void compute_profile(SkScalar sigma, unsigned int **profile_out) {
|
| // Implementation adapted from Michael Herf's approach:
|
| // http://stereopsis.com/shadowrect/
|
|
|
| -static inline unsigned int profile_lookup( unsigned int *profile, int loc, int blurred_width, int sharp_width ) {
|
| +uint8_t SkBlurMask::ProfileLookup(const uint8_t *profile, int loc, int blurred_width, int sharp_width) {
|
| int dx = SkAbs32(((loc << 1) + 1) - blurred_width) - sharp_width; // how far are we from the original edge?
|
| int ox = dx >> 1;
|
| if (ox < 0) {
|
| @@ -717,6 +717,30 @@ static inline unsigned int profile_lookup( unsigned int *profile, int loc, int b
|
| return profile[ox];
|
| }
|
|
|
| +void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile,
|
| + unsigned int width, SkScalar sigma) {
|
| +
|
| + unsigned int profile_size = SkScalarCeilToInt(6*sigma);
|
| + SkAutoTMalloc<uint8_t> horizontalScanline(width);
|
| +
|
| + unsigned int sw = width - profile_size;
|
| + // 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;
|
| +
|
| + for (unsigned int x = 0 ; x < width ; ++x) {
|
| + if (profile_size <= sw) {
|
| + pixels[x] = ProfileLookup(profile, x, width, w);
|
| + } else {
|
| + float span = float(sw)/(2*sigma);
|
| + float giX = 1.5f - (x+.5f)/(2*sigma);
|
| + pixels[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span)));
|
| + }
|
| + }
|
| +}
|
| +
|
| bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src,
|
| SkScalar radius, Style style,
|
| SkIPoint *margin, SkMask::CreateMode createMode) {
|
| @@ -757,10 +781,10 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
|
| }
|
| return true;
|
| }
|
| - unsigned int *profile = NULL;
|
| + uint8_t *profile = NULL;
|
|
|
| - compute_profile(sigma, &profile);
|
| - SkAutoTDeleteArray<unsigned int> ada(profile);
|
| + ComputeBlurProfile(sigma, &profile);
|
| + SkAutoTDeleteArray<uint8_t> ada(profile);
|
|
|
| size_t dstSize = dst->computeImageSize();
|
| if (0 == dstSize) {
|
| @@ -774,39 +798,17 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
|
| 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;
|
| -
|
| - int w = sw - center;
|
| - int h = sh - center;
|
| -
|
| uint8_t *outptr = dp;
|
|
|
| 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)/(2*sigma);
|
| - float giX = 1.5f - (x+.5f)/(2*sigma);
|
| - horizontalScanline[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegral(giX + span)));
|
| - }
|
| - }
|
| + SkAutoTMalloc<uint8_t> verticalScanline(dstHeight);
|
| +
|
| + ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma);
|
| + ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma);
|
|
|
| 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)/(2*sigma);
|
| - float giY = 1.5f - (y+.5f)/(2*sigma);
|
| - 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);
|
| + unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], verticalScanline[y]);
|
| *(outptr++) = maskval;
|
| }
|
| }
|
|
|