Out-line GrRRectBlurEffect find_or_create_rrect_blur_mask_fp
I'm going to make this function even more complex (with a thread-safe
shared uniquely-keyed proxy cache) so remove it from the header.
Change-Id: I810ed095729ac30862a8713624e6440380b1128d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/312862
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.cpp b/src/gpu/effects/generated/GrRRectBlurEffect.cpp
index 78d71df..6ff606a 100644
--- a/src/gpu/effects/generated/GrRRectBlurEffect.cpp
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.cpp
@@ -10,6 +10,95 @@
**************************************************************************************************/
#include "GrRRectBlurEffect.h"
+#include "include/gpu/GrRecordingContext.h"
+#include "src/core/SkBlurPriv.h"
+#include "src/core/SkGpuBlurUtils.h"
+#include "src/core/SkRRectPriv.h"
+#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrPaint.h"
+#include "src/gpu/GrProxyProvider.h"
+#include "src/gpu/GrRecordingContextPriv.h"
+#include "src/gpu/GrRenderTargetContext.h"
+#include "src/gpu/GrStyle.h"
+#include "src/gpu/effects/GrTextureEffect.h"
+
+static std::unique_ptr<GrFragmentProcessor> 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");
+ builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f);
+
+ int index = 1;
+ for (auto c : {SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner,
+ SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner}) {
+ SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) && SkScalarIsInt(rrectToDraw.radii(c).fY));
+ builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX);
+ builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY);
+ }
+ 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 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 nullptr;
+ }
+
+ GrPaint paint;
+
+ rtc->clear(SK_PMColor4fTRANSPARENT);
+ rtc->drawRRect(nullptr, std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
+ GrStyle::SimpleFill());
+
+ GrSurfaceProxyView srcView = rtc->readSurfaceView();
+ if (!srcView) {
+ return nullptr;
+ }
+ SkASSERT(srcView.asTextureProxy());
+ auto rtc2 = SkGpuBlurUtils::GaussianBlur(context,
+ std::move(srcView),
+ rtc->colorInfo().colorType(),
+ rtc->colorInfo().alphaType(),
+ nullptr,
+ SkIRect::MakeSize(dimensions),
+ SkIRect::MakeSize(dimensions),
+ xformedSigma,
+ xformedSigma,
+ SkTileMode::kClamp,
+ SkBackingFit::kExact);
+ if (!rtc2) {
+ return nullptr;
+ }
+
+ GrSurfaceProxyView mask = rtc2->readSurfaceView();
+ if (!mask) {
+ return nullptr;
+ }
+ SkASSERT(mask.asTextureProxy());
+ SkASSERT(mask.origin() == kMaskOrigin);
+ proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
+ return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
+}
+
std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
@@ -95,18 +184,18 @@
args.fUniformHandler->getUniformCStr(proxyRectVar),
args.fUniformHandler->getUniformCStr(blurRadiusVar),
args.fUniformHandler->getUniformCStr(cornerRadiusVar));
- SkString _sample9554 = this->invokeChild(0, args);
+ SkString _sample9630 = this->invokeChild(0, args);
fragBuilder->codeAppendf(
R"SkSL(
half4 inputColor = %s;)SkSL",
- _sample9554.c_str());
- SkString _coords9602("float2(texCoord)");
- SkString _sample9602 = this->invokeChild(1, args, _coords9602.c_str());
+ _sample9630.c_str());
+ SkString _coords9678("float2(texCoord)");
+ SkString _sample9678 = this->invokeChild(1, args, _coords9678.c_str());
fragBuilder->codeAppendf(
R"SkSL(
%s = inputColor * %s;
)SkSL",
- args.fOutputColor, _sample9602.c_str());
+ args.fOutputColor, _sample9678.c_str());
}
private: