aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/SkBlurMask.cpp
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-28 01:55:24 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-28 01:55:24 +0000
commitdcfa9ff57c009527e589dfc9c9fdc71483fd2f39 (patch)
tree2d35c0ea338b593891fd448ccc9b5fdb8a5daef4 /src/effects/SkBlurMask.cpp
parentc249088061061f46797ab756426346c74e321239 (diff)
Revert of Fast blurred rectangles on GPU (https://codereview.chromium.org/119343003/)
Reason for revert: Two problems: 1. broke compile on Build-Mac10.6-* bots 2. broke GM expectations on many bots We'll need to examine the GM impact before re-landing. I can work with you to do this on Tuesday if you like; just IM or email me. Original issue's description: > Perform the same analytic blur calculation on the GPU that we do on the CPU. Results in significant performance gains when using Ganesh to render drop shadows in Chrome. > > BUG= > > Committed: http://code.google.com/p/skia/source/detail?r=13210 R=bsalomon@google.com, reed@google.com, humper@google.com, rmistry@google.com TBR=bsalomon@google.com, humper@google.com, reed@google.com NOTREECHECKS=true NOTRY=true BUG= Author: epoger@google.com Review URL: https://codereview.chromium.org/140853008 git-svn-id: http://skia.googlecode.com/svn/trunk@13213 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects/SkBlurMask.cpp')
-rw-r--r--src/effects/SkBlurMask.cpp70
1 files changed, 34 insertions, 36 deletions
diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp
index f61536e65a..32a3d20d31 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);
}
-/* ComputeBlurProfile allocates and fills in an array of floating
+/* compute_profile 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.
*/
-void SkBlurMask::ComputeBlurProfile(SkScalar sigma, uint8_t **profile_out) {
+static void compute_profile(SkScalar sigma, unsigned int **profile_out) {
int size = SkScalarCeilToInt(6*sigma);
int center = size >> 1;
- uint8_t *profile = SkNEW_ARRAY(uint8_t, size);
+ unsigned int *profile = SkNEW_ARRAY(unsigned int, size);
float invr = 1.f/(2*sigma);
@@ -707,7 +707,7 @@ void SkBlurMask::ComputeBlurProfile(SkScalar sigma, uint8_t **profile_out) {
// Implementation adapted from Michael Herf's approach:
// http://stereopsis.com/shadowrect/
-uint8_t SkBlurMask::ProfileLookup(const uint8_t *profile, int loc, int blurred_width, int sharp_width) {
+static inline unsigned int profile_lookup( unsigned int *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,30 +717,6 @@ uint8_t SkBlurMask::ProfileLookup(const uint8_t *profile, int loc, int blurred_w
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) {
@@ -781,10 +757,10 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
}
return true;
}
- uint8_t *profile = NULL;
+ unsigned int *profile = NULL;
- ComputeBlurProfile(sigma, &profile);
- SkAutoTDeleteArray<uint8_t> ada(profile);
+ compute_profile(sigma, &profile);
+ SkAutoTDeleteArray<unsigned int> ada(profile);
size_t dstSize = dst->computeImageSize();
if (0 == dstSize) {
@@ -798,17 +774,39 @@ 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);
- SkAutoTMalloc<uint8_t> verticalScanline(dstHeight);
-
- ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma);
- ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma);
+
+ 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)));
+ }
+ }
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], verticalScanline[y]);
+ unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], profile_y);
*(outptr++) = maskval;
}
}