aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-02-14 15:20:41 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-14 20:46:24 +0000
commitcb25659eb152fe89efb7a44147853dda5e62b38d (patch)
tree0c1b9891fcd73a7aa19f8d656baa97a56f41e64b
parent9b009bb069aa81425438d5403a1a29f2d047f77f (diff)
DDL-ify GrRectBlurEffect
This allows the upload of the blur profile to be delayed until the draw is actually executed. Change-Id: I10a7e8fb0edc90ef509c418552740a867f1f3df2 Reviewed-on: https://skia-review.googlesource.com/107354 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
-rw-r--r--src/effects/SkBlurMask.cpp30
-rw-r--r--src/effects/SkBlurMask.h13
-rw-r--r--src/gpu/effects/GrRectBlurEffect.fp24
-rw-r--r--src/gpu/effects/GrRectBlurEffect.h24
4 files changed, 52 insertions, 39 deletions
diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp
index 59d70205c9..297d15c9d5 100644
--- a/src/effects/SkBlurMask.cpp
+++ b/src/effects/SkBlurMask.cpp
@@ -209,22 +209,18 @@ 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
+/* ComputeBlurProfile 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))
all the time, we actually fill in the profile pre-inverted
(already done 255-x).
-
- It's the responsibility of the caller to delete the
- memory returned in profile_out.
*/
-uint8_t* SkBlurMask::ComputeBlurProfile(SkScalar sigma) {
- int size = SkScalarCeilToInt(6*sigma);
+void SkBlurMask::ComputeBlurProfile(uint8_t* profile, int size, SkScalar sigma) {
+ SkASSERT(SkScalarCeilToInt(6*sigma) == size);
int center = size >> 1;
- uint8_t* profile = new uint8_t[size];
float invr = 1.f/(2*sigma);
@@ -234,8 +230,6 @@ uint8_t* SkBlurMask::ComputeBlurProfile(SkScalar sigma) {
float gi = gaussianIntegral(scaled_x);
profile[x] = 255 - (uint8_t) (255.f * gi);
}
-
- return profile;
}
// TODO MAYBE: Maintain a profile cache to avoid recomputing this for
@@ -245,8 +239,10 @@ uint8_t* SkBlurMask::ComputeBlurProfile(SkScalar sigma) {
// 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) {
- int dx = SkAbs32(((loc << 1) + 1) - blurred_width) - sharp_width; // how far are we from the original edge?
+uint8_t SkBlurMask::ProfileLookup(const uint8_t *profile, int loc,
+ int blurredWidth, int sharpWidth) {
+ // how far are we from the original edge?
+ int dx = SkAbs32(((loc << 1) + 1) - blurredWidth) - sharpWidth;
int ox = dx >> 1;
if (ox < 0) {
ox = 0;
@@ -282,9 +278,9 @@ void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile,
bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
const SkRect &src, SkBlurStyle style,
SkIPoint *margin, SkMask::CreateMode createMode) {
- int profile_size = SkScalarCeilToInt(6*sigma);
+ int profileSize = SkScalarCeilToInt(6*sigma);
- int pad = profile_size/2;
+ int pad = profileSize/2;
if (margin) {
margin->set( pad, pad );
}
@@ -312,7 +308,9 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
return true;
}
- std::unique_ptr<uint8_t[]> profile(ComputeBlurProfile(sigma));
+ SkAutoTMalloc<uint8_t> profile(profileSize);
+
+ ComputeBlurProfile(profile, profileSize, sigma);
size_t dstSize = dst->computeImageSize();
if (0 == dstSize) {
@@ -331,8 +329,8 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst,
SkAutoTMalloc<uint8_t> horizontalScanline(dstWidth);
SkAutoTMalloc<uint8_t> verticalScanline(dstHeight);
- ComputeBlurredScanline(horizontalScanline, profile.get(), dstWidth, sigma);
- ComputeBlurredScanline(verticalScanline, profile.get(), dstHeight, sigma);
+ ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma);
+ ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma);
for (int y = 0 ; y < dstHeight ; ++y) {
for (int x = 0 ; x < dstWidth ; x++) {
diff --git a/src/effects/SkBlurMask.h b/src/effects/SkBlurMask.h
index 9da19fab5a..67009b0bb5 100644
--- a/src/effects/SkBlurMask.h
+++ b/src/effects/SkBlurMask.h
@@ -54,8 +54,7 @@ public:
/* Helper functions for analytic rectangle blurs */
/** Look up the intensity of the (one dimnensional) blurred half-plane.
- @param profile The precomputed 1D blur profile; memory allocated by and managed by
- ComputeBlurProfile below.
+ @param profile The precomputed 1D blur profile; initialized by ComputeBlurProfile below.
@param loc the location to look up; The lookup will clamp invalid inputs, but
meaningful data are available between 0 and blurred_width
@param blurred_width The width of the final, blurred rectangle
@@ -63,12 +62,12 @@ public:
*/
static uint8_t ProfileLookup(const uint8_t* profile, int loc, int blurredWidth, int sharpWidth);
- /** Allocate memory for and populate the profile of a 1D blurred halfplane. The caller
- must free the memory. The amount of memory allocated will be exactly 6*sigma bytes.
- @param sigma The standard deviation of the gaussian blur kernel
+ /** Populate the profile of a 1D blurred halfplane.
+ @param profile The 1D table to fill in
+ @param size Should be 6*sigma bytes
+ @param sigma The standard deviation of the gaussian blur kernel
*/
-
- static uint8_t* ComputeBlurProfile(SkScalar sigma);
+ static void ComputeBlurProfile(uint8_t* profile, int size, SkScalar sigma);
/** Compute an entire scanline of a blurred step function. This is a 1D helper that
will produce both the horizontal and vertical profiles of the blurry rectangle.
diff --git a/src/gpu/effects/GrRectBlurEffect.fp b/src/gpu/effects/GrRectBlurEffect.fp
index 762942aaa4..7057a8e173 100644
--- a/src/gpu/effects/GrRectBlurEffect.fp
+++ b/src/gpu/effects/GrRectBlurEffect.fp
@@ -52,16 +52,24 @@ uniform half profileSize;
sk_sp<GrTextureProxy> blurProfile(proxyProvider->findOrCreateProxyByUniqueKey(
key, kTopLeft_GrSurfaceOrigin));
if (!blurProfile) {
- GrSurfaceDesc texDesc;
- texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
- texDesc.fWidth = profileSize;
- texDesc.fHeight = 1;
- texDesc.fConfig = kAlpha_8_GrPixelConfig;
+ SkImageInfo ii = SkImageInfo::MakeA8(profileSize, 1);
- std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
+ SkBitmap bitmap;
+ if (!bitmap.tryAllocPixels(ii)) {
+ return nullptr;
+ }
+
+ SkBlurMask::ComputeBlurProfile(bitmap.getAddr8(0, 0), profileSize, sigma);
+ bitmap.setImmutable();
+
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
+ if (!image) {
+ return nullptr;
+ }
- blurProfile = proxyProvider->createTextureProxy(texDesc, SkBudgeted::kYes,
- profile.get(), 0);
+ blurProfile = proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags,
+ kTopLeft_GrSurfaceOrigin, 1,
+ SkBudgeted::kYes, SkBackingFit::kExact);
if (!blurProfile) {
return nullptr;
}
diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h
index 91177072a1..b6b8a029f1 100644
--- a/src/gpu/effects/GrRectBlurEffect.h
+++ b/src/gpu/effects/GrRectBlurEffect.h
@@ -32,16 +32,24 @@ public:
sk_sp<GrTextureProxy> blurProfile(
proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
if (!blurProfile) {
- GrSurfaceDesc texDesc;
- texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
- texDesc.fWidth = profileSize;
- texDesc.fHeight = 1;
- texDesc.fConfig = kAlpha_8_GrPixelConfig;
+ SkImageInfo ii = SkImageInfo::MakeA8(profileSize, 1);
- std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
+ SkBitmap bitmap;
+ if (!bitmap.tryAllocPixels(ii)) {
+ return nullptr;
+ }
+
+ SkBlurMask::ComputeBlurProfile(bitmap.getAddr8(0, 0), profileSize, sigma);
+ bitmap.setImmutable();
+
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
+ if (!image) {
+ return nullptr;
+ }
- blurProfile =
- proxyProvider->createTextureProxy(texDesc, SkBudgeted::kYes, profile.get(), 0);
+ blurProfile = proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags,
+ kTopLeft_GrSurfaceOrigin, 1,
+ SkBudgeted::kYes, SkBackingFit::kExact);
if (!blurProfile) {
return nullptr;
}