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).
This commit is contained in:
parent
7f2401532e
commit
d941f40c21
Notes:
blender-bot
2023-02-14 08:59:10 +01:00
Referenced by issue #57571, Blender crashes on UV transformation.
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue