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')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc107
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.h16
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc15
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.h24
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_map.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc44
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc22
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc55
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_remove_noop.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_transitive.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.h6
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug.h6
-rw-r--r--source/blender/depsgraph/intern/debug/deg_time_average.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc8
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h18
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_physics.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc9
-rw-r--r--source/blender/depsgraph/intern/depsgraph_registry.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_relation.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc12
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_update.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc151
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_stats.h6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_visibility.cc147
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_visibility.h26
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.h6
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc7
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.h74
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_factory.h7
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_factory_impl.h6
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc9
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h23
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h19
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_time.h6
70 files changed, 641 insertions, 431 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index a3cd821e82f..5353f71685c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -29,6 +29,7 @@
#include "intern/depsgraph_tag.h"
#include "intern/depsgraph_type.h"
#include "intern/eval/deg_eval_copy_on_write.h"
+#include "intern/eval/deg_eval_visibility.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_id.h"
@@ -63,7 +64,7 @@ DepsgraphBuilder::DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuild
{
}
-bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
+bool DepsgraphBuilder::need_pull_base_into_graph(const Base *base)
{
/* Simple check: enabled bases are always part of dependency graph. */
const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
@@ -71,10 +72,15 @@ bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
if (base->flag & base_flag) {
return true;
}
+
/* More involved check: since we don't support dynamic changes in dependency graph topology and
* all visible objects are to be part of dependency graph, we pull all objects which has animated
* visibility. */
- Object *object = base->object;
+ return is_object_visibility_animated(base->object);
+}
+
+bool DepsgraphBuilder::is_object_visibility_animated(const Object *object)
+{
AnimatedPropertyID property_id;
if (graph_->mode == DAG_EVAL_VIEWPORT) {
property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_viewport");
@@ -89,7 +95,7 @@ bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
return cache_->isPropertyAnimated(&object->id, property_id);
}
-bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel *pchan)
+bool DepsgraphBuilder::check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan)
{
BLI_assert(object->type == OB_ARMATURE);
if (pchan == nullptr || pchan->bone == nullptr) {
@@ -109,12 +115,13 @@ bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel
cache_->isPropertyAnimated(&armature->id, property_id);
}
-bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan)
+bool DepsgraphBuilder::check_pchan_has_bbone_segments(const Object *object,
+ const bPoseChannel *pchan)
{
return check_pchan_has_bbone(object, pchan);
}
-bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const char *bone_name)
+bool DepsgraphBuilder::check_pchan_has_bbone_segments(const Object *object, const char *bone_name)
{
const bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name);
return check_pchan_has_bbone_segments(object, pchan);
@@ -126,97 +133,9 @@ bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const char
/** \name Builder Finalizer.
* \{ */
-namespace {
-
-void deg_graph_build_flush_visibility(Depsgraph *graph)
-{
- enum {
- DEG_NODE_VISITED = (1 << 0),
- };
-
- BLI_Stack *stack = BLI_stack_new(sizeof(OperationNode *), "DEG flush layers stack");
- for (IDNode *id_node : graph->id_nodes) {
- for (ComponentNode *comp_node : id_node->components.values()) {
- comp_node->affects_directly_visible |= id_node->is_directly_visible;
-
- /* Enforce "visibility" of the synchronization component.
- *
- * This component is never connected to other ID nodes, and hence can not be handled in the
- * same way as other components needed for evaluation. It is only needed for proper
- * evaluation of the ID node it belongs to.
- *
- * The design is such that the synchronization is supposed to happen whenever any part of the
- * ID changed/evaluated. Here we mark the component as "visible" so that genetic recalc flag
- * flushing and scheduling will handle the component in a generic manner. */
- if (comp_node->type == NodeType::SYNCHRONIZATION) {
- comp_node->affects_directly_visible = true;
- }
- }
- }
-
- for (OperationNode *op_node : graph->operations) {
- op_node->custom_flags = 0;
- op_node->num_links_pending = 0;
- for (Relation *rel : op_node->outlinks) {
- if ((rel->from->type == NodeType::OPERATION) && (rel->flag & RELATION_FLAG_CYCLIC) == 0) {
- ++op_node->num_links_pending;
- }
- }
- if (op_node->num_links_pending == 0) {
- BLI_stack_push(stack, &op_node);
- op_node->custom_flags |= DEG_NODE_VISITED;
- }
- }
-
- while (!BLI_stack_is_empty(stack)) {
- OperationNode *op_node;
- BLI_stack_pop(stack, &op_node);
- /* Flush layers to parents. */
- for (Relation *rel : op_node->inlinks) {
- if (rel->from->type == NodeType::OPERATION) {
- OperationNode *op_from = (OperationNode *)rel->from;
- ComponentNode *comp_from = op_from->owner;
- const bool target_directly_visible = op_node->owner->affects_directly_visible;
-
- /* Visibility component forces all components of the current ID to be considered as
- * affecting directly visible. */
- if (comp_from->type == NodeType::VISIBILITY) {
- if (target_directly_visible) {
- IDNode *id_node_from = comp_from->owner;
- for (ComponentNode *comp_node : id_node_from->components.values()) {
- comp_node->affects_directly_visible |= target_directly_visible;
- }
- }
- }
- else {
- comp_from->affects_directly_visible |= target_directly_visible;
- }
- }
- }
- /* Schedule parent nodes. */
- for (Relation *rel : op_node->inlinks) {
- if (rel->from->type == NodeType::OPERATION) {
- OperationNode *op_from = (OperationNode *)rel->from;
- if ((rel->flag & RELATION_FLAG_CYCLIC) == 0) {
- BLI_assert(op_from->num_links_pending > 0);
- --op_from->num_links_pending;
- }
- if ((op_from->num_links_pending == 0) && (op_from->custom_flags & DEG_NODE_VISITED) == 0) {
- BLI_stack_push(stack, &op_from);
- op_from->custom_flags |= DEG_NODE_VISITED;
- }
- }
- }
- }
- BLI_stack_free(stack);
-}
-
-} // namespace
-
void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
{
- /* Make sure dependencies of visible ID data-blocks are visible. */
- deg_graph_build_flush_visibility(graph);
+ deg_graph_flush_visibility_flags(graph);
deg_graph_remove_unused_noops(graph);
/* Re-tag IDs for update if it was tagged before the relations
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index 8fbe255ed9d..c44e5fd5f4d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -13,8 +13,7 @@ struct Main;
struct Object;
struct bPoseChannel;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
class DepsgraphBuilderCache;
@@ -23,11 +22,13 @@ class DepsgraphBuilder {
public:
virtual ~DepsgraphBuilder() = default;
- virtual bool need_pull_base_into_graph(Base *base);
+ virtual bool need_pull_base_into_graph(const Base *base);
- virtual bool check_pchan_has_bbone(Object *object, const bPoseChannel *pchan);
- virtual bool check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan);
- virtual bool check_pchan_has_bbone_segments(Object *object, const char *bone_name);
+ virtual bool is_object_visibility_animated(const Object *object);
+
+ virtual bool check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan);
+ virtual bool check_pchan_has_bbone_segments(const Object *object, const bPoseChannel *pchan);
+ virtual bool check_pchan_has_bbone_segments(const Object *object, const char *bone_name);
protected:
/* NOTE: The builder does NOT take ownership over any of those resources. */
@@ -43,5 +44,4 @@ bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig);
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base);
void deg_graph_build_finalize(Main *bmain, Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index 7f88f54fdca..6474f853390 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -35,13 +35,13 @@ AnimatedPropertyID::AnimatedPropertyID(const PointerRNA &pointer_rna,
{
}
-AnimatedPropertyID::AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name)
+AnimatedPropertyID::AnimatedPropertyID(const ID *id, StructRNA *type, const char *property_name)
: data(id)
{
property_rna = RNA_struct_type_find_property(type, property_name);
}
-AnimatedPropertyID::AnimatedPropertyID(ID * /*id*/,
+AnimatedPropertyID::AnimatedPropertyID(const ID * /*id*/,
StructRNA *type,
void *data,
const char *property_name)
@@ -100,13 +100,13 @@ AnimatedPropertyStorage::AnimatedPropertyStorage() : is_fully_initialized(false)
{
}
-void AnimatedPropertyStorage::initializeFromID(DepsgraphBuilderCache *builder_cache, ID *id)
+void AnimatedPropertyStorage::initializeFromID(DepsgraphBuilderCache *builder_cache, const ID *id)
{
AnimatedPropertyCallbackData data;
- RNA_id_pointer_create(id, &data.pointer_rna);
+ RNA_id_pointer_create(const_cast<ID *>(id), &data.pointer_rna);
data.animated_property_storage = this;
data.builder_cache = builder_cache;
- BKE_fcurves_id_cb(id, animated_property_cb, &data);
+ BKE_fcurves_id_cb(const_cast<ID *>(id), animated_property_cb, &data);
}
void AnimatedPropertyStorage::tagPropertyAsAnimated(const AnimatedPropertyID &property_id)
@@ -147,13 +147,14 @@ DepsgraphBuilderCache::~DepsgraphBuilderCache()
}
}
-AnimatedPropertyStorage *DepsgraphBuilderCache::ensureAnimatedPropertyStorage(ID *id)
+AnimatedPropertyStorage *DepsgraphBuilderCache::ensureAnimatedPropertyStorage(const ID *id)
{
return animated_property_storage_map_.lookup_or_add_cb(
id, []() { return new AnimatedPropertyStorage(); });
}
-AnimatedPropertyStorage *DepsgraphBuilderCache::ensureInitializedAnimatedPropertyStorage(ID *id)
+AnimatedPropertyStorage *DepsgraphBuilderCache::ensureInitializedAnimatedPropertyStorage(
+ const ID *id)
{
AnimatedPropertyStorage *animated_property_storage = ensureAnimatedPropertyStorage(id);
if (!animated_property_storage->is_fully_initialized) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.h b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
index 2d2bdeaf825..d85269c0f8b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
@@ -17,8 +17,7 @@ struct ID;
struct PointerRNA;
struct PropertyRNA;
-namespace blender {
-namespace deg {
+namespace blender::deg {
class DepsgraphBuilderCache;
@@ -28,14 +27,14 @@ class AnimatedPropertyID {
AnimatedPropertyID();
AnimatedPropertyID(const PointerRNA *pointer_rna, const PropertyRNA *property_rna);
AnimatedPropertyID(const PointerRNA &pointer_rna, const PropertyRNA *property_rna);
- AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name);
- AnimatedPropertyID(ID *id, StructRNA *type, void *data, const char *property_name);
+ AnimatedPropertyID(const ID *id, StructRNA *type, const char *property_name);
+ AnimatedPropertyID(const ID *id, StructRNA *type, void *data, const char *property_name);
uint64_t hash() const;
friend bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b);
/* Corresponds to PointerRNA.data. */
- void *data;
+ const void *data;
const PropertyRNA *property_rna;
MEM_CXX_CLASS_ALLOC_FUNCS("AnimatedPropertyID");
@@ -45,7 +44,7 @@ class AnimatedPropertyStorage {
public:
AnimatedPropertyStorage();
- void initializeFromID(DepsgraphBuilderCache *builder_cache, ID *id);
+ void initializeFromID(DepsgraphBuilderCache *builder_cache, const ID *id);
void tagPropertyAsAnimated(const AnimatedPropertyID &property_id);
void tagPropertyAsAnimated(const PointerRNA *pointer_rna, const PropertyRNA *property_rna);
@@ -59,7 +58,7 @@ class AnimatedPropertyStorage {
bool is_fully_initialized;
/* indexed by PointerRNA.data. */
- Set<void *> animated_objects_set;
+ Set<const void *> animated_objects_set;
Set<AnimatedPropertyID> animated_properties_set;
MEM_CXX_CLASS_ALLOC_FUNCS("AnimatedPropertyStorage");
@@ -71,8 +70,8 @@ class DepsgraphBuilderCache {
~DepsgraphBuilderCache();
/* Makes sure storage for animated properties exists and initialized for the given ID. */
- AnimatedPropertyStorage *ensureAnimatedPropertyStorage(ID *id);
- AnimatedPropertyStorage *ensureInitializedAnimatedPropertyStorage(ID *id);
+ AnimatedPropertyStorage *ensureAnimatedPropertyStorage(const ID *id);
+ AnimatedPropertyStorage *ensureInitializedAnimatedPropertyStorage(const ID *id);
/* Shortcuts to go through ensureInitializedAnimatedPropertyStorage and its
* isPropertyAnimated.
@@ -82,7 +81,7 @@ class DepsgraphBuilderCache {
*
* TODO(sergey): Technically, this makes this class something else than just a cache, but what is
* the better name? */
- template<typename... Args> bool isPropertyAnimated(ID *id, Args... args)
+ template<typename... Args> bool isPropertyAnimated(const ID *id, Args... args)
{
AnimatedPropertyStorage *animated_property_storage = ensureInitializedAnimatedPropertyStorage(
id);
@@ -96,10 +95,9 @@ class DepsgraphBuilderCache {
return animated_property_storage->isAnyPropertyAnimated(ptr);
}
- Map<ID *, AnimatedPropertyStorage *> animated_property_storage_map_;
+ Map<const ID *, AnimatedPropertyStorage *> animated_property_storage_map_;
MEM_CXX_CLASS_ALLOC_FUNCS("DepsgraphBuilderCache");
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.h b/source/blender/depsgraph/intern/builder/deg_builder_cycle.h
index 8e94e0ae21f..83d25f8c23f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.h
@@ -7,13 +7,11 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
/* Detect and solve dependency cycles. */
void deg_graph_detect_cycles(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.h b/source/blender/depsgraph/intern/builder/deg_builder_map.h
index 50ebadeb382..2b2b4d089e9 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_map.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_map.h
@@ -11,8 +11,7 @@
struct ID;
-namespace blender {
-namespace deg {
+namespace blender::deg {
class BuilderMap {
public:
@@ -60,5 +59,4 @@ class BuilderMap {
Map<ID *, int> id_tags_;
};
-} // namespace deg
-} // namespace blender
+} // 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 19e8e15fabd..b6b835bbeec 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -26,6 +26,7 @@
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
+#include "DNA_curves_types.h"
#include "DNA_effect_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_key_types.h"
@@ -109,6 +110,7 @@
#include "intern/depsgraph_tag.h"
#include "intern/depsgraph_type.h"
#include "intern/eval/deg_eval_copy_on_write.h"
+#include "intern/eval/deg_eval_visibility.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_id.h"
@@ -176,18 +178,32 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
ComponentNode *comp_cow = id_node->add_component(NodeType::COPY_ON_WRITE);
OperationNode *op_cow = comp_cow->add_operation(
[id_node](::Depsgraph *depsgraph) { deg_evaluate_copy_on_write(depsgraph, id_node); },
- OperationCode::COPY_ON_WRITE,
- "",
- -1);
+ OperationCode::COPY_ON_WRITE);
graph_->operations.append(op_cow);
}
ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY);
- OperationNode *visibility_operation = visibility_component->add_operation(
- nullptr, OperationCode::OPERATION, "", -1);
+ OperationNode *visibility_operation;
+
+ /* Optimization: currently only objects need a special visibility evaluation. For the rest ID
+ * types keep the node as a NO-OP so that relations can still be routed, but without penalty
+ * during the graph evaluation. */
+ if (id_type == ID_OB) {
+ visibility_operation = visibility_component->add_operation(
+ [id_node](::Depsgraph *depsgraph) {
+ deg_evaluate_object_node_visibility(depsgraph, id_node);
+ },
+ OperationCode::VISIBILITY);
+ }
+ else {
+ visibility_operation = visibility_component->add_operation(nullptr,
+ OperationCode::VISIBILITY);
+ }
+
/* Pin the node so that it and its relations are preserved by the unused nodes/relations
* deletion. This is mainly to make it easier to debug visibility. */
- visibility_operation->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
+ visibility_operation->flag |= (OperationFlag::DEPSOP_FLAG_PINNED |
+ OperationFlag::DEPSOP_FLAG_AFFECTS_VISIBILITY);
graph_->operations.append(visibility_operation);
}
return id_node;
@@ -669,7 +685,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
IDNode *id_node;
if (built_map_.checkIsBuiltAndTag(collection)) {
id_node = find_id_node(&collection->id);
- if (is_collection_visible && id_node->is_directly_visible == false &&
+ if (is_collection_visible && id_node->is_visible_on_build == false &&
id_node->is_collection_fully_expanded == true) {
/* Collection became visible, make sure nested collections and
* objects are poked with the new visibility flag, since they
@@ -686,7 +702,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
else {
/* Collection itself. */
id_node = add_id_node(&collection->id);
- id_node->is_directly_visible = is_collection_visible;
+ id_node->is_visible_on_build = is_collection_visible;
build_idproperties(collection->id.properties);
add_operation_node(&collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE);
@@ -733,7 +749,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
build_object_flags(base_index, object, linked_state);
}
id_node->linked_state = max(id_node->linked_state, linked_state);
- id_node->is_directly_visible |= is_visible;
+ id_node->is_visible_on_build |= is_visible;
id_node->has_base |= (base_index != -1);
/* There is no relation path which will connect current object with all the ones which come
@@ -752,10 +768,10 @@ void DepsgraphNodeBuilder::build_object(int base_index,
* Probably need to assign that to something non-nullptr, but then the logic here will still be
* somewhat weird. */
if (scene_ != nullptr && object == scene_->camera) {
- id_node->is_directly_visible = true;
+ id_node->is_visible_on_build = true;
}
else {
- id_node->is_directly_visible = is_visible;
+ id_node->is_visible_on_build = is_visible;
}
id_node->has_base |= (base_index != -1);
/* Various flags, flushing from bases/collections. */
@@ -1583,8 +1599,14 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata)
break;
}
case ID_CV: {
+ Curves *curves_id = reinterpret_cast<Curves *>(obdata);
+
op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
op_node->set_as_entry();
+
+ if (curves_id->surface != nullptr) {
+ build_object(-1, curves_id->surface, DEG_ID_LINKED_INDIRECTLY, false);
+ }
break;
}
case ID_PT: {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 27c3a3a36a3..b3fada2547d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -51,8 +51,7 @@ struct bNodeTree;
struct bPoseChannel;
struct bSound;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct ComponentNode;
struct Depsgraph;
@@ -319,5 +318,4 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
BuilderMap built_map_;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
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 32ec94211a0..5af9e7d4fe9 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
@@ -92,14 +92,20 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
int base_index = 0;
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
/* object itself */
- if (need_pull_base_into_graph(base)) {
- /* NOTE: We consider object visible even if it's currently
- * restricted by the base/restriction flags. Otherwise its drivers
- * will never be evaluated.
- *
- * TODO(sergey): Need to go more granular on visibility checks. */
- build_object(base_index, base->object, linked_state, true);
- base_index++;
+ if (!need_pull_base_into_graph(base)) {
+ continue;
+ }
+
+ /* NOTE: We consider object visible even if it's currently
+ * restricted by the base/restriction flags. Otherwise its drivers
+ * will never be evaluated.
+ *
+ * TODO(sergey): Need to go more granular on visibility checks. */
+ build_object(base_index, base->object, linked_state, true);
+ base_index++;
+
+ if (!graph_->has_animated_visibility) {
+ graph_->has_animated_visibility |= is_object_visibility_animated(base->object);
}
}
build_layer_collections(&view_layer->layer_collections);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h
index 2f98c8b419c..afb3a3c22bd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h
@@ -9,8 +9,7 @@
#include "intern/depsgraph_type.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct RootPChanMap {
/** Debug contents of map. */
@@ -30,5 +29,4 @@ struct RootPChanMap {
Map<StringRefNull, Set<StringRefNull>> map_;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index f5f4db73552..09d9d7448f9 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -27,6 +27,7 @@
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
+#include "DNA_curves_types.h"
#include "DNA_effect_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_key_types.h"
@@ -723,7 +724,7 @@ void DepsgraphRelationBuilder::build_object(Object *object)
const BuilderStack::ScopedEntry stack_entry = stack_.trace(object->id);
- /* Object Transforms */
+ /* Object Transforms. */
OperationCode base_op = (object->parent) ? OperationCode::TRANSFORM_PARENT :
OperationCode::TRANSFORM_LOCAL;
OperationKey base_op_key(&object->id, NodeType::TRANSFORM, base_op);
@@ -736,9 +737,12 @@ void DepsgraphRelationBuilder::build_object(Object *object)
OperationKey final_transform_key(
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL);
OperationKey ob_eval_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
+
add_relation(init_transform_key, local_transform_key, "Transform Init");
+
/* Various flags, flushing from bases/collections. */
build_object_layer_component_relations(object);
+
/* Parenting. */
if (object->parent != nullptr) {
/* Make sure parent object's relations are built. */
@@ -748,30 +752,35 @@ void DepsgraphRelationBuilder::build_object(Object *object)
/* Local -> parent. */
add_relation(local_transform_key, parent_transform_key, "ObLocal -> ObParent");
}
+
/* Modifiers. */
if (object->modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_modifiers_foreach_ID_link(object, modifier_walk, &data);
}
+
/* Grease Pencil Modifiers. */
if (object->greasepencil_modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_gpencil_modifiers_foreach_ID_link(object, modifier_walk, &data);
}
+
/* Shader FX. */
if (object->shader_fx.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_shaderfx_foreach_ID_link(object, modifier_walk, &data);
}
+
/* Constraints. */
if (object->constraints.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_constraints_id_loop(&object->constraints, constraint_walk, &data);
}
+
/* Object constraints. */
OperationKey object_transform_simulation_init_key(
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT);
@@ -798,32 +807,48 @@ void DepsgraphRelationBuilder::build_object(Object *object)
final_transform_key,
"Simulation -> Final Transform");
}
+
build_idproperties(object->id.properties);
+
/* Animation data */
build_animdata(&object->id);
+
/* Object data. */
build_object_data(object);
+
/* Particle systems. */
if (object->particlesystem.first != nullptr) {
build_particle_systems(object);
}
+
/* Force field Texture. */
if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
(object->pd->tex != nullptr)) {
build_texture(object->pd->tex);
}
+
/* Object dupligroup. */
if (object->instance_collection != nullptr) {
build_collection(nullptr, object, object->instance_collection);
}
+
/* Point caches. */
build_object_pointcache(object);
+
/* Synchronization back to original object. */
OperationKey synchronize_key(
&object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL);
add_relation(final_transform_key, synchronize_key, "Synchronize to Original");
+
/* Parameters. */
build_parameters(&object->id);
+
+ /* Visibility.
+ * Evaluate visibility node after the object's base_flags has been updated to the current state
+ * of collections restrict and object's restrict flags. */
+ const ComponentKey object_from_layer_entry_key(&object->id, NodeType::OBJECT_FROM_LAYER);
+ const ComponentKey visibility_key(&object->id, NodeType::VISIBILITY);
+ add_relation(object_from_layer_entry_key, visibility_key, "Object Visibility");
}
/* NOTE: Implies that the object has base in the current view layer. */
@@ -2207,8 +2232,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
* data mask to be used. We add relation here to ensure object is never
* evaluated prior to Scene's CoW is ready. */
OperationKey scene_key(&scene_->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL);
- Relation *rel = add_relation(scene_key, obdata_ubereval_key, "CoW Relation");
- rel->flag |= RELATION_FLAG_NO_FLUSH;
+ add_relation(scene_key, obdata_ubereval_key, "CoW Relation", RELATION_FLAG_NO_FLUSH);
/* Modifiers */
if (object->modifiers.first != nullptr) {
ModifierUpdateDepsgraphContext ctx = {};
@@ -2223,9 +2247,9 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
mti->updateDepsgraph(md, &ctx);
}
- if (BKE_object_modifier_use_time(scene_, object, md)) {
+ if (BKE_modifier_depends_ontime(scene_, md)) {
TimeSourceKey time_src_key;
- add_relation(time_src_key, obdata_ubereval_key, "Time Source");
+ add_relation(time_src_key, obdata_ubereval_key, "Time Source -> Modifier");
}
}
}
@@ -2242,7 +2266,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
mti->updateDepsgraph(md, &ctx, graph_->mode);
}
- if (BKE_object_modifier_gpencil_use_time(object, md)) {
+ if (BKE_gpencil_modifier_depends_ontime(md)) {
TimeSourceKey time_src_key;
add_relation(time_src_key, obdata_ubereval_key, "Time Source");
}
@@ -2260,7 +2284,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
fxi->updateDepsgraph(fx, &ctx);
}
- if (BKE_object_shaderfx_use_time(object, fx)) {
+ if (BKE_shaderfx_depends_ontime(fx)) {
TimeSourceKey time_src_key;
add_relation(time_src_key, obdata_ubereval_key, "Time Source");
}
@@ -2436,8 +2460,16 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
}
break;
}
- case ID_CV:
+ case ID_CV: {
+ Curves *curves_id = reinterpret_cast<Curves *>(obdata);
+ if (curves_id->surface != nullptr) {
+ build_object(curves_id->surface);
+
+ /* The relations between the surface and the curves are handled as part of the modifier
+ * stack building. */
+ }
break;
+ }
case ID_PT:
break;
case ID_VO: {
@@ -2493,6 +2525,13 @@ void DepsgraphRelationBuilder::build_camera(Camera *camera)
ComponentKey camera_parameters_key(&camera->id, NodeType::PARAMETERS);
ComponentKey dof_ob_key(&camera->dof.focus_object->id, NodeType::TRANSFORM);
add_relation(dof_ob_key, camera_parameters_key, "Camera DOF");
+ if (camera->dof.focus_subtarget[0]) {
+ OperationKey target_key(&camera->dof.focus_object->id,
+ NodeType::BONE,
+ camera->dof.focus_subtarget,
+ OperationCode::BONE_DONE);
+ add_relation(target_key, camera_parameters_key, "Camera DOF subtarget");
+ }
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index dbe2b364a68..65d06fc4c23 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -70,8 +70,7 @@ struct bSound;
struct PropertyRNA;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct ComponentNode;
struct DepsNodeHandle;
@@ -384,7 +383,6 @@ struct DepsNodeHandle {
const char *default_name;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
#include "intern/builder/deg_builder_relations_impl.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h
index e517dd6a927..9860b17fd56 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h
@@ -15,8 +15,7 @@
struct FCurve;
-namespace blender {
-namespace deg {
+namespace blender::deg {
/* Helper class for determining which relations are needed between driver evaluation nodes. */
class DriverDescriptor {
@@ -59,5 +58,4 @@ class DriverDescriptor {
bool resolve_rna();
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
index aba4a011e72..76066ce97a7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
@@ -15,8 +15,7 @@
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
template<typename KeyType>
OperationNode *DepsgraphRelationBuilder::find_operation_node(const KeyType &key)
@@ -209,5 +208,4 @@ bool DepsgraphRelationBuilder::is_same_nodetree_node_dependency(const KeyFrom &k
return true;
}
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.h b/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.h
index 922d2d7dc05..ad10eb7cd10 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.h
@@ -7,13 +7,11 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
/* Remove all no-op nodes that have zero outgoing relations. */
void deg_graph_remove_unused_noops(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index ac7a5bc2f30..5202ada5408 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -271,7 +271,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
RNA_struct_is_a(ptr->type, &RNA_LatticePoint) ||
RNA_struct_is_a(ptr->type, &RNA_MeshUVLoop) ||
RNA_struct_is_a(ptr->type, &RNA_MeshLoopColor) ||
- RNA_struct_is_a(ptr->type, &RNA_VertexGroupElement)) {
+ RNA_struct_is_a(ptr->type, &RNA_VertexGroupElement) ||
+ RNA_struct_is_a(ptr->type, &RNA_ShaderFx)) {
/* When modifier is used as FROM operation this is likely referencing to
* the property (for example, modifier's influence).
* But when it's used as TO operation, this is geometry component. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.h b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
index 4f482d4352d..9baa956bd80 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
@@ -14,8 +14,7 @@ struct ID;
struct PointerRNA;
struct PropertyRNA;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
struct Node;
@@ -94,5 +93,4 @@ class RNANodeQuery {
bool rna_prop_affects_parameters_node(const PointerRNA *ptr, const PropertyRNA *prop);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.h b/source/blender/depsgraph/intern/builder/deg_builder_transitive.h
index 8b208610203..63016431eec 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.h
@@ -7,13 +7,11 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
/* Performs a transitive reduction to remove redundant relations. */
void deg_graph_transitive_reduction(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc
index 540b8e173f1..815a06d03d1 100644
--- a/source/blender/depsgraph/intern/builder/pipeline.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline.cc
@@ -90,7 +90,7 @@ void AbstractBuilderPipeline::build_step_finalize()
}
#endif
/* Relations are up to date. */
- deg_graph_->need_update = false;
+ deg_graph_->need_update_relations = false;
}
unique_ptr<DepsgraphNodeBuilder> AbstractBuilderPipeline::construct_node_builder()
diff --git a/source/blender/depsgraph/intern/builder/pipeline.h b/source/blender/depsgraph/intern/builder/pipeline.h
index b106e73b97c..7568aa78106 100644
--- a/source/blender/depsgraph/intern/builder/pipeline.h
+++ b/source/blender/depsgraph/intern/builder/pipeline.h
@@ -16,8 +16,7 @@ struct Main;
struct Scene;
struct ViewLayer;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
class DepsgraphNodeBuilder;
@@ -57,5 +56,4 @@ class AbstractBuilderPipeline {
virtual void build_relations(DepsgraphRelationBuilder &relation_builder) = 0;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
index 74d151c65d7..6bc3b59a9d6 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
@@ -20,7 +20,7 @@ class AllObjectsNodeBuilder : public DepsgraphNodeBuilder {
{
}
- bool need_pull_base_into_graph(Base * /*base*/) override
+ bool need_pull_base_into_graph(const Base * /*base*/) override
{
return true;
}
@@ -33,7 +33,7 @@ class AllObjectsRelationBuilder : public DepsgraphRelationBuilder {
{
}
- bool need_pull_base_into_graph(Base * /*base*/) override
+ bool need_pull_base_into_graph(const Base * /*base*/) override
{
return true;
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.h b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
index 75d9605dec7..fde5e7e2163 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
@@ -9,8 +9,7 @@
#include "pipeline_view_layer.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
/* Builds a dependency graph that contains all objects in the view layer.
* This is contrary to the regular ViewLayerBuilderPipeline, which is limited to visible objects
@@ -24,5 +23,4 @@ class AllObjectsBuilderPipeline : public ViewLayerBuilderPipeline {
virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.h b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
index 3325741c94a..304f2d4ec9a 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_compositor.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
@@ -11,8 +11,7 @@
struct bNodeTree;
-namespace blender {
-namespace deg {
+namespace blender::deg {
class CompositorBuilderPipeline : public AbstractBuilderPipeline {
public:
@@ -26,5 +25,4 @@ class CompositorBuilderPipeline : public AbstractBuilderPipeline {
bNodeTree *nodetree_;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
index ee10b28a306..e256c8271f2 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
@@ -39,7 +39,7 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
{
}
- bool need_pull_base_into_graph(Base *base) override
+ bool need_pull_base_into_graph(const Base *base) override
{
if (!filter_.contains(&base->object->id)) {
return false;
@@ -61,7 +61,7 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
{
}
- bool need_pull_base_into_graph(Base *base) override
+ bool need_pull_base_into_graph(const Base *base) override
{
if (!filter_.contains(&base->object->id)) {
return false;
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
index a2c75c048cb..c277d44aaad 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
@@ -9,8 +9,7 @@
#include "pipeline.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
/* Optimized builders for dependency graph built from a given set of IDs.
*
@@ -37,5 +36,4 @@ class FromIDsBuilderPipeline : public AbstractBuilderPipeline {
Span<ID *> ids_;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.h b/source/blender/depsgraph/intern/builder/pipeline_render.h
index cb704f84c59..7eb65168ea6 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_render.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.h
@@ -9,8 +9,7 @@
#include "pipeline.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
class RenderBuilderPipeline : public AbstractBuilderPipeline {
public:
@@ -21,5 +20,4 @@ class RenderBuilderPipeline : public AbstractBuilderPipeline {
virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
index 18b9ce5d5ff..ffd6fa07776 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
@@ -9,8 +9,7 @@
#include "pipeline.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
class ViewLayerBuilderPipeline : public AbstractBuilderPipeline {
public:
@@ -21,5 +20,4 @@ class ViewLayerBuilderPipeline : public AbstractBuilderPipeline {
virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/debug/deg_debug.h b/source/blender/depsgraph/intern/debug/deg_debug.h
index ee6c5b046b7..8f18bd70d36 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug.h
+++ b/source/blender/depsgraph/intern/debug/deg_debug.h
@@ -14,8 +14,7 @@
#include "DEG_depsgraph_debug.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
class DepsgraphDebug {
public:
@@ -74,5 +73,4 @@ bool terminal_do_color(void);
string color_for_pointer(const void *pointer);
string color_end(void);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/debug/deg_time_average.h b/source/blender/depsgraph/intern/debug/deg_time_average.h
index cc47f03b221..d4eb05a9ddb 100644
--- a/source/blender/depsgraph/intern/debug/deg_time_average.h
+++ b/source/blender/depsgraph/intern/debug/deg_time_average.h
@@ -7,8 +7,7 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
/* Utility class which takes care of calculating average of time series, such as FPS counters. */
template<int MaxSamples> class AveragedTimeSampler {
@@ -52,5 +51,4 @@ template<int MaxSamples> class AveragedTimeSampler {
int next_sample_index_;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 4514084059a..316d0b615c6 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -45,9 +45,11 @@ namespace blender::deg {
Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
: time_source(nullptr),
- need_update(true),
- need_visibility_update(true),
- need_visibility_time_update(false),
+ has_animated_visibility(false),
+ need_update_relations(true),
+ need_update_nodes_visibility(true),
+ need_tag_id_on_graph_visibility_update(true),
+ need_tag_id_on_graph_visibility_time_update(false),
bmain(bmain),
scene(scene),
view_layer(view_layer),
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index ca4ce058904..2f88199384d 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -31,8 +31,7 @@ struct ID;
struct Scene;
struct ViewLayer;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct IDNode;
struct Node;
@@ -89,13 +88,19 @@ struct Depsgraph {
/* Top-level time source node. */
TimeSourceNode *time_source;
+ /* The graph contains data-blocks whose visibility depends on evaluation (driven or animated). */
+ bool has_animated_visibility;
+
/* Indicates whether relations needs to be updated. */
- bool need_update;
+ bool need_update_relations;
+
+ /* Indicates whether indirect effect of nodes on a directly visible ones needs to be updated. */
+ bool need_update_nodes_visibility;
/* Indicated whether IDs in this graph are to be tagged as if they first appear visible, with
* an optional tag for their animation (time) update. */
- bool need_visibility_update;
- bool need_visibility_time_update;
+ bool need_tag_id_on_graph_visibility_update;
+ bool need_tag_id_on_graph_visibility_time_update;
/* Indicates which ID types were updated. */
char id_type_updated[INDEX_ID_MAX];
@@ -162,5 +167,4 @@ struct Depsgraph {
MEM_CXX_CLASS_ALLOC_FUNCS("Depsgraph");
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index d52e95cb620..8dc84809516 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -296,7 +296,7 @@ void DEG_graph_tag_relations_update(Depsgraph *graph)
{
DEG_DEBUG_PRINTF(graph, TAG, "%s: Tagging relations for update.\n", __func__);
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- deg_graph->need_update = true;
+ deg_graph->need_update_relations = true;
/* NOTE: When relations are updated, it's quite possible that
* we've got new bases in the scene. This means, we need to
* re-create flat array of bases in view layer.
@@ -312,7 +312,7 @@ void DEG_graph_tag_relations_update(Depsgraph *graph)
void DEG_graph_relations_update(Depsgraph *graph)
{
deg::Depsgraph *deg_graph = (deg::Depsgraph *)graph;
- if (!deg_graph->need_update) {
+ if (!deg_graph->need_update_relations) {
/* Graph is up to date, nothing to do. */
return;
}
diff --git a/source/blender/depsgraph/intern/depsgraph_physics.h b/source/blender/depsgraph/intern/depsgraph_physics.h
index a8d37f76b09..2105eb62ce1 100644
--- a/source/blender/depsgraph/intern/depsgraph_physics.h
+++ b/source/blender/depsgraph/intern/depsgraph_physics.h
@@ -10,8 +10,7 @@
struct Collection;
struct ListBase;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -21,5 +20,4 @@ ListBase *build_collision_relations(Depsgraph *graph,
unsigned int modifier_type);
void clear_physics_relations(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 6ffc711a475..9a047c70d01 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -328,7 +328,7 @@ bool DEG_is_fully_evaluated(const struct Depsgraph *depsgraph)
{
const deg::Depsgraph *deg_graph = (const deg::Depsgraph *)depsgraph;
/* Check whether relations are up to date. */
- if (deg_graph->need_update) {
+ if (deg_graph->need_update_relations) {
return false;
}
/* Check whether IDs are up to date. */
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index bcde1839a0f..171c9875e2a 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -219,7 +219,9 @@ bool deg_iterator_objects_step(DEGObjectIterData *data)
for (; data->id_node_index < data->num_id_nodes; data->id_node_index++) {
deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
- if (!id_node->is_directly_visible) {
+ /* Use the build time visibility so that the ID is not appearing/disappearing throughout
+ * animation export. */
+ if (!id_node->is_visible_on_build) {
continue;
}
@@ -338,10 +340,13 @@ static void DEG_iterator_ids_step(BLI_Iterator *iter, deg::IDNode *id_node, bool
{
ID *id_cow = id_node->id_cow;
- if (!id_node->is_directly_visible) {
+ /* Use the build time visibility so that the ID is not appearing/disappearing throughout
+ * animation export. */
+ if (!id_node->is_visible_on_build) {
iter->skip = true;
return;
}
+
if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) {
/* Node-tree is considered part of the data-block. */
bNodeTree *ntree = ntreeFromID(id_cow);
diff --git a/source/blender/depsgraph/intern/depsgraph_registry.h b/source/blender/depsgraph/intern/depsgraph_registry.h
index 2746f17590a..4ab63dcc77d 100644
--- a/source/blender/depsgraph/intern/depsgraph_registry.h
+++ b/source/blender/depsgraph/intern/depsgraph_registry.h
@@ -11,8 +11,7 @@
struct Main;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -20,5 +19,4 @@ void register_graph(Depsgraph *depsgraph);
void unregister_graph(Depsgraph *depsgraph);
Span<Depsgraph *> get_all_registered_graphs(Main *bmain);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph_relation.h b/source/blender/depsgraph/intern/depsgraph_relation.h
index 4d51ad85878..1bacb9abfa6 100644
--- a/source/blender/depsgraph/intern/depsgraph_relation.h
+++ b/source/blender/depsgraph/intern/depsgraph_relation.h
@@ -9,8 +9,7 @@
#include "MEM_guardedalloc.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Node;
@@ -49,5 +48,4 @@ struct Relation {
MEM_CXX_CLASS_ALLOC_FUNCS("Relation");
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index b50081458ad..9cd5980d8fe 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -494,19 +494,19 @@ void deg_graph_node_tag_zero(Main *bmain,
void graph_tag_on_visible_update(Depsgraph *graph, const bool do_time)
{
- graph->need_visibility_update = true;
- graph->need_visibility_time_update |= do_time;
+ graph->need_tag_id_on_graph_visibility_update = true;
+ graph->need_tag_id_on_graph_visibility_time_update |= do_time;
}
} /* namespace */
void graph_tag_ids_for_visible_update(Depsgraph *graph)
{
- if (!graph->need_visibility_update) {
+ if (!graph->need_tag_id_on_graph_visibility_update) {
return;
}
- const bool do_time = graph->need_visibility_time_update;
+ const bool do_time = graph->need_tag_id_on_graph_visibility_time_update;
Main *bmain = graph->bmain;
/* NOTE: It is possible to have this function called with `do_time=false` first and later (prior
@@ -561,8 +561,8 @@ void graph_tag_ids_for_visible_update(Depsgraph *graph)
id_node->previously_visible_components_mask = id_node->visible_components_mask;
}
- graph->need_visibility_update = false;
- graph->need_visibility_time_update = false;
+ graph->need_tag_id_on_graph_visibility_update = false;
+ graph->need_tag_id_on_graph_visibility_time_update = false;
}
NodeType geometry_tag_to_component(const ID *id)
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.h b/source/blender/depsgraph/intern/depsgraph_tag.h
index a0518420bfb..b722aab5719 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.h
+++ b/source/blender/depsgraph/intern/depsgraph_tag.h
@@ -10,8 +10,7 @@
struct ID;
struct Main;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -29,5 +28,4 @@ void graph_id_tag_update(
* Will do nothing if the graph is not tagged for visibility update. */
void graph_tag_ids_for_visible_update(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph_type.h b/source/blender/depsgraph/intern/depsgraph_type.h
index 9cf14a831bc..9e21d124f83 100644
--- a/source/blender/depsgraph/intern/depsgraph_type.h
+++ b/source/blender/depsgraph/intern/depsgraph_type.h
@@ -34,8 +34,7 @@ struct Depsgraph;
struct CustomData_MeshMasks;
-namespace blender {
-namespace deg {
+namespace blender::deg {
/* Commonly used types. */
using std::deque;
@@ -153,5 +152,4 @@ struct DEGCustomDataMeshMasks {
}
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/depsgraph_update.h b/source/blender/depsgraph/intern/depsgraph_update.h
index 18f8e6acab6..c5a72157bd2 100644
--- a/source/blender/depsgraph/intern/depsgraph_update.h
+++ b/source/blender/depsgraph/intern/depsgraph_update.h
@@ -10,12 +10,10 @@
struct DEGEditorUpdateContext;
struct ID;
-namespace blender {
-namespace deg {
+namespace blender::deg {
void deg_editors_id_update(const DEGEditorUpdateContext *update_ctx, struct ID *id);
void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx, bool updated);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 2d9d40aede6..426e04a5cf9 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -37,6 +37,7 @@
#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/eval/deg_eval_flush.h"
#include "intern/eval/deg_eval_stats.h"
+#include "intern/eval/deg_eval_visibility.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_id.h"
@@ -69,6 +70,9 @@ enum class EvaluationStage {
* involved. */
COPY_ON_WRITE,
+ /* Evaluate actual ID nodes visiblity based on the current state of animation and drivers. */
+ DYNAMIC_VISIBILITY,
+
/* Threaded evaluation of all possible operations. */
THREADED_EVALUATION,
@@ -83,7 +87,8 @@ struct DepsgraphEvalState {
Depsgraph *graph;
bool do_stats;
EvaluationStage stage;
- bool need_single_thread_pass;
+ bool need_update_pending_parents = true;
+ bool need_single_thread_pass = false;
};
void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_node)
@@ -101,6 +106,12 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod
else {
operation_node->evaluate(depsgraph);
}
+
+ /* Clear the flag early on, allowing partial updates without re-evaluating the same node multiple
+ * times.
+ * This is a thread-safe modification as the node's flags are only read for a non-scheduled nodes
+ * and this node has been scheduled. */
+ operation_node->flag &= ~DEPSOP_FLAG_NEEDS_UPDATE;
}
void deg_task_run_func(TaskPool *pool, void *taskdata)
@@ -116,24 +127,31 @@ void deg_task_run_func(TaskPool *pool, void *taskdata)
schedule_children(state, operation_node, schedule_node_to_pool, pool);
}
-bool check_operation_node_visible(OperationNode *op_node)
+bool check_operation_node_visible(const DepsgraphEvalState *state, OperationNode *op_node)
{
const ComponentNode *comp_node = op_node->owner;
- /* Special exception, copy on write component is to be always evaluated,
- * to keep copied "database" in a consistent state. */
+ /* Special case for copy on write component: it is to be always evaluated, to keep copied
+ * "database" in a consistent state. */
if (comp_node->type == NodeType::COPY_ON_WRITE) {
return true;
}
- return comp_node->affects_directly_visible;
+
+ /* Special case for dynamic visiblity pass: the actual visibility is not yet known, so limit to
+ * only operations which affects visibility. */
+ if (state->stage == EvaluationStage::DYNAMIC_VISIBILITY) {
+ return op_node->flag & OperationFlag::DEPSOP_FLAG_AFFECTS_VISIBILITY;
+ }
+
+ return comp_node->affects_visible_id;
}
-void calculate_pending_parents_for_node(OperationNode *node)
+void calculate_pending_parents_for_node(const DepsgraphEvalState *state, OperationNode *node)
{
/* Update counters, applies for both visible and invisible IDs. */
node->num_links_pending = 0;
node->scheduled = false;
/* Invisible IDs requires no pending operations. */
- if (!check_operation_node_visible(node)) {
+ if (!check_operation_node_visible(state, node)) {
return;
}
/* No need to bother with anything if node is not tagged for update. */
@@ -147,7 +165,7 @@ void calculate_pending_parents_for_node(OperationNode *node)
* calculation, but how is it possible that visible object depends
* on an invisible? This is something what is prohibited after
* deg_graph_build_flush_layers(). */
- if (!check_operation_node_visible(from)) {
+ if (!check_operation_node_visible(state, from)) {
continue;
}
/* No need to wait for operation which is up to date. */
@@ -159,20 +177,24 @@ void calculate_pending_parents_for_node(OperationNode *node)
}
}
-void calculate_pending_parents(Depsgraph *graph)
+void calculate_pending_parents_if_needed(DepsgraphEvalState *state)
{
- for (OperationNode *node : graph->operations) {
- calculate_pending_parents_for_node(node);
+ if (!state->need_update_pending_parents) {
+ return;
}
+
+ for (OperationNode *node : state->graph->operations) {
+ calculate_pending_parents_for_node(state, node);
+ }
+
+ state->need_update_pending_parents = false;
}
void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph)
{
- const bool do_stats = state->do_stats;
- calculate_pending_parents(graph);
/* Clear tags and other things which needs to be clear. */
- for (OperationNode *node : graph->operations) {
- if (do_stats) {
+ if (state->do_stats) {
+ for (OperationNode *node : graph->operations) {
node->stats.reset_current();
}
}
@@ -197,11 +219,10 @@ bool need_evaluate_operation_at_stage(DepsgraphEvalState *state,
case EvaluationStage::COPY_ON_WRITE:
return (component_node->type == NodeType::COPY_ON_WRITE);
+ case EvaluationStage::DYNAMIC_VISIBILITY:
+ return operation_node->flag & OperationFlag::DEPSOP_FLAG_AFFECTS_VISIBILITY;
+
case EvaluationStage::THREADED_EVALUATION:
- /* Sanity check: copy-on-write node should be evaluated already. This will be indicated by
- * scheduled flag (we assume that scheduled operations have been actually handled by previous
- * stage). */
- BLI_assert(operation_node->scheduled || component_node->type != NodeType::COPY_ON_WRITE);
if (is_metaball_object_operation(operation_node)) {
state->need_single_thread_pass = true;
return false;
@@ -227,7 +248,7 @@ void schedule_node(DepsgraphEvalState *state,
ScheduleFunctionArgs... schedule_function_args)
{
/* No need to schedule nodes of invisible ID. */
- if (!check_operation_node_visible(node)) {
+ if (!check_operation_node_visible(state, node)) {
return;
}
/* No need to schedule operations which are not tagged for update, they are
@@ -302,8 +323,32 @@ void schedule_node_to_queue(OperationNode *node,
BLI_gsqueue_push(evaluation_queue, &node);
}
-void evaluate_graph_single_threaded(DepsgraphEvalState *state)
+/* Evaluate given stage of the dependency graph evaluation using multiple threads.
+ *
+ * NOTE: Will assign the `state->stage` to the given stage. */
+void evaluate_graph_threaded_stage(DepsgraphEvalState *state,
+ TaskPool *task_pool,
+ const EvaluationStage stage)
+{
+ state->stage = stage;
+
+ calculate_pending_parents_if_needed(state);
+
+ schedule_graph(state, schedule_node_to_pool, task_pool);
+ BLI_task_pool_work_and_wait(task_pool);
+}
+
+/* Evaluate remaining operations of the dependency graph in a single threaded manner. */
+void evaluate_graph_single_threaded_if_needed(DepsgraphEvalState *state)
{
+ if (!state->need_single_thread_pass) {
+ return;
+ }
+
+ BLI_assert(!state->need_update_pending_parents);
+
+ state->stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
+
GSQueue *evaluation_queue = BLI_gsqueue_new(sizeof(OperationNode *));
schedule_graph(state, schedule_node_to_queue, evaluation_queue);
@@ -334,9 +379,7 @@ void depsgraph_ensure_view_layer(Depsgraph *graph)
deg_update_copy_on_write_datablock(graph, scene_id_node);
}
-} // namespace
-
-static TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state)
+TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state)
{
if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) {
return BLI_task_pool_create_no_threads(state);
@@ -345,6 +388,8 @@ static TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state)
return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH);
}
+} // namespace
+
void deg_evaluate_on_refresh(Depsgraph *graph)
{
/* Nothing to update, early out. */
@@ -361,40 +406,66 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
graph->is_evaluating = true;
depsgraph_ensure_view_layer(graph);
+
/* Set up evaluation state. */
DepsgraphEvalState state;
state.graph = graph;
state.do_stats = graph->debug.do_time_debug();
- state.need_single_thread_pass = false;
+
/* Prepare all nodes for evaluation. */
initialize_execution(&state, graph);
- /* Do actual evaluation now. */
- /* First, process all Copy-On-Write nodes. */
- state.stage = EvaluationStage::COPY_ON_WRITE;
+ /* Evaluation happens in several incremental steps:
+ *
+ * - Start with the copy-on-write operations which never form dependency cycles. This will ensure
+ * that if a dependency graph has a cycle evaluation functions will always "see" valid expanded
+ * datablock. It might not be evaluated yet, but at least the datablock will be valid.
+ *
+ * - If there is potentially dynamically changing visibility in the graph update the actual
+ * nodes visibilities, so that actual heavy data evaluation can benefit from knowledge that
+ * something heavy is not currently visible.
+ *
+ * - Multi-threaded evaluation of all possible nodes.
+ * Certain operations (and their subtrees) could be ignored. For example, meta-balls are not
+ * safe from threading point of view, so the threaded evaluation will stop at the metaball
+ * operation node.
+ *
+ * - Single-threaded pass of all remaining operations. */
+
TaskPool *task_pool = deg_evaluate_task_pool_create(&state);
- schedule_graph(&state, schedule_node_to_pool, task_pool);
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
- /* After that, process all other nodes. */
- state.stage = EvaluationStage::THREADED_EVALUATION;
- task_pool = deg_evaluate_task_pool_create(&state);
- schedule_graph(&state, schedule_node_to_pool, task_pool);
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
+ evaluate_graph_threaded_stage(&state, task_pool, EvaluationStage::COPY_ON_WRITE);
+
+ if (graph->has_animated_visibility) {
+ /* Update pending parents including only the ones which are affecting operations which are
+ * affecting visibility. */
+ state.need_update_pending_parents = true;
+
+ evaluate_graph_threaded_stage(&state, task_pool, EvaluationStage::DYNAMIC_VISIBILITY);
+
+ deg_graph_flush_visibility_flags_if_needed(graph);
- if (state.need_single_thread_pass) {
- state.stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
- evaluate_graph_single_threaded(&state);
+ /* Update parents to an updated visibility and evaluation stage.
+ *
+ * Need to do it regardless of whether visibility is actually changed or not: current state of
+ * the pending parents are all zeroes because it was previously calculated for only visibility
+ * related nodes and those are fully evaluated by now. */
+ state.need_update_pending_parents = true;
}
+ evaluate_graph_threaded_stage(&state, task_pool, EvaluationStage::THREADED_EVALUATION);
+
+ BLI_task_pool_free(task_pool);
+
+ evaluate_graph_single_threaded_if_needed(&state);
+
/* Finalize statistics gathering. This is because we only gather single
* operation timing here, without aggregating anything to avoid any extra
* synchronization. */
if (state.do_stats) {
deg_eval_stats_aggregate(graph);
}
+
/* Clear any uncleared tags - just in case. */
deg_graph_clear_tags(graph);
graph->is_evaluating = false;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.h b/source/blender/depsgraph/intern/eval/deg_eval.h
index ba86e1a349d..6937231d81a 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval.h
@@ -9,8 +9,7 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -23,5 +22,4 @@ struct Depsgraph;
*/
void deg_evaluate_on_refresh(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
index 29322d58218..cbf450aa3f1 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
@@ -27,8 +27,7 @@ struct ID;
struct Depsgraph;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
class DepsgraphNodeBuilder;
@@ -77,5 +76,4 @@ bool deg_copy_on_write_is_expanded(const struct ID *id_cow);
bool deg_copy_on_write_is_needed(const ID *id_orig);
bool deg_copy_on_write_is_needed(const ID_Type id_type);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.h b/source/blender/depsgraph/intern/eval/deg_eval_flush.h
index 6eb232e76e5..614ca66faed 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.h
@@ -9,8 +9,7 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -24,5 +23,4 @@ void deg_graph_flush_updates(struct Depsgraph *graph);
*/
void deg_graph_clear_tags(struct Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
index deb21715a28..3d9b308c5ad 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
@@ -17,8 +17,7 @@
#include "intern/eval/deg_eval_runtime_backup_sound.h"
#include "intern/eval/deg_eval_runtime_backup_volume.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -59,5 +58,4 @@ class RuntimeBackup {
GPencilBackup gpencil_backup;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h
index 92847b330e8..807cc91242e 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h
@@ -11,8 +11,7 @@
#include "intern/depsgraph_type.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -46,5 +45,4 @@ class AnimationBackup {
Vector<AnimationValueBackup> values_backup;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h
index 68eff01fd60..95c0ca3a2fe 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h
@@ -9,8 +9,7 @@
struct bGPdata;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -25,5 +24,4 @@ class GPencilBackup {
const Depsgraph *depsgraph;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
index faec8f7c065..ee51204b24c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
@@ -11,8 +11,7 @@
struct ModifierData;
-namespace blender {
-namespace deg {
+namespace blender::deg {
class ModifierDataBackup {
public:
@@ -22,5 +21,4 @@ class ModifierDataBackup {
void *runtime;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h
index 0e826e8f72a..aa13914d8c8 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.h
@@ -11,8 +11,7 @@ struct MovieClip;
struct MovieClipCache;
struct anim;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -30,5 +29,4 @@ class MovieClipBackup {
struct MovieClipCache *cache;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
index 3b138feec0b..c9cc167d927 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
@@ -17,8 +17,7 @@
struct Object;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -46,5 +45,4 @@ class ObjectRuntimeBackup {
Map<SessionUUID, bPoseChannel_Runtime> pose_channel_runtime_data;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h
index 8fd5de44001..2f6a3dd4371 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_pose.h
@@ -11,8 +11,6 @@
#include "DNA_action_types.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
-}
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
index 17683966a22..155cb42a96d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
@@ -11,8 +11,7 @@
struct Scene;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -40,5 +39,4 @@ class SceneBackup {
SequencerBackup sequencer_backup;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h
index 95fbd2a3e4e..f97b6b200e9 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.h
@@ -11,8 +11,7 @@
struct Sequence;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -32,5 +31,4 @@ class SequenceBackup {
ListBase anims;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
index 19e1a63ab4c..38fb8e81cc3 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
@@ -16,8 +16,7 @@
struct Scene;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -34,5 +33,4 @@ class SequencerBackup {
Map<SessionUUID, SequenceBackup> sequences_backup;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h
index c4267be1421..9e1d15251e8 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.h
@@ -9,8 +9,7 @@
struct bSound;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -29,5 +28,4 @@ class SoundBackup {
void *playback_handle;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
index bc263cc58f8..60cba64f120 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
@@ -10,8 +10,7 @@
struct Volume;
struct VolumeGridVector;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
@@ -27,5 +26,4 @@ class VolumeBackup {
char filepath[1024]; /* FILE_MAX */
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_stats.h b/source/blender/depsgraph/intern/eval/deg_eval_stats.h
index a1e3cdaca76..c24c5f07135 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_stats.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_stats.h
@@ -7,13 +7,11 @@
#pragma once
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
/* Aggregate operation timings to overall component and ID nodes timing. */
void deg_eval_stats_aggregate(Depsgraph *graph);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
new file mode 100644
index 00000000000..8bf26e45e2a
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_visibility.h"
+
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_assert.h"
+#include "BLI_stack.h"
+
+#include "DEG_depsgraph.h"
+
+#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
+#include "intern/node/deg_node.h"
+#include "intern/node/deg_node_component.h"
+#include "intern/node/deg_node_id.h"
+#include "intern/node/deg_node_operation.h"
+
+namespace blender::deg {
+
+void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node)
+{
+ BLI_assert(GS(id_node->id_cow->name) == ID_OB);
+
+ Depsgraph *graph = reinterpret_cast<Depsgraph *>(depsgraph);
+ const Object *object = reinterpret_cast<const Object *>(id_node->id_cow);
+
+ DEG_debug_print_eval(depsgraph, __func__, object->id.name, &object->id);
+
+ const int required_flags = (graph->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
+ BASE_ENABLED_RENDER;
+
+ const bool is_enabled = object->base_flag & required_flags;
+
+ if (id_node->is_enabled_on_eval != is_enabled) {
+ id_node->is_enabled_on_eval = is_enabled;
+
+ /* Tag dependency graph for changed visibility, so that it is updated on all dependencies prior
+ * to a pass of an actual evaluation. */
+ graph->need_update_nodes_visibility = true;
+ }
+}
+
+void deg_graph_flush_visibility_flags(Depsgraph *graph)
+{
+ enum {
+ DEG_NODE_VISITED = (1 << 0),
+ };
+
+ for (IDNode *id_node : graph->id_nodes) {
+ for (ComponentNode *comp_node : id_node->components.values()) {
+ comp_node->possibly_affects_visible_id = id_node->is_visible_on_build;
+ comp_node->affects_visible_id = id_node->is_visible_on_build && id_node->is_enabled_on_eval;
+ }
+ }
+
+ BLI_Stack *stack = BLI_stack_new(sizeof(OperationNode *), "DEG flush layers stack");
+
+ for (OperationNode *op_node : graph->operations) {
+ op_node->custom_flags = 0;
+ op_node->num_links_pending = 0;
+ for (Relation *rel : op_node->outlinks) {
+ if ((rel->from->type == NodeType::OPERATION) && (rel->flag & RELATION_FLAG_CYCLIC) == 0) {
+ ++op_node->num_links_pending;
+ }
+ }
+ if (op_node->num_links_pending == 0) {
+ BLI_stack_push(stack, &op_node);
+ op_node->custom_flags |= DEG_NODE_VISITED;
+ }
+ }
+
+ while (!BLI_stack_is_empty(stack)) {
+ OperationNode *op_node;
+ BLI_stack_pop(stack, &op_node);
+
+ /* Flush flags to parents. */
+ for (Relation *rel : op_node->inlinks) {
+ if (rel->from->type == NodeType::OPERATION) {
+ const OperationNode *op_to = reinterpret_cast<const OperationNode *>(rel->to);
+ const ComponentNode *comp_to = op_to->owner;
+ OperationNode *op_from = reinterpret_cast<OperationNode *>(rel->from);
+ ComponentNode *comp_from = op_from->owner;
+
+ const bool target_possibly_affects_visible_id = comp_to->possibly_affects_visible_id;
+ const bool target_affects_visible_id = comp_to->affects_visible_id;
+
+ op_from->flag |= (op_to->flag & OperationFlag::DEPSOP_FLAG_AFFECTS_VISIBILITY);
+
+ /* Visibility component forces all components of the current ID to be considered as
+ * affecting directly visible. */
+ if (comp_from->type == NodeType::VISIBILITY) {
+ const IDNode *id_node_from = comp_from->owner;
+ if (target_possibly_affects_visible_id) {
+ for (ComponentNode *comp_node : id_node_from->components.values()) {
+ comp_node->possibly_affects_visible_id |= target_possibly_affects_visible_id;
+ }
+ }
+ if (target_affects_visible_id) {
+ for (ComponentNode *comp_node : id_node_from->components.values()) {
+ comp_node->affects_visible_id |= target_affects_visible_id;
+ }
+ }
+ }
+ else {
+ comp_from->possibly_affects_visible_id |= target_possibly_affects_visible_id;
+ comp_from->affects_visible_id |= target_affects_visible_id;
+ }
+ }
+ }
+
+ /* Schedule parent nodes. */
+ for (Relation *rel : op_node->inlinks) {
+ if (rel->from->type == NodeType::OPERATION) {
+ OperationNode *op_from = (OperationNode *)rel->from;
+ if ((rel->flag & RELATION_FLAG_CYCLIC) == 0) {
+ BLI_assert(op_from->num_links_pending > 0);
+ --op_from->num_links_pending;
+ }
+ if ((op_from->num_links_pending == 0) && (op_from->custom_flags & DEG_NODE_VISITED) == 0) {
+ BLI_stack_push(stack, &op_from);
+ op_from->custom_flags |= DEG_NODE_VISITED;
+ }
+ }
+ }
+ }
+ BLI_stack_free(stack);
+
+ graph->need_update_nodes_visibility = false;
+}
+
+void deg_graph_flush_visibility_flags_if_needed(Depsgraph *graph)
+{
+ if (!graph->need_update_nodes_visibility) {
+ return;
+ }
+
+ deg_graph_flush_visibility_flags(graph);
+}
+
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_visibility.h b/source/blender/depsgraph/intern/eval/deg_eval_visibility.h
new file mode 100644
index 00000000000..9e9db8ab34a
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_visibility.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+struct Depsgraph;
+
+namespace blender::deg {
+
+struct Depsgraph;
+struct IDNode;
+
+/* Evaluate actual node visibility flags based on the current state of object's visibility
+ * restriction flags. */
+void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node);
+
+/* Flush both static and dynamic visibility flags from leaves up to the roots, making it possible
+ * to know whether a node has affect on something (potentially) visible. */
+void deg_graph_flush_visibility_flags(Depsgraph *graph);
+void deg_graph_flush_visibility_flags_if_needed(Depsgraph *graph);
+
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/node/deg_node.h b/source/blender/depsgraph/intern/node/deg_node.h
index 509867ad47a..5b33528df33 100644
--- a/source/blender/depsgraph/intern/node/deg_node.h
+++ b/source/blender/depsgraph/intern/node/deg_node.h
@@ -18,8 +18,7 @@
struct ID;
struct Scene;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct Depsgraph;
struct OperationNode;
@@ -217,5 +216,4 @@ struct Node {
void deg_register_base_depsnodes();
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index cfcbec46569..32942f45a4a 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -67,7 +67,10 @@ uint64_t ComponentNode::OperationIDKey::hash() const
}
ComponentNode::ComponentNode()
- : entry_operation(nullptr), exit_operation(nullptr), affects_directly_visible(false)
+ : entry_operation(nullptr),
+ exit_operation(nullptr),
+ possibly_affects_visible_id(false),
+ affects_visible_id(false)
{
operations_map = new Map<ComponentNode::OperationIDKey, OperationNode *>();
}
@@ -90,7 +93,7 @@ string ComponentNode::identifier() const
const string idname = this->owner->name;
const string typebuf = "" + to_string(static_cast<int>(type)) + ")";
return typebuf + name + " : " + idname +
- "( affects_directly_visible: " + (affects_directly_visible ? "true" : "false") + ")";
+ "( affects_visible_id: " + (affects_visible_id ? "true" : "false") + ")";
}
OperationNode *ComponentNode::find_operation(OperationIDKey key) const
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h
index 6958866af3b..a616dfdfe4c 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.h
+++ b/source/blender/depsgraph/intern/node/deg_node_component.h
@@ -22,10 +22,8 @@
struct ID;
struct bPoseChannel;
-namespace blender {
-namespace deg {
+namespace blender::deg {
-struct BoneComponentNode;
struct Depsgraph;
struct IDNode;
struct OperationNode;
@@ -56,32 +54,45 @@ struct ComponentNode : public Node {
virtual string identifier() const override;
- /* Find an existing operation, if requested operation does not exist
- * nullptr will be returned. */
+ /* Find an existing operation, if requested operation does not exist nullptr will be returned.
+ * See #add_operation for the meaning and examples of #name and #name_tag.
+ */
OperationNode *find_operation(OperationIDKey key) const;
- OperationNode *find_operation(OperationCode opcode, const char *name, int name_tag) const;
+ OperationNode *find_operation(OperationCode opcode,
+ const char *name = "",
+ int name_tag = -1) const;
- /* Find an existing operation, will throw an assert() if it does not exist. */
+ /* Find an existing operation, will throw an assert() if it does not exist.
+ * See #add_operation for the meaning and examples of #name and #name_tag. */
OperationNode *get_operation(OperationIDKey key) const;
- OperationNode *get_operation(OperationCode opcode, const char *name, int name_tag) const;
+ OperationNode *get_operation(OperationCode opcode,
+ const char *name = "",
+ int name_tag = -1) const;
/* Check operation exists and return it. */
bool has_operation(OperationIDKey key) const;
- bool has_operation(OperationCode opcode, const char *name, int name_tag) const;
+ bool has_operation(OperationCode opcode, const char *name = "", int name_tag = -1) const;
/**
* Create a new node for representing an operation and add this to graph
+ *
* \warning If an existing node is found, it will be modified. This helps
* when node may have been partially created earlier (e.g. parent ref before
* parent item is added)
*
* \param opcode: The operation to perform.
- * \param name: Identifier for operation - used to find/locate it again.
+ * \param name: An optional identifier for operation. It will be used to tell operation nodes
+ * with the same code apart. For example, parameter operation code will have name
+ * set to the corresponding custom property name
+ * \param name_tag: An optional integer tag for the name. Is an additional way to tell operations
+ * apart. For example, RNA path to an array property will have the same opcode
+ * of PARAMETERS, name corresponding to the property name, and name tag
+ * corresponding to the array index within the property.
*/
OperationNode *add_operation(const DepsEvalOperationCb &op,
OperationCode opcode,
- const char *name,
- int name_tag);
+ const char *name = "",
+ int name_tag = -1);
/* Entry/exit operations management.
*
@@ -125,9 +136,17 @@ struct ComponentNode : public Node {
return true;
}
- /* Denotes whether this component affects (possibly indirectly) on a
- * directly visible object. */
- bool affects_directly_visible;
+ /* The component has (possibly indirect) effect on a data-block whose node has
+ * is_visible_on_build set to true.
+ *
+ * This field is ensured to be up-to-date prior to `IDNode::finalize_build()`. */
+ bool possibly_affects_visible_id;
+
+ /* Denotes whether this component actually affects (possibly indirectly) on a directly visible
+ * object. Includes possibly run-time visibility update of ID nodes.
+ *
+ * NOTE: Is only reliable after `deg_graph_flush_visibility()`. */
+ bool affects_visible_id;
};
/* ---------------------------------------- */
@@ -182,14 +201,32 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(ShadingParameters);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Transform);
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(ObjectFromLayer);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Dupli);
-DEG_COMPONENT_NODE_DECLARE_GENERIC(Synchronization);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Audio);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Armature);
DEG_COMPONENT_NODE_DECLARE_GENERIC(GenericDatablock);
-DEG_COMPONENT_NODE_DECLARE_NO_COW(Visibility);
+DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Visibility);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Simulation);
DEG_COMPONENT_NODE_DECLARE_GENERIC(NTreeOutput);
+/* Synchronization Component. */
+struct SynchronizationComponentNode : public ComponentNode {
+ SynchronizationComponentNode()
+ {
+ /* Enforce "visibility" of the synchronization component.
+ *
+ * This component is never connected to other ID nodes, and hence can not be handled in the
+ * same way as other components needed for evaluation. It is only needed for proper
+ * evaluation of the ID node it belongs to.
+ *
+ * The design is such that the synchronization is supposed to happen whenever any part of the
+ * ID changed/evaluated. Here we mark the component as "visible" so that genetic recalc flag
+ * flushing and scheduling will handle the component in a generic manner. */
+ affects_visible_id = true;
+ }
+
+ DEG_COMPONENT_NODE_DECLARE;
+};
+
/* Bone Component */
struct BoneComponentNode : public ComponentNode {
/** Initialize 'bone component' node - from pointer data given. */
@@ -218,5 +255,4 @@ struct ParametersComponentNode : public ComponentNode {
void deg_register_component_depsnodes();
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_factory.h b/source/blender/depsgraph/intern/node/deg_node_factory.h
index 6caf99ac9ba..ec5029e8352 100644
--- a/source/blender/depsgraph/intern/node/deg_node_factory.h
+++ b/source/blender/depsgraph/intern/node/deg_node_factory.h
@@ -14,9 +14,7 @@
struct ID;
-namespace blender {
-namespace deg {
-
+namespace blender::deg {
struct DepsNodeFactory {
virtual NodeType type() const = 0;
virtual const char *type_name() const = 0;
@@ -41,7 +39,6 @@ void register_node_typeinfo(DepsNodeFactory *factory);
/* Get typeinfo for specified type */
DepsNodeFactory *type_get_factory(NodeType type);
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
#include "intern/node/deg_node_factory_impl.h"
diff --git a/source/blender/depsgraph/intern/node/deg_node_factory_impl.h b/source/blender/depsgraph/intern/node/deg_node_factory_impl.h
index 76a91860cc1..d9d0a1c1e3e 100644
--- a/source/blender/depsgraph/intern/node/deg_node_factory_impl.h
+++ b/source/blender/depsgraph/intern/node/deg_node_factory_impl.h
@@ -11,8 +11,7 @@
struct ID;
-namespace blender {
-namespace deg {
+namespace blender::deg {
template<class ModeObjectType> NodeType DepsNodeFactoryImpl<ModeObjectType>::type() const
{
@@ -48,5 +47,4 @@ Node *DepsNodeFactoryImpl<ModeObjectType>::create_node(const ID *id,
return node;
}
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index 99224501e98..735d606ac9e 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -69,7 +69,8 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata))
customdata_masks = DEGCustomDataMeshMasks();
previous_customdata_masks = DEGCustomDataMeshMasks();
linked_state = DEG_ID_LINKED_INDIRECTLY;
- is_directly_visible = true;
+ is_visible_on_build = true;
+ is_enabled_on_eval = true;
is_collection_fully_expanded = false;
has_base = false;
is_user_modified = false;
@@ -138,8 +139,8 @@ string IDNode::identifier() const
BLI_snprintf(orig_ptr, sizeof(orig_ptr), "%p", id_orig);
BLI_snprintf(cow_ptr, sizeof(cow_ptr), "%p", id_cow);
return string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr +
- ", eval: " + cow_ptr + ", is_directly_visible " +
- (is_directly_visible ? "true" : "false") + ")";
+ ", eval: " + cow_ptr + ", is_visible_on_build " +
+ (is_visible_on_build ? "true" : "false") + ")";
}
ComponentNode *IDNode::find_component(NodeType type, const char *name) const
@@ -188,7 +189,7 @@ IDComponentsMask IDNode::get_visible_components_mask() const
{
IDComponentsMask result = 0;
for (ComponentNode *comp_node : components.values()) {
- if (comp_node->affects_directly_visible) {
+ if (comp_node->possibly_affects_visible_id) {
const int component_type_as_int = static_cast<int>(comp_node->type);
BLI_assert(component_type_as_int < 64);
result |= (1ULL << component_type_as_int);
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index a8b6294b482..7f0a656cb8d 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -12,8 +12,7 @@
#include "DNA_ID.h"
#include "intern/node/deg_node.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct ComponentNode;
@@ -92,8 +91,21 @@ struct IDNode : public Node {
eDepsNode_LinkedState_Type linked_state;
- /* Indicates the data-block is visible in the evaluated scene. */
- bool is_directly_visible;
+ /* Indicates the data-block is to be considered visible in the evaluated scene.
+ *
+ * This flag is set during dependency graph build where check for an actual visibility might not
+ * be available yet due to driven or animated restriction flags. So it is more of an intent or,
+ * in other words, plausibility of the data-block to be visible. */
+ bool is_visible_on_build;
+
+ /* Evaluated state of whether evaluation considered this data-block "enabled".
+ *
+ * For objects this is derived from the base restriction flags, which might be animated or
+ * driven. It is set to `BASE_ENABLED_<VIEWPORT, RENDER>` (depending on the graph mode) after
+ * the object's flags from layer were evaluated.
+ *
+ * For other data-types is currently always true. */
+ bool is_enabled_on_eval;
/* For the collection type of ID, denotes whether collection was fully
* recursed into. */
@@ -117,5 +129,4 @@ struct IDNode : public Node {
DEG_DEPSNODE_DECLARE;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 99be3b3310b..e7d6cbe487e 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -32,6 +32,8 @@ const char *operationCodeAsString(OperationCode opcode)
return "PARAMETERS_EVAL";
case OperationCode::PARAMETERS_EXIT:
return "PARAMETERS_EXIT";
+ case OperationCode::VISIBILITY:
+ return "VISIBILITY";
/* Animation, Drivers, etc. */
case OperationCode::ANIMATION_ENTRY:
return "ANIMATION_ENTRY";
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index 258215c0aa6..07116e85bc0 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -13,8 +13,7 @@
struct Depsgraph;
-namespace blender {
-namespace deg {
+namespace blender::deg {
struct ComponentNode;
@@ -34,6 +33,7 @@ enum class OperationCode {
PARAMETERS_ENTRY,
PARAMETERS_EVAL,
PARAMETERS_EXIT,
+ VISIBILITY,
/* Animation, Drivers, etc. --------------------------------------------- */
/* NLA + Action */
@@ -204,15 +204,21 @@ const char *operationCodeAsString(OperationCode opcode);
enum OperationFlag {
/* Node needs to be updated. */
DEPSOP_FLAG_NEEDS_UPDATE = (1 << 0),
+
/* Node was directly modified, causing need for update. */
DEPSOP_FLAG_DIRECTLY_MODIFIED = (1 << 1),
+
/* Node was updated due to user input. */
DEPSOP_FLAG_USER_MODIFIED = (1 << 2),
- /* Node may not be removed, even when it has no evaluation callback and no
- * outgoing relations. This is for NO-OP nodes that are purely used to indicate a
- * relation between components/IDs, and not for connecting to an operation. */
+
+ /* Node may not be removed, even when it has no evaluation callback and no outgoing relations.
+ * This is for NO-OP nodes that are purely used to indicate a relation between components/IDs,
+ * and not for connecting to an operation. */
DEPSOP_FLAG_PINNED = (1 << 3),
+ /* The operation directly or indirectly affects ID node visibility. */
+ DEPSOP_FLAG_AFFECTS_VISIBILITY = (1 << 4),
+
/* Set of flags which gets flushed along the relations. */
DEPSOP_FLAG_FLUSH = (DEPSOP_FLAG_USER_MODIFIED),
};
@@ -270,5 +276,4 @@ struct OperationNode : public Node {
void deg_register_operation_depsnodes();
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_time.h b/source/blender/depsgraph/intern/node/deg_node_time.h
index fcfe9a0fa80..3946b63384d 100644
--- a/source/blender/depsgraph/intern/node/deg_node_time.h
+++ b/source/blender/depsgraph/intern/node/deg_node_time.h
@@ -9,8 +9,7 @@
#include "intern/node/deg_node.h"
-namespace blender {
-namespace deg {
+namespace blender::deg {
/* Time Source Node. */
struct TimeSourceNode : public Node {
@@ -25,5 +24,4 @@ struct TimeSourceNode : public Node {
DEG_DEPSNODE_DECLARE;
};
-} // namespace deg
-} // namespace blender
+} // namespace blender::deg