Fix #22123 and #22124: some problems with mutex locks, also tweak to
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 25 Apr 2010 10:49:13 +0000 (10:49 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 25 Apr 2010 10:49:13 +0000 (10:49 +0000)
how removing opengl textures from outside main thread is done so it
happens as part of the main loop.

source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/threads.c
source/blender/gpu/GPU_draw.h
source/blender/gpu/intern/gpu_draw.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_init_exit.c

index a1e44f65200982394207670c89b3175d4f0f512e..6a0a711404cc0d3504700dd727b40d3361177a43 100644 (file)
@@ -65,7 +65,8 @@ int           BLI_system_thread_count(void); /* gets the number of threads the system can
 #define LOCK_PREVIEW   1
 #define LOCK_VIEWER            2
 #define LOCK_CUSTOM1   3
-#define LOCK_RCACHE            2
+#define LOCK_RCACHE            4
+#define LOCK_OPENGL            5
 
 void   BLI_lock_thread(int type);
 void   BLI_unlock_thread(int type);
@@ -73,7 +74,7 @@ void  BLI_unlock_thread(int type);
 /* Mutex Lock */
 
 typedef pthread_mutex_t ThreadMutex;
-#define BLI_MUTEX_INITIALIZER  PTHREAD_MUTEX_INITIALIZER;
+#define BLI_MUTEX_INITIALIZER  PTHREAD_MUTEX_INITIALIZER
 
 void BLI_mutex_init(ThreadMutex *mutex);
 void BLI_mutex_lock(ThreadMutex *mutex);
index de7842727df9a28fc38faa75d532a403213e6316..c6ad659226884f03b6150ce71e3162f58d3c76b3 100644 (file)
@@ -108,6 +108,7 @@ static pthread_mutex_t _preview_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_t mainid;
 static int thread_levels= 0;   /* threads can be invoked inside threads */
 
@@ -344,6 +345,8 @@ void BLI_lock_thread(int type)
                pthread_mutex_lock(&_custom1_lock);
        else if (type==LOCK_RCACHE)
                pthread_mutex_lock(&_rcache_lock);
+       else if (type==LOCK_OPENGL)
+               pthread_mutex_lock(&_opengl_lock);
 }
 
 void BLI_unlock_thread(int type)
@@ -356,8 +359,8 @@ void BLI_unlock_thread(int type)
                pthread_mutex_unlock(&_viewer_lock);
        else if(type==LOCK_CUSTOM1)
                pthread_mutex_unlock(&_custom1_lock);
-       else if(type==LOCK_RCACHE)
-               pthread_mutex_unlock(&_rcache_lock);
+       else if(type==LOCK_OPENGL)
+               pthread_mutex_unlock(&_opengl_lock);
 }
 
 /* Mutex Locks */
index d602d75bb350655747e5250cfd968f72dfd6eb15..e233a3f3d94274a8b4aa580bbf7b15ede29c6785 100644 (file)
@@ -122,6 +122,9 @@ void GPU_free_images(void);
 void GPU_free_smoke(struct SmokeModifierData *smd);
 void GPU_create_smoke(struct SmokeModifierData *smd, int highres);
 
+/* Delayed free of OpenGL buffers by main thread */
+void GPU_free_unused_buffers(void);
+
 #ifdef __cplusplus
 }
 #endif
index 4ded9dc61627ec695689685fab2dc16b985a68d7..5c85abef5817af30a53abbbe45e55f11d962f91b 100644 (file)
@@ -784,42 +784,36 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres)
        smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow);
 }
 
-ListBase image_free_queue = {NULL, NULL};
-static ThreadMutex queuelock = BLI_MUTEX_INITIALIZER;
+static ListBase image_free_queue = {NULL, NULL};
 
-static void flush_queued_free(void)
+static void gpu_queue_image_for_free(Image *ima)
 {
-       Image *ima, *imanext;
-
-       BLI_mutex_lock(&queuelock);
-
-       ima = image_free_queue.first;
-       image_free_queue.first = image_free_queue.last = NULL;
-       for (; ima; ima=imanext) {
-               imanext = (Image*)ima->id.next;
-               GPU_free_image(ima);
-               MEM_freeN(ima);
-       }
+    Image *cpy = MEM_dupallocN(ima);
 
-       BLI_mutex_unlock(&queuelock);
+       BLI_lock_thread(LOCK_OPENGL);
+       BLI_addtail(&image_free_queue, cpy);
+       BLI_unlock_thread(LOCK_OPENGL);
 }
 
-static void queue_image_for_free(Image *ima)
+void GPU_free_unused_buffers(void)
 {
-    Image *cpy = MEM_dupallocN(ima);
+       Image *ima;
 
-       BLI_mutex_lock(&queuelock);
-       BLI_addtail(&image_free_queue, cpy);
-       BLI_mutex_unlock(&queuelock);
+       BLI_lock_thread(LOCK_OPENGL);
+
+       for(ima=image_free_queue.first; ima; ima=ima->id.next)
+               GPU_free_image(ima);
+
+       BLI_freelistN(&image_free_queue);
+
+       BLI_unlock_thread(LOCK_OPENGL);
 }
 
 void GPU_free_image(Image *ima)
 {
-       if (!BLI_thread_is_main()) {
-               queue_image_for_free(ima);
+       if(!BLI_thread_is_main()) {
+               gpu_queue_image_for_free(ima);
                return;
-       } else if (image_free_queue.first) {
-               flush_queued_free();
        }
 
        /* free regular image binding */
index 008abceba4c3555b55819848c011709ff8fab7e3..0331613d392f510ef508b450094d6fd56ae74714 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "ED_screen.h"
 
+#include "GPU_draw.h"
 #include "GPU_extensions.h"
 
 #include "WM_api.h"
@@ -695,6 +696,8 @@ void wm_draw_update(bContext *C)
        wmWindowManager *wm= CTX_wm_manager(C);
        wmWindow *win;
        int drawmethod;
+
+       GPU_free_unused_buffers();
        
        for(win= wm->windows.first; win; win= win->next) {
                if(win->drawmethod != U.wmdrawmethod) {
index 862255d7cd5a21e8b2db1d305d16210b79bc1505..add80e9298cd3bd2dabcbcc9008f0afbf73b744e 100644 (file)
@@ -312,6 +312,7 @@ void WM_exit(bContext *C)
        }
        
        GPU_buffer_pool_free(0);
+       GPU_free_unused_buffers();
        GPU_extensions_exit();
        
 //     if (copybuf) MEM_freeN(copybuf);