Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-01-01 14:50:48 +0300
committerJacques Lucke <jacques@blender.org>2022-01-01 14:50:48 +0300
commit4c46203cb52ed37694709cc42aa6ca76ed24fe7a (patch)
tree837b8d2d24526f884faf8483f989983e4dc75cd6 /source/blender
parent6844304dda497b245f63934b3c5d8c52f4f6bb19 (diff)
Geometry Nodes: small refactor towards supporting partially lazy nodes
Currently, a node either supports lazyness during execution (like the Switch node), or it doesn't. If it does support lazyness, then every input is computed lazily. However, usually not all inputs actually have to be computed lazily. E.g. the boolean switch input is always required, while the other inputs should be computed lazily. Better support for such sockets can avoid unnecessary round trips through the node execution function.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/modifiers/intern/MOD_nodes_evaluator.cc31
1 files changed, 21 insertions, 10 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index 89987f261db..6b79c9e0f68 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -235,9 +235,10 @@ struct NodeState {
MutableSpan<OutputState> outputs;
/**
- * Nodes that don't support laziness have some special handling the first time they are executed.
+ * Most nodes have inputs that are always required. Those have special handling to avoid an extra
+ * call to the node execution function.
*/
- bool non_lazy_node_is_initialized = false;
+ bool non_lazy_inputs_handled = false;
/**
* Used to check that nodes that don't support laziness do not run more than once.
@@ -801,12 +802,12 @@ class GeometryNodesEvaluator {
if (!this->prepare_node_outputs_for_execution(locked_node)) {
return;
}
- /* Initialize nodes that don't support laziness. This is done after at least one output is
+ /* Initialize inputs that don't support laziness. This is done after at least one output is
* required and before we check that all required inputs are provided. This reduces the
* number of "round-trips" through the task pool by one for most nodes. */
- if (!node_state.non_lazy_node_is_initialized && !node_supports_laziness(node)) {
- this->initialize_non_lazy_node(locked_node);
- node_state.non_lazy_node_is_initialized = true;
+ if (!node_state.non_lazy_inputs_handled) {
+ this->require_non_lazy_inputs(locked_node);
+ node_state.non_lazy_inputs_handled = true;
}
/* Prepare inputs and check if all required inputs are provided. */
if (!this->prepare_node_inputs_for_execution(locked_node)) {
@@ -880,17 +881,27 @@ class GeometryNodesEvaluator {
return execution_is_necessary;
}
- void initialize_non_lazy_node(LockedNode &locked_node)
+ void require_non_lazy_inputs(LockedNode &locked_node)
{
+ this->foreach_non_lazy_input(locked_node, [&](const DInputSocket socket) {
+ this->set_input_required(locked_node, socket);
+ });
+ }
+
+ void foreach_non_lazy_input(LockedNode &locked_node, FunctionRef<void(DInputSocket socket)> fn)
+ {
+ if (node_supports_laziness(locked_node.node)) {
+ /* In the future only some of the inputs may support lazyness. */
+ return;
+ }
+ /* Nodes that don't support laziness require all inputs. */
for (const int i : locked_node.node->inputs().index_range()) {
InputState &input_state = locked_node.node_state.inputs[i];
if (input_state.type == nullptr) {
/* Ignore unavailable/non-data sockets. */
continue;
}
- /* Nodes that don't support laziness require all inputs. */
- const DInputSocket input_socket = locked_node.node.input(i);
- this->set_input_required(locked_node, input_socket);
+ fn(locked_node.node.input(i));
}
}