Index: src/effects/SkBlurMaskFilter.cpp |
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp |
index 65ed7c543a7ea525dc7175abd4f36649ba824905..070e23e106af07386458623a2cb9cc2d73c79126 100644 |
--- a/src/effects/SkBlurMaskFilter.cpp |
+++ b/src/effects/SkBlurMaskFilter.cpp |
@@ -1012,88 +1012,100 @@ private: |
typedef GrFragmentProcessor INHERITED; |
}; |
-static sk_sp<GrTexture> make_rrect_blur_mask(GrContext* context, |
- const SkRRect& rrect, |
- float sigma, |
- bool doAA) { |
- SkRRect rrectToDraw; |
- SkISize size; |
- SkScalar xs[4], ys[4]; |
- int numXs, numYs; |
- |
- SkBlurMaskFilter::ComputeBlurredRRectParams(rrect, sigma, &rrectToDraw, &size, |
- xs, &numXs, ys, &numYs); |
- |
- // TODO: this could be approx but the texture coords will need to be updated |
- sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact, |
- size.fWidth, size.fHeight, |
- kAlpha_8_GrPixelConfig, nullptr)); |
- if (!dc) { |
- return nullptr; |
+static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context, |
+ const SkRRect& rrectToDraw, |
+ const SkISize& size, |
+ float xformedSigma, |
+ bool doAA) { |
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
+ GrUniqueKey key; |
+ GrUniqueKey::Builder builder(&key, kDomain, 9); |
+ builder[0] = 3*SkScalarCeilToInt(xformedSigma-1/6.0f); |
bsalomon
2016/08/15 13:55:23
Why 3*?
robertphillips
2016/08/15 17:41:37
We/SVG requires that we include 3*sigma of the sha
bsalomon
2016/08/15 17:57:56
Right but does it matter for the key?
robertphillips
2016/08/15 18:30:38
Nope - removed.
|
+ |
+ int index = 1; |
+ for (auto c : { SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner, |
+ SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner }) { |
+ SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) && SkScalarIsInt(rrectToDraw.radii(c).fY)); |
+ builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX); |
bsalomon
2016/08/15 13:55:23
Is the idea to handle non-circular? Right now I th
robertphillips
2016/08/15 17:41:37
The code will soon be able to handle non-simple-ci
|
+ builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY); |
} |
+ builder.finish(); |
+ |
+ sk_sp<GrTexture> mask(context->textureProvider()->findAndRefTextureByUniqueKey(key)); |
+ if (!mask) { |
+ // TODO: this could be approx but the texture coords will need to be updated |
+ sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact, |
+ size.fWidth, size.fHeight, |
+ kAlpha_8_GrPixelConfig, nullptr)); |
+ if (!dc) { |
+ return nullptr; |
+ } |
- GrPaint grPaint; |
- grPaint.setAntiAlias(doAA); |
- |
- dc->clear(nullptr, 0x0, true); |
- dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::SimpleFill()); |
- |
- sk_sp<GrTexture> tex(dc->asTexture()); |
- sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context, |
- tex.get(), |
- nullptr, |
- SkIRect::MakeWH(size.fWidth, |
- size.fHeight), |
- nullptr, |
- sigma, sigma, SkBackingFit::kExact)); |
- if (!dc2) { |
- return nullptr; |
+ GrPaint grPaint; |
+ grPaint.setAntiAlias(doAA); |
+ |
+ dc->clear(nullptr, 0x0, true); |
+ dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::SimpleFill()); |
+ |
+ sk_sp<GrTexture> srcTexture(dc->asTexture()); |
+ sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context, |
+ srcTexture.get(), |
+ nullptr, |
+ SkIRect::MakeWH(size.fWidth, |
+ size.fHeight), |
+ nullptr, |
+ xformedSigma, xformedSigma, |
+ SkBackingFit::kExact)); |
+ if (!dc2) { |
+ return nullptr; |
+ } |
+ |
+ mask = dc2->asTexture(); |
+ SkASSERT(mask); |
+ context->textureProvider()->assignUniqueKeyToTexture(key, mask.get()); |
} |
- return dc2->asTexture(); |
+ return mask; |
} |
-sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sigma, |
- const SkRRect& rrect) { |
- if (rrect.isCircle()) { |
+sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, |
+ float xformedSigma, |
+ const SkRRect& devRRect) { |
+ if (devRRect.isCircle()) { |
return GrCircleBlurFragmentProcessor::Make(context->textureProvider(), |
- rrect.rect(), sigma); |
+ devRRect.rect(), xformedSigma); |
} |
// TODO: loosen this up |
- if (!rrect.isSimpleCircular()) { |
+ if (!devRRect.isSimpleCircular()) { |
return nullptr; |
} |
// Make sure we can successfully ninepatch this rrect -- the blur sigma has to be |
// sufficiently small relative to both the size of the corner radius and the |
// width (and height) of the rrect. |
- |
- unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); |
- unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); |
- if (cornerRadius + blurRadius > rrect.width()/2 || |
- cornerRadius + blurRadius > rrect.height()/2) { |
+ SkRRect rrectToDraw; |
+ SkISize size; |
+ SkScalar ignored[4]; |
+ int ignoredSize; |
+ |
+ bool ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(devRRect, xformedSigma, |
+ &rrectToDraw, &size, |
+ ignored, &ignoredSize, |
+ ignored, &ignoredSize); |
+ if (!ninePatchable) { |
return nullptr; |
} |
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
- GrUniqueKey key; |
- GrUniqueKey::Builder builder(&key, kDomain, 2); |
- builder[0] = blurRadius; |
- builder[1] = cornerRadius; |
- builder.finish(); |
- |
- sk_sp<GrTexture> blurNinePatchTexture( |
- context->textureProvider()->findAndRefTextureByUniqueKey(key)); |
- |
- if (!blurNinePatchTexture) { |
- blurNinePatchTexture = make_rrect_blur_mask(context, rrect, sigma, true); |
- if (!blurNinePatchTexture) { |
- return nullptr; |
- } |
- context->textureProvider()->assignUniqueKeyToTexture(key, blurNinePatchTexture.get()); |
+ sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, size, |
+ xformedSigma, true)); |
+ if (!mask) { |
+ return nullptr; |
} |
- return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture.get())); |
+ |
+ return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, |
+ devRRect, |
+ mask.get())); |
} |
void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { |