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>
This commit is contained in:
Robert Phillips 2020-08-24 14:42:39 -04:00 committed by Skia Commit-Bot
parent 6e727832b5
commit a1c4f1ad51
3 changed files with 117 additions and 112 deletions

View File

@ -14,6 +14,26 @@ layout(ctype=SkRect) uniform float4 proxyRect;
uniform half blurRadius;
@header {
#include "include/core/SkRect.h"
class GrRecordingContext;
class SkRRect;
}
@optimizationFlags {
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag
}
@make {
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
float sigma,
float xformedSigma,
const SkRRect& srcRRect,
const SkRRect& devRRect);
}
@cpp {
#include "include/gpu/GrRecordingContext.h"
#include "src/core/SkBlurPriv.h"
#include "src/core/SkGpuBlurUtils.h"
@ -25,9 +45,7 @@ uniform half blurRadius;
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrStyle.h"
#include "src/gpu/effects/GrTextureEffect.h"
}
@class {
static std::unique_ptr<GrFragmentProcessor> find_or_create_rrect_blur_mask_fp(
GrRecordingContext* context,
const SkRRect& rrectToDraw,
@ -105,23 +123,7 @@ uniform half blurRadius;
proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
}
}
@optimizationFlags {
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag
}
@make {
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
float sigma,
float xformedSigma,
const SkRRect& srcRRect,
const SkRRect& devRRect);
}
@cpp {
std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,

View File

@ -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 @@ half2 texCoord = translatedFragPos / proxyDims;)SkSL",
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:

View File

@ -14,100 +14,14 @@
#include "include/core/SkM44.h"
#include "include/core/SkTypes.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"
#include "include/core/SkRect.h"
class GrRecordingContext;
class SkRRect;
#include "src/gpu/GrFragmentProcessor.h"
class GrRRectBlurEffect : public GrFragmentProcessor {
public:
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);
}
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
float sigma,