From 71f6cfd65494901f5146bba3f6df1738f4d4a8ec Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Wed, 17 Jun 2020 17:14:12 -0400 Subject: [PATCH] GrRRectBlurEffect uses child for nine patch Bug: skia:10139 Change-Id: Ic306775bb8d1f5d8b29cc38c116d0f8c3e0d55a2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297193 Reviewed-by: Brian Osman Commit-Queue: Brian Salomon --- src/gpu/effects/GrRRectBlurEffect.fp | 42 ++++++++++------- .../effects/generated/GrRRectBlurEffect.cpp | 45 ++++++++----------- src/gpu/effects/generated/GrRRectBlurEffect.h | 42 ++++++++++------- 3 files changed, 69 insertions(+), 60 deletions(-) diff --git a/src/gpu/effects/GrRRectBlurEffect.fp b/src/gpu/effects/GrRRectBlurEffect.fp index e76d07f1d5..e8cb928439 100644 --- a/src/gpu/effects/GrRRectBlurEffect.fp +++ b/src/gpu/effects/GrRRectBlurEffect.fp @@ -9,7 +9,7 @@ in fragmentProcessor? inputFP; in float sigma; layout(ctype=SkRect) in float4 rect; in uniform half cornerRadius; -in uniform sampler2D ninePatchSampler; +in fragmentProcessor ninePatchFP; layout(ctype=SkRect) uniform float4 proxyRect; uniform half blurRadius; @@ -25,13 +25,15 @@ uniform half blurRadius; #include "src/gpu/GrRecordingContextPriv.h" #include "src/gpu/GrRenderTargetContext.h" #include "src/gpu/GrStyle.h" + #include "src/gpu/effects/GrTextureEffect.h" } @class { - static GrSurfaceProxyView find_or_create_rrect_blur_mask(GrRecordingContext* context, - const SkRRect& rrectToDraw, - const SkISize& dimensions, - float xformedSigma) { + static std::unique_ptr find_or_create_rrect_blur_mask_fp( + GrRecordingContext* context, + const SkRRect& rrectToDraw, + const SkISize& dimensions, + float xformedSigma) { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask"); @@ -47,19 +49,26 @@ uniform half blurRadius; } builder.finish(); + // It seems like we could omit this matrix and modify the shader code to not normalize + // the coords used to sample the texture effect. However, the "proxyDims" value in the + // shader is not always the actual the proxy dimensions. This is because 'dimensions' here + // was computed using integer corner radii as determined in + // SkComputeBlurredRRectParams whereas the shader code uses the float radius to compute + // 'proxyDims'. Why it draws correctly with these unequal values is a mystery for the ages. + auto m = SkMatrix::Scale(dimensions.width(), dimensions.height()); static constexpr auto kMaskOrigin = kBottomLeft_GrSurfaceOrigin; GrProxyProvider* proxyProvider = context->priv().proxyProvider(); if (auto view = proxyProvider->findCachedProxyWithColorTypeFallback( key, kMaskOrigin, GrColorType::kAlpha_8, 1)) { - return view; + return GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, m); } auto rtc = GrRenderTargetContext::MakeWithFallback( context, GrColorType::kAlpha_8, nullptr, SkBackingFit::kExact, dimensions, 1, GrMipMapped::kNo, GrProtected::kNo, kMaskOrigin); if (!rtc) { - return {}; + return nullptr; } GrPaint paint; @@ -70,7 +79,7 @@ uniform half blurRadius; GrSurfaceProxyView srcView = rtc->readSurfaceView(); if (!srcView) { - return {}; + return nullptr; } SkASSERT(srcView.asTextureProxy()); auto rtc2 = SkGpuBlurUtils::GaussianBlur(context, @@ -85,18 +94,17 @@ uniform half blurRadius; SkTileMode::kClamp, SkBackingFit::kExact); if (!rtc2) { - return {}; + return nullptr; } GrSurfaceProxyView mask = rtc2->readSurfaceView(); if (!mask) { - return {}; + return nullptr; } SkASSERT(mask.asTextureProxy()); SkASSERT(mask.origin() == kMaskOrigin); proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy()); - - return mask; + return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m); } } @@ -150,15 +158,15 @@ uniform half blurRadius; return nullptr; } - GrSurfaceProxyView mask = find_or_create_rrect_blur_mask(context, rrectToDraw, dimensions, - xformedSigma); - if (!mask) { + std::unique_ptr maskFP = find_or_create_rrect_blur_mask_fp( + context, rrectToDraw, dimensions, xformedSigma); + if (!maskFP) { return nullptr; } return std::unique_ptr( new GrRRectBlurEffect(std::move(inputFP), xformedSigma, devRRect.getBounds(), - SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(mask))); + SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(maskFP))); } } @@ -208,7 +216,7 @@ void main() { half2 texCoord = translatedFragPos / proxyDims; half4 inputColor = sample(inputFP, sk_InColor); - sk_OutColor = inputColor * sample(ninePatchSampler, texCoord); + sk_OutColor = inputColor * sample(ninePatchFP, texCoord); } @setData(pdman) { diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.cpp b/src/gpu/effects/generated/GrRRectBlurEffect.cpp index cf3b74cdfa..7067c8a05c 100644 --- a/src/gpu/effects/generated/GrRRectBlurEffect.cpp +++ b/src/gpu/effects/generated/GrRRectBlurEffect.cpp @@ -41,15 +41,15 @@ std::unique_ptr GrRRectBlurEffect::Make( return nullptr; } - GrSurfaceProxyView mask = - find_or_create_rrect_blur_mask(context, rrectToDraw, dimensions, xformedSigma); - if (!mask) { + std::unique_ptr maskFP = + find_or_create_rrect_blur_mask_fp(context, rrectToDraw, dimensions, xformedSigma); + if (!maskFP) { return nullptr; } return std::unique_ptr( new GrRRectBlurEffect(std::move(inputFP), xformedSigma, devRRect.getBounds(), - SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(mask))); + SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(maskFP))); } #include "src/gpu/GrTexture.h" #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" @@ -91,21 +91,19 @@ public: args.fUniformHandler->getUniformCStr(blurRadiusVar), args.fUniformHandler->getUniformCStr(cornerRadiusVar)); fragBuilder->codeAppendf("nslatedFragPos / proxyDims;"); - SkString _input8931 = SkStringPrintf("%s", args.fInputColor); - SkString _sample8931; + SkString _input9604 = SkStringPrintf("%s", args.fInputColor); + SkString _sample9604; if (_outer.inputFP_index >= 0) { - _sample8931 = this->invokeChild(_outer.inputFP_index, _input8931.c_str(), args); + _sample9604 = this->invokeChild(_outer.inputFP_index, _input9604.c_str(), args); } else { - _sample8931 = _input8931; + _sample9604 = _input9604; } - fragBuilder->codeAppendf( - "\nhalf4 inputColor = %s;\n%s = inputColor * sample(%s, float2(texCoord)).%s;\n", - _sample8931.c_str(), args.fOutputColor, - fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]), - fragBuilder->getProgramBuilder() - ->samplerSwizzle(args.fTexSamplers[0]) - .asString() - .c_str()); + fragBuilder->codeAppendf("\nhalf4 inputColor = %s;", _sample9604.c_str()); + SkString _sample9664; + SkString _coords9664("float2(texCoord)"); + _sample9664 = this->invokeChild(_outer.ninePatchFP_index, args, _coords9664.c_str()); + fragBuilder->codeAppendf("\n%s = inputColor * %s;\n", args.fOutputColor, + _sample9664.c_str()); } private: @@ -119,9 +117,6 @@ private: (void)rect; UniformHandle& cornerRadius = cornerRadiusVar; (void)cornerRadius; - const GrSurfaceProxyView& ninePatchSamplerView = _outer.textureSampler(0).view(); - GrTexture& ninePatchSampler = *ninePatchSamplerView.proxy()->peekTexture(); - (void)ninePatchSampler; UniformHandle& proxyRect = proxyRectVar; (void)proxyRect; UniformHandle& blurRadius = blurRadiusVar; @@ -149,26 +144,24 @@ bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const { if (sigma != that.sigma) return false; if (rect != that.rect) return false; if (cornerRadius != that.cornerRadius) return false; - if (ninePatchSampler != that.ninePatchSampler) return false; return true; } GrRRectBlurEffect::GrRRectBlurEffect(const GrRRectBlurEffect& src) : INHERITED(kGrRRectBlurEffect_ClassID, src.optimizationFlags()) , sigma(src.sigma) , rect(src.rect) - , cornerRadius(src.cornerRadius) - , ninePatchSampler(src.ninePatchSampler) { + , cornerRadius(src.cornerRadius) { if (src.inputFP_index >= 0) { inputFP_index = this->cloneAndRegisterChildProcessor(src.childProcessor(src.inputFP_index)); } - this->setTextureSamplerCnt(1); + { + ninePatchFP_index = + this->cloneAndRegisterChildProcessor(src.childProcessor(src.ninePatchFP_index)); + } } std::unique_ptr GrRRectBlurEffect::clone() const { return std::unique_ptr(new GrRRectBlurEffect(*this)); } -const GrFragmentProcessor::TextureSampler& GrRRectBlurEffect::onTextureSampler(int index) const { - return IthTextureSampler(index, ninePatchSampler); -} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); #if GR_TEST_UTILS std::unique_ptr GrRRectBlurEffect::TestCreate(GrProcessorTestData* d) { diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.h b/src/gpu/effects/generated/GrRRectBlurEffect.h index 94ff8fa7a4..4f3bd8c531 100644 --- a/src/gpu/effects/generated/GrRRectBlurEffect.h +++ b/src/gpu/effects/generated/GrRRectBlurEffect.h @@ -24,6 +24,7 @@ #include "src/gpu/GrProxyProvider.h" #include "src/gpu/GrRecordingContextPriv.h" #include "src/gpu/GrRenderTargetContext.h" +#include "src/gpu/effects/GrTextureEffect.h" #include "src/gpu/GrStyle.h" #include "src/gpu/GrCoordTransform.h" @@ -31,10 +32,11 @@ class GrRRectBlurEffect : public GrFragmentProcessor { public: - static GrSurfaceProxyView find_or_create_rrect_blur_mask(GrRecordingContext* context, - const SkRRect& rrectToDraw, - const SkISize& dimensions, - float xformedSigma) { + static std::unique_ptr find_or_create_rrect_blur_mask_fp( + GrRecordingContext* context, + const SkRRect& rrectToDraw, + const SkISize& dimensions, + float xformedSigma) { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask"); @@ -50,19 +52,26 @@ public: } builder.finish(); + // It seems like we could omit this matrix and modify the shader code to not normalize + // the coords used to sample the texture effect. However, the "proxyDims" value in the + // shader is not always the actual the proxy dimensions. This is because 'dimensions' here + // was computed using integer corner radii as determined in + // SkComputeBlurredRRectParams whereas the shader code uses the float radius to compute + // 'proxyDims'. Why it draws correctly with these unequal values is a mystery for the ages. + auto m = SkMatrix::Scale(dimensions.width(), dimensions.height()); static constexpr auto kMaskOrigin = kBottomLeft_GrSurfaceOrigin; GrProxyProvider* proxyProvider = context->priv().proxyProvider(); if (auto view = proxyProvider->findCachedProxyWithColorTypeFallback( key, kMaskOrigin, GrColorType::kAlpha_8, 1)) { - return view; + return GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, m); } auto rtc = GrRenderTargetContext::MakeWithFallback( context, GrColorType::kAlpha_8, nullptr, SkBackingFit::kExact, dimensions, 1, GrMipMapped::kNo, GrProtected::kNo, kMaskOrigin); if (!rtc) { - return {}; + return nullptr; } GrPaint paint; @@ -73,7 +82,7 @@ public: GrSurfaceProxyView srcView = rtc->readSurfaceView(); if (!srcView) { - return {}; + return nullptr; } SkASSERT(srcView.asTextureProxy()); auto rtc2 = SkGpuBlurUtils::GaussianBlur(context, @@ -88,18 +97,17 @@ public: SkTileMode::kClamp, SkBackingFit::kExact); if (!rtc2) { - return {}; + return nullptr; } GrSurfaceProxyView mask = rtc2->readSurfaceView(); if (!mask) { - return {}; + return nullptr; } SkASSERT(mask.asTextureProxy()); SkASSERT(mask.origin() == kMaskOrigin); proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy()); - - return mask; + return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m); } static std::unique_ptr Make(std::unique_ptr inputFP, @@ -115,31 +123,31 @@ public: float sigma; SkRect rect; float cornerRadius; - TextureSampler ninePatchSampler; + int ninePatchFP_index = -1; private: GrRRectBlurEffect(std::unique_ptr inputFP, float sigma, SkRect rect, float cornerRadius, - GrSurfaceProxyView ninePatchSampler) + std::unique_ptr ninePatchFP) : INHERITED(kGrRRectBlurEffect_ClassID, (OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) & kCompatibleWithCoverageAsAlpha_OptimizationFlag) , sigma(sigma) , rect(rect) - , cornerRadius(cornerRadius) - , ninePatchSampler(std::move(ninePatchSampler)) { + , cornerRadius(cornerRadius) { if (inputFP) { inputFP_index = this->registerChildProcessor(std::move(inputFP)); } - this->setTextureSamplerCnt(1); + SkASSERT(ninePatchFP); + ninePatchFP->setSampledWithExplicitCoords(); + ninePatchFP_index = this->registerChildProcessor(std::move(ninePatchFP)); } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; bool onIsEqual(const GrFragmentProcessor&) const override; - const TextureSampler& onTextureSampler(int) const override; GR_DECLARE_FRAGMENT_PROCESSOR_TEST typedef GrFragmentProcessor INHERITED; };