[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56273] trunk/blender/source/blender: Fix #34783: smoke simulation crash when changing frame while preview rendering.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Apr 24 19:31:09 CEST 2013


Revision: 56273
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56273
Author:   blendix
Date:     2013-04-24 17:31:09 +0000 (Wed, 24 Apr 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/smoke.c
    trunk/blender/source/blender/blenlib/BLI_threads.h
    trunk/blender/source/blender/blenlib/intern/threads.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_smoke_types.h
    trunk/blender/source/blender/render/intern/source/voxeldata.c

Modified: trunk/blender/source/blender/blenkernel/intern/smoke.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/smoke.c	2013-04-24 16:59:56 UTC (rev 56272)
+++ trunk/blender/source/blender/blenkernel/intern/smoke.c	2013-04-24 17:31:09 UTC (rev 56273)
@@ -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 @@
 		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 @@
 
 			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 @@
 			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 @@
 
 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 &&

Modified: trunk/blender/source/blender/blenlib/BLI_threads.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_threads.h	2013-04-24 16:59:56 UTC (rev 56272)
+++ trunk/blender/source/blender/blenlib/BLI_threads.h	2013-04-24 17:31:09 UTC (rev 56273)
@@ -92,9 +92,13 @@
 #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 @@
 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
  *

Modified: trunk/blender/source/blender/blenlib/intern/threads.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/threads.c	2013-04-24 16:59:56 UTC (rev 56272)
+++ trunk/blender/source/blender/blenlib/intern/threads.c	2013-04-24 17:31:09 UTC (rev 56273)
@@ -399,6 +399,19 @@
 	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 @@
 	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 {

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2013-04-24 16:59:56 UTC (rev 56272)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2013-04-24 17:31:09 UTC (rev 56273)
@@ -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 @@
 				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;

Modified: trunk/blender/source/blender/makesdna/DNA_smoke_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_smoke_types.h	2013-04-24 16:59:56 UTC (rev 56272)
+++ trunk/blender/source/blender/makesdna/DNA_smoke_types.h	2013-04-24 17:31:09 UTC (rev 56273)
@@ -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

Modified: trunk/blender/source/blender/render/intern/source/voxeldata.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/voxeldata.c	2013-04-24 16:59:56 UTC (rev 56272)
+++ trunk/blender/source/blender/render/intern/source/voxeldata.c	2013-04-24 17:31:09 UTC (rev 56273)
@@ -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 @@
 		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 @@
 				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 @@
 				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 @@
 					}
 				}
 			}  /* end of fluid condition */
+
+			BLI_rw_mutex_unlock(sds->fluid_mutex);
 		}
 	}
 	




More information about the Bf-blender-cvs mailing list