diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-04-25 14:49:13 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-04-25 14:49:13 +0400 |
commit | 3f12beb4d0440da93ccbe67c76f23a2f15452aac (patch) | |
tree | 3e3d34d0396a598abd4b40f8cc4de8d450d08d2c | |
parent | 6c3317612edce15095e3868e0cb3135e19eb77f2 (diff) |
Fix #22123 and #22124: some problems with mutex locks, also tweak to
how removing opengl textures from outside main thread is done so it
happens as part of the main loop.
-rw-r--r-- | source/blender/blenlib/BLI_threads.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/intern/threads.c | 7 | ||||
-rw-r--r-- | source/blender/gpu/GPU_draw.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 42 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 1 |
6 files changed, 33 insertions, 28 deletions
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index a1e44f65200..6a0a711404c 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -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); diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index de7842727df..c6ad6592268 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -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 */ diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index d602d75bb35..e233a3f3d94 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -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 diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 4ded9dc6162..5c85abef581 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -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 */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 008abceba4c..0331613d392 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -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) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 862255d7cd5..add80e9298c 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -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); |