From 5febb0963998c40d7ddd8e71d9f9abe6feaea7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= <lukas.toenne@gmail.com> Date: Tue, 18 Mar 2014 13:36:24 +0100 Subject: [PATCH] Fix T39180: Particle with fluid physics unstable. Fluid sims have a very nasty feature for interaction, in which a psys can directly update the bvhtree for //another object's psys//. This breaks with threaded depsgraph evaluation and is generally a no-go. To avoid crashes for now, use a global mutex to avoid concurrent writes to an object psys' bvhtree. --- .../blenkernel/intern/particle_system.c | 21 ++++++++++++++++--- source/blender/makesdna/DNA_particle_types.h | 4 ++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 32f8ba920e6..0e02f30a26e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -109,6 +109,8 @@ #endif // WITH_MOD_FLUID +static ThreadMutex psys_bvhtree_rwlock = BLI_RWLOCK_INITIALIZER; + /************************************************/ /* Reacting to system events */ /************************************************/ @@ -2209,15 +2211,22 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra) if (psys) { PARTICLE_P; int totpart = 0; + bool need_rebuild; - if (!psys->bvhtree || psys->bvhtree_frame != cfra) { + BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ); + need_rebuild = !psys->bvhtree || psys->bvhtree_frame != cfra; + BLI_rw_mutex_unlock(&psys_bvhtree_rwlock); + + if (need_rebuild) { LOOP_SHOWN_PARTICLES { totpart++; } + BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_WRITE); + BLI_bvhtree_free(psys->bvhtree); psys->bvhtree = BLI_bvhtree_new(totpart, 0.0, 4, 6); - + LOOP_SHOWN_PARTICLES { if (pa->alive == PARS_ALIVE) { if (pa->state.time == cfra) @@ -2227,8 +2236,10 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra) } } BLI_bvhtree_balance(psys->bvhtree); - + psys->bvhtree_frame = cfra; + + BLI_rw_mutex_unlock(&psys_bvhtree_rwlock); } } } @@ -2546,7 +2557,11 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], break; } else { + BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ); + BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr); + + BLI_rw_mutex_unlock(&psys_bvhtree_rwlock); } } } diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 7b06f2a46db..a2a724b6a32 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -304,8 +304,8 @@ typedef struct ParticleSystem { ParticleSpring *fluid_springs; int tot_fluidsprings, alloc_fluidsprings; - struct KDTree *tree; /* used for interactions with self and other systems */ - struct BVHTree *bvhtree; /* used for interactions with self and other systems */ + struct KDTree *tree; /* used for interactions with self and other systems */ + struct BVHTree *bvhtree; /* used for interactions with self and other systems */ struct ParticleDrawData *pdd; -- GitLab