| Index: src/effects/SkBlurMaskFilter.cpp
|
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
|
| index ac21300fe9d4bf9c2e30fb949286ca2c9107fcbb..0e6de9e8a1638bfe2b3f881dd98b252b57cce68c 100644
|
| --- a/src/effects/SkBlurMaskFilter.cpp
|
| +++ b/src/effects/SkBlurMaskFilter.cpp
|
| @@ -1012,45 +1012,60 @@ 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] = SkScalarCeilToInt(xformedSigma-1/6.0f);
|
| +
|
| + 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);
|
| + 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,
|
| @@ -1066,33 +1081,28 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context,
|
| // 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(xformedSigma-1/6.0f);
|
| - unsigned int cornerRadius = SkScalarCeilToInt(devRRect.getSimpleRadii().x());
|
| - if (cornerRadius + blurRadius > devRRect.width()/2 ||
|
| - cornerRadius + blurRadius > devRRect.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, devRRect, xformedSigma, 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(xformedSigma, devRRect,
|
| - blurNinePatchTexture.get()));
|
| +
|
| + return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma,
|
| + devRRect,
|
| + mask.get()));
|
| }
|
|
|
| void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
|
|
|