Update GrCircleBlurFragmentProcessor to use a child FP.

We are updating FPs to receive their input via a child FP where
possible, instead of relying on the input color.

Change-Id: If7c42e556aff3464ec0392f362c97c2e8c6ff91d
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294258
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-06-08 12:46:58 -04:00 committed by Skia Commit-Bot
parent 1ce11e676e
commit 88c6539a3f
4 changed files with 56 additions and 22 deletions

View File

@ -766,7 +766,8 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrRecordingContext* context,
fp = GrRectBlurEffect::Make(context, *context->priv().caps()->shaderCaps(),
devRRect.rect(), xformedSigma);
} else {
fp = GrCircleBlurFragmentProcessor::Make(context, devRRect.rect(), xformedSigma);
fp = GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, context, devRRect.rect(),
xformedSigma);
}
if (!fp) {

View File

@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
in fragmentProcessor? inputFP;
in half4 circleRect;
in half textureRadius;
in half solidRadius;
@ -17,12 +18,14 @@ in uniform sampler2D blurProfileSampler;
uniform half4 circleData;
@optimizationFlags {
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag
}
@make {
static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*,
const SkRect& circle, float sigma);
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext*, const SkRect& circle,
float sigma);
}
@setData(data) {
@ -265,7 +268,8 @@ uniform half4 circleData;
}
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
GrRecordingContext* context, const SkRect& circle, float sigma) {
std::unique_ptr<GrFragmentProcessor> inputFP, GrRecordingContext* context,
const SkRect& circle, float sigma) {
float solidRadius;
float textureRadius;
GrSurfaceProxyView profile = create_profile_texture(context, circle, sigma,
@ -274,22 +278,23 @@ uniform half4 circleData;
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
circle, textureRadius, solidRadius, std::move(profile)));
std::move(inputFP), circle, textureRadius, solidRadius, std::move(profile)));
}
}
void main() {
// We just want to compute "(length(vec) - circleData.z + 0.5) * circleData.w" but need to
// rearrange for precision.
half2 vec = half2(half((sk_FragCoord.x - circleData.x) * circleData.w),
half((sk_FragCoord.y - circleData.y) * circleData.w));
half2 vec = (half2(sk_FragCoord.xy) - circleData.xy) * circleData.w;
half dist = length(vec) + (0.5 - circleData.z) * circleData.w;
sk_OutColor = sk_InColor * sample(blurProfileSampler, half2(dist, 0.5)).a;
half4 inputColor = sample(inputFP, sk_InColor);
sk_OutColor = inputColor * sample(blurProfileSampler, half2(dist, 0.5)).a;
}
@test(testData) {
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
SkScalar sigma = testData->fRandom->nextRangeF(1.f,10.f);
SkRect circle = SkRect::MakeWH(wh, wh);
return GrCircleBlurFragmentProcessor::Make(testData->context(), circle, sigma);
return GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, testData->context(),
circle, sigma);
}

View File

@ -255,7 +255,10 @@ static GrSurfaceProxyView create_profile_texture(GrRecordingContext* context,
}
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
GrRecordingContext* context, const SkRect& circle, float sigma) {
std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
const SkRect& circle,
float sigma) {
float solidRadius;
float textureRadius;
GrSurfaceProxyView profile =
@ -264,7 +267,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
circle, textureRadius, solidRadius, std::move(profile)));
std::move(inputFP), circle, textureRadius, solidRadius, std::move(profile)));
}
#include "src/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
@ -289,16 +292,23 @@ public:
circleDataVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
kHalf4_GrSLType, "circleData");
fragBuilder->codeAppendf(
"half2 vec = half2(half((sk_FragCoord.x - float(%s.x)) * float(%s.w)), "
"half((sk_FragCoord.y - float(%s.y)) * float(%s.w)));\nhalf dist = length(vec) + "
"(0.5 - %s.z) * %s.w;\n%s = %s * sample(%s, float2(half2(dist, 0.5))).%s.w;\n",
"half2 vec = (half2(sk_FragCoord.xy) - %s.xy) * %s.w;\nhalf dist = length(vec) + "
"(0.5 - %s.z) * %s.w;",
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar), args.fOutputColor,
args.fInputColor,
args.fUniformHandler->getUniformCStr(circleDataVar));
SkString _input13170 = SkStringPrintf("%s", args.fInputColor);
SkString _sample13170;
if (_outer.inputFP_index >= 0) {
_sample13170 = this->invokeChild(_outer.inputFP_index, _input13170.c_str(), args);
} else {
_sample13170 = _input13170;
}
fragBuilder->codeAppendf(
"\nhalf4 inputColor = %s;\n%s = inputColor * sample(%s, float2(half2(dist, "
"0.5))).%s.w;\n",
_sample13170.c_str(), args.fOutputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
fragBuilder->getProgramBuilder()
->samplerSwizzle(args.fTexSamplers[0])
@ -344,10 +354,18 @@ bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other)
GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(
const GrCircleBlurFragmentProcessor& src)
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID, src.optimizationFlags())
, inputFP_index(src.inputFP_index)
, circleRect(src.circleRect)
, textureRadius(src.textureRadius)
, solidRadius(src.solidRadius)
, blurProfileSampler(src.blurProfileSampler) {
if (inputFP_index >= 0) {
auto clone = src.childProcessor(inputFP_index).clone();
if (src.childProcessor(inputFP_index).isSampledWithExplicitCoords()) {
clone->setSampledWithExplicitCoords();
}
this->registerChildProcessor(std::move(clone));
}
this->setTextureSamplerCnt(1);
}
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::clone() const {
@ -364,6 +382,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate(
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
SkScalar sigma = testData->fRandom->nextRangeF(1.f, 10.f);
SkRect circle = SkRect::MakeWH(wh, wh);
return GrCircleBlurFragmentProcessor::Make(testData->context(), circle, sigma);
return GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, testData->context(), circle,
sigma);
}
#endif

View File

@ -17,28 +17,37 @@
#include "src/gpu/GrFragmentProcessor.h"
class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*,
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext*,
const SkRect& circle,
float sigma);
GrCircleBlurFragmentProcessor(const GrCircleBlurFragmentProcessor& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "CircleBlurFragmentProcessor"; }
int inputFP_index = -1;
SkRect circleRect;
float textureRadius;
float solidRadius;
TextureSampler blurProfileSampler;
private:
GrCircleBlurFragmentProcessor(SkRect circleRect,
GrCircleBlurFragmentProcessor(std::unique_ptr<GrFragmentProcessor> inputFP,
SkRect circleRect,
float textureRadius,
float solidRadius,
GrSurfaceProxyView blurProfileSampler)
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID,
(OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
: kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, circleRect(circleRect)
, textureRadius(textureRadius)
, solidRadius(solidRadius)
, blurProfileSampler(std::move(blurProfileSampler)) {
if (inputFP) {
inputFP_index = this->numChildProcessors();
this->registerChildProcessor(std::move(inputFP));
}
this->setTextureSamplerCnt(1);
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;