[Bf-blender-cvs] [a3a60e96470] master: Nodes: Resolve performance bottleneck with mix node updates

Indy Ray noreply at git.blender.org
Fri Jan 6 15:42:15 CET 2023


Commit: a3a60e96470740f3b7439a3a4373667176f78fea
Author: Indy Ray
Date:   Fri Jan 6 08:30:55 2023 -0500
Branches: master
https://developer.blender.org/rBa3a60e96470740f3b7439a3a4373667176f78fea

Nodes: Resolve performance bottleneck with mix node updates

Improve animation playback performance in EEVEE for materials using Mix
nodes. Socket availability was being set and reset on every evaluation
of Mix nodes, during animation playback, this was causing the graph to
be marked dirty, and the whole graph being re-evaluated on every frame,
causing performance issues during playback.

Additionally, do a bit of cleanup, traversing the node sockets with
the next link to improve clarity and reduce errors. Also refactoring
`nodeSetSocketAvailability` to early out and increase clarity on no-op.

Differential Revision: https://developer.blender.org/D16929

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

M	source/blender/blenkernel/intern/node.cc
M	source/blender/nodes/shader/nodes/node_shader_mix.cc

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

diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index f72ba7a1378..0eb5889da65 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -3561,16 +3561,16 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
 void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
 {
   const bool was_available = (sock->flag & SOCK_UNAVAIL) == 0;
-  if (is_available != was_available) {
-    BKE_ntree_update_tag_socket_availability(ntree, sock);
+  if (is_available == was_available) {
+    return;
   }
-
   if (is_available) {
     sock->flag &= ~SOCK_UNAVAIL;
   }
   else {
     sock->flag |= SOCK_UNAVAIL;
   }
+  BKE_ntree_update_tag_socket_availability(ntree, sock);
 }
 
 int nodeSocketLinkLimit(const bNodeSocket *sock)
diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc
index 4200041605c..a9bc1f7f98e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mix.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc
@@ -108,22 +108,23 @@ static void sh_node_mix_update(bNodeTree *ntree, bNode *node)
   const NodeShaderMix &storage = node_storage(*node);
   const eNodeSocketDatatype data_type = static_cast<eNodeSocketDatatype>(storage.data_type);
 
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
-    nodeSetSocketAvailability(ntree, socket, socket->type == data_type);
-  }
-
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
-    nodeSetSocketAvailability(ntree, socket, socket->type == data_type);
-  }
+  bNodeSocket *sock_factor = static_cast<bNodeSocket *>(node->inputs.first);
+  bNodeSocket *sock_factor_vec = static_cast<bNodeSocket *>(sock_factor->next);
 
   bool use_vector_factor = data_type == SOCK_VECTOR &&
                            storage.factor_mode != NODE_MIX_MODE_UNIFORM;
 
-  bNodeSocket *sock_factor = (bNodeSocket *)BLI_findlink(&node->inputs, 0);
   nodeSetSocketAvailability(ntree, sock_factor, !use_vector_factor);
 
-  bNodeSocket *sock_factor_vec = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
   nodeSetSocketAvailability(ntree, sock_factor_vec, use_vector_factor);
+
+  for (bNodeSocket *socket = sock_factor_vec->next; socket != nullptr; socket = socket->next) {
+    nodeSetSocketAvailability(ntree, socket, socket->type == data_type);
+  }
+
+  LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
+    nodeSetSocketAvailability(ntree, socket, socket->type == data_type);
+  }
 }
 
 class SocketSearchOp {



More information about the Bf-blender-cvs mailing list