In runtime effects, treat all children as sampled
An unused child that used its coordinates would triggers asserts in the
GP - we expect that all FPs are sampled/invoked. This generates slightly
sub-optimal code (we compute and interpolate the local coordinates for
that child FP), but it's not likely to happen in real code.
Bug: skia:12429
Change-Id: Ic2ddc65d16a7e1f47af8c4192e5ff9ea329bf335
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/446836
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index aa84051..4b12857 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -317,8 +317,14 @@
c.type = child_type(varType);
c.index = children.size();
children.push_back(c);
- sampleUsages.push_back(SkSL::Analysis::GetSampleUsage(
- *program, var, sampleCoordsUsage.fWrite != 0, &elidedSampleCoords));
+ auto usage = SkSL::Analysis::GetSampleUsage(
+ *program, var, sampleCoordsUsage.fWrite != 0, &elidedSampleCoords);
+ // If the child is never sampled, we pretend that it's actually in PassThrough mode.
+ // Otherwise, the GP code for collecting transforms and emitting transform code gets
+ // very confused, leading to asserts and bad (backend) shaders. There's an implicit
+ // assumption that every FP is used by its parent. (skbug.com/12429)
+ sampleUsages.push_back(usage.isSampled() ? usage
+ : SkSL::SampleUsage::PassThrough());
}
// 'uniform' variables
else if (var.modifiers().fFlags & SkSL::Modifiers::kUniform_Flag) {
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 0d5f537..390105d 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -142,6 +142,8 @@
void GrFragmentProcessor::registerChild(std::unique_ptr<GrFragmentProcessor> child,
SkSL::SampleUsage sampleUsage) {
+ SkASSERT(sampleUsage.isSampled());
+
if (!child) {
fChildProcessors.push_back(nullptr);
return;
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index bf90812..428af17 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -498,6 +498,13 @@
effect.child("child") = rgbwShader;
effect.test({0xFF0000FF, 0xFFFF0000, 0xFF00FF00, 0xFFFFFFFF});
+ // Bind an image shader, but don't use it - ensure that we don't assert or generate bad shaders.
+ // (skbug.com/12429)
+ effect.build("uniform shader child;"
+ "half4 main(float2 p) { return half4(0, 1, 0, 1); }");
+ effect.child("child") = rgbwShader;
+ effect.test(0xFF00FF00);
+
//
// Helper functions
//