[Bf-blender-cvs] [6c6c4da718c] blender2.8: GPU: Fix texture being freed in threads without ogl context bound.

Clément Foucault noreply at git.blender.org
Sat Jun 2 21:22:47 CEST 2018


Commit: 6c6c4da718c19443d2feef6fc8bde83cd37792a4
Author: Clément Foucault
Date:   Sat Jun 2 21:16:23 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB6c6c4da718c19443d2feef6fc8bde83cd37792a4

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.

===================================================================

M	source/blender/gpu/GPU_texture.h
M	source/blender/gpu/intern/gpu_init_exit.c
M	source/blender/gpu/intern/gpu_texture.c
M	source/blender/windowmanager/intern/wm_window.c

===================================================================

diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 737b4a542c8..2427301782c 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -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);
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index c2f14687ff5..7b596e6d76b 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -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();
 
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)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 28fb4f2e011..ca5f95909f8 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -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);
 }



More information about the Bf-blender-cvs mailing list