From 53d69e6d048f918b2c9ee61d3e9f27db64fdfa52 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 23 Apr 2018 16:42:37 +0200 Subject: Depsgraph: Add relation flag to avoid flush across it This way we can avoid re-evaluation of certain parts of datablock when something unrelated has changed. --- .../intern/builder/deg_builder_relations.cc | 20 +++++++---- .../intern/builder/deg_builder_relations.h | 41 +++++++++++----------- .../intern/builder/deg_builder_relations_impl.h | 28 ++++++++------- .../intern/debug/deg_debug_relations_graphviz.cc | 25 +++++++++++-- source/blender/depsgraph/intern/depsgraph.h | 2 ++ .../depsgraph/intern/eval/deg_eval_flush.cc | 3 ++ 6 files changed, 77 insertions(+), 42 deletions(-) (limited to 'source/blender/depsgraph/intern') diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index dfc20286565..066c9868876 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -240,13 +240,14 @@ bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const return find_node(key) != NULL; } -void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, - DepsNode *node_to, - const char *description, - bool check_unique) +DepsRelation *DepsgraphRelationBuilder::add_time_relation( + TimeSourceDepsNode *timesrc, + DepsNode *node_to, + const char *description, + bool check_unique) { if (timesrc && node_to) { - graph_->add_new_relation(timesrc, node_to, description, check_unique); + return graph_->add_new_relation(timesrc, node_to, description, check_unique); } else { DEG_DEBUG_PRINTF(BUILD, "add_time_relation(%p = %s, %p = %s, %s) Failed\n", @@ -254,16 +255,20 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, node_to, (node_to) ? node_to->identifier().c_str() : "", description); } + return NULL; } -void DepsgraphRelationBuilder::add_operation_relation( +DepsRelation *DepsgraphRelationBuilder::add_operation_relation( OperationDepsNode *node_from, OperationDepsNode *node_to, const char *description, bool check_unique) { if (node_from && node_to) { - graph_->add_new_relation(node_from, node_to, description, check_unique); + return graph_->add_new_relation(node_from, + node_to, + description, + check_unique); } else { DEG_DEBUG_PRINTF(BUILD, "add_operation_relation(%p = %s, %p = %s, %s) Failed\n", @@ -271,6 +276,7 @@ void DepsgraphRelationBuilder::add_operation_relation( node_to, (node_to) ? node_to->identifier().c_str() : "", description); } + return NULL; } void DepsgraphRelationBuilder::add_collision_relations( diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index d1ca0b6c7dd..4a8e91f18db 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -80,6 +80,7 @@ namespace DEG { struct Depsgraph; struct DepsNode; struct DepsNodeHandle; +struct DepsRelation; struct RootDepsNode; struct IDDepsNode; struct TimeSourceDepsNode; @@ -173,22 +174,22 @@ struct DepsgraphRelationBuilder void begin_build(); template - void add_relation(const KeyFrom& key_from, - const KeyTo& key_to, - const char *description, - bool check_unique = false); + DepsRelation *add_relation(const KeyFrom& key_from, + const KeyTo& key_to, + const char *description, + bool check_unique = false); template - void add_relation(const TimeSourceKey& key_from, - const KeyTo& key_to, - const char *description, - bool check_unique = false); + DepsRelation *add_relation(const TimeSourceKey& key_from, + const KeyTo& key_to, + const char *description, + bool check_unique = false); template - void add_node_handle_relation(const KeyType& key_from, - const DepsNodeHandle *handle, - const char *description, - bool check_unique = false); + DepsRelation *add_node_handle_relation(const KeyType& key_from, + const DepsNodeHandle *handle, + const char *description, + bool check_unique = false); void build_scene(Scene *scene); void build_group(Object *object, Group *group); @@ -274,14 +275,14 @@ protected: OperationDepsNode *find_node(const OperationKey &key) const; bool has_node(const OperationKey &key) const; - void add_time_relation(TimeSourceDepsNode *timesrc, - DepsNode *node_to, - const char *description, - bool check_unique = false); - void add_operation_relation(OperationDepsNode *node_from, - OperationDepsNode *node_to, - const char *description, - bool check_unique = false); + DepsRelation *add_time_relation(TimeSourceDepsNode *timesrc, + DepsNode *node_to, + const char *description, + bool check_unique = false); + DepsRelation *add_operation_relation(OperationDepsNode *node_from, + OperationDepsNode *node_to, + const char *description, + bool check_unique = false); template DepsNodeHandle create_node_handle(const KeyType& key, 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 b7dd05517cf..570227601db 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h @@ -46,17 +46,17 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& } template -void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, - const KeyTo &key_to, - const char *description, - bool check_unique) +DepsRelation *DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, + const KeyTo &key_to, + const char *description, + bool check_unique) { DepsNode *node_from = get_node(key_from); DepsNode *node_to = get_node(key_to); OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; if (op_from && op_to) { - add_operation_relation(op_from, op_to, description, check_unique); + return add_operation_relation(op_from, op_to, description, check_unique); } else { if (!op_from) { @@ -78,24 +78,27 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, description, key_to.identifier().c_str()); } } + return NULL; } template -void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from, - const KeyTo &key_to, - const char *description, - bool check_unique) +DepsRelation *DepsgraphRelationBuilder::add_relation( + const TimeSourceKey &key_from, + const KeyTo &key_to, + const char *description, + bool check_unique) { TimeSourceDepsNode *time_from = get_node(key_from); DepsNode *node_to = get_node(key_to); OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; if (time_from != NULL && op_to != NULL) { - add_time_relation(time_from, op_to, description, check_unique); + return add_time_relation(time_from, op_to, description, check_unique); } + return NULL; } template -void DepsgraphRelationBuilder::add_node_handle_relation( +DepsRelation *DepsgraphRelationBuilder::add_node_handle_relation( const KeyType &key_from, const DepsNodeHandle *handle, const char *description, @@ -105,7 +108,7 @@ void DepsgraphRelationBuilder::add_node_handle_relation( OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; OperationDepsNode *op_to = handle->node->get_entry_operation(); if (op_from != NULL && op_to != NULL) { - add_operation_relation(op_from, op_to, description, check_unique); + return add_operation_relation(op_from, op_to, description, check_unique); } else { if (!op_from) { @@ -117,6 +120,7 @@ void DepsgraphRelationBuilder::add_node_handle_relation( description, key_from.identifier().c_str()); } } + return NULL; } template diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc index 7b93434710b..80772f9595f 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -256,6 +256,18 @@ static void deg_debug_graphviz_relation_color(const DebugContext &ctx, deg_debug_fprintf(ctx, "%s", color); } +static void deg_debug_graphviz_relation_style(const DebugContext &ctx, + const DepsRelation *rel) +{ + const char *style_default = "solid"; + const char *style_no_flush = "dashed"; + const char *style = style_default; + if (rel->flag & DEPSREL_FLAG_NO_FLUSH) { + style = style_no_flush; + } + deg_debug_fprintf(ctx, "%s", style); +} + static void deg_debug_graphviz_node_style(const DebugContext &ctx, const DepsNode *node) { const char *base_style = "filled"; /* default style */ @@ -469,16 +481,23 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx, /* Note: without label an id seem necessary to avoid bugs in graphviz/dot */ deg_debug_fprintf(ctx, "id=\"%s\"", rel->name); // deg_debug_fprintf(ctx, "label=\"%s\"", rel->name); - deg_debug_fprintf(ctx, ",color="); deg_debug_graphviz_relation_color(ctx, rel); + deg_debug_fprintf(ctx, ",color="); + deg_debug_graphviz_relation_color(ctx, rel); + deg_debug_fprintf(ctx, ",style="); + deg_debug_graphviz_relation_style(ctx, rel); deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth); /* NOTE: edge from node to own cluster is not possible and gives graphviz * warning, avoid this here by just linking directly to the invisible * placeholder node */ - if (deg_debug_graphviz_is_cluster(tail) && !deg_debug_graphviz_is_owner(head, tail)) { + if (deg_debug_graphviz_is_cluster(tail) && + !deg_debug_graphviz_is_owner(head, tail)) + { deg_debug_fprintf(ctx, ",ltail=\"cluster_%p\"", tail); } - if (deg_debug_graphviz_is_cluster(head) && !deg_debug_graphviz_is_owner(tail, head)) { + if (deg_debug_graphviz_is_cluster(head) && + !deg_debug_graphviz_is_owner(tail, head)) + { deg_debug_fprintf(ctx, ",lhead=\"cluster_%p\"", head); } deg_debug_fprintf(ctx, "];" NL); diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index f742587e19f..dda4da7bc13 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -63,6 +63,8 @@ typedef enum eDepsRelation_Flag { * which triggers a cyclic relationship to exist in the graph. */ DEPSREL_FLAG_CYCLIC = (1 << 0), + /* Update flush will not go through this relation. */ + DEPSREL_FLAG_NO_FLUSH = (1 << 1), } eDepsRelation_Flag; /* B depends on A (A -> B) */ diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 4033e1325e6..e7764cf5a27 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -223,6 +223,9 @@ BLI_INLINE OperationDepsNode *flush_schedule_children( { OperationDepsNode *result = NULL; foreach (DepsRelation *rel, op_node->outlinks) { + if (rel->flag & DEPSREL_FLAG_NO_FLUSH) { + continue; + } OperationDepsNode *to_node = (OperationDepsNode *)rel->to; if (to_node->scheduled == false) { if (result != NULL) { -- cgit v1.2.3