diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-03-18 16:36:24 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2014-03-18 16:39:13 +0400 |
commit | 5febb0963998c40d7ddd8e71d9f9abe6feaea7ca (patch) | |
tree | ee8b71a746f165c5341c012e9bfcc11ce576f467 /source/blender/blenkernel/intern/particle_system.c | |
parent | a6e347177bb61ce3d6e5657c1dfbd6ffa7663c55 (diff) |
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.
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 21 |
1 files changed, 18 insertions, 3 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); } } } |