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:
authorBrecht Van Lommel <brecht@blender.org>2022-07-15 13:44:35 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-07-15 17:31:28 +0300
commit1cf465bbc3312ae8eac3e1ae573b716e0fad92cf (patch)
tree27f1c1ee17327e2d6b9775c17faf6a431d677651
parent5e1229f25387a90fe626b4b2ac34f2eb5c7dc23a (diff)
Fix GPU backend deleting resources without an active context
This causes an assert with libepoxy, but was wrong already regardless. Refactor logic to work as follows: * GPU_exit() deletes backend resources * Destroy UI GPU resources with the context active * Call GPU_backend_exit() after deleting the context Ref D15291 Differential Revision: https://developer.blender.org/D15465
-rw-r--r--source/blender/gpu/GPU_context.h5
-rw-r--r--source/blender/gpu/intern/gpu_backend.hh1
-rw-r--r--source/blender/gpu/intern/gpu_context.cc33
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c2
-rw-r--r--source/blender/gpu/intern/gpu_private.h4
-rw-r--r--source/blender/gpu/metal/mtl_backend.hh5
-rw-r--r--source/blender/gpu/opengl/gl_backend.hh8
-rw-r--r--source/blender/gpu/tests/gpu_testing.cc3
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c26
9 files changed, 58 insertions, 29 deletions
diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h
index b04a4422baa..c81296093a1 100644
--- a/source/blender/gpu/GPU_context.h
+++ b/source/blender/gpu/GPU_context.h
@@ -17,8 +17,11 @@
extern "C" {
#endif
+/* GPU backends abstract the differences between different APIs. These must be
+ * initialized before creating contexts, and deleted after the last context is
+ * discarded. GPU_context_create automatically initializes a backend if none
+ * exists yet. */
bool GPU_backend_init_once(void);
-void GPU_backend_init(eGPUBackendType backend);
void GPU_backend_exit(void);
bool GPU_backend_supported(eGPUBackendType type);
diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh
index 6e07e6c3229..d2890efee72 100644
--- a/source/blender/gpu/intern/gpu_backend.hh
+++ b/source/blender/gpu/intern/gpu_backend.hh
@@ -30,6 +30,7 @@ class VertBuf;
class GPUBackend {
public:
virtual ~GPUBackend() = default;
+ virtual void delete_resources() = 0;
static GPUBackend *get();
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index d3b208dc6f6..9b0670da8cb 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -27,6 +27,7 @@
#include "gpu_batch_private.hh"
#include "gpu_context_private.hh"
#include "gpu_matrix_private.h"
+#include "gpu_private.h"
#ifdef WITH_OPENGL_BACKEND
# include "gl_backend.hh"
@@ -213,20 +214,17 @@ bool GPU_backend_supported(eGPUBackendType type)
bool GPU_backend_init_once()
{
- if (GPUBackend::get() == nullptr) {
- if (!GPU_backend_supported(GPU_BACKEND_OPENGL)) {
- return false;
- }
- /* TODO: move where it make sense. */
- GPU_backend_init(GPU_BACKEND_OPENGL);
+ if (GPUBackend::get() != nullptr) {
+ return true;
}
- return true;
-}
-void GPU_backend_init(eGPUBackendType backend_type)
-{
- BLI_assert(g_backend == nullptr);
- BLI_assert(GPU_backend_supported(backend_type));
+ const eGPUBackendType backend_type = GPU_BACKEND_OPENGL;
+ if (!GPU_backend_supported(backend_type)) {
+ return false;
+ }
+
+ static std::mutex backend_init_mutex;
+ std::scoped_lock lock(backend_init_mutex);
switch (backend_type) {
#ifdef WITH_OPENGL_BACKEND
@@ -243,12 +241,19 @@ void GPU_backend_init(eGPUBackendType backend_type)
BLI_assert(0);
break;
}
+
+ return true;
+}
+
+void gpu_backend_delete_resources()
+{
+ BLI_assert(backend);
+ g_backend->delete_resources();
}
void GPU_backend_exit()
{
- /* TODO: assert no resource left. Currently UI textures are still not freed in their context
- * correctly. */
+ /* TODO: assert no resource left. */
delete g_backend;
g_backend = nullptr;
}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 062614fb5cb..34b355eefaf 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -55,6 +55,8 @@ void GPU_exit(void)
gpu_shader_dependency_exit();
gpu_shader_create_info_exit();
+ gpu_backend_delete_resources();
+
initialized = false;
}
diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h
index a8ee5187d98..0e293302086 100644
--- a/source/blender/gpu/intern/gpu_private.h
+++ b/source/blender/gpu/intern/gpu_private.h
@@ -10,6 +10,10 @@
extern "C" {
#endif
+/* gpu_backend.cc */
+
+void gpu_backend_delete_resources(void);
+
/* gpu_pbvh.c */
void gpu_pbvh_init(void);
diff --git a/source/blender/gpu/metal/mtl_backend.hh b/source/blender/gpu/metal/mtl_backend.hh
index 7228a5f7596..3e09408e43e 100644
--- a/source/blender/gpu/metal/mtl_backend.hh
+++ b/source/blender/gpu/metal/mtl_backend.hh
@@ -40,6 +40,11 @@ class MTLBackend : public GPUBackend {
MTLBackend::platform_exit();
}
+ void delete_resources()
+ {
+ /* Delete any resources with context active. */
+ }
+
static bool metal_is_supported();
static MTLBackend *get()
{
diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh
index 29249111294..e425b87afe8 100644
--- a/source/blender/gpu/opengl/gl_backend.hh
+++ b/source/blender/gpu/opengl/gl_backend.hh
@@ -42,11 +42,15 @@ class GLBackend : public GPUBackend {
}
~GLBackend()
{
- GLTexture::samplers_free();
-
GLBackend::platform_exit();
}
+ void delete_resources() override
+ {
+ /* Delete any resources with context active. */
+ GLTexture::samplers_free();
+ }
+
static GLBackend *get()
{
return static_cast<GLBackend *>(GPUBackend::get());
diff --git a/source/blender/gpu/tests/gpu_testing.cc b/source/blender/gpu/tests/gpu_testing.cc
index 4e93e062b50..5a2ad893360 100644
--- a/source/blender/gpu/tests/gpu_testing.cc
+++ b/source/blender/gpu/tests/gpu_testing.cc
@@ -17,6 +17,7 @@ void GPUTest::SetUp()
GHOST_GLSettings glSettings = {0};
CLG_init();
ghost_system = GHOST_CreateSystem();
+ GPU_backend_init_once();
ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
GHOST_ActivateOpenGLContext(ghost_context);
context = GPU_context_create(nullptr);
@@ -26,9 +27,9 @@ void GPUTest::SetUp()
void GPUTest::TearDown()
{
GPU_exit();
- GPU_backend_exit();
GPU_context_discard(context);
GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
+ GPU_backend_exit();
GHOST_DisposeSystem(ghost_system);
CLG_exit();
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index b9bb1d88819..7324abfd096 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -576,14 +576,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
BLF_exit();
- if (opengl_is_init) {
- DRW_opengl_context_enable_ex(false);
- GPU_pass_cache_free();
- GPU_exit();
- DRW_opengl_context_disable_ex(false);
- DRW_opengl_context_destroy();
- }
-
BLT_lang_free();
ANIM_keyingset_infos_exit();
@@ -608,13 +600,25 @@ void WM_exit_ex(bContext *C, const bool do_python)
ED_file_exit(); /* for fsmenu */
- UI_exit();
+ /* Delete GPU resources and context. The UI also uses GPU resources and so
+ * is also deleted with the context active. */
+ if (opengl_is_init) {
+ DRW_opengl_context_enable_ex(false);
+ UI_exit();
+ GPU_pass_cache_free();
+ GPU_exit();
+ DRW_opengl_context_disable_ex(false);
+ DRW_opengl_context_destroy();
+ }
+ else {
+ UI_exit();
+ }
+ GPU_backend_exit();
+
BKE_blender_userdef_data_free(&U, false);
RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */
- GPU_backend_exit();
-
wm_ghost_exit();
CTX_free(C);