[Bf-blender-cvs] [7ea4342e73c] master: Geometry Nodes: reduce number of scheduled nodes in evaluator

Jacques Lucke noreply at git.blender.org
Wed Nov 24 12:57:47 CET 2021


Commit: 7ea4342e73c3b8d6323bb94096a1833ccbb309da
Author: Jacques Lucke
Date:   Wed Nov 24 12:55:10 2021 +0100
Branches: master
https://developer.blender.org/rB7ea4342e73c3b8d6323bb94096a1833ccbb309da

Geometry Nodes: reduce number of scheduled nodes in evaluator

Previously, there were a couple of cases where nodes were scheduled when
that was not really necessary. This change doesn't seem to have a big impact
on performance, but simplifies the code a bit.

===================================================================

M	source/blender/modifiers/intern/MOD_nodes_evaluator.cc

===================================================================

diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index 4af2caaaf7e..798942f71f5 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -1184,10 +1184,9 @@ class GeometryNodesEvaluator {
 
   /**
    * Load the required input from the socket or trigger nodes to the left to compute the value.
-   * When this function is called, the node will always be executed again eventually (either
-   * immediately, or when all required inputs have been computed by other nodes).
+   * \return True when the node will be triggered by another node again when the value is computed.
    */
-  void set_input_required(LockedNode &locked_node, const DInputSocket input_socket)
+  bool set_input_required(LockedNode &locked_node, const DInputSocket input_socket)
   {
     BLI_assert(locked_node.node == input_socket.node());
     InputState &input_state = locked_node.node_state.inputs[input_socket->index()];
@@ -1195,19 +1194,16 @@ class GeometryNodesEvaluator {
     /* Value set as unused cannot become used again. */
     BLI_assert(input_state.usage != ValueUsage::Unused);
 
-    if (input_state.usage == ValueUsage::Required) {
-      /* The value is already required, but the node might expect to be evaluated again. */
-      this->schedule_node(locked_node);
-      /* Returning here also ensure that the code below is executed at most once per input. */
-      return;
+    if (input_state.was_ready_for_execution) {
+      return false;
     }
-    input_state.usage = ValueUsage::Required;
 
-    if (input_state.was_ready_for_execution) {
-      /* The value was already ready, but the node might expect to be evaluated again. */
-      this->schedule_node(locked_node);
-      return;
+    if (input_state.usage == ValueUsage::Required) {
+      /* If the input was not ready for execution but is required, the node will be triggered again
+       * once the input has been computed. */
+      return true;
     }
+    input_state.usage = ValueUsage::Required;
 
     /* Count how many values still have to be added to this input until it is "complete". */
     int missing_values = 0;
@@ -1222,9 +1218,7 @@ class GeometryNodesEvaluator {
       }
     }
     if (missing_values == 0) {
-      /* The input is fully available already, but the node might expect to be evaluated again. */
-      this->schedule_node(locked_node);
-      return;
+      return false;
     }
     /* Increase the total number of missing required inputs. This ensures that the node will be
      * scheduled correctly when all inputs have been provided. */
@@ -1239,30 +1233,28 @@ class GeometryNodesEvaluator {
       /* If there are no origin sockets, just load the value from the socket directly. */
       this->load_unlinked_input_value(locked_node, input_socket, input_state, input_socket);
       locked_node.node_state.missing_required_inputs -= 1;
-      this->schedule_node(locked_node);
-      return;
+      return false;
     }
-    bool will_be_triggered_by_other_node = false;
+    bool requested_from_other_node = false;
     for (const DSocket &origin_socket : origin_sockets) {
       if (origin_socket->is_input()) {
         /* Load the value directly from the origin socket. In most cases this is an unlinked
          * group input. */
         this->load_unlinked_input_value(locked_node, input_socket, input_state, origin_socket);
         locked_node.node_state.missing_required_inputs -= 1;
-        this->schedule_node(locked_node);
       }
       else {
         /* The value has not been computed yet, so when it will be forwarded by another node, this
          * node will be triggered. */
-        will_be_triggered_by_other_node = true;
-
+        requested_from_other_node = true;
         locked_node.delayed_required_outputs.append(DOutputSocket(origin_socket));
       }
     }
     /* If this node will be triggered by another node, we don't have to schedule it now. */
-    if (!will_be_triggered_by_other_node) {
-      this->schedule_node(locked_node);
+    if (requested_from_other_node) {
+      return true;
     }
+    return false;
   }
 
   void set_input_unused(LockedNode &locked_node, const DInputSocket socket)
@@ -1798,7 +1790,11 @@ bool NodeParamsProvider::lazy_require_input(StringRef identifier)
     return false;
   }
   evaluator_.with_locked_node(this->dnode, node_state_, [&](LockedNode &locked_node) {
-    evaluator_.set_input_required(locked_node, socket);
+    if (!evaluator_.set_input_required(locked_node, socket)) {
+      /* Schedule the currently executed node again because the value is available now but was not
+       * ready for the current execution. */
+      evaluator_.schedule_node(locked_node);
+    }
   });
   return true;
 }



More information about the Bf-blender-cvs mailing list