[Bf-blender-cvs] [0c30873d822] master: Node Editor: Use the topology cache more when drawing node tree

Hans Goudey noreply at git.blender.org
Mon Jan 2 23:59:01 CET 2023


Commit: 0c30873d822f44d40d7ebb5aa2bd667fe9c96beb
Author: Hans Goudey
Date:   Mon Jan 2 17:55:32 2023 -0500
Branches: master
https://developer.blender.org/rB0c30873d822f44d40d7ebb5aa2bd667fe9c96beb

Node Editor: Use the topology cache more when drawing node tree

Partly a cleanup, but also iterating over spans can be faster than
linked lists. Also rewrite the multi-input socket link counting
to avoid the need for a temporary map. Overall, on my setup the changes
save about 5% (3ms) when drawing a large node tree (the mouse house file).

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

M	source/blender/blenkernel/BKE_node_runtime.hh
M	source/blender/editors/space_node/node_draw.cc

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

diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh
index cedb3a6fd8c..a577630678f 100644
--- a/source/blender/blenkernel/BKE_node_runtime.hh
+++ b/source/blender/blenkernel/BKE_node_runtime.hh
@@ -169,7 +169,10 @@ class bNodeSocketRuntime : NonCopyable, NonMovable {
   float locx = 0;
   float locy = 0;
 
-  /* Runtime-only cache of the number of input links, for multi-input sockets. */
+  /**
+   * Runtime-only cache of the number of input links, for multi-input sockets,
+   * including dragged node links that aren't actually in the tree.
+   */
   short total_inputs = 0;
 
   /** Only valid when #topology_cache_is_dirty is false. */
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index cf8a8a1e40a..fdc82307ce0 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -348,7 +348,7 @@ static void node_update_basis(const bContext &C,
   bool add_output_space = false;
 
   int buty;
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
+  for (bNodeSocket *socket : node.output_sockets()) {
     if (!socket->is_visible()) {
       continue;
     }
@@ -471,7 +471,7 @@ static void node_update_basis(const bContext &C,
   }
 
   /* Input sockets. */
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+  for (bNodeSocket *socket : node.input_sockets()) {
     if (!socket->is_visible()) {
       continue;
     }
@@ -564,12 +564,12 @@ static void node_update_hidden(bNode &node, uiBlock &block)
   loc.y = round(loc.y);
 
   /* Calculate minimal radius. */
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+  for (const bNodeSocket *socket : node.input_sockets()) {
     if (socket->is_visible()) {
       totin++;
     }
   }
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
+  for (const bNodeSocket *socket : node.output_sockets()) {
     if (socket->is_visible()) {
       totout++;
     }
@@ -590,7 +590,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
   float rad = float(M_PI) / (1.0f + float(totout));
   float drad = rad;
 
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
+  for (bNodeSocket *socket : node.output_sockets()) {
     if (socket->is_visible()) {
       /* Round the socket location to stop it from jiggling. */
       socket->runtime->locx = round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad);
@@ -602,7 +602,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
   /* Input sockets. */
   rad = drad = -float(M_PI) / (1.0f + float(totin));
 
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+  for (bNodeSocket *socket : node.input_sockets()) {
     if (socket->is_visible()) {
       /* Round the socket location to stop it from jiggling. */
       socket->runtime->locx = round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad);
@@ -1397,10 +1397,7 @@ static void node_draw_sockets(const View2D &v2d,
                               const bool draw_outputs,
                               const bool select_all)
 {
-  const uint total_input_len = BLI_listbase_count(&node.inputs);
-  const uint total_output_len = BLI_listbase_count(&node.outputs);
-
-  if (total_input_len + total_output_len == 0) {
+  if (node.input_sockets().is_empty() && node.output_sockets().is_empty()) {
     return;
   }
 
@@ -1431,12 +1428,12 @@ static void node_draw_sockets(const View2D &v2d,
   scale *= socket_draw_size;
 
   if (!select_all) {
-    immBeginAtMost(GPU_PRIM_POINTS, total_input_len + total_output_len);
+    immBeginAtMost(GPU_PRIM_POINTS, node.input_sockets().size() + node.output_sockets().size());
   }
 
   /* Socket inputs. */
-  short selected_input_len = 0;
-  LISTBASE_FOREACH (bNodeSocket *, sock, &node.inputs) {
+  int selected_input_len = 0;
+  for (const bNodeSocket *sock : node.input_sockets()) {
     if (!sock->is_visible()) {
       continue;
     }
@@ -1467,9 +1464,9 @@ static void node_draw_sockets(const View2D &v2d,
   }
 
   /* Socket outputs. */
-  short selected_output_len = 0;
+  int selected_output_len = 0;
   if (draw_outputs) {
-    LISTBASE_FOREACH (bNodeSocket *, sock, &node.outputs) {
+    for (const bNodeSocket *sock : node.output_sockets()) {
       if (!sock->is_visible()) {
         continue;
       }
@@ -1507,7 +1504,7 @@ static void node_draw_sockets(const View2D &v2d,
 
     if (selected_input_len) {
       /* Socket inputs. */
-      LISTBASE_FOREACH (bNodeSocket *, sock, &node.inputs) {
+      for (const bNodeSocket *sock : node.input_sockets()) {
         if (!sock->is_visible()) {
           continue;
         }
@@ -1537,7 +1534,7 @@ static void node_draw_sockets(const View2D &v2d,
 
     if (selected_output_len) {
       /* Socket outputs. */
-      LISTBASE_FOREACH (bNodeSocket *, sock, &node.outputs) {
+      for (const bNodeSocket *sock : node.output_sockets()) {
         if (!sock->is_visible()) {
           continue;
         }
@@ -1571,7 +1568,7 @@ static void node_draw_sockets(const View2D &v2d,
 
   /* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox`
    * rather than with `GL_POINT`. */
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+  for (const bNodeSocket *socket : node.input_sockets()) {
     if (!socket->is_visible()) {
       continue;
     }
@@ -1905,7 +1902,7 @@ static std::optional<NodeExtraInfoRow> node_get_accessed_attributes_row(
            GEO_NODE_REMOVE_ATTRIBUTE,
            GEO_NODE_INPUT_NAMED_ATTRIBUTE)) {
     /* Only show the overlay when the name is passed in from somewhere else. */
-    LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+    for (const bNodeSocket *socket : node.input_sockets()) {
       if (STREQ(socket->name, "Name")) {
         if (!socket->is_directly_linked()) {
           return std::nullopt;
@@ -2037,7 +2034,6 @@ static void node_draw_extra_info_panel(TreeDrawContext &tree_draw_ctx,
                                        uiBlock &block)
 {
   Vector<NodeExtraInfoRow> extra_info_rows = node_get_extra_info(tree_draw_ctx, snode, node);
-
   if (extra_info_rows.size() == 0) {
     return;
   }
@@ -2048,7 +2044,7 @@ static void node_draw_extra_info_panel(TreeDrawContext &tree_draw_ctx,
 
   const float width = (node.width - 6.0f) * U.dpi_fac;
 
-  if (node.type == NODE_FRAME) {
+  if (node.is_frame()) {
     extra_info_rect.xmin = rct.xmin;
     extra_info_rect.xmax = rct.xmin + 95.0f * U.dpi_fac;
     extra_info_rect.ymin = rct.ymin + 2.0f * U.dpi_fac;
@@ -2655,27 +2651,18 @@ void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor)
 
 static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode)
 {
-  Map<bNodeSocket *, int> counts;
-  LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
-    if (link->tosock->flag & SOCK_MULTI_INPUT) {
-      int &count = counts.lookup_or_add(link->tosock, 0);
-      count++;
+  for (bNode *node : ntree.all_nodes()) {
+    for (bNodeSocket *socket : node->input_sockets()) {
+      if (socket->is_multi_input()) {
+        socket->runtime->total_inputs = socket->directly_linked_links().size();
+      }
     }
   }
   /* Count temporary links going into this socket. */
   if (snode.runtime->linkdrag) {
     for (const bNodeLink &link : snode.runtime->linkdrag->links) {
       if (link.tosock && (link.tosock->flag & SOCK_MULTI_INPUT)) {
-        int &count = counts.lookup_or_add(link.tosock, 0);
-        count++;
-      }
-    }
-  }
-
-  for (bNode *node : ntree.all_nodes()) {
-    LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
-      if (socket->flag & SOCK_MULTI_INPUT) {
-        socket->runtime->total_inputs = counts.lookup_default(socket, 0);
+        link.tosock->runtime->total_inputs++;
       }
     }
   }
@@ -2768,12 +2755,12 @@ static void node_update_nodetree(const bContext &C,
   for (const int i : nodes.index_range()) {
     bNode &node = *nodes[i];
     uiBlock &block = *blocks[i];
-    if (node.type == NODE_FRAME) {
+    if (node.is_frame()) {
       /* Frame sizes are calculated after all other nodes have calculating their #totr. */
       continue;
     }
 
-    if (node.type == NODE_REROUTE) {
+    if (node.is_reroute()) {
       reroute_node_prepare_for_draw(node);
     }
     else {
@@ -2789,7 +2776,7 @@ static void node_update_nodetree(const bContext &C,
   /* Now calculate the size of frame nodes, which can depend on the size of other nodes.
    * Update nodes in reverse, so children sizes get updated before parents. */
   for (int i = nodes.size() - 1; i >= 0; i--) {
-    if (nodes[i]->type == NODE_FRAME) {
+    if (nodes[i]->is_frame()) {
       frame_node_prepare_for_draw(*nodes[i], nodes);
     }
   }
@@ -2992,10 +2979,10 @@ static void node_draw(const bContext &C,
                       uiBlock &block,
                       bNodeInstanceKey key)
 {
-  if (node.type == NODE_FRAME) {
+  if (node.is_frame()) {
     frame_node_draw(C, tree_draw_ctx, region, snode, ntree, node, block);
   }
-  else if (node.type == NODE_REROUTE) {
+  else if (node.is_reroute()) {
     reroute_node_draw(C, region, ntree, node, block);
   }
   else {



More information about the Bf-blender-cvs mailing list