diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-05-30 13:32:38 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-05-30 13:35:03 +0300 |
commit | 673fabbb64092f8a3fd5bf87f4b3ce0e80760aa5 (patch) | |
tree | 333ef4f2a477735e19130337801bdc0b35868b09 /source/blender/depsgraph/intern/builder/deg_builder.cc | |
parent | 4aaf7b0c7a65473b4d1356fb36ba24eb2df4be49 (diff) |
Depsgraph: Fix wrong layers flush form children to parent
It was possible to have issues in cases when several child dependencies
goes to IDs with different layers. In this case order of flushing was not
really well defined, which could lead to cases when indirect dependency
via invisible object wouldn't work.
Need some sort of barrier to prevent scheduling of parent nodes for until
all children are done, but that's becoming quite nasty thing to implement.
Added a temp field to component for now. maybe it's not so crazy actually
and we might use it for evaluation as well, so we wouldn't flush updates
to components which does not affect visible stuff.
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder.cc')
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder.cc | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index cf9b0cee6b2..9f80c21a6a4 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -61,9 +61,10 @@ void deg_graph_build_finalize(Depsgraph *graph) std::stack<OperationDepsNode *> stack; foreach (OperationDepsNode *node, graph->operations) { + IDDepsNode *id_node = node->owner->owner; node->done = 0; node->num_links_pending = 0; - foreach (DepsRelation *rel, node->inlinks) { + foreach (DepsRelation *rel, node->outlinks) { if ((rel->from->type == DEPSNODE_TYPE_OPERATION) && (rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { @@ -72,36 +73,33 @@ void deg_graph_build_finalize(Depsgraph *graph) } if (node->num_links_pending == 0) { stack.push(node); + node->done = 1; } - IDDepsNode *id_node = node->owner->owner; + node->owner->layers = id_node->layers; id_node->id->tag |= LIB_TAG_DOIT; } while (!stack.empty()) { OperationDepsNode *node = stack.top(); - if (node->done == 0 && node->outlinks.size() != 0) { - foreach (DepsRelation *rel, node->outlinks) { - if (rel->to->type == DEPSNODE_TYPE_OPERATION) { - OperationDepsNode *to = (OperationDepsNode *)rel->to; - if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { - BLI_assert(to->num_links_pending > 0); - --to->num_links_pending; - } - if (to->num_links_pending == 0) { - stack.push(to); - } - } + stack.pop(); + /* Flush layers to parents. */ + foreach (DepsRelation *rel, node->inlinks) { + if (rel->from->type == DEPSNODE_TYPE_OPERATION) { + OperationDepsNode *from = (OperationDepsNode *)rel->from; + from->owner->layers |= node->owner->layers; } - node->done = 1; } - else { - stack.pop(); - IDDepsNode *id_node = node->owner->owner; - foreach (DepsRelation *rel, node->outlinks) { - if (rel->to->type == DEPSNODE_TYPE_OPERATION) { - OperationDepsNode *to = (OperationDepsNode *)rel->to; - IDDepsNode *id_to = to->owner->owner; - id_node->layers |= id_to->layers; + /* Schedule parent nodes. */ + foreach (DepsRelation *rel, node->inlinks) { + if (rel->from->type == DEPSNODE_TYPE_OPERATION) { + OperationDepsNode *from = (OperationDepsNode *)rel->from; + if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { + BLI_assert(from->num_links_pending > 0); + --from->num_links_pending; + } + if (from->num_links_pending == 0 && from->done == 0) { + stack.push(from); + from->done = 1; } } } @@ -110,6 +108,12 @@ void deg_graph_build_finalize(Depsgraph *graph) /* Re-tag IDs for update if it was tagged before the relations update tag. */ GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash) { + GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp, id_node->components) + { + id_node->layers |= comp->layers; + } + GHASH_FOREACH_END(); + ID *id = id_node->id; if (id->tag & LIB_TAG_ID_RECALC_ALL && id->tag & LIB_TAG_DOIT) |