Use GrResourceProvider::MakeApprox for mask filter proxy sizes
This allows us to demand exact matches in size and eliminate our
dependence on absClear.
In the future we can take this a step further and offset the mask to
leave a transparent border on all sides, thereby creating a "decal"
effect.
Bug: skia:
Change-Id: I8cd02ba1365ace0ccaae250a7195f51d0c77ce8d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/242720
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index c8fdc0b..c22d0f0 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -174,14 +174,24 @@
const SkMatrix& origViewMatrix,
const GrShape& shape,
int sampleCnt) {
+ // Use GrResourceProvider::MakeApprox to implement our own approximate size matching, but demand
+ // a "SkBackingFit::kExact" size match on the actual render target. We do this because the
+ // filter will reach outside the src bounds, so we need to pre-clear these values to ensure a
+ // "decal" sampling effect (i.e., ensure reads outside the src bounds return alpha=0).
+ //
+ // FIXME: Reads outside the left and top edges will actually clamp to the edge pixel. And in the
+ // event that MakeApprox does not change the size, reads outside the right and/or bottom will do
+ // the same. We should offset our filter within the render target and expand the size as needed
+ // to guarantee at least 1px of padding on all sides.
auto rtContext = context->priv().makeDeferredRenderTargetContextWithFallback(
- SkBackingFit::kApprox, maskRect.width(), maskRect.height(), GrColorType::kAlpha_8,
- nullptr, sampleCnt, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
+ SkBackingFit::kExact, GrResourceProvider::MakeApprox(maskRect.width()),
+ GrResourceProvider::MakeApprox(maskRect.height()), GrColorType::kAlpha_8, nullptr,
+ sampleCnt, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
if (!rtContext) {
return nullptr;
}
- rtContext->priv().absClear(nullptr);
+ rtContext->clear(SK_PMColor4fTRANSPARENT);
GrPaint maskPaint;
maskPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 83c20f7..1bc8165 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -81,6 +81,10 @@
*/
void clear(const SkIRect* rect, const SkPMColor4f& color, CanClearFullscreen);
+ void clear(const SkPMColor4f& color) {
+ return this->clear(nullptr, color, CanClearFullscreen::kYes);
+ }
+
/**
* Draw everywhere (respecting the clip) with the paint.
*/
diff --git a/src/gpu/effects/GrRRectBlurEffect.fp b/src/gpu/effects/GrRRectBlurEffect.fp
index 74ad750..9974955 100644
--- a/src/gpu/effects/GrRRectBlurEffect.fp
+++ b/src/gpu/effects/GrRRectBlurEffect.fp
@@ -53,11 +53,12 @@
sk_sp<GrTextureProxy> mask(proxyProvider->findOrCreateProxyByUniqueKey(
key, GrColorType::kAlpha_8, kBottomLeft_GrSurfaceOrigin));
if (!mask) {
- // TODO: this could be approx but the texture coords will need to be updated
- auto rtc =
- context->priv().makeDeferredRenderTargetContextWithFallback(
- SkBackingFit::kExact, size.fWidth,
- size.fHeight, GrColorType::kAlpha_8, nullptr);
+ // TODO: this could be SkBackingFit::kApprox, but:
+ // 1) The texture coords would need to be updated.
+ // 2) We would have to use GrTextureDomain::kClamp_Mode for the GaussianBlur.
+ auto rtc = context->priv().makeDeferredRenderTargetContextWithFallback(
+ SkBackingFit::kExact, size.fWidth, size.fHeight, GrColorType::kAlpha_8,
+ nullptr);
if (!rtc) {
return nullptr;
}
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.h b/src/gpu/effects/generated/GrRRectBlurEffect.h
index 8b48489..e2f3dd5 100644
--- a/src/gpu/effects/generated/GrRRectBlurEffect.h
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.h
@@ -54,7 +54,9 @@
sk_sp<GrTextureProxy> mask(proxyProvider->findOrCreateProxyByUniqueKey(
key, GrColorType::kAlpha_8, kBottomLeft_GrSurfaceOrigin));
if (!mask) {
- // TODO: this could be approx but the texture coords will need to be updated
+ // TODO: this could be SkBackingFit::kApprox, but:
+ // 1) The texture coords would need to be updated.
+ // 2) We would have to use GrTextureDomain::kClamp_Mode for the GaussianBlur.
auto rtc = context->priv().makeDeferredRenderTargetContextWithFallback(
SkBackingFit::kExact, size.fWidth, size.fHeight, GrColorType::kAlpha_8,
nullptr);