[Bf-blender-cvs] [05ddc7daa23] master: Nodes: Avoid small allocations for internal links

Hans Goudey noreply at git.blender.org
Tue Jan 10 05:32:07 CET 2023


Commit: 05ddc7daa23ec57a59156db4ebf5f0ba72a668b0
Author: Hans Goudey
Date:   Mon Jan 9 23:29:58 2023 -0500
Branches: master
https://developer.blender.org/rB05ddc7daa23ec57a59156db4ebf5f0ba72a668b0

Nodes: Avoid small allocations for internal links

Since internal links are only runtime data, we have the flexibility to
allocating every link individually. Instead we can store links directly
in the node runtime vector. This allows avoiding many small allocations
when copying and changing node trees.

In the future we could use a smaller type like a pair of sockets
instead of `bNodeLink` to save memory.

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

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

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/BKE_node_runtime.hh
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/node_runtime.cc
M	source/blender/blenkernel/intern/node_tree_update.cc
M	source/blender/compositor/intern/COM_NodeGraph.cc
M	source/blender/editors/space_node/node_draw.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/intern/derived_node_tree.cc
M	source/blender/nodes/intern/geometry_nodes_lazy_function.cc
M	source/blender/nodes/intern/node_exec.cc
M	source/blender/nodes/intern/node_socket.cc

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

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 47e198c9a12..3cb577fb92e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -690,7 +690,7 @@ void nodeRemoveNode(struct Main *bmain,
 
 void nodeDimensionsGet(const struct bNode *node, float *r_width, float *r_height);
 void nodeTagUpdateID(struct bNode *node);
-void nodeInternalLinks(struct bNode *node, struct bNodeLink ***r_links, int *r_len);
+void nodeInternalLinks(struct bNode *node, struct bNodeLink **r_links, int *r_len);
 
 #ifdef __cplusplus
 
diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh
index 6146e8ea7ae..c5322b7c6ba 100644
--- a/source/blender/blenkernel/BKE_node_runtime.hh
+++ b/source/blender/blenkernel/BKE_node_runtime.hh
@@ -254,7 +254,7 @@ class bNodeRuntime : NonCopyable, NonMovable {
   float anim_ofsx;
 
   /** List of cached internal links (input to output), for muted nodes and operators. */
-  Vector<bNodeLink *> internal_links;
+  Vector<bNodeLink> internal_links;
 
   /** Eagerly maintained cache of the node's index in the tree. */
   int index_in_tree = -1;
@@ -626,7 +626,7 @@ inline bool bNode::is_group_output() const
   return this->type == NODE_GROUP_OUTPUT;
 }
 
-inline blender::Span<const bNodeLink *> bNode::internal_links() const
+inline blender::Span<bNodeLink> bNode::internal_links() const
 {
   return this->runtime->internal_links;
 }
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 0eb5889da65..e42a974eba2 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -1959,10 +1959,10 @@ void nodeRemoveSocketEx(bNodeTree *ntree, bNode *node, bNodeSocket *sock, bool d
     }
   }
 
-  for (bNodeLink *link : node->runtime->internal_links) {
-    if (link->fromsock == sock || link->tosock == sock) {
-      node->runtime->internal_links.remove_first_occurrence_and_reorder(link);
-      MEM_freeN(link);
+  for (const int64_t i : node->runtime->internal_links.index_range()) {
+    const bNodeLink &link = node->runtime->internal_links[i];
+    if (link.fromsock == sock || link.tosock == sock) {
+      node->runtime->internal_links.remove_and_reorder(i);
       BKE_ntree_update_tag_node_internal_link(ntree, node);
       break;
     }
@@ -1986,9 +1986,6 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
     }
   }
 
-  for (bNodeLink *link : node->runtime->internal_links) {
-    MEM_freeN(link);
-  }
   node->runtime->internal_links.clear();
 
   LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
@@ -2312,14 +2309,12 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree,
     node_dst->prop = IDP_CopyProperty_ex(node_src.prop, flag);
   }
 
-  node_dst->runtime->internal_links.clear();
-  for (const bNodeLink *src_link : node_src.runtime->internal_links) {
-    bNodeLink *dst_link = (bNodeLink *)MEM_dupallocN(src_link);
-    dst_link->fromnode = node_dst;
-    dst_link->tonode = node_dst;
-    dst_link->fromsock = socket_map.lookup(src_link->fromsock);
-    dst_link->tosock = socket_map.lookup(src_link->tosock);
-    node_dst->runtime->internal_links.append(dst_link);
+  node_dst->runtime->internal_links = node_src.runtime->internal_links;
+  for (bNodeLink &dst_link : node_dst->runtime->internal_links) {
+    dst_link.fromnode = node_dst;
+    dst_link.tonode = node_dst;
+    dst_link.fromsock = socket_map.lookup(dst_link.fromsock);
+    dst_link.tosock = socket_map.lookup(dst_link.tosock);
   }
 
   if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
@@ -2474,8 +2469,8 @@ static void adjust_multi_input_indices_after_removed_link(bNodeTree *ntree,
 void nodeInternalRelink(bNodeTree *ntree, bNode *node)
 {
   /* store link pointers in output sockets, for efficient lookup */
-  for (bNodeLink *link : node->runtime->internal_links) {
-    link->tosock->link = link;
+  for (bNodeLink &link : node->runtime->internal_links) {
+    link.tosock->link = &link;
   }
 
   /* redirect downstream links */
@@ -2989,11 +2984,6 @@ void node_free_node(bNodeTree *ntree, bNode *node)
     MEM_freeN(sock);
   }
 
-  for (bNodeLink *link : node->runtime->internal_links) {
-    MEM_freeN(link);
-  }
-  node->runtime->internal_links.clear();
-
   if (node->prop) {
     /* Remember, no ID user refcount management here! */
     IDP_FreePropertyContent_ex(node->prop, false);
@@ -3644,7 +3634,7 @@ void nodeTagUpdateID(bNode *node)
   node->runtime->update |= NODE_UPDATE_ID;
 }
 
-void nodeInternalLinks(bNode *node, bNodeLink ***r_links, int *r_len)
+void nodeInternalLinks(bNode *node, bNodeLink **r_links, int *r_len)
 {
   *r_links = node->runtime->internal_links.data();
   *r_len = node->runtime->internal_links.size();
diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc
index d3b16d4c1a5..dc24e5ddbc4 100644
--- a/source/blender/blenkernel/intern/node_runtime.cc
+++ b/source/blender/blenkernel/intern/node_runtime.cc
@@ -95,8 +95,8 @@ static void update_internal_link_inputs(const bNodeTree &ntree)
     for (bNodeSocket *socket : node->runtime->outputs) {
       socket->runtime->internal_link_input = nullptr;
     }
-    for (bNodeLink *link : node->runtime->internal_links) {
-      link->tosock->runtime->internal_link_input = link->fromsock;
+    for (bNodeLink &link : node->runtime->internal_links) {
+      link.tosock->runtime->internal_link_input = link.fromsock;
     }
   }
 }
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index 93e8f24787a..397556e23fc 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -635,8 +635,8 @@ class NodeTreeMainUpdater {
           const bNodeSocket *from_socket = item.first;
           const bNodeSocket *to_socket = item.second;
           bool found = false;
-          for (const bNodeLink *internal_link : node->runtime->internal_links) {
-            if (from_socket == internal_link->fromsock && to_socket == internal_link->tosock) {
+          for (const bNodeLink &internal_link : node->runtime->internal_links) {
+            if (from_socket == internal_link.fromsock && to_socket == internal_link.tosock) {
               found = true;
             }
           }
@@ -682,19 +682,17 @@ class NodeTreeMainUpdater {
                                      bNode &node,
                                      Span<std::pair<bNodeSocket *, bNodeSocket *>> links)
   {
-    for (bNodeLink *link : node.runtime->internal_links) {
-      MEM_freeN(link);
-    }
     node.runtime->internal_links.clear();
+    node.runtime->internal_links.reserve(links.size());
     for (const auto &item : links) {
       bNodeSocket *from_socket = item.first;
       bNodeSocket *to_socket = item.second;
-      bNodeLink *link = MEM_cnew<bNodeLink>(__func__);
-      link->fromnode = &node;
-      link->fromsock = from_socket;
-      link->tonode = &node;
-      link->tosock = to_socket;
-      link->flag |= NODE_LINK_VALID;
+      bNodeLink link{};
+      link.fromnode = &node;
+      link.fromsock = from_socket;
+      link.tonode = &node;
+      link.tosock = to_socket;
+      link.flag |= NODE_LINK_VALID;
       node.runtime->internal_links.append(link);
     }
     BKE_ntree_update_tag_node_internal_link(&ntree, &node);
diff --git a/source/blender/compositor/intern/COM_NodeGraph.cc b/source/blender/compositor/intern/COM_NodeGraph.cc
index 34a145f6bf5..c4f840cde4e 100644
--- a/source/blender/compositor/intern/COM_NodeGraph.cc
+++ b/source/blender/compositor/intern/COM_NodeGraph.cc
@@ -181,8 +181,8 @@ void NodeGraph::add_proxies_mute(bNodeTree *b_ntree,
                                  bNodeInstanceKey key,
                                  bool is_active_group)
 {
-  for (const bNodeLink *b_link : b_node->internal_links()) {
-    SocketProxyNode *proxy = new SocketProxyNode(b_node, b_link->fromsock, b_link->tosock, false);
+  for (const bNodeLink &b_link : b_node->internal_links()) {
+    SocketProxyNode *proxy = new SocketProxyNode(b_node, b_link.fromsock, b_link.tosock, false);
     add_node(proxy, b_ntree, key, is_active_group);
   }
 }
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 098c08686b4..ef284c3e3bf 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -675,9 +675,9 @@ static void node_draw_mute_line(const bContext &C,
 {
   GPU_blend(GPU_BLEND_ALPHA);
 
-  for (const bNodeLink *link : node.internal_links()) {
-    if (!nodeLinkIsHidden(link)) {
-      node_draw_link_bezier(C, v2d, snode, *link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false);
+  for (const bNodeLink &link : node.internal_links()) {
+    if (!nodeLinkIsHidden(&link)) {
+      node_draw_link_bezier(C, v2d, snode, link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false);
     }
   }
 
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 7053836f7ff..2ddf166566a 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -375,7 +375,7 @@ typedef struct bNode {
   bool is_group_output() const;
   const blender::nodes::NodeDeclaration *declaration() const;
   /** A span containing all internal links when the node is muted. */
-  blender::Span<const bNodeLink *> internal_links() const;
+  blender::Span<bNodeLink> internal_links() const;
 
   /* The following methods are only available when #bNodeTree.ensure_topology_cache has been
    * called. */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 300bca9e369..f895a00e23a 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2377,10 +2377,10 @@ static void rna_Node_parent_set(PointerRNA *ptr,
 static void rna_Node_internal_links_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
   bNode *node = ptr->data;
-  bNodeLink **begin;
+  bNodeLink *begin;
   int le

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list