Fix Ganesh analytic blurred rect draws
This CL does two things:
It fixes the SkBlurMaskFilterImpl::directFilterRRectMaskGPU draw path to explicitly handle rects
It fixes the SkGpuDevice::drawTextureProducerImpl draw path to provide the correct (src & device space) inputs to directFilterRRectMaskGPU.
How this was working before was that GrRRectBlurEffect::Make would reject rect-rrects and the code would fallback to
GrBlurUtils::drawPathWithMaskFilter which mapped the rect-rrect into device space correctly (of course,
the rect-ness of the path was removed at that point so it was going through the slow path).
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2268583002
Review-Url: https://codereview.chromium.org/2268583002
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index cbaed9b..d2781db 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -1158,7 +1158,7 @@
sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context,
float sigma, float xformedSigma,
const SkRRect& srcRRect, const SkRRect& devRRect) {
- SkASSERT(!devRRect.isCircle()); // Should've been caught up-stream
+ SkASSERT(!devRRect.isCircle() && !devRRect.isRect()); // Should've been caught up-stream
// TODO: loosen this up
if (!devRRect.isSimpleCircular()) {
@@ -1351,11 +1351,23 @@
SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
- if (devRRect.isCircle()) {
- sk_sp<GrFragmentProcessor> fp(GrCircleBlurFragmentProcessor::Make(
- context->textureProvider(),
- devRRect.rect(),
- xformedSigma));
+ if (devRRect.isRect() || devRRect.isCircle()) {
+ if (this->ignoreXform()) {
+ return false;
+ }
+
+ sk_sp<GrFragmentProcessor> fp;
+ if (devRRect.isRect()) {
+ SkScalar pad = 3.0f * xformedSigma;
+ const SkRect dstCoverageRect = devRRect.rect().makeOutset(pad, pad);
+
+ fp = GrRectBlurEffect::Make(context->textureProvider(), dstCoverageRect, xformedSigma);
+ } else {
+ fp = GrCircleBlurFragmentProcessor::Make(context->textureProvider(),
+ devRRect.rect(),
+ xformedSigma);
+ }
+
if (!fp) {
return false;
}
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index c387574..46a3699 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -225,17 +225,23 @@
}
// First see if we can do the draw + mask filter direct to the dst.
- SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
- if (mf->directFilterRRectMaskGPU(fContext,
- fDrawContext.get(),
- &grPaint,
- clip,
- viewMatrix,
- rec,
- SkRRect::MakeRect(clippedSrcRect),
- SkRRect::MakeRect(clippedDstRect))) {
- return;
+ if (viewMatrix.isScaleTranslate()) {
+ SkRect devClippedDstRect;
+ viewMatrix.mapRectScaleTranslate(&devClippedDstRect, clippedDstRect);
+
+ SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
+ if (mf->directFilterRRectMaskGPU(fContext,
+ fDrawContext.get(),
+ &grPaint,
+ clip,
+ viewMatrix,
+ rec,
+ SkRRect::MakeRect(clippedDstRect),
+ SkRRect::MakeRect(devClippedDstRect))) {
+ return;
+ }
}
+
SkPath rectPath;
rectPath.addRect(clippedDstRect);
rectPath.setIsVolatile(true);