Chromium Code Reviews| 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 { |