Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-05-12 13:05:57 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-05-12 14:06:37 +0300
commitbac735380189c63d2b8824cba8e0398bb35e9af2 (patch)
treed9bc3e73a89520ef7e23782419d880964d1a4fb7 /source/blender/blenkernel/intern
parenta09341469ee3874a0874492a7dcad79c2b99179a (diff)
Depsgraph: New dependency graph integration commit
This commit integrates the work done so far on the new dependency graph system, where goal was to replace legacy depsgraph with the new one, supporting loads of neat features like: - More granular dependency relation nature, which solves issues with fake cycles in the dependencies. - Move towards all-animatable, by better integration of drivers into the system. - Lay down some basis for upcoming copy-on-write, overrides and so on. The new system is living side-by-side with the previous one and disabled by default, so nothing will become suddenly broken. The way to enable new depsgraph is to pass `--new-depsgraph` command line argument. It's a bit early to consider the system production-ready, there are some TODOs and issues were discovered during the merge period, they'll be addressed ASAP. But it's important to merge, because it's the only way to attract artists to really start testing this system. There are number of assorted documents related on the design of the new system: * http://wiki.blender.org/index.php/User:Aligorith/GSoC2013_Depsgraph#Design_Documents * http://wiki.blender.org/index.php/User:Nazg-gul/DependencyGraph There are also some user-related information online: * http://code.blender.org/2015/02/blender-dependency-graph-branch-for-users/ * http://code.blender.org/2015/03/more-dependency-graph-tricks/ Kudos to everyone who was involved into the project: - Joshua "Aligorith" Leung -- design specification, initial code - Lukas "lukas_t" Toenne -- integrating code into blender, with further fixes - Sergey "Sergey" "Sharybin" -- some mocking around, trying to wrap up the project and so - Bassam "slikdigit" Kurdali -- stressing the new system, reporting all the issues and recording/writing documentation. - Everyone else who i forgot to mention here :)
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/action.c7
-rw-r--r--source/blender/blenkernel/intern/armature_update.c2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c405
-rw-r--r--source/blender/blenkernel/intern/library.c7
-rw-r--r--source/blender/blenkernel/intern/mesh.c5
-rw-r--r--source/blender/blenkernel/intern/object_update.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c120
7 files changed, 499 insertions, 49 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 708c64f8ffc..7e09ad355a7 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -54,6 +54,7 @@
#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_deform.h"
+#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -1318,9 +1319,13 @@ bool BKE_pose_copy_result(bPose *to, bPose *from)
}
/* Tag pose for recalc. Also tag all related data to be recalc. */
-void BKE_pose_tag_recalc(Main *UNUSED(bmain), bPose *pose)
+void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
{
pose->flag |= POSE_RECALC;
+ /* Depsgraph components depends on actual pose state,
+ * if pose was changed depsgraph is to be updated as well.
+ */
+ DAG_relations_tag_update(bmain);
}
/* For the calculation of the effects of an Action at the given frame on an object
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 44ffb6a6697..aa36036ed6a 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -51,6 +51,8 @@
#include "BKE_global.h"
#include "BKE_main.h"
+#include "DEG_depsgraph.h"
+
#ifdef WITH_LEGACY_DEPSGRAPH
# define DEBUG_PRINT if (!DEG_depsgraph_use_legacy() && G.debug & G_DEBUG_DEPSGRAPH) printf
#else
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 869404ae4a6..9ee9f3d57af 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -88,16 +88,25 @@
#include "depsgraph_private.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_debug.h"
+#include "DEG_depsgraph_query.h"
+
+#ifdef WITH_LEGACY_DEPSGRAPH
+
static SpinLock threaded_update_lock;
void DAG_init(void)
{
BLI_spin_init(&threaded_update_lock);
+ DEG_register_node_types();
}
void DAG_exit(void)
{
BLI_spin_end(&threaded_update_lock);
+ DEG_free_node_types();
}
/* Queue and stack operations for dag traversal
@@ -1329,8 +1338,14 @@ static void (*EditorsUpdateSceneCb)(Main *bmain, Scene *scene, int updated) = NU
void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id), void (*scene_func)(Main *bmain, Scene *scene, int updated))
{
- EditorsUpdateIDCb = id_func;
- EditorsUpdateSceneCb = scene_func;
+ if (DEG_depsgraph_use_legacy()) {
+ EditorsUpdateIDCb = id_func;
+ EditorsUpdateSceneCb = scene_func;
+ }
+ else {
+ /* New dependency graph. */
+ DEG_editors_set_update_cb(id_func, scene_func);
+ }
}
static void dag_editors_id_update(Main *bmain, ID *id)
@@ -1529,7 +1544,7 @@ static void dag_scene_build(Main *bmain, Scene *sce)
Base *base;
BLI_listbase_clear(&tempbase);
-
+
build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA);
dag_check_cycle(sce->theDag);
@@ -1621,32 +1636,65 @@ static void dag_scene_build(Main *bmain, Scene *sce)
/* clear all dependency graphs */
void DAG_relations_tag_update(Main *bmain)
{
- Scene *sce;
-
- for (sce = bmain->scene.first; sce; sce = sce->id.next)
- dag_scene_free(sce);
+ if (DEG_depsgraph_use_legacy()) {
+ Scene *sce;
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
+ dag_scene_free(sce);
+ }
+ }
+ else {
+ /* New dependency graph. */
+ DEG_relations_tag_update(bmain);
+ }
}
/* rebuild dependency graph only for a given scene */
void DAG_scene_relations_rebuild(Main *bmain, Scene *sce)
{
- dag_scene_free(sce);
- DAG_scene_relations_update(bmain, sce);
+ if (DEG_depsgraph_use_legacy()) {
+ dag_scene_free(sce);
+ DAG_scene_relations_update(bmain, sce);
+ }
+ else {
+ /* New dependency graph. */
+ DEG_scene_relations_rebuild(bmain, sce);
+ }
}
/* create dependency graph if it was cleared or didn't exist yet */
void DAG_scene_relations_update(Main *bmain, Scene *sce)
{
- if (!sce->theDag)
- dag_scene_build(bmain, sce);
+ if (DEG_depsgraph_use_legacy()) {
+ if (!sce->theDag)
+ dag_scene_build(bmain, sce);
+ }
+ else {
+ /* New dependency graph. */
+ DEG_scene_relations_update(bmain, sce);
+ }
+}
+
+void DAG_scene_relations_validate(Main *bmain, Scene *sce)
+{
+ if (!DEG_depsgraph_use_legacy()) {
+ DEG_debug_scene_relations_validate(bmain, sce);
+ }
}
void DAG_scene_free(Scene *sce)
{
- if (sce->theDag) {
- free_forest(sce->theDag);
- MEM_freeN(sce->theDag);
- sce->theDag = NULL;
+ if (DEG_depsgraph_use_legacy()) {
+ if (sce->theDag) {
+ free_forest(sce->theDag);
+ MEM_freeN(sce->theDag);
+ sce->theDag = NULL;
+ }
+ }
+ else {
+ if (sce->depsgraph) {
+ DEG_graph_free(sce->depsgraph);
+ sce->depsgraph = NULL;
+ }
}
}
@@ -1889,7 +1937,11 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho
DagAdjList *itA;
Object *ob;
int lasttime;
-
+
+ if (!DEG_depsgraph_use_legacy()) {
+ return;
+ }
+
if (sce->theDag == NULL) {
printf("DAG zero... not allowed to happen!\n");
DAG_scene_relations_update(bmain, sce);
@@ -2300,7 +2352,7 @@ static void dag_current_scene_layers(Main *bmain, ListBase *lb)
}
}
-static void dag_group_on_visible_update(Group *group)
+static void dag_group_on_visible_update(Scene *scene, Group *group)
{
GroupObject *go;
@@ -2322,7 +2374,7 @@ static void dag_group_on_visible_update(Group *group)
}
if (go->ob->dup_group)
- dag_group_on_visible_update(go->ob->dup_group);
+ dag_group_on_visible_update(scene, go->ob->dup_group);
}
}
@@ -2330,7 +2382,13 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
{
ListBase listbase;
DagSceneLayer *dsl;
-
+
+ if (!DEG_depsgraph_use_legacy()) {
+ /* Inform new dependnecy graphs about visibility changes. */
+ DEG_on_visible_update(bmain, do_time);
+ return;
+ }
+
/* get list of visible scenes and layers */
dag_current_scene_layers(bmain, &listbase);
@@ -2357,7 +2415,8 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
oblay = (node) ? node->lay : ob->lay;
if ((oblay & lay) & ~scene->lay_updated) {
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
+ /* TODO(sergey): Why do we need armature here now but didn't need before? */
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE, OB_ARMATURE)) {
ob->recalc |= OB_RECALC_DATA;
lib_id_recalc_tag(bmain, &ob->id);
}
@@ -2375,7 +2434,7 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
lib_id_recalc_tag(bmain, &ob->id);
}
if (ob->dup_group)
- dag_group_on_visible_update(ob->dup_group);
+ dag_group_on_visible_update(scene, ob->dup_group);
}
}
@@ -2609,7 +2668,12 @@ void DAG_ids_flush_tagged(Main *bmain)
ListBase *lbarray[MAX_LIBARRAY];
int a;
bool do_flush = false;
-
+
+ if (!DEG_depsgraph_use_legacy()) {
+ DEG_ids_flush_tagged(bmain);
+ return;
+ }
+
/* get list of visible scenes and layers */
dag_current_scene_layers(bmain, &listbase);
@@ -2653,6 +2717,11 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
int a;
bool updated = false;
+ if (!DEG_depsgraph_use_legacy()) {
+ DEG_ids_check_recalc(bmain, scene, time);
+ return;
+ }
+
/* loop over all ID types */
a = set_listbasepointers(bmain, lbarray);
@@ -2769,6 +2838,11 @@ void DAG_ids_clear_recalc(Main *bmain)
void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
{
+ if (!DEG_depsgraph_use_legacy()) {
+ DEG_id_tag_update_ex(bmain, id, flag);
+ return;
+ }
+
if (id == NULL) return;
if (G.debug & G_DEBUG_DEPSGRAPH) {
@@ -3160,6 +3234,10 @@ short DAG_get_eval_flags_for_object(Scene *scene, void *object)
{
DagNode *node;
+ if (!DEG_depsgraph_use_legacy()) {
+ return DEG_get_eval_flags_for_id(scene->depsgraph, (ID*)object);
+ }
+
if (scene->theDag == NULL) {
/* Happens when converting objects to mesh from a python script
* after modifying scene graph.
@@ -3198,3 +3276,286 @@ bool DAG_is_acyclic(Scene *scene)
{
return scene->theDag->is_acyclic;
}
+
+#else
+
+/* *********************************************************************
+ * Stubs to avoid linking issues and make sure legacy crap is not used *
+ * *********************************************************************
+ */
+
+DagNodeQueue *queue_create(int UNUSED(slots))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+void queue_raz(DagNodeQueue *UNUSED(queue))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void queue_delete(DagNodeQueue *UNUSED(queue))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void push_queue(DagNodeQueue *UNUSED(queue), DagNode *UNUSED(node))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void push_stack(DagNodeQueue *UNUSED(queue), DagNode *UNUSED(node))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+DagNode *pop_queue(DagNodeQueue *UNUSED(queue))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+DagNode *get_top_node_queue(DagNodeQueue *UNUSED(queue))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+DagForest *dag_init(void)
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+DagForest *build_dag(Main *UNUSED(bmain),
+ Scene *UNUSED(sce),
+ short UNUSED(mask))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+void free_forest(DagForest *UNUSED(Dag))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+DagNode *dag_find_node(DagForest *UNUSED(forest), void *UNUSED(fob))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+DagNode *dag_add_node(DagForest *UNUSED(forest), void *UNUSED(fob))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+DagNode *dag_get_node(DagForest *UNUSED(forest), void *UNUSED(fob))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+DagNode *dag_get_sub_node(DagForest *UNUSED(forest), void *UNUSED(fob))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+void dag_add_relation(DagForest *UNUSED(forest),
+ DagNode *UNUSED(fob1),
+ DagNode *UNUSED(fob2),
+ short UNUSED(rel),
+ const char *UNUSED(name))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+/* debug test functions */
+
+void graph_print_queue(DagNodeQueue *UNUSED(nqueue))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void graph_print_queue_dist(DagNodeQueue *UNUSED(nqueue))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void graph_print_adj_list(DagForest *UNUSED(dag))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void DAG_scene_flush_update(Main *UNUSED(bmain),
+ Scene *UNUSED(sce),
+ unsigned int UNUSED(lay),
+ const short UNUSED(time))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+void DAG_scene_update_flags(Main *UNUSED(bmain),
+ Scene *UNUSED(scene),
+ unsigned int UNUSED(lay),
+ const bool UNUSED(do_time),
+ const bool UNUSED(do_invisible_flush))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+/* ******************* DAG FOR ARMATURE POSE ***************** */
+
+void DAG_pose_sort(Object *UNUSED(ob))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+}
+
+/* ************************ DAG FOR THREADED UPDATE ********************* */
+
+void DAG_threaded_update_begin(Scene *UNUSED(scene),
+ void (*func)(void *node, void *user_data),
+ void *UNUSED(user_data))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ (void)func;
+}
+
+void DAG_threaded_update_handle_node_updated(void *UNUSED(node_v),
+ void (*func)(void *node, void *user_data),
+ void *UNUSED(user_data))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ (void)func;
+}
+
+/* ************************ DAG querying ********************* */
+
+Object *DAG_get_node_object(void *UNUSED(node_v))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return NULL;
+}
+
+const char *DAG_get_node_name(Scene *UNUSED(scene), void *UNUSED(node_v))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return "INVALID";
+}
+
+bool DAG_is_acyclic(Scene *UNUSED(scene))
+{
+ BLI_assert(!"Should not be used with new dependnecy graph");
+ return false;
+}
+
+/* ************************************
+ * This functions are to be supported *
+ * ************************************
+ */
+
+void DAG_init(void)
+{
+ DEG_register_node_types();
+}
+
+void DAG_exit(void)
+{
+ DEG_free_node_types();
+}
+
+/* ************************ API *********************** */
+
+void DAG_editors_update_cb(DEG_EditorUpdateIDCb id_func,
+ DEG_EditorUpdateSceneCb scene_func)
+{
+ DEG_editors_set_update_cb(id_func, scene_func);
+}
+
+/* Tag all relations for update. */
+void DAG_relations_tag_update(Main *bmain)
+{
+ DEG_relations_tag_update(bmain);
+}
+
+/* Rebuild dependency graph only for a given scene. */
+void DAG_scene_relations_rebuild(Main *bmain, Scene *scene)
+{
+ DEG_scene_relations_rebuild(bmain, scene);
+}
+
+/* Create dependency graph if it was cleared or didn't exist yet. */
+void DAG_scene_relations_update(Main *bmain, Scene *scene)
+{
+ DEG_scene_relations_update(bmain, scene);
+}
+
+void DAG_scene_relations_validate(Main *bmain, Scene *scene)
+{
+ DEG_debug_scene_relations_validate(bmain, scene);
+}
+
+void DAG_scene_free(Scene *scene)
+{
+ DEG_scene_graph_free(scene);
+}
+
+void DAG_on_visible_update(Main *bmain, const bool do_time)
+{
+ DEG_on_visible_update(bmain, do_time);
+}
+
+void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
+{
+ DEG_ids_check_recalc(bmain, scene, time);
+}
+
+void DAG_id_tag_update(ID *id, short flag)
+{
+ DEG_id_tag_update_ex(G.main, id, flag);
+}
+
+void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
+{
+ DEG_id_tag_update_ex(bmain, id, flag);
+}
+
+void DAG_id_type_tag(Main *bmain, short idtype)
+{
+ DEG_id_type_tag(bmain, idtype);
+}
+
+int DAG_id_type_tagged(Main *bmain, short idtype)
+{
+ return DEG_id_type_tagged(bmain, idtype);
+}
+
+void DAG_ids_clear_recalc(Main *bmain)
+{
+ DEG_ids_clear_recalc(bmain);
+}
+
+short DAG_get_eval_flags_for_object(Scene *scene, void *object)
+{
+ return DEG_get_eval_flags_for_id(scene->depsgraph, (ID*)object);
+}
+
+void DAG_ids_flush_tagged(Main *bmain)
+{
+ DEG_ids_flush_tagged(bmain);
+}
+
+/* ************************ DAG DEBUGGING ********************* */
+
+void DAG_print_dependencies(Main *UNUSED(bmain),
+ Scene *scene,
+ Object *UNUSED(ob))
+{
+ DEG_debug_graphviz(scene->depsgraph, stdout, "Depsgraph", false);
+}
+
+#endif
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ce118fe9fde..543d2de939a 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -115,6 +115,8 @@
#include "BKE_texture.h"
#include "BKE_world.h"
+#include "DEG_depsgraph.h"
+
#include "RNA_access.h"
#ifdef WITH_PYTHON
@@ -1081,8 +1083,7 @@ void BKE_libblock_free_us(Main *bmain, void *idv) /* test users */
Main *BKE_main_new(void)
{
Main *bmain = MEM_callocN(sizeof(Main), "new main");
- bmain->eval_ctx = MEM_callocN(sizeof(EvaluationContext),
- "EvaluationContext");
+ bmain->eval_ctx = DEG_evaluation_context_new(DAG_EVAL_VIEWPORT);
bmain->lock = MEM_mallocN(sizeof(SpinLock), "main lock");
BLI_spin_init((SpinLock *)bmain->lock);
return bmain;
@@ -1149,7 +1150,7 @@ void BKE_main_free(Main *mainvar)
BLI_spin_end((SpinLock *)mainvar->lock);
MEM_freeN(mainvar->lock);
- MEM_freeN(mainvar->eval_ctx);
+ DEG_evaluation_context_free(mainvar->eval_ctx);
MEM_freeN(mainvar);
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 735e4358cb8..37a98eae58b 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -61,6 +61,7 @@
#include "BKE_object.h"
#include "BKE_editmesh.h"
+#include "DEG_depsgraph.h"
enum {
MESHCMP_DVERT_WEIGHTMISMATCH = 1,
@@ -2397,8 +2398,8 @@ Mesh *BKE_mesh_new_from_object(
* only contains for_render flag. As soon as CoW is
* implemented, this is to be rethinked.
*/
- EvaluationContext eval_ctx = {0};
- eval_ctx.mode = DAG_EVAL_RENDER;
+ EvaluationContext eval_ctx;
+ DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_RENDER);
BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp);
BKE_mesh_from_metaball(&disp, tmpmesh);
BKE_displist_free(&disp);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 76c20adf8c5..972a93b4a35 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -57,6 +57,8 @@
#include "BKE_material.h"
#include "BKE_image.h"
+#include "DEG_depsgraph.h"
+
#ifdef WITH_LEGACY_DEPSGRAPH
# define DEBUG_PRINT if (!DEG_depsgraph_use_legacy() && G.debug & G_DEBUG_DEPSGRAPH) printf
#else
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index f810630c83b..3d87279e054 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -89,6 +89,8 @@
#include "BKE_unit.h"
#include "BKE_world.h"
+#include "DEG_depsgraph.h"
+
#include "RE_engine.h"
#include "PIL_time.h"
@@ -193,6 +195,7 @@ Scene *BKE_scene_copy(Scene *sce, int type)
scen->ed = NULL;
scen->theDag = NULL;
+ scen->depsgraph = NULL;
scen->obedit = NULL;
scen->stats = NULL;
scen->fps_info = NULL;
@@ -431,6 +434,8 @@ void BKE_scene_free(Scene *sce)
}
DAG_scene_free(sce);
+ if (sce->depsgraph)
+ DEG_graph_free(sce->depsgraph);
if (sce->nodetree) {
ntreeFreeTree(sce->nodetree);
@@ -1167,6 +1172,7 @@ void BKE_scene_frame_set(struct Scene *scene, double cfra)
scene->r.cfra = (int)intpart;
}
+#ifdef WITH_LEGACY_DEPSGRAPH
/* drivers support/hacks
* - this method is called from scene_update_tagged_recursive(), so gets included in viewport + render
* - these are always run since the depsgraph can't handle non-object data
@@ -1267,6 +1273,7 @@ static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scen
}
}
}
+#endif /* WITH_LEGACY_DEPSGRAPH */
/* That's like really a bummer, because currently animation data for armatures
* might want to use pose, and pose might be missing on the object.
@@ -1318,7 +1325,12 @@ static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
* would pollute STDERR with whole bunch of timing information which then
* could be parsed and nicely visualized.
*/
-#undef DETAILED_ANALYSIS_OUTPUT
+#ifdef WITH_LEGACY_DEPSGRAPH
+# undef DETAILED_ANALYSIS_OUTPUT
+#else
+/* ALWAYS KEEY DISABLED! */
+# undef DETAILED_ANALYSIS_OUTPUT
+#endif
/* Mballs evaluation uses BKE_scene_base_iter_next which calls
* duplilist for all objects in the scene. This leads to conflict
@@ -1330,6 +1342,7 @@ static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
*/
#define MBALL_SINGLETHREAD_HACK
+#ifdef WITH_LEGACY_DEPSGRAPH
typedef struct StatisicsEntry {
struct StatisicsEntry *next, *prev;
Object *object;
@@ -1619,6 +1632,7 @@ static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bma
BKE_mask_update_scene(bmain, scene);
}
+#endif /* WITH_LEGACY_DEPSGRAPH */
static bool check_rendered_viewport_visible(Main *bmain)
{
@@ -1670,13 +1684,26 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *scene)
{
Scene *sce_iter;
-
+#ifdef WITH_LEGACY_DEPSGRAPH
+ bool use_new_eval = !DEG_depsgraph_use_legacy();
+#endif
+
/* keep this first */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
/* (re-)build dependency graph if needed */
- for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
+ for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set) {
DAG_scene_relations_update(bmain, sce_iter);
+ /* Uncomment this to check if graph was properly tagged for update. */
+#if 0
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (use_new_eval)
+#endif
+ {
+ DAG_scene_relations_validate(bmain, sce_iter);
+ }
+#endif
+ }
/* flush editing data if needed */
prepare_mesh_for_viewport_render(bmain, scene);
@@ -1697,7 +1724,17 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
*
* in the future this should handle updates for all datablocks, not
* only objects and scenes. - brecht */
- scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (use_new_eval) {
+ DEG_evaluate_on_refresh(eval_ctx, scene->depsgraph, scene);
+ }
+ else {
+ scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
+ }
+#else
+ DEG_evaluate_on_refresh(eval_ctx, bmain, scene->depsgraph, scene);
+#endif
+
/* update sound system animation (TODO, move to depsgraph) */
BKE_sound_update_scene(bmain, scene);
@@ -1715,7 +1752,8 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
* Need to do this so changing material settings from the graph/dopesheet
* will update stuff in the viewport.
*/
- if (DAG_id_type_tagged(bmain, ID_MA)) {
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!use_new_eval && DAG_id_type_tagged(bmain, ID_MA)) {
Material *material;
float ctime = BKE_scene_frame_get(scene);
@@ -1730,7 +1768,7 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
}
/* Also do the same for node trees. */
- if (DAG_id_type_tagged(bmain, ID_NT)) {
+ if (!use_new_eval && DAG_id_type_tagged(bmain, ID_NT)) {
float ctime = BKE_scene_frame_get(scene);
FOREACH_NODETREE(bmain, ntree, id)
@@ -1741,9 +1779,12 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
}
FOREACH_NODETREE_END
}
+#endif
/* notify editors and python about recalc */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
+
+ /* Inform editors about possible changes. */
DAG_ids_check_recalc(bmain, scene, false);
/* clear recalc flags */
@@ -1763,6 +1804,12 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
#ifdef DETAILED_ANALYSIS_OUTPUT
double start_time = PIL_check_seconds_timer();
#endif
+#ifdef WITH_LEGACY_DEPSGRAPH
+ bool use_new_eval = !DEG_depsgraph_use_legacy();
+#else
+ /* TODO(sergey): Pass to evaluation routines instead of storing layer in the graph? */
+ (void) do_invisible_flush;
+#endif
/* keep this first */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
@@ -1772,12 +1819,16 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
* call this at the start so modifiers with textures don't lag 1 frame */
BKE_image_update_frame(bmain, sce->r.cfra);
+#ifdef WITH_LEGACY_DEPSGRAPH
/* rebuild rigid body worlds before doing the actual frame update
* this needs to be done on start frame but animation playback usually starts one frame later
* we need to do it here to avoid rebuilding the world on every simulation change, which can be very expensive
*/
- scene_rebuild_rbw_recursive(sce, ctime);
-
+ if (!use_new_eval) {
+ scene_rebuild_rbw_recursive(sce, ctime);
+ }
+#endif
+
BKE_sound_set_cfra(sce->r.cfra);
/* clear animation overrides */
@@ -1786,14 +1837,18 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set)
DAG_scene_relations_update(bmain, sce_iter);
- /* flush recalc flags to dependencies, if we were only changing a frame
- * this would not be necessary, but if a user or a script has modified
- * some datablock before BKE_scene_update_tagged was called, we need the flush */
- DAG_ids_flush_tagged(bmain);
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!use_new_eval) {
+ /* flush recalc flags to dependencies, if we were only changing a frame
+ * this would not be necessary, but if a user or a script has modified
+ * some datablock before BKE_scene_update_tagged was called, we need the flush */
+ DAG_ids_flush_tagged(bmain);
- /* Following 2 functions are recursive
- * so don't call within 'scene_update_tagged_recursive' */
- DAG_scene_update_flags(bmain, sce, lay, true, do_invisible_flush); // only stuff that moves or needs display still
+ /* Following 2 functions are recursive
+ * so don't call within 'scene_update_tagged_recursive' */
+ DAG_scene_update_flags(bmain, sce, lay, true, do_invisible_flush); // only stuff that moves or needs display still
+ }
+#endif
BKE_mask_evaluate_all_masks(bmain, ctime, true);
@@ -1807,8 +1862,12 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
* can be overridden by settings from Scene, which owns the Texture through a hierarchy
* such as Scene->World->MTex/Texture) can still get correctly overridden.
*/
- BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
- /*...done with recursive funcs */
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!use_new_eval) {
+ BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
+ /*...done with recursive funcs */
+ }
+#endif
/* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later
* when trying to find materials with drivers that need evaluating [#32017]
@@ -1818,19 +1877,38 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
/* run rigidbody sim */
/* NOTE: current position is so that rigidbody sim affects other objects, might change in the future */
- scene_do_rb_simulation_recursive(sce, ctime);
-
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!use_new_eval) {
+ scene_do_rb_simulation_recursive(sce, ctime);
+ }
+#endif
+
/* BKE_object_handle_update() on all objects, groups and sets */
- scene_update_tagged_recursive(eval_ctx, bmain, sce, sce);
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (use_new_eval) {
+ DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
+ }
+ else {
+ scene_update_tagged_recursive(eval_ctx, bmain, sce, sce);
+ }
+#else
+ DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
+#endif
+
/* update sound system animation (TODO, move to depsgraph) */
BKE_sound_update_scene(bmain, sce);
- scene_depsgraph_hack(eval_ctx, sce, sce);
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!use_new_eval) {
+ scene_depsgraph_hack(eval_ctx, sce, sce);
+ }
+#endif
/* notify editors and python about recalc */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
+ /* Inform editors about possible changes. */
DAG_ids_check_recalc(bmain, sce, true);
/* clear recalc flags */