Update GrClampFragmentProcessor 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: Ic30224a45c6e4dba46c1cbaa27735013e8b3935f
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293937
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-06-04 10:57:21 -04:00 committed by Skia Commit-Bot
parent d13487e71b
commit 5a2a7b3096
6 changed files with 56 additions and 31 deletions

View File

@ -181,11 +181,7 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ClampPremulOutput(
if (!fp) {
return nullptr;
}
std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {
std::move(fp),
GrClampFragmentProcessor::Make(true)
};
return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
return GrClampFragmentProcessor::Make(std::move(fp), /*clampToPremul=*/true);
}
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(

View File

@ -395,7 +395,8 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
#endif
if (GrColorTypeClampType(dstColorInfo.colorType()) == GrClampType::kManual) {
if (grPaint->numColorFragmentProcessors()) {
grPaint->addColorFragmentProcessor(GrClampFragmentProcessor::Make(false));
grPaint->addColorFragmentProcessor(
GrClampFragmentProcessor::Make(/*inputFP=*/nullptr, /*clampToPremul=*/false));
} else {
auto color = grPaint->getColor4f();
grPaint->setColor4f({SkTPin(color.fR, 0.f, 1.f),

View File

@ -5,19 +5,22 @@
* found in the LICENSE file.
*/
in fragmentProcessor? inputFP;
layout(key) in bool clampToPremul;
@optimizationFlags {
kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
(kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)
}
void main() {
half4 inputColor = (inputFP != null) ? sample(inputFP) : sk_InColor;
@if (clampToPremul) {
half alpha = saturate(sk_InColor.a);
sk_OutColor = half4(clamp(sk_InColor.rgb, 0, alpha), alpha);
half alpha = saturate(inputColor.a);
sk_OutColor = half4(clamp(inputColor.rgb, 0, alpha), alpha);
} else {
sk_OutColor = saturate(sk_InColor);
sk_OutColor = saturate(inputColor);
}
}
@ -33,5 +36,5 @@ void main() {
}
@test(d) {
return GrClampFragmentProcessor::Make(d->fRandom->nextBool());
return GrClampFragmentProcessor::Make(/*inputFP=*/nullptr, d->fRandom->nextBool());
}

View File

@ -25,11 +25,18 @@ public:
(void)_outer;
auto clampToPremul = _outer.clampToPremul;
(void)clampToPremul;
SkString _sample484;
if (_outer.inputFP_index >= 0) {
_sample484 = this->invokeChild(_outer.inputFP_index, args);
} else {
_sample484 = "half4(1)";
}
fragBuilder->codeAppendf(
"@if (%s) {\n half alpha = clamp(%s.w, 0.0, 1.0);\n %s = half4(clamp(%s.xyz, "
"0.0, alpha), alpha);\n} else {\n %s = clamp(%s, 0.0, 1.0);\n}\n",
(_outer.clampToPremul ? "true" : "false"), args.fInputColor, args.fOutputColor,
args.fInputColor, args.fOutputColor, args.fInputColor);
"half4 inputColor = %s ? %s : %s;\n@if (%s) {\n half alpha = "
"clamp(inputColor.w, 0.0, 1.0);\n %s = half4(clamp(inputColor.xyz, 0.0, alpha), "
"alpha);\n} else {\n %s = clamp(inputColor, 0.0, 1.0);\n}\n",
_outer.inputFP_index >= 0 ? "true" : "false", _sample484.c_str(), args.fInputColor,
(_outer.clampToPremul ? "true" : "false"), args.fOutputColor, args.fOutputColor);
}
private:
@ -51,13 +58,22 @@ bool GrClampFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const
}
GrClampFragmentProcessor::GrClampFragmentProcessor(const GrClampFragmentProcessor& src)
: INHERITED(kGrClampFragmentProcessor_ClassID, src.optimizationFlags())
, clampToPremul(src.clampToPremul) {}
, inputFP_index(src.inputFP_index)
, clampToPremul(src.clampToPremul) {
if (inputFP_index >= 0) {
auto clone = src.childProcessor(inputFP_index).clone();
if (src.childProcessor(inputFP_index).isSampledWithExplicitCoords()) {
clone->setSampledWithExplicitCoords();
}
this->registerChildProcessor(std::move(clone));
}
}
std::unique_ptr<GrFragmentProcessor> GrClampFragmentProcessor::clone() const {
return std::unique_ptr<GrFragmentProcessor>(new GrClampFragmentProcessor(*this));
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrClampFragmentProcessor);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrClampFragmentProcessor::TestCreate(GrProcessorTestData* d) {
return GrClampFragmentProcessor::Make(d->fRandom->nextBool());
return GrClampFragmentProcessor::Make(/*inputFP=*/nullptr, d->fRandom->nextBool());
}
#endif

View File

@ -23,20 +23,30 @@ public:
return {SkTPin(input.fR, 0.f, clampVal), SkTPin(input.fG, 0.f, clampVal),
SkTPin(input.fB, 0.f, clampVal), clampedAlpha};
}
static std::unique_ptr<GrFragmentProcessor> Make(bool clampToPremul) {
return std::unique_ptr<GrFragmentProcessor>(new GrClampFragmentProcessor(clampToPremul));
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
bool clampToPremul) {
return std::unique_ptr<GrFragmentProcessor>(
new GrClampFragmentProcessor(std::move(inputFP), clampToPremul));
}
GrClampFragmentProcessor(const GrClampFragmentProcessor& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "ClampFragmentProcessor"; }
int inputFP_index = -1;
bool clampToPremul;
private:
GrClampFragmentProcessor(bool clampToPremul)
GrClampFragmentProcessor(std::unique_ptr<GrFragmentProcessor> inputFP, bool clampToPremul)
: INHERITED(kGrClampFragmentProcessor_ClassID,
(OptimizationFlags)kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)
, clampToPremul(clampToPremul) {}
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
: kAll_OptimizationFlags) &
(kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag))
, clampToPremul(clampToPremul) {
if (inputFP) {
inputFP_index = this->numChildProcessors();
this->registerChildProcessor(std::move(inputFP));
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;

View File

@ -1058,21 +1058,20 @@ std::unique_ptr<GrDrawOp> GrTextureOp::Make(GrRecordingContext* context,
const auto& caps = *context->priv().caps();
SkRect localRect;
if (quad->fLocal.asRect(&localRect)) {
fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(), filter,
*subset, localRect, caps);
fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(),
filter, *subset, localRect, caps);
} else {
fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(), filter,
*subset, caps);
fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(),
filter, *subset, caps);
}
} else {
fp = GrTextureEffect::Make(std::move(proxyView), alphaType, SkMatrix::I(), filter);
}
fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(textureXform));
paint.addColorFragmentProcessor(std::move(fp));
if (saturate == GrTextureOp::Saturate::kYes) {
paint.addColorFragmentProcessor(GrClampFragmentProcessor::Make(false));
fp = GrClampFragmentProcessor::Make(std::move(fp), /*clampToPremul=*/false);
}
paint.addColorFragmentProcessor(std::move(fp));
return GrFillRectOp::Make(context, std::move(paint), aaType, quad);
}
}