[Bf-blender-cvs] [8bffadcdc4f] master: Refactor: Simplify transfer of tags in the depsgraph builder

Sergey Sharybin noreply at git.blender.org
Wed Sep 21 16:48:57 CEST 2022


Commit: 8bffadcdc4ff605a5fb0ac0c2a22bbc344509b99
Author: Sergey Sharybin
Date:   Thu Sep 15 15:57:54 2022 +0200
Branches: master
https://developer.blender.org/rB8bffadcdc4ff605a5fb0ac0c2a22bbc344509b99

Refactor: Simplify transfer of tags in the depsgraph builder

Base it in an existing building blocks rather than having dedicated
structure for it.

No functional changes is expected, just preparing to make the code
more reusable.

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

M	source/blender/depsgraph/intern/builder/deg_builder_key.h
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.h

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

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_key.h b/source/blender/depsgraph/intern/builder/deg_builder_key.h
index cbb0daa4fc9..4f8b2dc9f8f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_key.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_key.h
@@ -9,6 +9,9 @@
 
 #include "intern/builder/deg_builder_rna.h"
 #include "intern/depsgraph_type.h"
+#include "intern/node/deg_node_component.h"
+#include "intern/node/deg_node_id.h"
+#include "intern/node/deg_node_operation.h"
 
 #include "DNA_ID.h"
 
@@ -120,6 +123,12 @@ struct OperationKey {
   {
   }
 
+  OperationKey(OperationKey &&other) noexcept = default;
+  OperationKey &operator=(OperationKey &&other) = default;
+
+  OperationKey(const OperationKey &other) = default;
+  OperationKey &operator=(const OperationKey &other) = default;
+
   string identifier() const;
 
   const ID *id = nullptr;
@@ -130,6 +139,53 @@ struct OperationKey {
   int name_tag = -1;
 };
 
+/* Similar to the the OperationKey but does not contain external references, which makes it
+ * suitable to identify operations even after the original database or graph was destroyed.
+ * The downside of this key over the OperationKey is that it performs string allocation upon
+ * the key construction. */
+struct PersistentOperationKey : public OperationKey {
+  /* Create the key which identifies the given operation node. */
+  PersistentOperationKey(const OperationNode *operation_node)
+  {
+    const ComponentNode *component_node = operation_node->owner;
+    const IDNode *id_node = component_node->owner;
+
+    /* Copy names over to our object, so that the key stays valid even after the `operation_node`
+     * is destroyed.*/
+    component_name_storage_ = component_node->name;
+    name_storage_ = operation_node->name;
+
+    /* Assign fields used by the OperationKey API.  */
+    id = id_node->id_orig;
+    component_type = component_node->type;
+    component_name = component_name_storage_.c_str();
+    opcode = operation_node->opcode;
+    name = name_storage_.c_str();
+    name_tag = operation_node->name_tag;
+  }
+
+  PersistentOperationKey(PersistentOperationKey &&other) noexcept : OperationKey(other)
+  {
+    component_name_storage_ = std::move(other.component_name_storage_);
+    name_storage_ = std::move(other.name_storage_);
+
+    /* Re-assign pointers to the strings.
+     * This is needed because string content can actually change address if the string uses the
+     * small string optimization. */
+    component_name = component_name_storage_.c_str();
+    name = name_storage_.c_str();
+  }
+
+  PersistentOperationKey &operator=(PersistentOperationKey &&other) = delete;
+
+  PersistentOperationKey(const PersistentOperationKey &other) = delete;
+  PersistentOperationKey &operator=(const PersistentOperationKey &other) = delete;
+
+ private:
+  string component_name_storage_;
+  string name_storage_;
+};
+
 struct RNAPathKey {
   RNAPathKey(ID *id, const char *path, RNAPointerSource source);
   RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPointerSource source);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index db89a60f81e..f95c0700a47 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -104,6 +104,7 @@
 #include "SEQ_sequencer.h"
 
 #include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_key.h"
 #include "intern/builder/deg_builder_rna.h"
 #include "intern/depsgraph.h"
 #include "intern/depsgraph_tag.h"
@@ -342,6 +343,12 @@ OperationNode *DepsgraphNodeBuilder::find_operation_node(
   return find_operation_node(id, comp_type, "", opcode, name, name_tag);
 }
 
+OperationNode *DepsgraphNodeBuilder::find_operation_node(const OperationKey &key)
+{
+  return find_operation_node(
+      key.id, key.component_type, key.component_name, key.opcode, key.name, key.name_tag);
+}
+
 ID *DepsgraphNodeBuilder::get_cow_id(const ID *id_orig) const
 {
   return graph_->get_cow_id(id_orig);
@@ -385,17 +392,8 @@ void DepsgraphNodeBuilder::begin_build()
     id_node->id_cow = nullptr;
   }
 
-  for (OperationNode *op_node : graph_->entry_tags) {
-    ComponentNode *comp_node = op_node->owner;
-    IDNode *id_node = comp_node->owner;
-
-    SavedEntryTag entry_tag;
-    entry_tag.id_orig = id_node->id_orig;
-    entry_tag.component_type = comp_node->type;
-    entry_tag.opcode = op_node->opcode;
-    entry_tag.name = op_node->name;
-    entry_tag.name_tag = op_node->name_tag;
-    saved_entry_tags_.append(entry_tag);
+  for (const OperationNode *op_node : graph_->entry_tags) {
+    saved_entry_tags_.append_as(op_node);
   }
 
   /* Make sure graph has no nodes left from previous state. */
@@ -513,23 +511,15 @@ void DepsgraphNodeBuilder::update_invalid_cow_pointers()
 
 void DepsgraphNodeBuilder::tag_previously_tagged_nodes()
 {
-  for (const SavedEntryTag &entry_tag : saved_entry_tags_) {
-    IDNode *id_node = find_id_node(entry_tag.id_orig);
-    if (id_node == nullptr) {
-      continue;
-    }
-    ComponentNode *comp_node = id_node->find_component(entry_tag.component_type);
-    if (comp_node == nullptr) {
-      continue;
-    }
-    OperationNode *op_node = comp_node->find_operation(
-        entry_tag.opcode, entry_tag.name.c_str(), entry_tag.name_tag);
-    if (op_node == nullptr) {
+  for (const OperationKey &operation_key : saved_entry_tags_) {
+    OperationNode *operation_node = find_operation_node(operation_key);
+    if (operation_node == nullptr) {
       continue;
     }
+
     /* Since the tag is coming from a saved copy of entry tags, this means
      * that originally node was explicitly tagged for user update. */
-    op_node->tag_update(graph_, DEG_UPDATE_SOURCE_USER_EDIT);
+    operation_node->tag_update(graph_, DEG_UPDATE_SOURCE_USER_EDIT);
   }
 }
 
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index a749409b3ab..a8efe8fca9f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -8,6 +8,7 @@
 #pragma once
 
 #include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_key.h"
 #include "intern/builder/deg_builder_map.h"
 #include "intern/depsgraph_type.h"
 #include "intern/node/deg_node_id.h"
@@ -56,6 +57,7 @@ struct ComponentNode;
 struct Depsgraph;
 class DepsgraphBuilderCache;
 struct IDNode;
+struct OperationKey;
 struct OperationNode;
 struct TimeSourceNode;
 
@@ -151,6 +153,8 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
                                      const char *name = "",
                                      int name_tag = -1);
 
+  OperationNode *find_operation_node(const OperationKey &key);
+
   virtual void build_id(ID *id);
 
   /* Build function for ID types that do not need their own build_xxx() function. */
@@ -259,17 +263,9 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
   };
 
  protected:
-  /* Allows to identify an operation which was tagged for update at the time
-   * relations are being updated. We can not reuse operation node pointer
-   * since it will change during dependency graph construction. */
-  struct SavedEntryTag {
-    ID *id_orig;
-    NodeType component_type;
-    OperationCode opcode;
-    string name;
-    int name_tag;
-  };
-  Vector<SavedEntryTag> saved_entry_tags_;
+  /* Entry tags from the previous state of the dependency graph.
+   * Stored before the graph is re-created so that they can be transferred over. */
+  Vector<PersistentOperationKey> saved_entry_tags_;
 
   struct BuilderWalkUserData {
     DepsgraphNodeBuilder *builder;



More information about the Bf-blender-cvs mailing list