Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/gpu/gpu_buffers.h8
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c78
-rw-r--r--source/blender/gpu/intern/gpu_draw.c4
3 files changed, 56 insertions, 34 deletions
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);
}