Index: src/effects/SkBlurMaskFilter.cpp |
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp |
index c044333efb289fbd7efe8871998cc139b8ac60fa..510442b566bdfbba6b8a5ff03a24b0aa4cabf9fd 100644 |
--- a/src/effects/SkBlurMaskFilter.cpp |
+++ b/src/effects/SkBlurMaskFilter.cpp |
@@ -1081,7 +1081,7 @@ public: |
private: |
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; |
- GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); |
+ GrRRectBlurEffect(float xformedSigma, const SkRRect& devRRect, GrTexture* mask); |
virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
GrProcessorKeyBuilder* b) const override; |
@@ -1192,19 +1192,19 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, |
return nullptr; |
} |
- return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, |
- devRRect, |
- mask.get())); |
+ return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, devRRect, mask.get())); |
} |
void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
inout->mulByUnknownSingleComponent(); |
} |
-GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture) |
- : fRRect(rrect), |
- fSigma(sigma), |
- fNinePatchAccess(ninePatchTexture) { |
+GrRRectBlurEffect::GrRRectBlurEffect(float xformedSigma, |
+ const SkRRect& devRRect, |
+ GrTexture *ninePatchTexture) |
+ : fRRect(devRRect) |
+ , fSigma(xformedSigma) |
+ , fNinePatchAccess(ninePatchTexture) { |
this->initClassID<GrRRectBlurEffect>(); |
this->addTextureAccess(&fNinePatchAccess); |
this->setWillReadFragmentPosition(); |
@@ -1351,6 +1351,9 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, |
SkScalar xformedSigma = this->computeXformedSigma(viewMatrix); |
+ GrPaint newPaint(*grp); |
+ newPaint.setAntiAlias(false); |
+ |
if (devRRect.isCircle()) { |
sk_sp<GrFragmentProcessor> fp(GrCircleBlurFragmentProcessor::Make( |
context->textureProvider(), |
@@ -1360,9 +1363,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, |
return false; |
} |
- GrPaint newPaint(*grp); |
newPaint.addCoverageFragmentProcessor(std::move(fp)); |
- newPaint.setAntiAlias(false); |
SkRect srcProxyRect = srcRRect.rect(); |
srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma); |
@@ -1371,51 +1372,69 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, |
return true; |
} |
- sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, fSigma, xformedSigma, |
- srcRRect, devRRect)); |
- if (!fp) { |
+ SkRRect maskSpaceRRectToDraw; |
+ SkISize maskSize; |
+ SkScalar rectXs[SkBlurMaskFilter::kMaxDivisions], rectYs[SkBlurMaskFilter::kMaxDivisions]; |
+ SkScalar texXs[SkBlurMaskFilter::kMaxDivisions], texYs[SkBlurMaskFilter::kMaxDivisions]; |
+ int numX, numY; |
+ uint32_t skipMask; |
+ |
+ bool ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(srcRRect, devRRect, fOccluder, |
+ fSigma, xformedSigma, |
+ &maskSpaceRRectToDraw, |
+ &maskSize, |
+ rectXs, rectYs, texXs, texYs, |
+ &numX, &numY, &skipMask); |
+ if (!ninePatchable) { |
return false; |
} |
- GrPaint newPaint(*grp); |
- newPaint.addCoverageFragmentProcessor(std::move(fp)); |
- newPaint.setAntiAlias(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; |
+ if (!this->ignoreXform()) { |
+ sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, |
+ maskSpaceRRectToDraw, maskSize, |
+ xformedSigma, true)); |
+ if (!mask) { |
+ return false; |
+ } |
- SkRect temp = fOccluder; |
+ SkMatrix texMatrix; |
+ texMatrix.setIDiv(mask->width(), mask->height()); |
- if (!temp.isEmpty() && (srcProxyRect.contains(temp) || temp.intersect(srcProxyRect))) { |
- srcProxyRect.toQuad(points); |
- temp.toQuad(&points[4]); |
- numPoints = 8; |
+ GrTextureParams params; |
+ params.reset(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); |
- 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; |
+ sk_sp<GrFragmentProcessor> fp = GrSimpleTextureEffect::Make(mask.get(), nullptr, |
+ texMatrix, params); |
+ if (!fp) { |
+ return false; |
+ } |
- static const uint16_t fullI[6] = { 0, 1, 2, 0, 2, 3 }; |
- memcpy(indices, fullI, sizeof(fullI)); |
- numIndices = 6; |
- } |
+ newPaint.addColorFragmentProcessor(std::move(fp)); |
+ |
+ uint32_t checkBit = 0x1; |
+ for (int y = 0; y < numY-1; ++y) { |
+ for (int x = 0; x < numX-1; ++x) { |
+ if (skipMask & checkBit) { |
+ checkBit <<= 1; |
+ continue; |
+ } |
+ drawContext->fillRectToRect( |
+ clip, newPaint, viewMatrix, |
+ SkRect::MakeLTRB(rectXs[x], rectYs[y], rectXs[x+1], rectYs[y+1]), // dst |
+ SkRect::MakeLTRB(texXs[x], texYs[y], texXs[x+1], texYs[y+1])); // src |
+ checkBit <<= 1; |
+ } |
+ } |
+ } else { |
+ sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, |
+ fSigma, xformedSigma, |
+ srcRRect, devRRect)); |
+ if (!fp) { |
+ return false; |
+ } |
- drawContext->drawVertices(clip, newPaint, viewMatrix, kTriangles_GrPrimitiveType, |
- numPoints, points, nullptr, nullptr, indices, numIndices); |
+ newPaint.addCoverageFragmentProcessor(std::move(fp)); |
- } else { |
SkMatrix inverse; |
if (!viewMatrix.invert(&inverse)) { |
return false; |