In FPs, store pointers for all child slots, even nullptr
This simplifies things like ConstantOutputForConstantInput and
invokeChild. It also removes the need for child indices: generated
FPs now directly refer to their children by slot number.
Change-Id: I69bbb042d5d72d21b999256f969c467702d0774d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302436
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index eb84ee8..01900b2 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -18,6 +18,7 @@
void GrGLSLFragmentProcessor::emitChildFunction(int childIndex, EmitArgs& args) {
SkASSERT(childIndex >= 0);
+ SkASSERT(args.fFp.childProcessor(childIndex));
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
while (childIndex >= (int) fFunctionNames.size()) {
fFunctionNames.emplace_back();
@@ -29,7 +30,7 @@
EmitArgs childArgs(fragBuilder,
args.fUniformHandler,
args.fShaderCaps,
- args.fFp.childProcessor(childIndex),
+ *args.fFp.childProcessor(childIndex),
"_output",
"_input",
"_coords",
@@ -41,7 +42,16 @@
SkString GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor,
EmitArgs& args, SkSL::String skslCoords) {
+ if (!inputColor) {
+ inputColor = "half4(1)";
+ }
+
SkASSERT(childIndex >= 0);
+ const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
+ if (!childProc) {
+ return SkString(inputColor);
+ }
+
this->emitChildFunction(childIndex, args);
if (skslCoords.empty()) {
@@ -49,49 +59,53 @@
skslCoords = args.fSampleCoord;
}
- const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
-
- if (childProc.isSampledWithExplicitCoords()) {
+ if (childProc->isSampledWithExplicitCoords()) {
// The child's function takes a half4 color and a float2 coordinate
return SkStringPrintf("%s(%s, %s)", fFunctionNames[childIndex].c_str(),
- inputColor ? inputColor : "half4(1)",
- skslCoords.c_str());
+ inputColor, skslCoords.c_str());
} else {
// The child's function just takes a color. We should only get here for a call to sample
// without explicit coordinates. Assert that the child has no sample matrix and skslCoords
// is _coords (a uniform matrix sample call would go through invokeChildWithMatrix, and if
// a child was sampled with sample(matrix) and sample(), it should have been flagged as
// variable and hit the branch above).
- SkASSERT(skslCoords == args.fSampleCoord && !childProc.sampleUsage().hasMatrix());
- return SkStringPrintf("%s(%s)", fFunctionNames[childIndex].c_str(),
- inputColor ? inputColor : "half4(1)");
+ SkASSERT(skslCoords == args.fSampleCoord && !childProc->sampleUsage().hasMatrix());
+ return SkStringPrintf("%s(%s)", fFunctionNames[childIndex].c_str(), inputColor);
}
}
SkString GrGLSLFragmentProcessor::invokeChildWithMatrix(int childIndex, const char* inputColor,
EmitArgs& args,
SkSL::String skslMatrix) {
+ if (!inputColor) {
+ inputColor = "half4(1)";
+ }
+
SkASSERT(childIndex >= 0);
+ const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
+ if (!childProc) {
+ return SkString(inputColor);
+ }
+
this->emitChildFunction(childIndex, args);
- const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
- SkASSERT(childProc.sampleUsage().hasMatrix());
+ SkASSERT(childProc->sampleUsage().hasMatrix());
// Since this is uniform, the provided sksl expression should exactly match the expression
// stored on the FP, or it should match the mangled uniform name.
if (skslMatrix.empty()) {
// Empty matrix expression replaces with the sample matrix expression stored on the FP, but
// that is only valid for uniform sampled FPs
- SkASSERT(childProc.sampleUsage().hasUniformMatrix());
- skslMatrix.assign(childProc.sampleUsage().fExpression);
+ SkASSERT(childProc->sampleUsage().hasUniformMatrix());
+ skslMatrix.assign(childProc->sampleUsage().fExpression);
}
- if (childProc.sampleUsage().hasUniformMatrix()) {
+ if (childProc->sampleUsage().hasUniformMatrix()) {
// Attempt to resolve the uniform name from the raw name stored in the sample usage.
// Since this is uniform, the provided expression better match what was given to the FP.
- SkASSERT(childProc.sampleUsage().fExpression == skslMatrix);
+ SkASSERT(childProc->sampleUsage().fExpression == skslMatrix);
GrShaderVar uniform = args.fUniformHandler->getUniformMapping(
- args.fFp, SkString(childProc.sampleUsage().fExpression));
+ args.fFp, SkString(childProc->sampleUsage().fExpression));
if (uniform.getType() != kVoid_GrSLType) {
// Found the uniform, so replace the expression with the actual uniform name
SkASSERT(uniform.getType() == kFloat3x3_GrSLType);
@@ -108,28 +122,24 @@
//
// In all other cases, we need to insert sksl to compute matrix * parent coords and then invoke
// the function.
- if (childProc.isSampledWithExplicitCoords()) {
+ if (childProc->isSampledWithExplicitCoords()) {
// Only check perspective for this specific matrix transform, not the aggregate FP property.
// Any parent perspective will have already been applied when evaluated in the FS.
- if (childProc.sampleUsage().fHasPerspective) {
+ if (childProc->sampleUsage().fHasPerspective) {
return SkStringPrintf("%s(%s, proj((%s) * %s.xy1))", fFunctionNames[childIndex].c_str(),
- inputColor ? inputColor : "half4(1)", skslMatrix.c_str(),
- args.fSampleCoord);
+ inputColor, skslMatrix.c_str(), args.fSampleCoord);
} else {
- return SkStringPrintf("%s(%s, ((%s) * %s.xy1).xy)",
- fFunctionNames[childIndex].c_str(),
- inputColor ? inputColor : "half4(1)",
- skslMatrix.c_str(), args.fSampleCoord);
+ return SkStringPrintf("%s(%s, ((%s) * %s.xy1).xy)", fFunctionNames[childIndex].c_str(),
+ inputColor, skslMatrix.c_str(), args.fSampleCoord);
}
} else {
// A variable matrix expression should mark the child as explicitly sampled. A no-op
// matrix should match sample(color), not sample(color, matrix).
- SkASSERT(childProc.sampleUsage().hasUniformMatrix());
+ SkASSERT(childProc->sampleUsage().hasUniformMatrix());
// Since this is uniform and not explicitly sampled, it's transform has been promoted to
// the vertex shader and the signature doesn't take a float2 coord.
- return SkStringPrintf("%s(%s)", fFunctionNames[childIndex].c_str(),
- inputColor ? inputColor : "half4(1)");
+ return SkStringPrintf("%s(%s)", fFunctionNames[childIndex].c_str(), inputColor);
}
}
@@ -175,7 +185,9 @@
const GrGLSLFragmentProcessor* back = fFPStack.back();
fFPStack.pop_back();
for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
- fFPStack.push_back(back->childProcessor(i));
+ if (auto child = back->childProcessor(i)) {
+ fFPStack.push_back(child);
+ }
}
return *this;
}