| Index: src/effects/SkBlurMaskFilter.cpp
|
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
|
| index c3b60cb71db8537a52d7dd28a567d49cc2ef23de..421573349260ac7d03c2d09a768dd15502fdd371 100644
|
| --- a/src/effects/SkBlurMaskFilter.cpp
|
| +++ b/src/effects/SkBlurMaskFilter.cpp
|
| @@ -22,7 +22,7 @@
|
| #include "GrTexture.h"
|
| #include "GrFragmentProcessor.h"
|
| #include "GrInvariantOutput.h"
|
| -#include "GrStyle.h"
|
| +#include "SkDraw.h"
|
| #include "effects/GrSimpleTextureEffect.h"
|
| #include "glsl/GrGLSLFragmentProcessor.h"
|
| #include "glsl/GrGLSLFragmentShaderBuilder.h"
|
| @@ -56,7 +56,7 @@
|
| const SkMatrix& viewMatrix,
|
| const SkStrokeRec& strokeRec,
|
| const SkPath& path) const override;
|
| - bool directFilterRRectMaskGPU(GrContext*,
|
| + bool directFilterRRectMaskGPU(GrTextureProvider* texProvider,
|
| GrDrawContext* drawContext,
|
| GrPaint* grp,
|
| const GrClip&,
|
| @@ -910,7 +910,7 @@
|
| class GrRRectBlurEffect : public GrFragmentProcessor {
|
| public:
|
|
|
| - static sk_sp<GrFragmentProcessor> Make(GrContext*, float sigma, const SkRRect&);
|
| + static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*, float sigma, const SkRRect&);
|
|
|
| virtual ~GrRRectBlurEffect() {};
|
| const char* name() const override { return "GrRRectBlur"; }
|
| @@ -939,109 +939,13 @@
|
| typedef GrFragmentProcessor INHERITED;
|
| };
|
|
|
| -bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect,
|
| - SkScalar sigma,
|
| - SkRRect* rrectToDraw,
|
| - SkISize* widthHeight,
|
| - SkScalar xs[4],
|
| - int* numXs,
|
| - SkScalar ys[4],
|
| - int* numYs) {
|
| - unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f);
|
| -
|
| - const SkRect& orig = rrect.getBounds();
|
| - const SkVector& radiiUL = rrect.radii(SkRRect::kUpperLeft_Corner);
|
| - const SkVector& radiiUR = rrect.radii(SkRRect::kUpperRight_Corner);
|
| - const SkVector& radiiLR = rrect.radii(SkRRect::kLowerRight_Corner);
|
| - const SkVector& radiiLL = rrect.radii(SkRRect::kLowerLeft_Corner);
|
| -
|
| - const int left = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUL.fX, radiiLL.fX));
|
| - const int top = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUL.fY, radiiUR.fY));
|
| - const int right = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUR.fX, radiiLR.fX));
|
| - const int bot = SkScalarCeilToInt(SkTMax<SkScalar>(radiiLL.fY, radiiLR.fY));
|
| -
|
| - // This is a conservative check for nine-patchability
|
| - if (orig.fLeft + left + blurRadius >= orig.fRight - right - blurRadius ||
|
| - orig.fTop + top + blurRadius >= orig.fBottom - bot - blurRadius) {
|
| - return false;
|
| - }
|
| -
|
| - int newRRWidth, newRRHeight;
|
| -
|
| - // 3x3 case
|
| - newRRWidth = 2*blurRadius + left + right + 1;
|
| - newRRHeight = 2*blurRadius + top + bot + 1;
|
| - widthHeight->fWidth = newRRWidth + 2 * blurRadius;
|
| - widthHeight->fHeight = newRRHeight + 2 * blurRadius;
|
| - // TODO: need to return non-normalized indices
|
| - xs[0] = 0.0f;
|
| - xs[1] = (blurRadius + left) / (float) widthHeight->fWidth;
|
| - xs[2] = (blurRadius + left + 1.0f) / widthHeight->fWidth;
|
| - xs[3] = 1.0f;
|
| - *numXs = 4;
|
| - ys[0] = 0.0f;
|
| - ys[1] = (blurRadius + top) / (float) widthHeight->fHeight;
|
| - ys[2] = (blurRadius + top + 1.0f) / widthHeight->fHeight;
|
| - ys[3] = 1.0f;
|
| - *numYs = 4;
|
| -
|
| - const SkRect newRect = SkRect::MakeXYWH(SkIntToScalar(blurRadius), SkIntToScalar(blurRadius),
|
| - SkIntToScalar(newRRWidth), SkIntToScalar(newRRHeight));
|
| - SkVector newRadii[4];
|
| - newRadii[0] = { SkScalarCeilToScalar(radiiUL.fX), SkScalarCeilToScalar(radiiUL.fY) };
|
| - newRadii[1] = { SkScalarCeilToScalar(radiiUR.fX), SkScalarCeilToScalar(radiiUR.fY) };
|
| - newRadii[2] = { SkScalarCeilToScalar(radiiLR.fX), SkScalarCeilToScalar(radiiLR.fY) };
|
| - newRadii[3] = { SkScalarCeilToScalar(radiiLL.fX), SkScalarCeilToScalar(radiiLL.fY) };
|
| -
|
| - rrectToDraw->setRectRadii(newRect, newRadii);
|
| - return true;
|
| -}
|
| -
|
| -static sk_sp<GrTexture> make_rrect_blur_mask(GrContext* context,
|
| - const SkRRect& rrect,
|
| - float sigma) {
|
| - 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;
|
| - }
|
| -
|
| - GrPaint grPaint;
|
| -
|
| - dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::SimpleFill());
|
| -
|
| - sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context,
|
| - dc->asTexture().release(),
|
| - nullptr,
|
| - SkIRect::MakeWH(size.fWidth,
|
| - size.fHeight),
|
| - nullptr,
|
| - sigma, sigma, SkBackingFit::kExact));
|
| - if (!dc2) {
|
| - return nullptr;
|
| - }
|
| -
|
| - return dc2->asTexture();
|
| -}
|
| -
|
| -sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sigma,
|
| - const SkRRect& rrect) {
|
| +
|
| +sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrTextureProvider* texProvider, float sigma,
|
| + const SkRRect& rrect) {
|
| if (rrect.isCircle()) {
|
| - return GrCircleBlurFragmentProcessor::Make(context->textureProvider(),
|
| - rrect.rect(), sigma);
|
| - }
|
| -
|
| - // TODO: loosen this up
|
| + return GrCircleBlurFragmentProcessor::Make(texProvider, rrect.rect(), sigma);
|
| + }
|
| +
|
| if (!rrect.isSimpleCircular()) {
|
| return nullptr;
|
| }
|
| @@ -1064,17 +968,55 @@
|
| builder[1] = cornerRadius;
|
| builder.finish();
|
|
|
| - sk_sp<GrTexture> blurNinePatchTexture(
|
| - context->textureProvider()->findAndRefTextureByUniqueKey(key));
|
| + SkAutoTUnref<GrTexture> blurNinePatchTexture(texProvider->findAndRefTextureByUniqueKey(key));
|
|
|
| if (!blurNinePatchTexture) {
|
| - blurNinePatchTexture = make_rrect_blur_mask(context, rrect, sigma);
|
| + SkMask mask;
|
| +
|
| + unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1;
|
| +
|
| + mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide);
|
| + mask.fFormat = SkMask::kA8_Format;
|
| + mask.fRowBytes = mask.fBounds.width();
|
| + mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize());
|
| + SkAutoMaskFreeImage amfi(mask.fImage);
|
| +
|
| + memset(mask.fImage, 0, mask.computeTotalImageSize());
|
| +
|
| + SkRect smallRect;
|
| + smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSide));
|
| +
|
| + SkRRect smallRRect;
|
| + smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScalar(cornerRadius));
|
| +
|
| + SkPath path;
|
| + path.addRRect(smallRRect);
|
| +
|
| + SkDraw::DrawToMask(path, &mask.fBounds, nullptr, nullptr, &mask,
|
| + SkMask::kJustRenderImage_CreateMode, SkStrokeRec::kFill_InitStyle);
|
| +
|
| + SkMask blurredMask;
|
| + if (!SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle,
|
| + kHigh_SkBlurQuality, nullptr, true)) {
|
| + return nullptr;
|
| + }
|
| +
|
| + unsigned int texSide = smallRectSide + 2*blurRadius;
|
| + GrSurfaceDesc texDesc;
|
| + texDesc.fWidth = texSide;
|
| + texDesc.fHeight = texSide;
|
| + texDesc.fConfig = kAlpha_8_GrPixelConfig;
|
| + texDesc.fIsMipMapped = false;
|
| +
|
| + blurNinePatchTexture.reset(
|
| + texProvider->createTexture(texDesc, SkBudgeted::kYes , blurredMask.fImage, 0));
|
| + SkMask::FreeImage(blurredMask.fImage);
|
| if (!blurNinePatchTexture) {
|
| return nullptr;
|
| }
|
| - context->textureProvider()->assignUniqueKeyToTexture(key, blurNinePatchTexture.get());
|
| - }
|
| - return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture.get()));
|
| + texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture);
|
| + }
|
| + return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture));
|
| }
|
|
|
| void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
|
| @@ -1108,7 +1050,7 @@
|
| SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f);
|
| SkRRect rrect;
|
| rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
|
| - return GrRRectBlurEffect::Make(d->fContext, sigma, rrect);
|
| + return GrRRectBlurEffect::Make(d->fContext->textureProvider(), sigma, rrect);
|
| }
|
|
|
| //////////////////////////////////////////////////////////////////////////////
|
| @@ -1211,7 +1153,7 @@
|
| return new GrGLRRectBlurEffect;
|
| }
|
|
|
| -bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
|
| +bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvider,
|
| GrDrawContext* drawContext,
|
| GrPaint* grp,
|
| const GrClip& clip,
|
| @@ -1230,7 +1172,7 @@
|
|
|
| SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
|
|
|
| - sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma, rrect));
|
| + sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSigma, rrect));
|
| if (!fp) {
|
| return false;
|
| }
|
|
|