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:
parent
1ce11e676e
commit
88c6539a3f
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user