[Bf-blender-cvs] [d941f40c21f] blender2.8: Fix T57571: Blender crashes on UV transformation

Clément Foucault noreply at git.blender.org
Mon Nov 12 18:07:06 CET 2018


Commit: d941f40c21f9b7eae861914db5b24427413044c9
Author: Clément Foucault
Date:   Mon Nov 12 18:06:32 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBd941f40c21f9b7eae861914db5b24427413044c9

Fix T57571: Blender crashes on UV transformation

That was caused by a thread safety issue on gpu_batch_presets_unregister()
which was not designed to be used for this kind of situation (managing 3D
meshes batches).

===================================================================

M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/gpu/intern/gpu_batch_presets.c

===================================================================

diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 63c93e95754..8cd2da1a898 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -2195,12 +2195,24 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
 	GPU_INDEXBUF_DISCARD_SAFE(cache->edituv_visible_faces);
 	GPU_INDEXBUF_DISCARD_SAFE(cache->edituv_visible_edges);
 
-	gpu_batch_presets_unregister(cache->edituv_faces_strech_area);
-	gpu_batch_presets_unregister(cache->edituv_faces_strech_angle);
-	gpu_batch_presets_unregister(cache->edituv_faces);
-	gpu_batch_presets_unregister(cache->edituv_edges);
-	gpu_batch_presets_unregister(cache->edituv_verts);
-	gpu_batch_presets_unregister(cache->edituv_facedots);
+	if (cache->edituv_faces_strech_area) {
+		gpu_batch_presets_unregister(cache->edituv_faces_strech_area);
+	}
+	if (cache->edituv_faces_strech_angle) {
+		gpu_batch_presets_unregister(cache->edituv_faces_strech_angle);
+	}
+	if (cache->edituv_faces) {
+		gpu_batch_presets_unregister(cache->edituv_faces);
+	}
+	if (cache->edituv_edges) {
+		gpu_batch_presets_unregister(cache->edituv_edges);
+	}
+	if (cache->edituv_verts) {
+		gpu_batch_presets_unregister(cache->edituv_verts);
+	}
+	if (cache->edituv_facedots) {
+		gpu_batch_presets_unregister(cache->edituv_facedots);
+	}
 
 	GPU_BATCH_DISCARD_SAFE(cache->edituv_faces_strech_area);
 	GPU_BATCH_DISCARD_SAFE(cache->edituv_faces_strech_angle);
diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c
index 126897ac8bf..562971c760d 100644
--- a/source/blender/gpu/intern/gpu_batch_presets.c
+++ b/source/blender/gpu/intern/gpu_batch_presets.c
@@ -57,6 +57,8 @@ static struct {
 	struct {
 		uint pos, nor;
 	} attr_id;
+
+	ThreadMutex mutex;
 } g_presets_3d = {{0}};
 
 static ListBase presets_list = {NULL, NULL};
@@ -214,33 +216,42 @@ void gpu_batch_presets_init(void)
 
 	g_presets_3d.batch.sphere_wire_med = batch_sphere_wire(8, 16);
 	gpu_batch_presets_register(g_presets_3d.batch.sphere_wire_med);
+
+	BLI_mutex_init(&g_presets_3d.mutex);
 }
 
 void gpu_batch_presets_register(GPUBatch *preset_batch)
 {
+	BLI_mutex_lock(&g_presets_3d.mutex);
 	BLI_addtail(&presets_list, BLI_genericNodeN(preset_batch));
+	BLI_mutex_unlock(&g_presets_3d.mutex);
 }
 
 bool gpu_batch_presets_unregister(GPUBatch *preset_batch)
 {
+	BLI_mutex_lock(&g_presets_3d.mutex);
 	for (LinkData *link = presets_list.last; link; link = link->prev) {
 		if (preset_batch == link->data) {
 			BLI_remlink(&presets_list, link);
+			BLI_mutex_unlock(&g_presets_3d.mutex);
 			MEM_freeN(link);
 			return true;
 		}
 	}
+	BLI_mutex_unlock(&g_presets_3d.mutex);
 	return false;
 }
 
 void gpu_batch_presets_reset(void)
 {
+	BLI_mutex_lock(&g_presets_3d.mutex);
 	/* Reset vao caches for these every time we switch opengl context.
 	 * This way they will draw correctly for each window. */
 	for (LinkData *link = presets_list.first; link; link = link->next) {
 		GPUBatch *preset = link->data;
 		GPU_batch_vao_cache_clear(preset);
 	}
+	BLI_mutex_unlock(&g_presets_3d.mutex);
 }
 
 void gpu_batch_presets_exit(void)
@@ -251,4 +262,6 @@ void gpu_batch_presets_exit(void)
 		GPU_batch_discard(preset);
 		MEM_freeN(link);
 	}
+
+	BLI_mutex_end(&g_presets_3d.mutex);
 }



More information about the Bf-blender-cvs mailing list