diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-11-24 17:07:09 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-11-24 17:46:25 +0300 |
commit | a365f1dd65763d37855b0b7ecb65a74f0b1a7be3 (patch) | |
tree | a39b939e1b94b99cc4c4fdbf055046820a9d8ce6 /source | |
parent | dde05cbcc27e4b6f067248c0b0519d1c130e5047 (diff) |
Depsgraph: Re-schedule pending tags after relations update
It is possible to have situation when we need to both update relations and do
some updates on random IDs. This was only done before for objects using their
recalc field. This means, every update tag which did not fit into there would
have been lost after updating relations.
Now we do some smarter re-scheduling of operations after relations are updated.
Diffstat (limited to 'source')
3 files changed, 42 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index c0bad457b6f..a2a0f633fd9 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -381,12 +381,45 @@ void DepsgraphNodeBuilder::begin_build() { } } + GSET_FOREACH_BEGIN(OperationDepsNode *, op_node, graph_->entry_tags) + { + ComponentDepsNode *comp_node = op_node->owner; + IDDepsNode *id_node = comp_node->owner; + + SavedEntryTag entry_tag; + entry_tag.id = id_node->id_orig; + entry_tag.component_type = comp_node->type; + entry_tag.opcode = op_node->opcode; + saved_entry_tags_.push_back(entry_tag); + }; + GSET_FOREACH_END(); + /* Make sure graph has no nodes left from previous state. */ graph_->clear_all_nodes(); graph_->operations.clear(); BLI_gset_clear(graph_->entry_tags, NULL); } +void DepsgraphNodeBuilder::end_build() +{ + foreach (const SavedEntryTag& entry_tag, saved_entry_tags_) { + IDDepsNode *id_node = find_id_node(entry_tag.id); + if (id_node == NULL) { + continue; + } + ComponentDepsNode *comp_node = + id_node->find_component(entry_tag.component_type); + if (comp_node == NULL) { + continue; + } + OperationDepsNode *op_node = comp_node->find_operation(entry_tag.opcode); + if (op_node == NULL) { + continue; + } + op_node->tag_update(graph_); + } +} + void DepsgraphNodeBuilder::build_group(Group *group) { ID *group_id = &group->id; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 0b7b00a2ed8..5c0a5054590 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -110,6 +110,7 @@ struct DepsgraphNodeBuilder { } void begin_build(); + void end_build(); IDDepsNode *add_id_node(ID *id, bool do_tag = true); IDDepsNode *find_id_node(ID *id); @@ -213,6 +214,13 @@ struct DepsgraphNodeBuilder { LayerCollectionState *state); void build_view_layer_collections(Scene *scene, ViewLayer *view_layer); protected: + struct SavedEntryTag { + ID *id; + eDepsNode_Type component_type; + eDepsOperation_Code opcode; + }; + vector<SavedEntryTag> saved_entry_tags_; + /* State which never changes, same for the whole builder time. */ Main *bmain_; Depsgraph *graph_; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index e4e0247f251..68cf4d77360 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -221,6 +221,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph, node_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY); + node_builder.end_build(); /* 2) Hook up relationships between operations - to determine evaluation * order. |