diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_context.cc')
-rw-r--r-- | source/blender/gpu/intern/gpu_context.cc | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 4a0a9ecc7f6..e29b0d5801d 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" @@ -43,6 +44,12 @@ using namespace blender::gpu; static thread_local Context *active_ctx = nullptr; +static std::mutex backend_users_mutex; +static int num_backend_users = 0; + +static void gpu_backend_create(); +static void gpu_backend_discard(); + /* -------------------------------------------------------------------- */ /** \name gpu::Context methods * \{ */ @@ -85,9 +92,13 @@ Context *Context::get() GPUContext *GPU_context_create(void *ghost_window) { - if (GPUBackend::get() == nullptr) { - /* TODO: move where it make sense. */ - GPU_backend_init(GPU_BACKEND_OPENGL); + { + std::scoped_lock lock(backend_users_mutex); + if (num_backend_users == 0) { + /* Automatically create backend when first context is created. */ + gpu_backend_create(); + } + num_backend_users++; } Context *ctx = GPUBackend::get()->context_alloc(ghost_window); @@ -101,6 +112,16 @@ void GPU_context_discard(GPUContext *ctx_) Context *ctx = unwrap(ctx_); delete ctx; active_ctx = nullptr; + + { + std::scoped_lock lock(backend_users_mutex); + num_backend_users--; + BLI_assert(num_backend_users >= 0); + if (num_backend_users == 0) { + /* Discard backend when last context is discarded. */ + gpu_backend_discard(); + } + } } void GPU_context_active_set(GPUContext *ctx_) @@ -191,11 +212,12 @@ void GPU_render_step() /** \name Backend selection * \{ */ +static const eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL; static GPUBackend *g_backend = nullptr; -bool GPU_backend_supported(eGPUBackendType type) +bool GPU_backend_supported(void) { - switch (type) { + switch (g_backend_type) { case GPU_BACKEND_OPENGL: #ifdef WITH_OPENGL_BACKEND return true; @@ -214,12 +236,12 @@ bool GPU_backend_supported(eGPUBackendType type) } } -void GPU_backend_init(eGPUBackendType backend_type) +static void gpu_backend_create() { BLI_assert(g_backend == nullptr); - BLI_assert(GPU_backend_supported(backend_type)); + BLI_assert(GPU_backend_supported()); - switch (backend_type) { + switch (g_backend_type) { #ifdef WITH_OPENGL_BACKEND case GPU_BACKEND_OPENGL: g_backend = new GLBackend; @@ -236,10 +258,15 @@ void GPU_backend_init(eGPUBackendType backend_type) } } -void GPU_backend_exit() +void gpu_backend_delete_resources() +{ + BLI_assert(g_backend); + g_backend->delete_resources(); +} + +void gpu_backend_discard() { - /* 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; } |