addRenderStep method
Adds step to into — the renderer's steps as the same plugin sees
them — with a pass that draws once its stage for this backend is
loaded.
A backend step has no stage for adds the step anyway, switched off,
with the reason in statuses: FrameResult.skipped names it, and a
plugin list can say why.
Implementation
Registration addRenderStep(RuntimeRenderStep step, RendererSteps into) {
final needs = <RenderStep>{
for (final name in step.needs) _builtInStep(name, step.name),
};
final renderStep = RenderStep(step.name, needs: needs);
final node = _RuntimeEffectNode(step.name, present: step.present);
final registrations = <Registration>[
into.addStep(renderStep),
into.addNode(
node,
at: step.anchor,
step: renderStep,
after: step.after,
before: step.before,
),
];
final backend = _store.backend;
final source = backend == null ? null : step.shaders[backend];
final material = step.shaders[RuntimeRenderStep.materialStage];
if (material != null && backend != null) {
_materialStep(step, material, node);
} else if (source == null) {
_store.statuses[step.name] = backend == null
? 'this engine draws nothing'
: 'it has a stage for ${step.shaders.keys.join(', ')} and this '
'engine draws with $backend';
} else if (backend != RuntimeBackends.webgl) {
_store.statuses[step.name] =
'a raw stage is compiled at run time on '
'${RuntimeBackends.webgl} only; this engine draws with $backend';
} else {
_store.statuses[step.name] = null;
final bundle = ShaderBundle(
name: step.name,
sdk: runtimeShaderSdk,
stages: <ShaderBundleStage>[
ShaderBundleStage(step.name, fragment: true),
],
sections: <String, ByteData>{
ShaderBundle.webglSection: encodeWebGlSection(
vertex: const <String, String>{},
fragment: <String, String>{step.name: source},
),
},
);
_store.load(bundle, step.name, (library) {
final shader = library[step.name];
if (shader == null) {
_store.statuses[step.name] =
'the loaded library has no stage named '
'"${step.name}"';
return;
}
node.effect = step.present
? FullscreenEffect.present(name: step.name, shader: shader)
: FullscreenEffect.overlay(name: step.name, shader: shader);
});
}
return _tracked(
Registration(() {
node.effect = null;
for (final registration in registrations.reversed) {
registration.cancel();
}
_store.statuses.remove(step.name);
}),
);
}