Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph/intern/builder')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_key.cc (renamed from source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc)32
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_key.h201
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc95
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h32
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc31
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h127
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc4
12 files changed, 334 insertions, 205 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 097c377ece4..16510d5f9a6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -178,6 +178,9 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
if (GS(id_orig->name) == ID_OB) {
flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
}
+ if (GS(id_orig->name) == ID_NT) {
+ flag |= ID_RECALC_NTREE_OUTPUT;
+ }
}
/* Restore recalc flags from original ID, which could possibly contain recalc flags set by
* an operator and then were carried on by the undo system. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index 129e0093d11..a9f8d1f73d3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -59,9 +59,9 @@ bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b)
uint64_t AnimatedPropertyID::hash() const
{
- uintptr_t ptr1 = (uintptr_t)data;
- uintptr_t ptr2 = (uintptr_t)property_rna;
- return static_cast<uint64_t>(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
+ uintptr_t ptr1 = uintptr_t(data);
+ uintptr_t ptr2 = uintptr_t(property_rna);
+ return uint64_t(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
}
namespace {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
index 8ba6c840a59..7f3c59f1522 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
@@ -60,7 +60,7 @@ struct CyclesSolverState {
inline void set_node_visited_state(Node *node, eCyclicCheckVisitedState state)
{
- node->custom_flags = (node->custom_flags & ~0x3) | (int)state;
+ node->custom_flags = (node->custom_flags & ~0x3) | int(state);
}
inline eCyclicCheckVisitedState get_node_visited_state(Node *node)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_key.cc
index 8506a97c408..741c415b5cd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_key.cc
@@ -7,20 +7,26 @@
* Methods for constructing depsgraph
*/
-#include "intern/builder/deg_builder_relations.h"
+#include "intern/builder/deg_builder_key.h"
+
+#include "RNA_path.h"
namespace blender::deg {
-////////////////////////////////////////////////////////////////////////////////
-/* Time source. */
+/* -------------------------------------------------------------------- */
+/** \name Time source
+ * \{ */
string TimeSourceKey::identifier() const
{
return string("TimeSourceKey");
}
-////////////////////////////////////////////////////////////////////////////////
-// Component.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Component
+ * \{ */
string ComponentKey::identifier() const
{
@@ -35,8 +41,11 @@ string ComponentKey::identifier() const
return result;
}
-////////////////////////////////////////////////////////////////////////////////
-// Operation.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operation
+ * \{ */
string OperationKey::identifier() const
{
@@ -51,8 +60,11 @@ string OperationKey::identifier() const
return result;
}
-////////////////////////////////////////////////////////////////////////////////
-// RNA path.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name RNA path
+ * \{ */
RNAPathKey::RNAPathKey(ID *id, const char *path, RNAPointerSource source) : id(id), source(source)
{
@@ -79,4 +91,6 @@ string RNAPathKey::identifier() const
return string("RnaPathKey(") + "id: " + id_name + ", prop: '" + prop_name + "')";
}
+/** \} */
+
} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_key.h b/source/blender/depsgraph/intern/builder/deg_builder_key.h
new file mode 100644
index 00000000000..4f8b2dc9f8f
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_key.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2013 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#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"
+
+#include "RNA_access.h"
+#include "RNA_types.h"
+
+struct ID;
+struct PropertyRNA;
+
+namespace blender::deg {
+
+struct TimeSourceKey {
+ TimeSourceKey() = default;
+
+ string identifier() const;
+};
+
+struct ComponentKey {
+ ComponentKey() = default;
+
+ inline ComponentKey(const ID *id, NodeType type, const char *name = "")
+ : id(id), type(type), name(name)
+ {
+ }
+
+ string identifier() const;
+
+ const ID *id = nullptr;
+ NodeType type = NodeType::UNDEFINED;
+ const char *name = "";
+};
+
+struct OperationKey {
+ OperationKey() = default;
+
+ inline OperationKey(const ID *id, NodeType component_type, const char *name, int name_tag = -1)
+ : id(id),
+ component_type(component_type),
+ component_name(""),
+ opcode(OperationCode::OPERATION),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ const char *component_name,
+ const char *name,
+ int name_tag)
+ : id(id),
+ component_type(component_type),
+ component_name(component_name),
+ opcode(OperationCode::OPERATION),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(const ID *id, NodeType component_type, OperationCode opcode)
+ : id(id),
+ component_type(component_type),
+ component_name(""),
+ opcode(opcode),
+ name(""),
+ name_tag(-1)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ const char *component_name,
+ OperationCode opcode)
+ : id(id),
+ component_type(component_type),
+ component_name(component_name),
+ opcode(opcode),
+ name(""),
+ name_tag(-1)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ OperationCode opcode,
+ const char *name,
+ int name_tag = -1)
+ : id(id),
+ component_type(component_type),
+ component_name(""),
+ opcode(opcode),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ OperationKey(const ID *id,
+ NodeType component_type,
+ const char *component_name,
+ OperationCode opcode,
+ const char *name,
+ int name_tag = -1)
+ : id(id),
+ component_type(component_type),
+ component_name(component_name),
+ opcode(opcode),
+ name(name),
+ name_tag(name_tag)
+ {
+ }
+
+ 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;
+ NodeType component_type = NodeType::UNDEFINED;
+ const char *component_name = "";
+ OperationCode opcode = OperationCode::OPERATION;
+ const char *name = "";
+ 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);
+
+ string identifier() const;
+
+ ID *id;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ RNAPointerSource source;
+};
+
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 324197118d2..c84852788fd 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"
@@ -155,14 +156,12 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
IDComponentsMask previously_visible_components_mask = 0;
uint32_t previous_eval_flags = 0;
DEGCustomDataMeshMasks previous_customdata_masks;
- int id_invisible_recalc = 0;
IDInfo *id_info = id_info_hash_.lookup_default(id->session_uuid, nullptr);
if (id_info != nullptr) {
id_cow = id_info->id_cow;
previously_visible_components_mask = id_info->previously_visible_components_mask;
previous_eval_flags = id_info->previous_eval_flags;
previous_customdata_masks = id_info->previous_customdata_masks;
- id_invisible_recalc = id_info->id_invisible_recalc;
/* Tag ID info to not free the CoW ID pointer. */
id_info->id_cow = nullptr;
}
@@ -170,7 +169,6 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
id_node->previously_visible_components_mask = previously_visible_components_mask;
id_node->previous_eval_flags = previous_eval_flags;
id_node->previous_customdata_masks = previous_customdata_masks;
- id_node->id_invisible_recalc = id_invisible_recalc;
/* NOTE: Zero number of components indicates that ID node was just created. */
const bool is_newly_created = id_node->components.is_empty();
@@ -211,7 +209,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
return id_node;
}
-IDNode *DepsgraphNodeBuilder::find_id_node(ID *id)
+IDNode *DepsgraphNodeBuilder::find_id_node(const ID *id)
{
return graph_->find_id_node(id);
}
@@ -231,6 +229,17 @@ ComponentNode *DepsgraphNodeBuilder::add_component_node(ID *id,
return comp_node;
}
+ComponentNode *DepsgraphNodeBuilder::find_component_node(const ID *id,
+ const NodeType comp_type,
+ const char *comp_name)
+{
+ IDNode *id_node = find_id_node(id);
+ if (id_node == nullptr) {
+ return nullptr;
+ }
+ return id_node->find_component(comp_type, comp_name);
+}
+
OperationNode *DepsgraphNodeBuilder::add_operation_node(ComponentNode *comp_node,
OperationCode opcode,
const DepsEvalOperationCb &op,
@@ -314,23 +323,32 @@ bool DepsgraphNodeBuilder::has_operation_node(ID *id,
return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
}
-OperationNode *DepsgraphNodeBuilder::find_operation_node(ID *id,
+OperationNode *DepsgraphNodeBuilder::find_operation_node(const ID *id,
NodeType comp_type,
const char *comp_name,
OperationCode opcode,
const char *name,
int name_tag)
{
- ComponentNode *comp_node = add_component_node(id, comp_type, comp_name);
+ ComponentNode *comp_node = find_component_node(id, comp_type, comp_name);
+ if (comp_node == nullptr) {
+ return nullptr;
+ }
return comp_node->find_operation(opcode, name, name_tag);
}
OperationNode *DepsgraphNodeBuilder::find_operation_node(
- ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
+ const ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
{
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);
@@ -369,23 +387,13 @@ void DepsgraphNodeBuilder::begin_build()
id_info->previously_visible_components_mask = id_node->visible_components_mask;
id_info->previous_eval_flags = id_node->eval_flags;
id_info->previous_customdata_masks = id_node->customdata_masks;
- id_info->id_invisible_recalc = id_node->id_invisible_recalc;
BLI_assert(!id_info_hash_.contains(id_node->id_orig_session_uuid));
id_info_hash_.add_new(id_node->id_orig_session_uuid, id_info);
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. */
@@ -445,6 +453,11 @@ static int foreach_id_cow_detect_need_for_update_callback(LibraryIDLinkCallbackD
if (id == nullptr) {
return IDWALK_RET_NOP;
}
+ if (!ID_TYPE_IS_COW(GS(id->name))) {
+ /* No need to go further if the id never had a cow copy in the depsgraph. This function is
+ * only concerned with keeping the mapping between original and COW ids intact. */
+ return IDWALK_RET_NOP;
+ }
DepsgraphNodeBuilder *builder = static_cast<DepsgraphNodeBuilder *>(cb_data->user_data);
ID *id_cow_self = cb_data->id_self;
@@ -503,23 +516,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);
}
}
@@ -1745,14 +1750,19 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
/* Animation, */
build_animdata(&ntree->id);
/* Output update. */
- ID *id_cow = get_cow_id(&ntree->id);
- add_operation_node(&ntree->id,
- NodeType::NTREE_OUTPUT,
- OperationCode::NTREE_OUTPUT,
- [id_cow](::Depsgraph * /*depsgraph*/) {
- bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
- bke::node_tree_runtime::handle_node_tree_output_changed(*ntree_cow);
- });
+ add_operation_node(&ntree->id, NodeType::NTREE_OUTPUT, OperationCode::NTREE_OUTPUT);
+ if (ntree->type == NTREE_GEOMETRY) {
+ ID *id_cow = get_cow_id(&ntree->id);
+ add_operation_node(&ntree->id,
+ NodeType::NTREE_GEOMETRY_PREPROCESS,
+ OperationCode::NTREE_GEOMETRY_PREPROCESS,
+ [id_cow](::Depsgraph * /*depsgraph*/) {
+ bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
+ bke::node_tree_runtime::preprocess_geometry_node_tree_for_evaluation(
+ *ntree_cow);
+ });
+ }
+
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
@@ -2129,9 +2139,10 @@ void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
});
}
-void DepsgraphNodeBuilder::build_scene_speakers(Scene * /*scene*/, ViewLayer *view_layer)
+void DepsgraphNodeBuilder::build_scene_speakers(Scene *scene, ViewLayer *view_layer)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 29cca0a8ddd..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;
@@ -92,10 +94,11 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
int foreach_id_cow_detect_need_for_update_callback(ID *id_cow_self, ID *id_pointer);
IDNode *add_id_node(ID *id);
- IDNode *find_id_node(ID *id);
+ IDNode *find_id_node(const ID *id);
TimeSourceNode *add_time_source();
ComponentNode *add_component_node(ID *id, NodeType comp_type, const char *comp_name = "");
+ ComponentNode *find_component_node(const ID *id, NodeType comp_type, const char *comp_name = "");
OperationNode *add_operation_node(ComponentNode *comp_node,
OperationCode opcode,
@@ -137,15 +140,20 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
const char *name = "",
int name_tag = -1);
- OperationNode *find_operation_node(ID *id,
+ OperationNode *find_operation_node(const ID *id,
NodeType comp_type,
const char *comp_name,
OperationCode opcode,
const char *name = "",
int name_tag = -1);
- OperationNode *find_operation_node(
- ID *id, NodeType comp_type, OperationCode opcode, const char *name = "", int name_tag = -1);
+ OperationNode *find_operation_node(const ID *id,
+ NodeType comp_type,
+ OperationCode opcode,
+ const char *name = "",
+ int name_tag = -1);
+
+ OperationNode *find_operation_node(const OperationKey &key);
virtual void build_id(ID *id);
@@ -250,24 +258,14 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
IDComponentsMask previously_visible_components_mask;
/* Special evaluation flag mask from the previous depsgraph. */
uint32_t previous_eval_flags;
- /* Recalculation flags which were not evaluated for the ID in the previous depsgraph. */
- int id_invisible_recalc;
/* Mesh CustomData mask from the previous depsgraph. */
DEGCustomDataMeshMasks previous_customdata_masks;
};
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;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 5af9e7d4fe9..d7420b91db4 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -90,7 +90,8 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
* but object is expected to be an original one. Hence we go into some
* tricks here iterating over the view layer. */
int base_index = 0;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* object itself */
if (!need_pull_base_into_graph(base)) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 313d4996dcf..b657d39df69 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -191,7 +191,7 @@ bool check_id_has_anim_component(ID *id)
if (adt == nullptr) {
return false;
}
- return (adt->action != nullptr) || (!BLI_listbase_is_empty(&adt->nla_tracks));
+ return (adt->action != nullptr) || !BLI_listbase_is_empty(&adt->nla_tracks);
}
bool check_id_has_driver_component(ID *id)
@@ -1723,6 +1723,11 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
if (GS(id_ptr->name) == ID_NT) {
ComponentKey ntree_output_key(id_ptr, NodeType::NTREE_OUTPUT);
add_relation(driver_key, ntree_output_key, "Drivers -> NTree Output");
+ if (reinterpret_cast<bNodeTree *>(id_ptr)->type == NTREE_GEOMETRY) {
+ OperationKey ntree_geo_preprocess_key(
+ id, NodeType::NTREE_GEOMETRY_PREPROCESS, OperationCode::NTREE_GEOMETRY_PREPROCESS);
+ add_relation(driver_key, ntree_geo_preprocess_key, "Drivers -> NTree Geo Preprocess");
+ }
}
}
@@ -2611,6 +2616,16 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
build_animdata(&ntree->id);
build_parameters(&ntree->id);
OperationKey ntree_output_key(&ntree->id, NodeType::NTREE_OUTPUT, OperationCode::NTREE_OUTPUT);
+ OperationKey ntree_geo_preprocess_key(
+ &ntree->id, NodeType::NTREE_GEOMETRY_PREPROCESS, OperationCode::NTREE_GEOMETRY_PREPROCESS);
+ if (ntree->type == NTREE_GEOMETRY) {
+ OperationKey ntree_cow_key(&ntree->id, NodeType::COPY_ON_WRITE, OperationCode::COPY_ON_WRITE);
+ add_relation(ntree_cow_key, ntree_geo_preprocess_key, "COW -> Preprocess");
+ add_relation(ntree_geo_preprocess_key,
+ ntree_output_key,
+ "Preprocess -> Output",
+ RELATION_FLAG_NO_FLUSH);
+ }
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
@@ -2687,6 +2702,12 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
* the output). Currently, we lack the infrastructure to check for these cases efficiently.
* That can be added later. */
add_relation(group_output_key, ntree_output_key, "Group Node");
+ if (group_ntree->type == NTREE_GEOMETRY) {
+ OperationKey group_preprocess_key(&group_ntree->id,
+ NodeType::NTREE_GEOMETRY_PREPROCESS,
+ OperationCode::NTREE_GEOMETRY_PREPROCESS);
+ add_relation(group_preprocess_key, ntree_geo_preprocess_key, "Group Node Preprocess");
+ }
}
else {
BLI_assert_msg(0, "Unknown ID type used for node");
@@ -2703,6 +2724,9 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
if (check_id_has_anim_component(&ntree->id)) {
ComponentKey animation_key(&ntree->id, NodeType::ANIMATION);
add_relation(animation_key, ntree_output_key, "NTree Shading Parameters");
+ if (ntree->type == NTREE_GEOMETRY) {
+ add_relation(animation_key, ntree_geo_preprocess_key, "NTree Animation -> Preprocess");
+ }
}
}
@@ -3050,9 +3074,10 @@ void DepsgraphRelationBuilder::build_scene_audio(Scene *scene)
}
}
-void DepsgraphRelationBuilder::build_scene_speakers(Scene * /*scene*/, ViewLayer *view_layer)
+void DepsgraphRelationBuilder::build_scene_speakers(Scene *scene, ViewLayer *view_layer)
{
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 7d3a0fd9217..901e4a1acbb 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -14,14 +14,13 @@
#include "DNA_ID.h"
-#include "RNA_access.h"
#include "RNA_path.h"
-#include "RNA_types.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_key.h"
#include "intern/builder/deg_builder_map.h"
#include "intern/builder/deg_builder_rna.h"
#include "intern/builder/deg_builder_stack.h"
@@ -69,8 +68,6 @@ struct bNodeTree;
struct bPoseChannel;
struct bSound;
-struct PropertyRNA;
-
namespace blender::deg {
struct ComponentNode;
@@ -84,128 +81,6 @@ struct Relation;
struct RootPChanMap;
struct TimeSourceNode;
-struct TimeSourceKey {
- TimeSourceKey() = default;
-
- string identifier() const;
-};
-
-struct ComponentKey {
- ComponentKey() = default;
-
- inline ComponentKey(const ID *id, NodeType type, const char *name = "")
- : id(id), type(type), name(name)
- {
- }
-
- string identifier() const;
-
- const ID *id = nullptr;
- NodeType type = NodeType::UNDEFINED;
- const char *name = "";
-};
-
-struct OperationKey {
- OperationKey() = default;
-
- inline OperationKey(const ID *id, NodeType component_type, const char *name, int name_tag = -1)
- : id(id),
- component_type(component_type),
- component_name(""),
- opcode(OperationCode::OPERATION),
- name(name),
- name_tag(name_tag)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- const char *component_name,
- const char *name,
- int name_tag)
- : id(id),
- component_type(component_type),
- component_name(component_name),
- opcode(OperationCode::OPERATION),
- name(name),
- name_tag(name_tag)
- {
- }
-
- OperationKey(const ID *id, NodeType component_type, OperationCode opcode)
- : id(id),
- component_type(component_type),
- component_name(""),
- opcode(opcode),
- name(""),
- name_tag(-1)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- const char *component_name,
- OperationCode opcode)
- : id(id),
- component_type(component_type),
- component_name(component_name),
- opcode(opcode),
- name(""),
- name_tag(-1)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- OperationCode opcode,
- const char *name,
- int name_tag = -1)
- : id(id),
- component_type(component_type),
- component_name(""),
- opcode(opcode),
- name(name),
- name_tag(name_tag)
- {
- }
-
- OperationKey(const ID *id,
- NodeType component_type,
- const char *component_name,
- OperationCode opcode,
- const char *name,
- int name_tag = -1)
- : id(id),
- component_type(component_type),
- component_name(component_name),
- opcode(opcode),
- name(name),
- name_tag(name_tag)
- {
- }
-
- string identifier() const;
-
- const ID *id = nullptr;
- NodeType component_type = NodeType::UNDEFINED;
- const char *component_name = "";
- OperationCode opcode = OperationCode::OPERATION;
- const char *name = "";
- int name_tag = -1;
-};
-
-struct RNAPathKey {
- RNAPathKey(ID *id, const char *path, RNAPointerSource source);
- RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPointerSource source);
-
- string identifier() const;
-
- ID *id;
- PointerRNA ptr;
- PropertyRNA *prop;
- RNAPointerSource source;
-};
-
class DepsgraphRelationBuilder : public DepsgraphBuilder {
public:
DepsgraphRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index d723e5beb75..938c0979de9 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -75,11 +75,12 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
{
/* Setup currently building context. */
scene_ = scene;
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* Scene objects. */
/* NOTE: Nodes builder requires us to pass CoW base because it's being
* passed to the evaluation functions. During relations builder we only
* do nullptr-pointer check of the base, so it's fine to pass original one. */
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (need_pull_base_into_graph(base)) {
build_object_from_view_layer_base(base->object);
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index d94746fb7fa..1a4356c4a92 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -138,8 +138,8 @@ bool RNANodeQuery::contains(const char *prop_identifier, const char *rna_path_co
return false;
}
- /* If substr != prop_identifier, it means that the substring is found further in prop_identifier,
- * and that thus index -1 is a valid memory location. */
+ /* If `substr != prop_identifier`, it means that the sub-string is found further in
+ * `prop_identifier`, and that thus index -1 is a valid memory location. */
const bool start_ok = substr == prop_identifier || substr[-1] == '.';
if (!start_ok) {
return false;