[Bf-blender-cvs] [5353ae3] object_nodes: Separation of dependencies of node trees and their users for compiling vs. evaluation.

Lukas Tönne noreply at git.blender.org
Wed Dec 16 13:26:34 CET 2015


Commit: 5353ae384df3cd28172b9c6e87d8a97703e4876d
Author: Lukas Tönne
Date:   Wed Dec 16 12:02:17 2015 +0100
Branches: object_nodes
https://developer.blender.org/rB5353ae384df3cd28172b9c6e87d8a97703e4876d

Separation of dependencies of node trees and their users for compiling vs. evaluation.

So far any change in a node tree would cause both a recompile of bvm functions
as well as a re-evaluation of any users of that function. This is quite inefficient
and should be separated to allow caching of the bvm functions independent from
their users.

To this end the nodes now have 2 callbacks: one for getting compile deps, the other
for getting eval deps.
* Compile dependencies are typically other node trees (node groups). In the future
  this could also be Text datablocks, similar to how OSL script nodes work.
* Eval dependencies are all the blend_data blocks that a function might access.
  For modifier nodes these could typically be meshes, curves; for shaders could
  be images, textures; and so forth.

Separating these dependencies means the bvm functions will have to be recompiled
only when the actual bNodes change (add/remove, linking, socket values).
Conversely when some modifier input data changes (editing, cfra) the modifier
function will be re-evaluated.

===================================================================

M	release/scripts/nodes/common_nodes.py
M	release/scripts/nodes/geometry_nodes.py
M	release/scripts/nodes/group_nodes.py
M	release/scripts/nodes/object_nodes.py
M	source/blender/blenkernel/intern/depsgraph.c
M	source/blender/blenkernel/intern/texture.c
M	source/blender/blenvm/BVM_api.h
M	source/blender/blenvm/CMakeLists.txt
M	source/blender/blenvm/intern/bvm_api.cc
M	source/blender/depsgraph/CMakeLists.txt
M	source/blender/depsgraph/intern/depsgraph_build.cc
M	source/blender/depsgraph/intern/depsgraph_build.h
M	source/blender/depsgraph/intern/depsgraph_build_nodes.cc
M	source/blender/depsgraph/intern/depsgraph_build_relations.cc
M	source/blender/depsgraph/intern/depsnode_opcodes.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/render/intern/source/render_texture.c

===================================================================

diff --git a/release/scripts/nodes/common_nodes.py b/release/scripts/nodes/common_nodes.py
index b0c5b7f..dc411f2 100644
--- a/release/scripts/nodes/common_nodes.py
+++ b/release/scripts/nodes/common_nodes.py
@@ -41,40 +41,18 @@ def enum_property_value_prop(name):
 
 ###############################################################################
 
-# Utility class with the same API as DepsNode, to gather needed ID datablocks
-class GlobalsBuilder():
-    def __init__(self, eval_globals):
-        self.eval_globals = eval_globals
-
-    @staticmethod
-    def get_id_key(id_data):
-        return BVMEvalGlobals.get_id_key(id_data)
-
-    def add_scene_relation(self, scene, component='PARAMETERS', description=""):
-        pass
-
-    def add_object_relation(self, ob, component='PARAMETERS', description=""):
-        self.eval_globals.add_object(self.get_id_key(ob), ob)
-
-    def add_bone_relation(self, ob, bone, component='PARAMETERS', description=""):
-        self.eval_globals.add_object(self.get_id_key(ob), ob)
-
-    def add_texture_relation(self, tex, component='PARAMETERS', description=""):
-        pass
-
-    def add_nodetree_relation(self, ntree, component='PARAMETERS', description=""):
-        pass
-
 
 class NodeTreeBase():
-    def depsgraph_update(self, depsnode):
+    def bvm_compile_dependencies(self, depsnode):
+        # own changes require recompile
+        depsnode.add_nodetree_relation(self, 'PARAMETERS')
+
         for node in self.nodes:
-            node.relations_update(depsnode)
+            node.compile_dependencies(depsnode)
 
-    def bvm_globals_update(self, eval_globals):
-        builder = GlobalsBuilder(eval_globals)
+    def bvm_eval_dependencies(self, depsnode):
         for node in self.nodes:
-            node.relations_update(builder)
+            node.eval_dependencies(depsnode)
 
     def bvm_compile(self, graph):
         compiler = NodeCompiler(graph)
@@ -115,7 +93,10 @@ class NodeBase():
         finally:
             self.is_updating = False
 
-    def relations_update(self, depsnode):
+    def compile_dependencies(self, depsnode):
+        pass
+
+    def eval_dependencies(self, depsnode):
         pass
 
 
diff --git a/release/scripts/nodes/geometry_nodes.py b/release/scripts/nodes/geometry_nodes.py
index 5758c3b..76bf022 100644
--- a/release/scripts/nodes/geometry_nodes.py
+++ b/release/scripts/nodes/geometry_nodes.py
@@ -288,10 +288,11 @@ class GeometryBooleanNode(GeometryNodeBase, ObjectNode):
         layout.prop(self, "use_connect_regions")
         layout.prop(self, "threshold")
 
-    def relations_update(self, depsnode):
-        if self.id is not None:
-            depsnode.add_object_relation(self.id, 'TRANSFORM')
-            depsnode.add_object_relation(self.id, 'GEOMETRY')
+    def eval_dependencies(self, depsnode):
+        curveob = self.id
+        if curveob:
+            depsnode.add_object_relation(curveob, 'TRANSFORM')
+            depsnode.add_object_relation(curveob, 'GEOMETRY')
 
     def init(self, context):
         self.inputs.new('GeometrySocket', "")
@@ -334,10 +335,11 @@ class CurvePathNode(CurveNodeBase, ObjectNode):
     def draw_buttons(self, context, layout):
         layout.template_ID(self, "id")
 
-    def relations_update(self, depsnode):
-        if self.id is not None:
-            depsnode.add_object_relation(self.id, 'TRANSFORM')
-            depsnode.add_object_relation(self.id, 'GEOMETRY')
+    def eval_dependencies(self, depsnode):
+        curveob = self.id
+        if curveob:
+            depsnode.add_object_relation(curveob, 'TRANSFORM')
+            depsnode.add_object_relation(curveob, 'GEOMETRY')
 
     def init(self, context):
         self.inputs.new('NodeSocketFloat', "Parameter")
diff --git a/release/scripts/nodes/group_nodes.py b/release/scripts/nodes/group_nodes.py
index e2b81eb..91834ec 100644
--- a/release/scripts/nodes/group_nodes.py
+++ b/release/scripts/nodes/group_nodes.py
@@ -298,9 +298,15 @@ def make_node_group_types(prefix, treetype, node_base):
         def draw_buttons(self, context, layout):
             layout.template_ID(self, "id", new="object_nodes.geometry_nodes_new")
 
-        def relations_update(self, depsnode):
-            if self.id is not None:
-                depsnode.add_nodetree_relation(self.id)
+        def compile_dependencies(self, depsnode):
+            ntree = self.id
+            if ntree:
+                ntree.bvm_compile_dependencies(depsnode)
+
+        def eval_dependencies(self, depsnode):
+            ntree = self.id
+            if ntree:
+                ntree.bvm_eval_dependencies(depsnode)
 
         def update(self):
             if self.is_updating:
diff --git a/release/scripts/nodes/object_nodes.py b/release/scripts/nodes/object_nodes.py
index b0862ad..f2464e2 100644
--- a/release/scripts/nodes/object_nodes.py
+++ b/release/scripts/nodes/object_nodes.py
@@ -69,9 +69,15 @@ class GeometryNode(ObjectNodeBase, ObjectNode):
     def bl_id_property_poll(self, ntree):
         return ntree.bl_idname == 'GeometryNodeTree'
 
-    def relations_update(self, depsnode):
-        if self.id is not None:
-            depsnode.add_nodetree_relation(self.id)
+    def compile_dependencies(self, depsnode):
+        ntree = self.id
+        if ntree:
+            ntree.bvm_compile_dependencies(depsnode)
+
+    def eval_dependencies(self, depsnode):
+        ntree = self.id
+        if ntree:
+            ntree.bvm_eval_dependencies(depsnode)
 
     def draw_buttons(self, context, layout):
         layout.template_ID(self, "id", new="object_nodes.geometry_nodes_new")
@@ -90,9 +96,15 @@ class ForceFieldNode(ObjectNodeBase, ObjectNode):
     def bl_id_property_poll(self, ntree):
         return ntree.bl_idname == 'ForceFieldNodeTree'
 
-    def relations_update(self, depsnode):
-        if self.id is not None:
-            depsnode.add_nodetree_relation(self.id)
+    def compile_dependencies(self, depsnode):
+        ntree = self.id
+        if ntree:
+            ntree.bvm_compile_dependencies(depsnode)
+
+    def eval_dependencies(self, depsnode):
+        ntree = self.id
+        if ntree:
+            ntree.bvm_eval_dependencies(depsnode)
 
     def draw_buttons(self, context, layout):
         layout.template_ID(self, "id", new="object_nodes.force_field_nodes_new")
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 54652e7..6ce02df 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2649,7 +2649,7 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
 
 		if (ELEM(idtype, ID_TE)) {
 			Tex *tex = (Tex *)id;
-			BVM_function_cache_remove(BVM_texture_key(tex));
+			BVM_function_cache_remove(tex->nodetree);
 		}
 
 		if (idtype == ID_MC) {
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 5d4dc94..273f5d3 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -1689,6 +1689,6 @@ void BKE_texture_get_value(
 
 void BKE_texture_invalidate(EvaluationContext *UNUSED(eval_ctx), Tex *tex)
 {
-	BVM_function_cache_remove(BVM_texture_key(tex));
+	BVM_function_cache_remove(tex->nodetree);
 }
 
diff --git a/source/blender/blenvm/BVM_api.h b/source/blender/blenvm/BVM_api.h
index 0b24a01..3355786 100644
--- a/source/blender/blenvm/BVM_api.h
+++ b/source/blender/blenvm/BVM_api.h
@@ -48,14 +48,12 @@ void BVM_free(void);
 
 /* ------------------------------------------------------------------------- */
 
-typedef unsigned int BVMFunctionKey;
-
 void BVM_function_free(struct BVMFunction *fn);
 
-struct BVMFunction *BVM_function_cache_acquire(BVMFunctionKey key);
+struct BVMFunction *BVM_function_cache_acquire(void *key);
 void BVM_function_release(struct BVMFunction *_fn);
-void BVM_function_cache_set(BVMFunctionKey key, struct BVMFunction *_fn);
-void BVM_function_cache_remove(BVMFunctionKey key);
+void BVM_function_cache_set(void *key, struct BVMFunction *_fn);
+void BVM_function_cache_remove(void *key);
 void BVM_function_cache_clear(void);
 
 /* ------------------------------------------------------------------------- */
@@ -138,8 +136,6 @@ void BVM_eval_texture(struct BVMEvalContext *context, struct BVMFunction *fn,
                       float coord[3], float dxt[3], float dyt[3], int osatex,
                       short which_output, int cfra, int preview);
 
-BVMFunctionKey BVM_texture_key(struct Tex *tex);
-
 /* ------------------------------------------------------------------------- */
 
 struct DerivedMesh;
diff --git a/source/blender/blenvm/CMakeLists.txt b/source/blender/blenvm/CMakeLists.txt
index ccdf26e..fddccd5 100644
--- a/source/blender/blenvm/CMakeLists.txt
+++ b/source/blender/blenvm/CMakeLists.txt
@@ -33,6 +33,7 @@ set(INC
 	util
 	../blenkernel
 	../blenlib
+	../depsgraph
 	../makesdna
 	../makesrna
 	../render/extern/include
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index 129ce68..d8f4b7d 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -44,6 +44,8 @@ extern "C" {
 #include "BKE_effect.h"
 #include "BKE_node.h"
 
+#include "DEG_depsgraph_build.h"
+
 #include "RE_shader_ext.h"
 
 #include "BVM_api.h"
@@ -94,8 +96,8 @@ void BVM_function_free(struct BVMFunction *fn)
 
 namespace bvm {
 
-typedef unordered_map<BVMFunctionKey, Function*> FunctionCache;
-typedef std::pair<BVMFunctionKey, Function*> FunctionCachePair;
+typedef unordered_map<void*, Function*> FunctionCache;
+typedef std::pair<void*, Function*> FunctionCachePair;
 
 static FunctionCache bvm_function_cache;
 static mutex bvm_function_cache_mutex;
@@ -103,7 +105,7 @@ static spin_lock bvm_function_cache_lock = spin_lock(bvm_function_cache_mutex);
 
 } /* namespace bvm */
 
-struct BVMFunction *BVM_function_cache_acquire(BVMFunctionKey key)
+struct BVMFunction *BVM_function_cache_acquire(void *key)
 {
 	using namespace bvm;
 	
@@ -143,7 +145,7 @@ void BVM_function_release(BVMFunction *_fn)
 	}
 }
 
-void BVM_function_cache_set(BVMFunctionKey key, BVMFunction *_fn)
+void BVM_function_cache_set(void *key, BVMF

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list