From 0c8aa85069fabd20d5f030f016a85ad060839066 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 7 Nov 2018 13:40:41 +0100 Subject: Physics baking: tag interface locked during backing This is a variation of older hach which was setting is_rendering to truth to tell window manager to not do dependency graph update. In the nowadays reality window manager is supposed to do dependency graph update during rendering, that was the whole purpose of CoW project. This works fine for rendering, since render engines has their own dependency graphs. Physics, on the other hand, is using same dependency graph as used for the viewport, and what's worse: it modifies objects from it. For example, in a single threaded evaluation ASAN instantly catches case when cached BVH constructed by smoke is referencing looptri layer which is freed by viewport's update. Now we are locking interface, allowing only a subset of navigation operators to run. This seems to be safest way of dealing with the problem. There are following variations which we can consider doing: - Allow viewport navigation, which will require making it so draw manager does not write to the objects. A bit dangerous, since smoke simulation might in theory modify data which is also used by a draw manager. - Make physics simulation to have own dedicated dependency graph, solving all threading conflicts all together. This fixes crash when baking smoke. Steps to reproduce: - Call "Quick Smoke" - In smoke panel, click "Bake". --- source/blender/editors/physics/physics_pointcache.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 7fc3dc2e1b8..58bd761a2a9 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -69,6 +69,7 @@ static bool ptcache_poll(bContext *C) } typedef struct PointCacheJob { + wmWindowManager *wm; void *owner; short *stop, *do_update; float *progress; @@ -123,8 +124,7 @@ static void ptcache_job_startjob(void *customdata, short *stop, short *do_update /* XXX annoying hack: needed to prevent data corruption when changing * scene frame in separate threads */ - G.is_rendering = true; - BKE_spacedata_draw_locks(true); + WM_set_locked_interface(job->wm, true); BKE_ptcache_bake(job->baker); @@ -137,10 +137,7 @@ static void ptcache_job_endjob(void *customdata) PointCacheJob *job = customdata; Scene *scene = job->baker->scene; - G.is_rendering = false; - BKE_spacedata_draw_locks(false); - - WM_set_locked_interface(G_MAIN->wm.first, false); + WM_set_locked_interface(job->wm, false); WM_main_add_notifier(NC_SCENE | ND_FRAME, scene); WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, job->baker->pid.ob); @@ -199,6 +196,7 @@ static int ptcache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE bool all = STREQ(op->type->idname, "PTCACHE_OT_bake_all"); PointCacheJob *job = MEM_mallocN(sizeof(PointCacheJob), "PointCacheJob"); + job->wm = CTX_wm_manager(C); job->baker = ptcache_baker_create(C, op, all); job->baker->bake_job = job; job->baker->update_progress = ptcache_job_update; -- cgit v1.2.3