diff options
6 files changed, 42 insertions, 33 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 89e1f1add18..9b2ce2bb707 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -111,7 +111,8 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod * 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; + operation_node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | + DEPSOP_FLAG_USER_MODIFIED); } void deg_task_run_func(TaskPool *pool, void *taskdata) @@ -466,7 +467,7 @@ void deg_evaluate_on_refresh(Depsgraph *graph) deg_eval_stats_aggregate(graph); } - /* Clear any uncleared tags - just in case. */ + /* Clear any uncleared tags. */ deg_graph_clear_tags(graph); graph->is_evaluating = false; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index de4e26aa4b5..1c313d42d8e 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -378,11 +378,6 @@ void deg_graph_flush_updates(Depsgraph *graph) void deg_graph_clear_tags(Depsgraph *graph) { - /* Go over all operation nodes, clearing tags. */ - for (OperationNode *node : graph->operations) { - node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | - DEPSOP_FLAG_USER_MODIFIED); - } /* Clear any entry tags which haven't been flushed. */ graph->entry_tags.clear(); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc index 8bf26e45e2a..05f7631b0d4 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc @@ -57,6 +57,27 @@ void deg_graph_flush_visibility_flags(Depsgraph *graph) 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; + + /* Visibility component is always to be considered to have the same visibility as the + * `id_node->is_visible_on_build`. This is because the visibility is to be evaluated + * regardless of its current state as it might get changed due to animation. */ + if (comp_node->type == NodeType::VISIBILITY) { + comp_node->affects_visible_id = id_node->is_visible_on_build; + } + + /* 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->possibly_affects_visible_id = true; + comp_node->affects_visible_id = true; + } } } @@ -85,6 +106,13 @@ void deg_graph_flush_visibility_flags(Depsgraph *graph) if (rel->from->type == NodeType::OPERATION) { const OperationNode *op_to = reinterpret_cast<const OperationNode *>(rel->to); const ComponentNode *comp_to = op_to->owner; + + /* Ignore the synchronization target. + * It is always visible and should not affect on other components. */ + if (comp_to->type == NodeType::SYNCHRONIZATION) { + continue; + } + OperationNode *op_from = reinterpret_cast<OperationNode *>(rel->from); ComponentNode *comp_from = op_from->owner; diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc index 32942f45a4a..f2d82e80fa6 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.cc +++ b/source/blender/depsgraph/intern/node/deg_node_component.cc @@ -218,10 +218,9 @@ void ComponentNode::clear_operations() void ComponentNode::tag_update(Depsgraph *graph, eUpdateSource source) { - OperationNode *entry_op = get_entry_operation(); - if (entry_op != nullptr && entry_op->flag & DEPSOP_FLAG_NEEDS_UPDATE) { - return; - } + /* Note that the node might already be tagged for an update due invisible state of the node + * during previous dependency evaluation. Here the node gets re-tagged, so we need to give + * the evaluated clues that evaluation needs to happen again. */ for (OperationNode *op_node : operations) { op_node->tag_update(graph, source); } diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h index a616dfdfe4c..f7f38b88854 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.h +++ b/source/blender/depsgraph/intern/node/deg_node_component.h @@ -201,6 +201,7 @@ 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); @@ -208,25 +209,6 @@ 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. */ diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 3029379d141..de4bc0668cf 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -218,9 +218,13 @@ string OperationNode::full_identifier() const void OperationNode::tag_update(Depsgraph *graph, eUpdateSource source) { - if ((flag & DEPSOP_FLAG_NEEDS_UPDATE) == 0) { - graph->add_entry_tag(this); - } + /* Ensure that there is an entry tag for this update. + * + * Note that the node might already be tagged for an update due invisible state of the node + * during previous dependency evaluation. Here the node gets re-tagged, so we need to give + * the evaluated clues that evaluation needs to happen again. */ + graph->add_entry_tag(this); + /* Tag for update, but also note that this was the source of an update. */ flag |= (DEPSOP_FLAG_NEEDS_UPDATE | DEPSOP_FLAG_DIRECTLY_MODIFIED); switch (source) { |