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

Unified Diff: src/effects/SkBlurMask.cpp

Issue 119343003: Fast blurred rectangles on GPU (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: handle null input color, and some comments from Brian Created 7 years 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 d2484c84b79511a54f8aea4a5d4a5769cd826698..efe3cb6d7031762e58d05ad3650d6d7c5b68a274 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( 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,28 @@ static inline unsigned int profile_lookup( unsigned int *profile, int loc, int b
return profile[ox];
}
+void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, uint8_t *profile, unsigned int profile_size,
+ unsigned int width, float 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 +779,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) {
@@ -787,7 +809,7 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
for (int x = 0 ; x < dstWidth ; ++x) {
if (profile_size <= sw) {
- horizontalScanline[x] = profile_lookup(profile, x, dstWidth, w);
+ horizontalScanline[x] = ProfileLookup(profile, x, dstWidth, w);
} else {
float span = float(sw)/(2*sigma);
float giX = 1.5f - (x+.5f)/(2*sigma);
@@ -796,9 +818,9 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
}
for (int y = 0 ; y < dstHeight ; ++y) {
- unsigned int profile_y;
+ uint8_t profile_y;
if (profile_size <= sh) {
- profile_y = profile_lookup(profile, y, dstHeight, h);
+ profile_y = ProfileLookup(profile, y, dstHeight, h);
} else {
float span = float(sh)/(2*sigma);
float giY = 1.5f - (y+.5f)/(2*sigma);

Powered by Google App Engine
This is Rietveld 408576698