diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_depsgraph.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/depsgraph_private.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 22 |
4 files changed, 29 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 4fedf373a22..df7e9561c46 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -159,6 +159,7 @@ void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Obje struct Object *DAG_get_node_object(void *node_v); const char *DAG_get_node_name(void *node_v); short DAG_get_eval_flags_for_object(struct Scene *scene, void *object); +bool DAG_is_acyclic(struct Scene *scene); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h index e178667e5a5..bf0179a4911 100644 --- a/source/blender/blenkernel/depsgraph_private.h +++ b/source/blender/blenkernel/depsgraph_private.h @@ -127,7 +127,7 @@ typedef struct DagForest { ListBase DagNode; struct GHash *nodeHash; int numNodes; - int is_acyclic; + bool is_acyclic; int time; /* for flushing/tagging, compare with node->lasttime */ } DagForest; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 01327452831..ea76ff291e5 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1193,6 +1193,8 @@ static void dag_check_cycle(DagForest *dag) DagNode *node; DagAdjList *itA; + dag->is_acyclic = true; + /* debugging print */ if (dag_print_dependencies) for (node = dag->DagNode.first; node; node = node->next) @@ -1213,6 +1215,7 @@ static void dag_check_cycle(DagForest *dag) for (itA = node->parent; itA; itA = itA->next) { if (itA->node->ancestor_count > node->ancestor_count) { if (node->ob && itA->node->ob) { + dag->is_acyclic = false; printf("Dependency cycle detected:\n"); dag_node_print_dependency_cycle(dag, itA->node, node, itA->name); } @@ -2904,3 +2907,7 @@ short DAG_get_eval_flags_for_object(struct Scene *scene, void *object) return node->eval_flags; } +bool DAG_is_acyclic(Scene *scene) +{ + return scene->theDag->is_acyclic; +} diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 4d8075e9cba..1ef3d6cef30 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1388,6 +1388,7 @@ static void scene_update_objects(EvaluationContext *eval_ctx, Main *bmain, Scene TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; ThreadedObjectUpdateState state; + bool need_singlethread_pass; /* Early check for whether we need to invoke all the task-based * tihngs (spawn new ppol, traverse dependency graph and so on). @@ -1453,11 +1454,28 @@ static void scene_update_objects(EvaluationContext *eval_ctx, Main *bmain, Scene print_threads_statistics(&state); } + /* We do single thread pass to update all the objects which are in cyclic dependency. + * Such objects can not be handled by a generic DAG traverse and it's really tricky + * to detect whether cycle could be solved or not. + * + * In this situation we simply update all remaining objects in a single thread and + * it'll happen in the same exact order as it was in single-threaded DAG. + * + * We couldn't use threaded update for objects which are in cycle because they might + * access data of each other which is being re-evaluated. + * + * Also, as was explained above, for now we also update all the mballs in single thread. + * + * - sergey - + */ + need_singlethread_pass = DAG_is_acyclic(scene) == false; #ifdef MBALL_SINGLETHREAD_HACK - if (state.has_mballs) { + need_singlethread_pass |= state.has_mballs; +#endif + + if (need_singlethread_pass) { scene_update_all_bases(eval_ctx, scene, scene_parent); } -#endif } static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Scene *scene_parent) |