Add separate src and dst arguments to runtime-blend SkSL functions.
When called in the typical FP context, we only have a paint color, not a
separate source and destination color. So we pass the paint color in
each slot. This seems counterintuitive, but the upshot is that a runtime
blender will now pass the paint color as the input color to the source
effect and dest effect. (In a followup CL, sampling directly from a
runtime blender will allow distinct values to be passed into each slot,
and these values will be honored as-is.)
Change-Id: I96b016527d1066f0431a763f6609c3983b4854ec
Bug: skia:12257
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/433516
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 30e14b9..1b08730 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -175,6 +175,20 @@
this->invokeChild(fp.fInputChildIndex, args).c_str());
}
+ if (fp.fEffect->allowBlender()) {
+ // If we have an dest-color child, we invoke it now, and make the result of that be the
+ // "dest color" for all other purposes later.
+ if (fp.fDestColorChildIndex >= 0) {
+ args.fFragBuilder->codeAppendf(
+ "%s = %s;\n",
+ args.fDestColor,
+ this->invokeChild(fp.fDestColorChildIndex, args.fDestColor, args).c_str());
+ }
+ } else {
+ // We're not making a blender, so we don't expect a dest-color child FP to exist.
+ SkASSERT(fp.fDestColorChildIndex < 0);
+ }
+
// Snap off a global copy of the input color at the start of main. We need this when
// we call child processors (particularly from helper functions, which can't "see" the
// parameter to main). Even from within main, if the code mutates the parameter, calls to
@@ -202,17 +216,6 @@
args.fFragBuilder->codeAppendf("float2 %s = %s;\n", coords, args.fSampleCoord);
}
- // For runtime blends, the destination color is stored as a child FP.
- // Invoke that FP here and store it in a local variable.
- const char* destColor = "half4(1)";
- SkString destColorVarName;
- if (fp.fDestColorChildIndex >= 0) {
- destColorVarName = args.fFragBuilder->newTmpVarName("destColor");
- destColor = destColorVarName.c_str();
- SkString childFP = this->invokeChild(fp.fDestColorChildIndex, args);
- args.fFragBuilder->codeAppendf("half4 %s = %s;", destColor, childFP.c_str());
- }
-
FPCallbacks callbacks(this,
args,
inputColorName.c_str(),
@@ -220,7 +223,7 @@
fp.uniformData(),
fp.uniformFlags());
SkSL::PipelineStage::ConvertProgram(
- program, coords, args.fInputColor, destColor, &callbacks);
+ program, coords, args.fInputColor, args.fDestColor, &callbacks);
}
void onSetData(const GrGLSLProgramDataManager& pdman,
@@ -285,6 +288,7 @@
}
if (destColorFP) {
fp->setDestColorFP(std::move(destColorFP));
+ fp->setIsBlendFunction();
}
return fp;
}