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
path: root/source
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 /source
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
Diffstat (limited to 'source')
-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);