GPU: Fix texture being freed in threads without ogl context bound.
This is a dirty fix. A bit more cleaner approach would be to check if a context is bound and delay the deletion only in this case. Also we may want to do this orphan deletion at some other places than wm_window_swap_buffers.
This commit is contained in:
@@ -173,6 +173,11 @@ void GPU_invalid_tex_free(void);
|
||||
|
||||
void GPU_texture_free(GPUTexture *tex);
|
||||
|
||||
void GPU_texture_init_orphans(void);
|
||||
void GPU_texture_exit_orphans(void);
|
||||
/* This has to be called from a thread with an ogl context bound. */
|
||||
void GPU_texture_delete_orphans(void);
|
||||
|
||||
void GPU_texture_ref(GPUTexture *tex);
|
||||
void GPU_texture_bind(GPUTexture *tex, int number);
|
||||
void GPU_texture_unbind(GPUTexture *tex);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "GPU_init_exit.h" /* interface */
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_texture.h"
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "intern/gpu_codegen.h"
|
||||
@@ -56,6 +57,7 @@ void GPU_init(void)
|
||||
|
||||
gpu_extensions_init(); /* must come first */
|
||||
|
||||
GPU_texture_init_orphans();
|
||||
gpu_codegen_init();
|
||||
|
||||
if (G.debug & G_DEBUG_GPU)
|
||||
@@ -80,6 +82,8 @@ void GPU_exit(void)
|
||||
|
||||
gpu_batch_exit();
|
||||
|
||||
GPU_texture_exit_orphans();
|
||||
|
||||
if (G.debug & G_DEBUG_GPU)
|
||||
gpu_debug_exit();
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
|
||||
@@ -49,6 +51,9 @@ static struct GPUTextureGlobal {
|
||||
GPUTexture *invalid_tex_3D;
|
||||
} GG = {NULL, NULL, NULL};
|
||||
|
||||
static ListBase g_orphaned_tex = {NULL, NULL};
|
||||
static ThreadMutex g_orphan_lock;
|
||||
|
||||
/* Maximum number of FBOs a texture can be attached to. */
|
||||
#define GPU_TEX_MAX_FBO_ATTACHED 8
|
||||
|
||||
@@ -1083,6 +1088,16 @@ void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat)
|
||||
glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, repeat);
|
||||
}
|
||||
|
||||
static void gpu_texture_delete(GPUTexture *tex)
|
||||
{
|
||||
if (tex->bindcode && !tex->fromblender)
|
||||
glDeleteTextures(1, &tex->bindcode);
|
||||
|
||||
gpu_texture_memory_footprint_remove(tex);
|
||||
|
||||
MEM_freeN(tex);
|
||||
}
|
||||
|
||||
void GPU_texture_free(GPUTexture *tex)
|
||||
{
|
||||
tex->refcount--;
|
||||
@@ -1097,15 +1112,39 @@ void GPU_texture_free(GPUTexture *tex)
|
||||
}
|
||||
}
|
||||
|
||||
if (tex->bindcode && !tex->fromblender)
|
||||
glDeleteTextures(1, &tex->bindcode);
|
||||
|
||||
gpu_texture_memory_footprint_remove(tex);
|
||||
|
||||
MEM_freeN(tex);
|
||||
/* TODO(fclem): Check if the thread has an ogl context. */
|
||||
if (BLI_thread_is_main()) {
|
||||
gpu_texture_delete(tex);
|
||||
}
|
||||
else{
|
||||
BLI_mutex_lock(&g_orphan_lock);
|
||||
BLI_addtail(&g_orphaned_tex, BLI_genericNodeN(tex));
|
||||
BLI_mutex_unlock(&g_orphan_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_texture_init_orphans(void)
|
||||
{
|
||||
BLI_mutex_init(&g_orphan_lock);
|
||||
}
|
||||
|
||||
void GPU_texture_delete_orphans(void)
|
||||
{
|
||||
BLI_mutex_lock(&g_orphan_lock);
|
||||
LinkData *link;
|
||||
while((link = BLI_pophead(&g_orphaned_tex))) {
|
||||
gpu_texture_delete((GPUTexture *)link->data);
|
||||
}
|
||||
BLI_mutex_unlock(&g_orphan_lock);
|
||||
}
|
||||
|
||||
void GPU_texture_exit_orphans(void)
|
||||
{
|
||||
GPU_texture_delete_orphans();
|
||||
BLI_mutex_end(&g_orphan_lock);
|
||||
}
|
||||
|
||||
void GPU_texture_ref(GPUTexture *tex)
|
||||
{
|
||||
tex->refcount++;
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_init_exit.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_texture.h"
|
||||
#include "BLF_api.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
@@ -2023,6 +2024,7 @@ void wm_window_raise(wmWindow *win)
|
||||
|
||||
void wm_window_swap_buffers(wmWindow *win)
|
||||
{
|
||||
GPU_texture_delete_orphans(); /* XXX should be done elsewhere. */
|
||||
GHOST_SwapWindowBuffers(win->ghostwin);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user