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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-04-24 21:31:09 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-04-24 21:31:09 +0400
commitdbeec2be86db5b4ba440175e59c52ff84eb98462 (patch)
tree8bedb75ea7937279d318b86f5eecc98f8e03a950
parent64e28b21ba8472f4fd822b918d6e7d7c1be87dcb (diff)
Fix #34783: smoke simulation crash when changing frame while preview rendering.
Added a mutex lock for smoke data access. The render was already working with a copy of the volume data, so it's just a short lock to copy things and should not block the UI much.
-rw-r--r--source/blender/blenkernel/intern/smoke.c16
-rw-r--r--source/blender/blenlib/BLI_threads.h12
-rw-r--r--source/blender/blenlib/intern/threads.c26
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/makesdna/DNA_smoke_types.h1
-rw-r--r--source/blender/render/intern/source/voxeldata.c25
6 files changed, 77 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 009112be2c9..f31a672c664 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -50,6 +50,7 @@
#include "BLI_edgehash.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLI_voxel.h"
@@ -365,6 +366,9 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd)
if (smd->domain->fluid)
smoke_free(smd->domain->fluid);
+ if (smd->domain->fluid_mutex)
+ BLI_rw_mutex_free(smd->domain->fluid_mutex);
+
if (smd->domain->wt)
smoke_turbulence_free(smd->domain->wt);
@@ -436,8 +440,12 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
if (smd->domain->fluid)
{
+ BLI_rw_mutex_lock(smd->domain->fluid_mutex, THREAD_LOCK_WRITE);
+
smoke_free(smd->domain->fluid);
smd->domain->fluid = NULL;
+
+ BLI_rw_mutex_unlock(smd->domain->fluid_mutex);
}
smokeModifier_reset_turbulence(smd);
@@ -497,6 +505,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].last = NULL;
/* set some standard values */
smd->domain->fluid = NULL;
+ smd->domain->fluid_mutex = BLI_rw_mutex_alloc();
smd->domain->wt = NULL;
smd->domain->eff_group = NULL;
smd->domain->fluid_group = NULL;
@@ -2316,8 +2325,15 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *
struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
{
+ /* lock so preview render does not read smoke data while it gets modified */
+ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+ BLI_rw_mutex_lock(smd->domain->fluid_mutex, THREAD_LOCK_WRITE);
+
smokeModifier_process(smd, scene, ob, dm);
+ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+ BLI_rw_mutex_unlock(smd->domain->fluid_mutex);
+
/* return generated geometry for adaptive domain */
if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain &&
smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN &&
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index ec8e567c0ef..614cd4ee59d 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -92,9 +92,13 @@ typedef pthread_mutex_t ThreadMutex;
#define BLI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
void BLI_mutex_init(ThreadMutex *mutex);
+void BLI_mutex_end(ThreadMutex *mutex);
+
+ThreadMutex *BLI_mutex_alloc(void);
+void BLI_mutex_free(ThreadMutex *mutex);
+
void BLI_mutex_lock(ThreadMutex *mutex);
void BLI_mutex_unlock(ThreadMutex *mutex);
-void BLI_mutex_end(ThreadMutex *mutex);
/* Spin Lock */
@@ -117,9 +121,13 @@ void BLI_spin_end(SpinLock *spin);
typedef pthread_rwlock_t ThreadRWMutex;
void BLI_rw_mutex_init(ThreadRWMutex *mutex);
+void BLI_rw_mutex_end(ThreadRWMutex *mutex);
+
+ThreadRWMutex *BLI_rw_mutex_alloc(void);
+void BLI_rw_mutex_free(ThreadRWMutex *mutex);
+
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode);
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex);
-void BLI_rw_mutex_end(ThreadRWMutex *mutex);
/* ThreadedWorker
*
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 1d3312fafb1..8b1ba38a35a 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -399,6 +399,19 @@ void BLI_mutex_end(ThreadMutex *mutex)
pthread_mutex_destroy(mutex);
}
+ThreadMutex *BLI_mutex_alloc(void)
+{
+ ThreadMutex *mutex = MEM_callocN(sizeof(ThreadMutex), "ThreadMutex");
+ BLI_mutex_init(mutex);
+ return mutex;
+}
+
+void BLI_mutex_free(ThreadMutex *mutex)
+{
+ BLI_mutex_end(mutex);
+ MEM_freeN(mutex);
+}
+
/* Spin Locks */
void BLI_spin_init(SpinLock *spin)
@@ -464,6 +477,19 @@ void BLI_rw_mutex_end(ThreadRWMutex *mutex)
pthread_rwlock_destroy(mutex);
}
+ThreadRWMutex *BLI_rw_mutex_alloc(void)
+{
+ ThreadRWMutex *mutex = MEM_callocN(sizeof(ThreadRWMutex), "ThreadRWMutex");
+ BLI_rw_mutex_init(mutex);
+ return mutex;
+}
+
+void BLI_rw_mutex_free(ThreadRWMutex *mutex)
+{
+ BLI_rw_mutex_end(mutex);
+ MEM_freeN(mutex);
+}
+
/* ************************************************ */
typedef struct ThreadedWorker {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 466c0b6dcb2..a2e97e8063c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -107,6 +107,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
+#include "BLI_threads.h"
#include "BLF_translation.h"
@@ -4595,6 +4596,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->domain->smd = smd;
smd->domain->fluid = NULL;
+ smd->domain->fluid_mutex = BLI_rw_mutex_alloc();
smd->domain->wt = NULL;
smd->domain->shadow = NULL;
smd->domain->tex = NULL;
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index 76ba3fcf7f8..fa31717b9e2 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -71,6 +71,7 @@
typedef struct SmokeDomainSettings {
struct SmokeModifierData *smd; /* for fast RNA access */
struct FLUID_3D *fluid;
+ void *fluid_mutex;
struct Group *fluid_group;
struct Group *eff_group; // UNUSED
struct Group *coll_group; // collision objects group
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 9990ad7e900..1c76a228566 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -42,6 +42,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_threads.h"
#include "BLI_voxel.h"
#include "BLI_utildefines.h"
@@ -239,6 +240,13 @@ static void init_frame_smoke(VoxelData *vd, float cfra)
SmokeDomainSettings *sds = smd->domain;
if (sds && sds->fluid) {
+ BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
+
+ if (!sds->fluid) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
+
if (cfra < sds->point_cache[0]->startframe)
; /* don't show smoke before simulation starts, this could be made an option in the future */
else if (vd->smoked_type == TEX_VD_SMOKEHEAT) {
@@ -246,7 +254,10 @@ static void init_frame_smoke(VoxelData *vd, float cfra)
size_t i;
float *heat;
- if (!smoke_has_heat(sds->fluid)) return;
+ if (!smoke_has_heat(sds->fluid)) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
copy_v3_v3_int(vd->resol, sds->res);
totRes = vd_resol_size(vd);
@@ -283,12 +294,18 @@ static void init_frame_smoke(VoxelData *vd, float cfra)
float *flame;
if (sds->flags & MOD_SMOKE_HIGHRES) {
- if (!smoke_turbulence_has_fuel(sds->wt)) return;
+ if (!smoke_turbulence_has_fuel(sds->wt)) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
smoke_turbulence_get_res(sds->wt, vd->resol);
flame = smoke_turbulence_get_flame(sds->wt);
}
else {
- if (!smoke_has_fuel(sds->fluid)) return;
+ if (!smoke_has_fuel(sds->fluid)) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
copy_v3_v3_int(vd->resol, sds->res);
flame = smoke_get_flame(sds->fluid);
}
@@ -333,6 +350,8 @@ static void init_frame_smoke(VoxelData *vd, float cfra)
}
}
} /* end of fluid condition */
+
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
}
}