Create FP GrFragmentProcessor::UseDestColorAsInput.

Returns a fragment processor which samples the passed-in fragment
processor using `args.fDestColor` as its input color. Pass a null FP
and it will return `args.fDestColor` directly. (This is only meaningful
in contexts like blenders, which use a source and dest color.)

This also fixes a bug in invokeChild which failed to forward along the
dest color when one blend function invokes another blend function, and
fixes an edge case where GrSkSLFP where it would fail to enable the
blend-function mode when the dstFP is null.

Change-Id: I46c8bffeb602d0c0b2b4dd1723a893582f3007ed
Bug: skia:12257
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/434681
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2021-07-29 19:36:20 -04:00 committed by SkCQ
parent 5f7c32a568
commit 2a6f73cb27
5 changed files with 38 additions and 6 deletions

View File

@ -441,6 +441,20 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
//////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::UseDestColorAsInput(
std::unique_ptr<GrFragmentProcessor> fp) {
static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForBlender, R"(
uniform colorFilter fp; // Declared as colorFilter so we can use sample(..., color)
half4 main(half4 src, half4 dst) {
return sample(fp, dst);
}
)");
return GrSkSLFP::Make(effect, "UseDestColorAsInput", /*inputFP=*/nullptr,
GrSkSLFP::OptFlags::kNone, "fp", std::move(fp));
}
//////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputOpaqueAndPostApplyAlpha(
std::unique_ptr<GrFragmentProcessor> fp) {
if (!fp) {

View File

@ -93,6 +93,14 @@ public:
const SkPMColor4f&,
bool useUniform = true);
/**
* Returns a fragment processor which samples the passed-in fragment processor using
* `args.fDestColor` as its input color. Pass a null FP to access `args.fDestColor` directly.
* (This is only meaningful in contexts like blenders, which use a source and dest color.)
*/
static std::unique_ptr<GrFragmentProcessor> UseDestColorAsInput(
std::unique_ptr<GrFragmentProcessor>);
/**
* Returns a parent fragment processor that adopts the passed fragment processor as a child.
* The parent will unpremul its input color, make it opaque, and pass that as the input to

View File

@ -270,17 +270,19 @@ std::unique_ptr<GrSkSLFP> GrSkSLFP::MakeWithData(
size_t uniformSize = uniforms->size();
size_t uniformFlagSize = effect->uniforms().count() * sizeof(UniformFlags);
std::unique_ptr<GrSkSLFP> fp(new (uniformSize + uniformFlagSize)
GrSkSLFP(std::move(effect), name, OptFlags::kNone));
GrSkSLFP(effect, name, OptFlags::kNone));
sk_careful_memcpy(fp->uniformData(), uniforms->data(), uniformSize);
for (auto& childFP : childFPs) {
fp->addChild(std::move(childFP), /*mergeOptFlags=*/true);
}
if (effect->allowBlender()) {
fp->setIsBlendFunction();
}
if (inputFP) {
fp->setInput(std::move(inputFP));
}
if (destColorFP) {
fp->setDestColorFP(std::move(destColorFP));
fp->setIsBlendFunction();
}
return fp;
}

View File

@ -147,9 +147,11 @@ public:
#endif
size_t uniformPayloadSize = UniformPayloadSize(effect.get());
std::unique_ptr<GrSkSLFP> fp(new (uniformPayloadSize)
GrSkSLFP(std::move(effect), name, optFlags));
std::unique_ptr<GrSkSLFP> fp(new (uniformPayloadSize) GrSkSLFP(effect, name, optFlags));
fp->appendArgs(fp->uniformData(), fp->uniformFlags(), std::forward<Args>(args)...);
if (effect->allowBlender()) {
fp->setIsBlendFunction();
}
if (inputFP) {
fp->setInput(std::move(inputFP));
}

View File

@ -57,7 +57,10 @@ SkString GrGLSLFragmentProcessor::invokeChild(int childIndex,
inputColor);
if (childProc->isBlendFunction()) {
invocation.appendf(", %s", destColor ? destColor : "half4(1)");
if (!destColor) {
destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
}
invocation.appendf(", %s", destColor);
}
if (childProc->isSampledWithExplicitCoords()) {
@ -100,7 +103,10 @@ SkString GrGLSLFragmentProcessor::invokeChildWithMatrix(int childIndex, const ch
inputColor);
if (childProc->isBlendFunction()) {
invocation.appendf(", %s", destColor ? destColor : "half4(1)");
if (!destColor) {
destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
}
invocation.appendf(", %s", destColor);
}
// Produce a string containing the call to the helper function. We have a uniform variable