diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index ecf6403199c..f8e27c91f86 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -34,6 +34,8 @@ #include "DNA_object_types.h" #include "DNA_ID.h" +#include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BLI_stack.h" extern "C" { @@ -64,6 +66,13 @@ void deg_graph_build_flush_visibility(Depsgraph *graph) BLI_Stack *stack = BLI_stack_new(sizeof(OperationDepsNode *), "DEG flush layers stack"); + foreach (IDDepsNode *id_node, graph->id_nodes) { + GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components) + { + comp_node->affects_directly_visible = id_node->is_directly_visible; + } + GHASH_FOREACH_END(); + } foreach (OperationDepsNode *op_node, graph->operations) { op_node->custom_flags = 0; op_node->num_links_pending = 0; @@ -86,8 +95,8 @@ void deg_graph_build_flush_visibility(Depsgraph *graph) foreach (DepsRelation *rel, op_node->inlinks) { if (rel->from->type == DEG_NODE_TYPE_OPERATION) { OperationDepsNode *op_from = (OperationDepsNode *)rel->from; - op_from->owner->owner->is_visible |= - op_node->owner->owner->is_visible; + op_from->owner->affects_directly_visible |= + op_node->owner->affects_directly_visible; } } /* Schedule parent nodes. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index ec279a1c716..da47465dd47 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -163,16 +163,16 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) { IDDepsNode *id_node = NULL; ID *id_cow = NULL; - bool is_previous_visible = false; + bool is_previous_directly_visible = false; IDInfo *id_info = (IDInfo *)BLI_ghash_lookup(id_info_hash_, id); if (id_info != NULL) { id_cow = id_info->id_cow; - is_previous_visible = id_info->is_visible; + is_previous_directly_visible = id_info->is_directly_visible; /* Tag ID info to not free the CoW ID pointer. */ id_info->id_cow = NULL; } id_node = graph_->add_id_node(id, id_cow); - id_node->is_previous_visible = is_previous_visible; + id_node->is_previous_directly_visible = is_previous_directly_visible; /* Currently all ID nodes are supposed to have copy-on-write logic. * * NOTE: Zero number of components indicates that ID node was just created. @@ -352,7 +352,7 @@ void DepsgraphNodeBuilder::begin_build() else { id_info->id_cow = NULL; } - id_info->is_visible = id_node->is_visible; + id_info->is_directly_visible = id_node->is_directly_visible; BLI_ghash_insert(id_info_hash_, id_node->id_orig, id_info); id_node->id_cow = NULL; } @@ -489,7 +489,7 @@ void DepsgraphNodeBuilder::build_collection(Collection *collection) !is_collection_restricted && is_parent_collection_visible_; if (built_map_.checkIsBuiltAndTag(collection)) { IDDepsNode *id_node = find_id_node(&collection->id); - if (is_collection_visible && !id_node->is_visible) { + if (is_collection_visible && !id_node->is_directly_visible) { /* Collection became visible, make sure nested collections and * objects are poked with the new visibility flag, since they * might become visible too. @@ -502,7 +502,7 @@ void DepsgraphNodeBuilder::build_collection(Collection *collection) else { /* Collection itself. */ IDDepsNode *id_node = add_id_node(&collection->id); - id_node->is_visible = is_collection_visible; + id_node->is_directly_visible = is_collection_visible; } /* Backup state. */ Collection *current_state_collection = collection_; @@ -541,13 +541,20 @@ 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_visible |= is_visible; + if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) { + id_node->is_directly_visible |= is_visible; + } return; } /* Create ID node for object and begin init. */ IDDepsNode *id_node = add_id_node(&object->id); id_node->linked_state = linked_state; - id_node->is_visible = is_visible; + if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) { + id_node->is_directly_visible = is_visible; + } + else { + id_node->is_directly_visible = false; + } object->customdata_mask = 0; /* Various flags, flushing from bases/collections. */ build_object_flags(base_index, object, linked_state); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 8e33dbf4292..37000c958ce 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -228,7 +228,7 @@ struct DepsgraphNodeBuilder { /* State of the is_visible from ID node from previous state of the * dependency graph. */ - bool is_visible; + bool is_directly_visible; }; protected: diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 791e5edbfc6..ac3122d2159 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -163,7 +163,7 @@ void deg_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_node) /* Set it early in case we need to exit and we are running from within a loop. */ iter->skip = true; - if (!id_node->is_visible) { + if (!id_node->is_directly_visible) { return; } @@ -302,7 +302,7 @@ static void DEG_iterator_ids_step(BLI_Iterator *iter, DEG::IDDepsNode *id_node, { ID *id_cow = id_node->id_cow; - if (!id_node->is_visible) { + if (!id_node->is_directly_visible) { iter->skip = true; return; } diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 79f103a3b8f..4d4e0e8be15 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -485,14 +485,17 @@ void deg_id_tag_update(Main *bmain, ID *id, int flag) void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph) { + /* TODO(sergey): We might want to tag components which did not affect + * anything visible before new objects became visible. + */ foreach (DEG::IDDepsNode *id_node, graph->id_nodes) { - if (!id_node->is_visible) { + if (!id_node->is_directly_visible) { /* ID is not visible within the current dependency graph, no need * botherwith it to tag or anything. */ continue; } - if (id_node->is_previous_visible) { + if (id_node->is_previous_directly_visible) { /* The ID was already visible and evaluated, all the subsequent * updates and tags are to be done explicitly. */ @@ -527,7 +530,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph) * tags we request from here will be applied in the updated state of * dependency graph. */ - id_node->is_previous_visible = true; + id_node->is_previous_directly_visible = true; } } diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 0d1adfb0144..db6ab21b9a6 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -112,8 +112,7 @@ static bool check_operation_node_visible(OperationDepsNode *op_node) if (comp_node->type == DEG_NODE_TYPE_COPY_ON_WRITE) { return true; } - const IDDepsNode *id_node = comp_node->owner; - return id_node->is_visible; + return comp_node->affects_directly_visible; } static void calculate_pending_func( diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 72718fb48a0..494c823a4b1 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -124,7 +124,8 @@ static void comp_node_hash_value_free(void *value_v) ComponentDepsNode::ComponentDepsNode() : entry_operation(NULL), - exit_operation(NULL) + exit_operation(NULL), + affects_directly_visible(false) { operations_map = BLI_ghash_new(comp_node_hash_key, comp_node_hash_key_cmp, diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 9a87269b301..1cc4dd9797a 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -150,6 +150,11 @@ struct ComponentDepsNode : public DepsNode { * is tagged for update. */ virtual bool need_tag_cow_before_update() { return true; } + + /* Denotes whether this component affects (possibly indirectly) on a + * directly visible object. + */ + bool affects_directly_visible; }; /* ---------------------------------------- */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.cc b/source/blender/depsgraph/intern/nodes/deg_node_id.cc index b522efa6d0d..7589be8c0a8 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.cc @@ -104,8 +104,8 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) id_orig = (ID *)id; eval_flags = 0; linked_state = DEG_ID_LINKED_INDIRECTLY; - is_visible = true; - is_previous_visible = false; + is_directly_visible = true; + is_previous_directly_visible = false; components = BLI_ghash_new(id_deps_node_hash_key, id_deps_node_hash_key_cmp, @@ -174,7 +174,8 @@ string IDDepsNode::identifier() const BLI_snprintf(cow_ptr, sizeof(cow_ptr), "%p", id_cow); return string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr + ", eval: " + cow_ptr + - ", is_visible " + (is_visible ? "true" : "false") + ")"; + ", is_directly_visible " + (is_directly_visible ? "true" + : "false") + ")"; } ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type, diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.h b/source/blender/depsgraph/intern/nodes/deg_node_id.h index 572abb90fab..187b5067c5b 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.h @@ -77,17 +77,15 @@ struct IDDepsNode : public DepsNode { eDepsNode_LinkedState_Type linked_state; - /* Indicates the datablock is visible, meaning, it is to be evaluated by - * the dependency graph. - */ - bool is_visible; + /* Indicates the datablock is visible in the evaluated scene. */ + bool is_directly_visible; /* Is used to detect when ID becomes visible within a dependency graph, * this value equals to: * - False if the ID was never inside of the dependency graph. * - Value if is_visible of ID node from the previous state of the * dependency graph. */ - bool is_previous_visible; + bool is_previous_directly_visible; DEG_DEPSNODE_DECLARE; };