[Bf-blender-cvs] [6a59cf05309] master: Nodes: add separately allocated runtime data for nodes and sockets

Jacques Lucke noreply at git.blender.org
Mon May 30 15:32:27 CEST 2022


Commit: 6a59cf053091dc45e0f94b829bee6c34cf940534
Author: Jacques Lucke
Date:   Mon May 30 15:31:13 2022 +0200
Branches: master
https://developer.blender.org/rB6a59cf053091dc45e0f94b829bee6c34cf940534

Nodes: add separately allocated runtime data for nodes and sockets

This is a follow up to rBbb0fc675822f313c5546a2498a162472c2571ecb.
Now the same kind of run-time data is added to nodes and sockets.

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

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

M	source/blender/blenkernel/BKE_node_runtime.hh
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/node_tree_update.cc
M	source/blender/editors/space_node/drawnode.cc
M	source/blender/editors/space_node/node_draw.cc
M	source/blender/editors/space_node/node_relationships.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/NOD_node_tree_ref.hh
M	source/blender/nodes/intern/node_geometry_exec.cc
M	source/blender/nodes/intern/node_socket.cc
M	source/blender/nodes/intern/node_socket_declarations.cc

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

diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh
index c9c4577a2d4..c835279061c 100644
--- a/source/blender/blenkernel/BKE_node_runtime.hh
+++ b/source/blender/blenkernel/BKE_node_runtime.hh
@@ -9,7 +9,8 @@
 
 namespace blender::nodes {
 struct FieldInferencingInterface;
-}
+struct NodeDeclaration;
+}  // namespace blender::nodes
 
 namespace blender::bke {
 
@@ -37,4 +38,52 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
   std::unique_ptr<nodes::FieldInferencingInterface> field_inferencing_interface;
 };
 
+/**
+ * Run-time data for every socket. This should only contain data that is somewhat persistent (i.e.
+ * data that lives longer than a single depsgraph evaluation + redraw). Data that's only used in
+ * smaller scopes should generally be stored in separate arrays and/or maps.
+ */
+class bNodeSocketRuntime : NonCopyable, NonMovable {
+ public:
+  /**
+   * References a socket declaration that is owned by `node->declaration`. This is only runtime
+   * data. It has to be updated when the node declaration changes.
+   */
+  const SocketDeclarationHandle *declaration = nullptr;
+
+  /** #eNodeTreeChangedFlag. */
+  uint32_t changed_flag = 0;
+};
+
+/**
+ * Run-time data for every node. This should only contain data that is somewhat persistent (i.e.
+ * data that lives longer than a single depsgraph evaluation + redraw). Data that's only used in
+ * smaller scopes should generally be stored in separate arrays and/or maps.
+ */
+class bNodeRuntime : NonCopyable, NonMovable {
+ public:
+  /**
+   * Describes the desired interface of the node. This is run-time data only.
+   * The actual interface of the node may deviate from the declaration temporarily.
+   * It's possible to sync the actual state of the node to the desired state. Currently, this is
+   * only done when a node is created or loaded.
+   *
+   * In the future, we may want to keep more data only in the declaration, so that it does not have
+   * to be synced to other places that are stored in files. That especially applies to data that
+   * can't be edited by users directly (e.g. min/max values of sockets, tooltips, ...).
+   *
+   * The declaration of a node can be recreated at any time when it is used. Caching it here is
+   * just a bit more efficient when it is used a lot. To make sure that the cache is up-to-date,
+   * call #nodeDeclarationEnsure before using it.
+   *
+   * Currently, the declaration is the same for every node of the same type. Going forward, that is
+   * intended to change though. Especially when nodes become more dynamic with respect to how many
+   * sockets they have.
+   */
+  NodeDeclarationHandle *declaration = nullptr;
+
+  /** #eNodeTreeChangedFlag. */
+  uint32_t changed_flag = 0;
+};
+
 }  // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 95a514ef474..cf50e8a3b43 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -95,6 +95,8 @@ using blender::Stack;
 using blender::StringRef;
 using blender::Vector;
 using blender::VectorSet;
+using blender::bke::bNodeRuntime;
+using blender::bke::bNodeSocketRuntime;
 using blender::bke::bNodeTreeRuntime;
 using blender::nodes::FieldInferencingInterface;
 using blender::nodes::InputSocketFieldType;
@@ -662,7 +664,7 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
   BLO_read_data_address(reader, &sock->default_attribute_name);
   sock->total_inputs = 0; /* Clear runtime data set before drawing. */
   sock->cache = nullptr;
-  sock->declaration = nullptr;
+  sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
 }
 
 void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
@@ -682,8 +684,8 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
 
   BLO_read_list(reader, &ntree->nodes);
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+    node->runtime = MEM_new<bNodeRuntime>(__func__);
     node->typeinfo = nullptr;
-    node->declaration = nullptr;
 
     BLO_read_list(reader, &node->inputs);
     BLO_read_list(reader, &node->outputs);
@@ -1514,6 +1516,7 @@ static bNodeSocket *make_socket(bNodeTree *ntree,
       unique_identifier_check, lb, "socket", '_', auto_identifier, sizeof(auto_identifier));
 
   bNodeSocket *sock = MEM_cnew<bNodeSocket>("sock");
+  sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
   sock->in_out = in_out;
 
   BLI_strncpy(sock->identifier, auto_identifier, NODE_MAXSTR);
@@ -1919,6 +1922,7 @@ static void node_socket_free(bNodeSocket *sock, const bool do_id_user)
     }
     MEM_freeN(sock->default_value);
   }
+  MEM_delete(sock->runtime);
 }
 
 void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
@@ -2124,6 +2128,7 @@ void nodeUniqueName(bNodeTree *ntree, bNode *node)
 bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idname)
 {
   bNode *node = MEM_cnew<bNode>("new node");
+  node->runtime = MEM_new<bNodeRuntime>(__func__);
   BLI_addtail(&ntree->nodes, node);
 
   BLI_strncpy(node->idname, idname, sizeof(node->idname));
@@ -2161,6 +2166,7 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
 
 static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag)
 {
+  sock_dst->runtime = MEM_new<bNodeSocketRuntime>(__func__);
   if (sock_src->prop) {
     sock_dst->prop = IDP_CopyProperty_ex(sock_src->prop, flag);
   }
@@ -2193,6 +2199,8 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree,
   bNode *node_dst = (bNode *)MEM_mallocN(sizeof(bNode), __func__);
   *node_dst = node_src;
 
+  node_dst->runtime = MEM_new<bNodeRuntime>(__func__);
+
   /* Can be called for nodes outside a node tree (e.g. clipboard). */
   if (dst_tree) {
     if (unique_name) {
@@ -2253,7 +2261,6 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree,
   }
 
   /* Reset the declaration of the new node. */
-  node_dst->declaration = nullptr;
   nodeDeclarationEnsure(dst_tree, node_dst);
 
   return node_dst;
@@ -2972,9 +2979,10 @@ static void node_free_node(bNodeTree *ntree, bNode *node)
   }
 
   if (node->typeinfo->declaration_is_dynamic) {
-    delete node->declaration;
+    delete node->runtime->declaration;
   }
 
+  MEM_delete(node->runtime);
   MEM_freeN(node);
 
   if (ntree) {
@@ -3066,6 +3074,7 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
     }
     MEM_freeN(sock->default_value);
   }
+  MEM_delete(sock->runtime);
 }
 
 static void free_localized_node_groups(bNodeTree *ntree)
@@ -3292,6 +3301,7 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree,
   }
 
   bNodeSocket *sock = MEM_cnew<bNodeSocket>("socket template");
+  sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
   BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname));
   sock->in_out = in_out;
   sock->type = SOCK_CUSTOM; /* int type undefined by default */
@@ -3679,34 +3689,34 @@ static void update_socket_declarations(ListBase *sockets,
   int index;
   LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, index) {
     const SocketDeclaration &socket_decl = *declarations[index];
-    socket->declaration = &socket_decl;
+    socket->runtime->declaration = &socket_decl;
   }
 }
 
 void nodeSocketDeclarationsUpdate(bNode *node)
 {
-  BLI_assert(node->declaration != nullptr);
-  update_socket_declarations(&node->inputs, node->declaration->inputs());
-  update_socket_declarations(&node->outputs, node->declaration->outputs());
+  BLI_assert(node->runtime->declaration != nullptr);
+  update_socket_declarations(&node->inputs, node->runtime->declaration->inputs());
+  update_socket_declarations(&node->outputs, node->runtime->declaration->outputs());
 }
 
 bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *UNUSED(ntree), bNode *node)
 {
-  if (node->declaration != nullptr) {
+  if (node->runtime->declaration != nullptr) {
     return false;
   }
   if (node->typeinfo->declare == nullptr) {
     return false;
   }
   if (node->typeinfo->declaration_is_dynamic) {
-    node->declaration = new blender::nodes::NodeDeclaration();
-    blender::nodes::NodeDeclarationBuilder builder{*node->declaration};
+    node->runtime->declaration = new blender::nodes::NodeDeclaration();
+    blender::nodes::NodeDeclarationBuilder builder{*node->runtime->declaration};
     node->typeinfo->declare(builder);
   }
   else {
     /* Declaration should have been created in #nodeRegisterType. */
     BLI_assert(node->typeinfo->fixed_declaration != nullptr);
-    node->declaration = node->typeinfo->fixed_declaration;
+    node->runtime->declaration = node->typeinfo->fixed_declaration;
   }
   return true;
 }
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index d4b7f695ee1..019ab114b83 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -55,13 +55,13 @@ static void add_tree_tag(bNodeTree *ntree, const eNodeTreeChangedFlag flag)
 static void add_node_tag(bNodeTree *ntree, bNode *node, const eNodeTreeChangedFlag flag)
 {
   add_tree_tag(ntree, flag);
-  node->changed_flag |= flag;
+  node->runtime->changed_flag |= flag;
 }
 
 static void add_socket_tag(bNodeTree *ntree, bNodeSocket *socket, const eNodeTreeChangedFlag flag)
 {
   add_tree_tag(ntree, flag);
-  socket->changed_flag |= flag;
+  socket->runtime->changed_flag |= flag;
 }
 
 namespace blender::bke {
@@ -1082,7 +1082,7 @@ class NodeTreeMainUpdater {
     if (ntree.runtime->changed_flag & NTREE_CHANGED_ANY) {
       return true;
     }
-    if (bnode.changed_flag & NTREE_CHANGED_NODE_PROPERTY) {
+    if (bnode.runtime->changed_flag & NTREE_CHANGED_NODE_PROPERTY) {
       return true;
     }
     if (ntree.runtime->changed_flag & NTREE_CHANGED_LINK) {
@@ -1542,12 +1542,12 @@ class NodeTreeMainUpdater {
       const NodeRef &node = in_out_socket.node();
       const bNode &bnode = *node.bnode();
       const bNodeSocket &bsocket = *in_out_socket.bsocket();
-      if (bsocket.changed_flag != NTREE_CHANGED_NOTHING) {
+      if (bsocket.runtime->changed_flag != NTREE_CHA

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list