diff --git a/source/blender/gpu/gpu_buffers.h b/source/blender/gpu/gpu_buffers.h index 98cefa7a696..983133a6d4b 100644 --- a/source/blender/gpu/gpu_buffers.h +++ b/source/blender/gpu/gpu_buffers.h @@ -69,8 +69,9 @@ typedef struct GPUBuffer typedef struct GPUBufferPool { - int size; /* number of allocated buffers stored */ - GPUBuffer* buffers[MAX_FREE_GPU_BUFFERS]; + int size; /* number of allocated buffers stored */ + int maxsize; /* size of the array */ + GPUBuffer **buffers; } GPUBufferPool; typedef struct GPUBufferMaterial @@ -119,7 +120,8 @@ typedef struct GPUAttrib } GPUAttrib; GPUBufferPool *GPU_buffer_pool_new(); -void GPU_buffer_pool_free( GPUBufferPool *pool ); /* TODO: Find a place where to call this function on exit */ +void GPU_buffer_pool_free( GPUBufferPool *pool ); +void GPU_buffer_pool_free_unused( GPUBufferPool *pool ); GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool ); void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool ); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 1d615c8e67b..e0a47c0c5bc 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -38,8 +38,9 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_ghash.h" +#include "BLI_math.h" +#include "BLI_threads.h" #include "DNA_meshdata_types.h" @@ -82,37 +83,12 @@ GPUBufferPool *GPU_buffer_pool_new() } pool = MEM_callocN(sizeof(GPUBufferPool), "GPU_buffer_pool_new"); + pool->maxsize = MAX_FREE_GPU_BUFFERS; + pool->buffers = MEM_callocN(sizeof(GPUBuffer*)*pool->maxsize, "GPU_buffer_pool_new buffers"); return pool; } -void GPU_buffer_pool_free(GPUBufferPool *pool) -{ - int i; - - DEBUG_VBO("GPU_buffer_pool_free\n"); - - if( pool == 0 ) - pool = globalPool; - if( pool == 0 ) - return; - - for( i = 0; i < pool->size; i++ ) { - if( pool->buffers[i] != 0 ) { - if( useVBOs ) { - glDeleteBuffersARB( 1, &pool->buffers[i]->id ); - } - else { - MEM_freeN( pool->buffers[i]->pointer ); - } - MEM_freeN(pool->buffers[i]); - } else { - ERROR_VBO("Why are we accessing a null buffer in GPU_buffer_pool_free?\n"); - } - } - MEM_freeN(pool); -} - void GPU_buffer_pool_remove( int index, GPUBufferPool *pool ) { int i; @@ -159,6 +135,35 @@ void GPU_buffer_pool_delete_last( GPUBufferPool *pool ) pool->size--; } +void GPU_buffer_pool_free(GPUBufferPool *pool) +{ + DEBUG_VBO("GPU_buffer_pool_free\n"); + + if( pool == 0 ) + pool = globalPool; + if( pool == 0 ) + return; + + while( pool->size ) + GPU_buffer_pool_delete_last(pool); + + MEM_freeN(pool->buffers); + MEM_freeN(pool); +} + +void GPU_buffer_pool_free_unused(GPUBufferPool *pool) +{ + DEBUG_VBO("GPU_buffer_pool_free_unused\n"); + + if( pool == 0 ) + pool = globalPool; + if( pool == 0 ) + return; + + while( pool->size > MAX_FREE_GPU_BUFFERS ) + GPU_buffer_pool_delete_last(pool); +} + GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool ) { char buffer[60]; @@ -226,6 +231,7 @@ GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool ) void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool ) { int i; + DEBUG_VBO("GPU_buffer_free\n"); if( buffer == 0 ) @@ -235,9 +241,19 @@ void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool ) if( pool == 0 ) globalPool = GPU_buffer_pool_new(); - /* free the last used buffer in the queue if no more space */ - if( pool->size == MAX_FREE_GPU_BUFFERS ) { - GPU_buffer_pool_delete_last( pool ); + /* free the last used buffer in the queue if no more space, but only + if we are in the main thread. for e.g. rendering or baking it can + happen that we are in other thread and can't call OpenGL, in that + case cleanup will be done GPU_buffer_pool_free_unused */ + if( BLI_thread_is_main() ) { + while( pool->size >= MAX_FREE_GPU_BUFFERS ) + GPU_buffer_pool_delete_last( pool ); + } + else { + if( pool->maxsize == pool->size ) { + pool->maxsize += MAX_FREE_GPU_BUFFERS; + pool->buffers = MEM_reallocN(pool->buffers, sizeof(GPUBuffer*)*pool->maxsize); + } } for( i =pool->size; i > 0; i-- ) { diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 9a5a6704428..506ce94b763 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -804,11 +804,15 @@ 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); BLI_freelistN(&image_free_queue); + /* vbo buffers */ + GPU_buffer_pool_free_unused(0); + BLI_unlock_thread(LOCK_OPENGL); }