diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_context.cc')
-rw-r--r-- | source/blender/gpu/intern/gpu_context.cc | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index c6eaf7defdc..bcc418169b7 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -23,12 +23,11 @@ #include "GPU_context.h" #include "GPU_framebuffer.h" -#include "GHOST_C-api.h" - #include "gpu_backend.hh" #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" @@ -45,17 +44,27 @@ 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 * \{ */ namespace blender::gpu { +int Context::context_counter = 0; Context::Context() { thread_ = pthread_self(); is_active_ = false; matrix_state = GPU_matrix_state_create(); + + context_id = Context::context_counter; + Context::context_counter++; } Context::~Context() @@ -87,9 +96,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); @@ -103,6 +116,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_) @@ -125,6 +148,22 @@ GPUContext *GPU_context_active_get() return wrap(Context::get()); } +void GPU_context_begin_frame(GPUContext *ctx) +{ + blender::gpu::Context *_ctx = unwrap(ctx); + if (_ctx) { + _ctx->begin_frame(); + } +} + +void GPU_context_end_frame(GPUContext *ctx) +{ + blender::gpu::Context *_ctx = unwrap(ctx); + if (_ctx) { + _ctx->end_frame(); + } +} + /* -------------------------------------------------------------------- */ /** \name Main context global mutex * @@ -177,11 +216,12 @@ void GPU_render_step() /** \name Backend selection * \{ */ -static GPUBackend *g_backend; +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; @@ -200,12 +240,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; @@ -222,10 +262,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; } |