Depsgraph: Fix missing updates when tweaking node tree parameters
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 29 Aug 2017 10:51:56 +0000 (12:51 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 29 Aug 2017 10:58:55 +0000 (12:58 +0200)
The is following: split copy on write update for node trees, and if we are only
tagging for uniform buffer update we skip whole datablock copy and only invoke
copy default_values form original nodetree to a copied one.

Thing which i'm not sure is: whether we need to use different branches in graph
itself to control such a conditional behavior, or whether we need to store tag
somewhere in the dependency graph. There are obviously cons and pros in both
approaches, and need to think about this. Maybe with more examples it becomes
more obvious which way is better.

This only fixes manual tweaks for now, animation support is coming.

source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
source/blender/depsgraph/intern/depsgraph_tag.cc
source/blender/depsgraph/intern/depsgraph_types.h
source/blender/depsgraph/intern/eval/deg_eval_flush.cc
source/blender/depsgraph/intern/nodes/deg_node_component.cc
source/blender/depsgraph/intern/nodes/deg_node_component.h

index 5bc47f62b6401d03ddac6b30d3668f988de1e547..ea0b350b8af938cebf275999114dbc2b8ca61c9f 100644 (file)
@@ -1053,8 +1053,13 @@ void free_nodesystem(void);
 /* -------------------------------------------------------------------- */
 /* evaluation support, */
 
+struct EvaluationContext;
+
 void BKE_nodetree_copy_default_values(struct bNodeTree *ntree_dst,
                                       const struct bNodeTree *ntree_src);
 
+void BKE_nodetree_shading_params_eval(const struct EvaluationContext *eval_ctx,
+                                      struct bNodeTree *ntree_dst,
+                                      const struct bNodeTree *ntree_src);
 
 #endif  /* __BKE_NODE_H__ */
index 1c24d72759eb79e72e6290c2d606e9676c08e38d..3ff4885f7fcaf1585eba357084c5ea810659177b 100644 (file)
@@ -3826,6 +3826,9 @@ static void node_copy_default_values(bNode *node_dst, const bNode *node_src)
 void BKE_nodetree_copy_default_values(bNodeTree *ntree_dst,
                                       const bNodeTree *ntree_src)
 {
+       if (ntree_dst == ntree_src) {
+               return;
+       }
        bNode *node_dst = ntree_dst->nodes.first;
        const bNode *node_src = ntree_src->nodes.first;
        while (node_dst != NULL) {
@@ -3834,3 +3837,13 @@ void BKE_nodetree_copy_default_values(bNodeTree *ntree_dst,
                node_src = node_src->next;
        }
 }
+
+void BKE_nodetree_shading_params_eval(const struct EvaluationContext *UNUSED(eval_ctx),
+                                      bNodeTree *ntree_dst,
+                                      const bNodeTree *ntree_src)
+{
+       if (G.debug & G_DEBUG_DEPSGRAPH) {
+               printf("%s on %s (%p)\n", __func__, ntree_src->id.name, ntree_dst);
+       }
+       BKE_nodetree_copy_default_values(ntree_dst, ntree_src);
+}
index 6684937073954a8375dcefe3ef5f12f1ca97b04d..d29b87a07429fee365f56e9a90cab2bd89f68234 100644 (file)
@@ -1095,28 +1095,33 @@ void DepsgraphNodeBuilder::build_lamp(Object *ob)
 
 void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
 {
-       if (!ntree)
+       if (ntree == NULL) {
                return;
-
+       }
        /* nodetree itself */
        ID *ntree_id = &ntree->id;
        OperationDepsNode *op_node;
-
+       add_id_node(ntree_id);
+       bNodeTree *ntree_cow = get_cow_datablock(ntree);
+       /* Animation, */
        build_animdata(ntree_id);
-
        /* Parameters for drivers. */
        op_node = add_operation_node(ntree_id,
                                     DEG_NODE_TYPE_PARAMETERS,
                                     NULL,
                                     DEG_OPCODE_PARAMETERS_EVAL);
        op_node->set_as_exit();
-
        /* Shading update. */
        add_operation_node(ntree_id,
                           DEG_NODE_TYPE_SHADING,
                           NULL,
                           DEG_OPCODE_MATERIAL_UPDATE);
 
+       add_operation_node(ntree_id,
+                          DEG_NODE_TYPE_SHADING_PARAMETERS,
+                          function_bind(BKE_nodetree_shading_params_eval,
+                                        _1, ntree_cow, ntree),
+                          DEG_OPCODE_MATERIAL_UPDATE);
        /* nodetree's nodes... */
        LINKLIST_FOREACH (bNode *, bnode, &ntree->nodes) {
                ID *id = bnode->id;
index 18326baab45b0d05a87bc9799376a2dccd57d8d5..87f7117bb1469c38348eb81829eb327fccf53e8d 100644 (file)
@@ -1853,7 +1853,11 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
        OperationKey shading_update_key(ntree_id,
                                        DEG_NODE_TYPE_SHADING,
                                        DEG_OPCODE_MATERIAL_UPDATE);
+       OperationKey shading_parameters_key(ntree_id,
+                                           DEG_NODE_TYPE_SHADING_PARAMETERS,
+                                           DEG_OPCODE_MATERIAL_UPDATE);
        add_relation(parameters_key, shading_update_key, "NTree Parameters");
+       add_relation(shading_parameters_key, shading_update_key, "NTree Shading Parameters");
 }
 
 /* Recursively build graph for material */
@@ -2005,6 +2009,10 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node
                        /* Copy-on-write component never depends on itself. */
                        continue;
                }
+               if (!comp_node->depends_on_cow()) {
+                       /* Component explicitly requests to not add relation. */
+                       continue;
+               }
                /* All entry operations of each component should wait for a proper
                 * copy of ID.
                 */
index 66b63f861ee108e40266b0a3672f0e519607dca9..ba1b91629db83ec7625caf32d4a930993091c68a 100644 (file)
@@ -88,9 +88,10 @@ static const int deg_debug_node_type_color_map[][2] = {
     {DEG_NODE_TYPE_GEOMETRY,          6},
     {DEG_NODE_TYPE_SEQUENCER,         7},
     {DEG_NODE_TYPE_SHADING,           8},
-    {DEG_NODE_TYPE_CACHE,             9},
-    {DEG_NODE_TYPE_LAYER_COLLECTIONS, 10},
-    {DEG_NODE_TYPE_COPY_ON_WRITE,     11},
+    {DEG_NODE_TYPE_SHADING_PARAMETERS,9},
+    {DEG_NODE_TYPE_CACHE,             10},
+    {DEG_NODE_TYPE_LAYER_COLLECTIONS, 11},
+    {DEG_NODE_TYPE_COPY_ON_WRITE,     12},
     {-1,                              0}
 };
 #endif
@@ -377,6 +378,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
                case DEG_NODE_TYPE_EVAL_POSE:
                case DEG_NODE_TYPE_BONE:
                case DEG_NODE_TYPE_SHADING:
+               case DEG_NODE_TYPE_SHADING_PARAMETERS:
                case DEG_NODE_TYPE_CACHE:
                case DEG_NODE_TYPE_LAYER_COLLECTIONS:
                case DEG_NODE_TYPE_EVAL_PARTICLES:
@@ -395,7 +397,9 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
                        }
                        break;
                }
-               default:
+               case DEG_NODE_TYPE_UNDEFINED:
+               case DEG_NODE_TYPE_TIMESOURCE:
+               case DEG_NODE_TYPE_OPERATION:
                        deg_debug_graphviz_node_single(ctx, node);
                        break;
        }
index 9f2081c816903a88b2be87273ad8c64deec48c71..839865d0dfb48eaec23a1c642039e7f538ad3062 100644 (file)
@@ -248,8 +248,13 @@ void id_tag_update_particle(Depsgraph *graph, IDDepsNode *id_node, int tag)
 
 void id_tag_update_shading(Depsgraph *graph, IDDepsNode *id_node)
 {
-       ComponentDepsNode *shading_comp =
-               id_node->find_component(DEG_NODE_TYPE_SHADING);
+       ComponentDepsNode *shading_comp;
+       if (GS(id_node->id_orig->name) == ID_NT) {
+               shading_comp = id_node->find_component(DEG_NODE_TYPE_SHADING_PARAMETERS);
+       }
+       else {
+               shading_comp = id_node->find_component(DEG_NODE_TYPE_SHADING);
+       }
        if (shading_comp == NULL) {
 #ifdef STRICT_COMPONENT_TAGGING
                DEG_ERROR_PRINTF("ERROR: Unable to find shading component for %s\n",
index 57a47c4084bdeadb9d661ec643f186b3a2d32099..9ea6dfedefeadd88da08f00b2e75b04d1db0433a 100644 (file)
@@ -130,6 +130,7 @@ typedef enum eDepsNode_Type {
        DEG_NODE_TYPE_EVAL_PARTICLES,
        /* Material Shading Component */
        DEG_NODE_TYPE_SHADING,
+       DEG_NODE_TYPE_SHADING_PARAMETERS,
        /* Cache Component */
        DEG_NODE_TYPE_CACHE,
 } eDepsNode_Type;
index 3eaa9cdaa173d04fa3d33335ba0f3f94d6a8febf..6777c21f2ed8d7ec50bad2fce62aa875c2691a4c 100644 (file)
@@ -144,9 +144,11 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
                                 *
                                 * TODO(sergey): This is something we need to avoid.
                                 */
-                               ComponentDepsNode *cow_comp =
-                                       id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
-                               cow_comp->tag_update(graph);
+                               if (comp_node->depends_on_cow()) {
+                                       ComponentDepsNode *cow_comp =
+                                               id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
+                                       cow_comp->tag_update(graph);
+                               }
 #endif
                        }
 
@@ -202,6 +204,8 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
                                                case DEG_NODE_TYPE_PROXY:
                                                        object->recalc |= OB_RECALC_DATA;
                                                        break;
+                                               case DEG_NODE_TYPE_SHADING_PARAMETERS:
+                                                       break;
                                        }
 
                                        /* TODO : replace with more granular flags */
index bd9583a7b677024cd7759ef499d9fbcf8e9800a5..a250dce123927da9179d60ed012b08e5b797e0ed 100644 (file)
@@ -396,6 +396,11 @@ static DepsNodeFactoryImpl<ParticlesComponentDepsNode> DNTI_EVAL_PARTICLES;
 DEG_DEPSNODE_DEFINE(ShadingComponentDepsNode, DEG_NODE_TYPE_SHADING, "Shading Component");
 static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING;
 
+/* Shading Parameters Component Defines ============================ */
+
+DEG_DEPSNODE_DEFINE(ShadingParametersComponentDepsNode, DEG_NODE_TYPE_SHADING_PARAMETERS, "Shading Parameters Component");
+static DepsNodeFactoryImpl<ShadingParametersComponentDepsNode> DNTI_SHADING_PARAMETERS;
+
 /* Cache Component Defines ============================ */
 
 DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEG_NODE_TYPE_CACHE, "Cache Component");
@@ -426,7 +431,9 @@ void deg_register_component_depsnodes()
        deg_register_node_typeinfo(&DNTI_BONE);
 
        deg_register_node_typeinfo(&DNTI_EVAL_PARTICLES);
+
        deg_register_node_typeinfo(&DNTI_SHADING);
+       deg_register_node_typeinfo(&DNTI_SHADING_PARAMETERS);
 
        deg_register_node_typeinfo(&DNTI_CACHE);
 
index 955d197b33ae0c435523108833803e3ae3451cc2..36945daf1b84aa697d7be2196c54dd7ac06d20db 100644 (file)
@@ -151,6 +151,7 @@ struct ComponentDepsNode : public DepsNode {
        OperationDepsNode *exit_operation;
 
        // XXX: a poll() callback to check if component's first node can be started?
+       virtual bool depends_on_cow() { return true; }
 };
 
 /* ---------------------------------------- */
@@ -200,6 +201,11 @@ struct ShadingComponentDepsNode : public ComponentDepsNode {
        DEG_DEPSNODE_DECLARE;
 };
 
+struct ShadingParametersComponentDepsNode : public ComponentDepsNode {
+       DEG_DEPSNODE_DECLARE;
+       virtual bool depends_on_cow() { return false; }
+};
+
 struct CacheComponentDepsNode : public ComponentDepsNode {
        DEG_DEPSNODE_DECLARE;
 };