Depsgraph: Add relation flag to avoid flush across it
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 23 Apr 2018 14:42:37 +0000 (16:42 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 23 Apr 2018 14:42:37 +0000 (16:42 +0200)
This way we can avoid re-evaluation of certain parts of datablock
when something unrelated has changed.

source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
source/blender/depsgraph/intern/depsgraph.h
source/blender/depsgraph/intern/eval/deg_eval_flush.cc

index dfc20286565249bb71bda64e74b5cd336c3153a8..066c9868876afa09fe4eea44fd4cfa8c11e749a1 100644 (file)
@@ -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() : "<None>",
                                 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() : "<None>",
                                 description);
        }
+       return NULL;
 }
 
 void DepsgraphRelationBuilder::add_collision_relations(
index d1ca0b6c7dd72df31cd7ec1a122af4344fd3e4c9..4a8e91f18dbeba9aecfd4d3a0ade93c1102b9e02 100644 (file)
@@ -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 <typename KeyFrom, typename KeyTo>
-       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 <typename KeyTo>
-       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 <typename KeyType>
-       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 <typename KeyType>
        DepsNodeHandle create_node_handle(const KeyType& key,
index b7dd05517cfffbb50062162969732bb8fa842dfd..570227601db656160850516c1fd688d3ce03d4dd 100644 (file)
@@ -46,17 +46,17 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType&
 }
 
 template <typename KeyFrom, typename KeyTo>
-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 <typename KeyTo>
-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 <typename KeyType>
-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 <typename KeyType>
index 7b93434710b2d4ba549f7eda2c62cc00ad9f7a58..80772f9595f06cc714710a91ed1039e9d9bce952 100644 (file)
@@ -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);
index f742587e19f80ee4f05f05c312bf857e631ce91f..dda4da7bc13f0ceefac4da059f073846b06436e6 100644 (file)
@@ -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) */
index 4033e1325e6400aa6f3a780017cd62587ebe8a06..e7764cf5a27ad1c4e03324e20013ddf8acb6a73f 100644 (file)
@@ -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) {