| Index: src/effects/SkBlurMaskFilter.cpp
|
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
|
| index f66cb9c8dbda657061bb06bafd77e1c38dbd80a1..e0358bfb1b56ac6cbdee373693cd123ff5e165da 100644
|
| --- a/src/effects/SkBlurMaskFilter.cpp
|
| +++ b/src/effects/SkBlurMaskFilter.cpp
|
| @@ -37,7 +37,7 @@ SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) {
|
|
|
| class SkBlurMaskFilterImpl : public SkMaskFilter {
|
| public:
|
| - SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags);
|
| + SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, const SkRect& occluder, uint32_t flags);
|
|
|
| // overrides from SkMaskFilter
|
| SkMask::Format getFormat() const override;
|
| @@ -62,7 +62,8 @@ public:
|
| const GrClip&,
|
| const SkMatrix& viewMatrix,
|
| const SkStrokeRec& strokeRec,
|
| - const SkRRect& rrect) const override;
|
| + const SkRRect& rrect,
|
| + const SkRRect& devRRect) const override;
|
| bool filterMaskGPU(GrTexture* src,
|
| const SkMatrix& ctm,
|
| const SkIRect& maskRect,
|
| @@ -101,6 +102,7 @@ private:
|
|
|
| SkScalar fSigma;
|
| SkBlurStyle fBlurStyle;
|
| + SkRect fOccluder;
|
| uint32_t fBlurFlags;
|
|
|
| SkBlurQuality getQuality() const {
|
| @@ -123,7 +125,8 @@ private:
|
|
|
| const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128);
|
|
|
| -sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma, uint32_t flags) {
|
| +sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma,
|
| + const SkRect& occluder, uint32_t flags) {
|
| if (!SkScalarIsFinite(sigma) || sigma <= 0) {
|
| return nullptr;
|
| }
|
| @@ -133,7 +136,7 @@ sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma, ui
|
| SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
|
| flags &= SkBlurMaskFilter::kAll_BlurFlag;
|
|
|
| - return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, flags));
|
| + return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, occluder, flags));
|
| }
|
|
|
| bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect,
|
| @@ -196,9 +199,11 @@ bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect,
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, uint32_t flags)
|
| +SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style,
|
| + const SkRect& occluder, uint32_t flags)
|
| : fSigma(sigma)
|
| , fBlurStyle(style)
|
| + , fOccluder(occluder)
|
| , fBlurFlags(flags) {
|
| SkASSERT(fSigma > 0);
|
| SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle);
|
| @@ -645,8 +650,16 @@ sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
|
| const SkScalar sigma = buffer.readScalar();
|
| const unsigned style = buffer.readUInt();
|
| const unsigned flags = buffer.readUInt();
|
| +
|
| + SkRect occluder;
|
| + if (buffer.isVersionLT(SkReadBuffer::kBlurMaskFilterWritesOccluder)) {
|
| + occluder.setEmpty();
|
| + } else {
|
| + buffer.readRect(&occluder);
|
| + }
|
| +
|
| if (style <= kLastEnum_SkBlurStyle) {
|
| - return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, flags);
|
| + return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, occluder, flags);
|
| }
|
| return nullptr;
|
| }
|
| @@ -655,6 +668,7 @@ void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
|
| buffer.writeScalar(fSigma);
|
| buffer.writeUInt(fBlurStyle);
|
| buffer.writeUInt(fBlurFlags);
|
| + buffer.writeRect(fOccluder);
|
| }
|
|
|
|
|
| @@ -1222,7 +1236,8 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
|
| const GrClip& clip,
|
| const SkMatrix& viewMatrix,
|
| const SkStrokeRec& strokeRec,
|
| - const SkRRect& rrect) const {
|
| + const SkRRect& srcRRect,
|
| + const SkRRect& devRRect) const {
|
| SkASSERT(drawContext);
|
|
|
| if (fBlurStyle != kNormal_SkBlurStyle) {
|
| @@ -1235,7 +1250,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
|
|
|
| SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
|
|
|
| - sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma, rrect));
|
| + sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma, devRRect));
|
| if (!fp) {
|
| return false;
|
| }
|
| @@ -1244,17 +1259,54 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
|
| newPaint.addCoverageFragmentProcessor(std::move(fp));
|
| newPaint.setAntiAlias(false);
|
|
|
| - SkMatrix inverse;
|
| - if (!viewMatrix.invert(&inverse)) {
|
| - return false;
|
| - }
|
| + if (!this->ignoreXform()) {
|
| + SkRect srcProxyRect = srcRRect.rect();
|
| + srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
|
| +
|
| + SkPoint points[8];
|
| + uint16_t indices[24];
|
| + int numPoints, numIndices;
|
| +
|
| + SkRect temp = fOccluder;
|
| +
|
| + if (!temp.isEmpty() && (srcProxyRect.contains(temp) || temp.intersect(srcProxyRect))) {
|
| + srcProxyRect.toQuad(points);
|
| + temp.toQuad(&points[4]);
|
| + numPoints = 8;
|
|
|
| - float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
|
| + static const uint16_t ringI[24] = { 0, 1, 5, 5, 4, 0,
|
| + 1, 2, 6, 6, 5, 1,
|
| + 2, 3, 7, 7, 6, 2,
|
| + 3, 0, 4, 4, 7, 3 };
|
| + memcpy(indices, ringI, sizeof(ringI));
|
| + numIndices = 24;
|
| + } else {
|
| + // full rect case
|
| + srcProxyRect.toQuad(points);
|
| + numPoints = 4;
|
| +
|
| + static const uint16_t fullI[6] = { 0, 1, 2, 0, 2, 3 };
|
| + memcpy(indices, fullI, sizeof(fullI));
|
| + numIndices = 6;
|
| + }
|
| +
|
| + drawContext->drawVertices(clip, newPaint, viewMatrix, kTriangles_GrPrimitiveType,
|
| + numPoints, points, nullptr, nullptr, indices, numIndices);
|
|
|
| - SkRect proxyRect = rrect.rect();
|
| - proxyRect.outset(extra, extra);
|
| + } else {
|
| + SkMatrix inverse;
|
| + if (!viewMatrix.invert(&inverse)) {
|
| + return false;
|
| + }
|
| +
|
| + float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
|
| + SkRect proxyRect = devRRect.rect();
|
| + proxyRect.outset(extra, extra);
|
| +
|
| +
|
| + drawContext->fillRectWithLocalMatrix(clip, newPaint, SkMatrix::I(), proxyRect, inverse);
|
| + }
|
|
|
| - drawContext->fillRectWithLocalMatrix(clip, newPaint, SkMatrix::I(), proxyRect, inverse);
|
| return true;
|
| }
|
|
|
| @@ -1369,9 +1421,7 @@ void SkBlurMaskFilterImpl::toString(SkString* str) const {
|
| str->append("flags: (");
|
| if (fBlurFlags) {
|
| bool needSeparator = false;
|
| - SkAddFlagToString(str,
|
| - SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag),
|
| - "IgnoreXform", &needSeparator);
|
| + SkAddFlagToString(str, this->ignoreXform(), "IgnoreXform", &needSeparator);
|
| SkAddFlagToString(str,
|
| SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag),
|
| "HighQuality", &needSeparator);
|
|
|