From ee8d353fdd8966a95fa3dc40f4f0407cc19cdd6b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 15 Jun 2013 14:01:16 +0000 Subject: Fix #35768: crash in with "free image textures" option and 3D viewport with textured draw mode open. OpenGL texture free needs to happen in the main thread, but it was freeing a copy of the image datablock. I can't understand how this code ever worked, probably it never did. --- source/blender/gpu/intern/gpu_draw.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'source/blender/gpu') diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index a96796b95a3..9ed1f994a33 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -34,7 +34,10 @@ #include "GL/glew.h" +#include "BLI_blenlib.h" +#include "BLI_linklist.h" #include "BLI_math.h" +#include "BLI_threads.h" #include "BLI_utildefines.h" #include "DNA_lamp_types.h" @@ -52,9 +55,6 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "BLI_threads.h" -#include "BLI_blenlib.h" - #include "BKE_bmfont.h" #include "BKE_global.h" #include "BKE_image.h" @@ -1123,19 +1123,18 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres) #endif // WITH_SMOKE } -static ListBase image_free_queue = {NULL, NULL}; +static LinkNode *image_free_queue = NULL; static void gpu_queue_image_for_free(Image *ima) { - Image *cpy = MEM_dupallocN(ima); - BLI_lock_thread(LOCK_OPENGL); - BLI_addtail(&image_free_queue, cpy); + BLI_linklist_append(&image_free_queue, ima); BLI_unlock_thread(LOCK_OPENGL); } void GPU_free_unused_buffers(void) { + LinkNode *node; Image *ima; if (!BLI_thread_is_main()) @@ -1144,10 +1143,16 @@ void GPU_free_unused_buffers(void) BLI_lock_thread(LOCK_OPENGL); /* images */ - for (ima=image_free_queue.first; ima; ima=ima->id.next) - GPU_free_image(ima); + for (node=image_free_queue; node; node=node->next) { + ima = node->link; + + /* check in case it was freed in the meantime */ + if (BLI_findindex(&G.main->image, ima) != -1) + GPU_free_image(ima); + } - BLI_freelistN(&image_free_queue); + BLI_linklist_free(image_free_queue, NULL); + image_free_queue = NULL; /* vbo buffers */ /* it's probably not necessary to free all buffers every frame */ -- cgit v1.2.3