Merging r58464 through r58474 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / blenkernel / intern / depsgraph.c
index 4ce06623baec8f31dbac01188934478ec66c7c2d..f3a824665e0e08e5348760cde1c5de1a26c94b91 100644 (file)
@@ -29,6 +29,7 @@
 
  
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
 
@@ -2653,6 +2654,98 @@ void DAG_pose_sort(Object *ob)
        ugly_hack_sorry = 1;
 }
 
+/* ************************  DAG FOR THREADED UPDATE  ********************* */
+
+/* Initialize the DAG for threaded update.
+ *
+ * Sets up all the data needed for faster check whether DAG node is
+ * updatable already (whether all the dependencies are met).
+ */
+void DAG_threaded_update_begin(Scene *scene)
+{
+       DagNode *node;
+
+       /* We reset valency to zero first... */
+       for (node = scene->theDag->DagNode.first; node; node = node->next) {
+               node->valency = 0;
+       }
+
+       /* ... and then iterate over all the nodes and
+        * increase valency for node childs.
+        */
+       for (node = scene->theDag->DagNode.first; node; node = node->next) {
+               DagAdjList *itA;
+
+               for (itA = node->child; itA; itA = itA->next) {
+                       if (itA->node != node) {
+                               itA->node->valency++;
+                       }
+               }
+       }
+}
+
+/* Call functor for every node in the graph which is ready for
+ * update (all it's dependencies are met). Quick check for this
+ * is valency == 0.
+ */
+void DAG_threaded_update_foreach_ready_node(Scene *scene,
+                                            void (*func)(void *node, void *user_data),
+                                            void *user_data)
+{
+       DagNode *node;
+
+       for (node = scene->theDag->DagNode.first; node; node = node->next) {
+               if (node->valency == 0) {
+                       func(node, user_data);
+               }
+       }
+}
+
+/* Will return Object ID if node represents Object,
+ * and will return NULL otherwise.
+ */
+Object *DAG_threaded_update_get_node_object(void *node_v)
+{
+       DagNode *node = node_v;
+
+       if (node->type == ID_OB) {
+               return node->ob;
+       }
+
+       return NULL;
+}
+
+/* Returns node name, used for debug output only, atm. */
+const char *DAG_threaded_update_get_node_name(void *node_v)
+{
+       DagNode *node = node_v;
+
+       return dag_node_name(node);
+}
+
+/* This function is called when handling node is done.
+ *
+ * This function updates valency for all childs and
+ * schedules them if they're ready.
+ */
+void DAG_threaded_update_handle_node_updated(void *node_v,
+                                             void (*func)(void *node, void *user_data),
+                                             void *user_data)
+{
+       DagNode *node = node_v;
+       DagAdjList *itA;
+
+       for (itA = node->child; itA; itA = itA->next) {
+               if (itA->node != node) {
+                       itA->node->valency--;
+
+                       if (itA->node->valency == 0) {
+                               func(itA->node, user_data);
+                       }
+               }
+       }
+}
+
 /* ************************ DAG DEBUGGING ********************* */
 
 void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob)
@@ -2671,4 +2764,3 @@ void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob)
        
        dag_print_dependencies = 0;
 }
-