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:
authorClément Foucault <foucault.clem@gmail.com>2018-06-02 22:16:23 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-06-02 22:16:40 +0300
commit6c6c4da718c19443d2feef6fc8bde83cd37792a4 (patch)
tree2ba3f7da406cbbbde555024da0b592d0b330b4ba /source/blender/gpu/intern/gpu_texture.c
parentbc6358a580081dfaf5e7711733c9cd9ba7b23eaa (diff)
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.
Diffstat (limited to 'source/blender/gpu/intern/gpu_texture.c')
-rw-r--r--source/blender/gpu/intern/gpu_texture.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 14d0b27bc28..d916b75417f 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -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,13 +1112,37 @@ void GPU_texture_free(GPUTexture *tex)
}
}
- if (tex->bindcode && !tex->fromblender)
- glDeleteTextures(1, &tex->bindcode);
+ /* 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);
+ }
+ }
+}
- gpu_texture_memory_footprint_remove(tex);
+void GPU_texture_init_orphans(void)
+{
+ BLI_mutex_init(&g_orphan_lock);
+}
- MEM_freeN(tex);
+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)