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 <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2020-06-17 17:14:12 -04:00 committed by Skia Commit-Bot
parent 8c662a7d6e
commit 71f6cfd654
3 changed files with 69 additions and 60 deletions

View File

@ -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<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");
@ -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<GrFragmentProcessor> maskFP = find_or_create_rrect_blur_mask_fp(
context, rrectToDraw, dimensions, xformedSigma);
if (!maskFP) {
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(
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) {

View File

@ -41,15 +41,15 @@ std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(
return nullptr;
}
GrSurfaceProxyView mask =
find_or_create_rrect_blur_mask(context, rrectToDraw, dimensions, xformedSigma);
if (!mask) {
std::unique_ptr<GrFragmentProcessor> maskFP =
find_or_create_rrect_blur_mask_fp(context, rrectToDraw, dimensions, xformedSigma);
if (!maskFP) {
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(
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<GrFragmentProcessor> GrRRectBlurEffect::clone() const {
return std::unique_ptr<GrFragmentProcessor>(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<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d) {

View File

@ -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<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");
@ -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<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
@ -115,31 +123,31 @@ public:
float sigma;
SkRect rect;
float cornerRadius;
TextureSampler ninePatchSampler;
int ninePatchFP_index = -1;
private:
GrRRectBlurEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
float sigma,
SkRect rect,
float cornerRadius,
GrSurfaceProxyView ninePatchSampler)
std::unique_ptr<GrFragmentProcessor> 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;
};