From 1dd737759639c63d3279be774202585de778dac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 7 Aug 2020 17:00:28 +0200 Subject: GPUBackend: Add new GPUBackend object to manage GL object allocations This just set a global object responsible for allocating new objects in a thread safe way without needing any GPUContext bound to this thread. This also introduce the GLContext which will contain all the GL related functions for the current context. --- source/blender/gpu/CMakeLists.txt | 8 +++ source/blender/gpu/GPU_context.h | 8 +++ source/blender/gpu/intern/gpu_backend.hh | 37 ++++++++++ source/blender/gpu/intern/gpu_context.cc | 95 +++++++++++++------------ source/blender/gpu/intern/gpu_context_private.h | 44 +++++++++++- source/blender/gpu/intern/gpu_init_exit.c | 3 + source/blender/gpu/opengl/gl_backend.hh | 36 ++++++++++ source/blender/gpu/opengl/gl_context.cc | 53 ++++++++++++++ source/blender/gpu/opengl/gl_context.hh | 50 +++++++++++++ 9 files changed, 286 insertions(+), 48 deletions(-) create mode 100644 source/blender/gpu/intern/gpu_backend.hh create mode 100644 source/blender/gpu/opengl/gl_backend.hh create mode 100644 source/blender/gpu/opengl/gl_context.cc create mode 100644 source/blender/gpu/opengl/gl_context.hh diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 4e9b4a5b313..6ee992e5726 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -28,6 +28,8 @@ endif() set(INC . + intern + opengl ../blenkernel ../blenlib ../bmesh @@ -86,6 +88,8 @@ set(SRC intern/gpu_vertex_format.cc intern/gpu_viewport.c + opengl/gl_context.cc + GPU_attr_binding.h GPU_batch.h GPU_batch_presets.h @@ -117,6 +121,7 @@ set(SRC GPU_viewport.h intern/gpu_attr_binding_private.h + intern/gpu_backend.hh intern/gpu_batch_private.h intern/gpu_codegen.h intern/gpu_context_private.h @@ -128,6 +133,9 @@ set(SRC intern/gpu_select_private.h intern/gpu_shader_private.h intern/gpu_vertex_format_private.h + + opengl/gl_backend.hh + opengl/gl_context.hh ) set(LIB diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h index 0d9e1014803..e3d47cfe084 100644 --- a/source/blender/gpu/GPU_context.h +++ b/source/blender/gpu/GPU_context.h @@ -35,6 +35,14 @@ extern "C" { typedef struct GPUContext GPUContext; +typedef enum eGPUBackendType { + GPU_BACKEND_NONE = 0, + GPU_BACKEND_OPENGL, +} eGPUBackendType; + +void GPU_backend_init(eGPUBackendType backend); +void GPU_backend_exit(void); + GPUContext *GPU_context_create(void *ghost_window); void GPU_context_discard(GPUContext *); diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh new file mode 100644 index 00000000000..24f592f214f --- /dev/null +++ b/source/blender/gpu/intern/gpu_backend.hh @@ -0,0 +1,37 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * GPUBackend derived class contain allocators that do not need a context bound. + * The backend is init at startup and is accessible using GPU_backend_get() */ + +#pragma once + +struct GPUContext; + +class GPUBackend { + public: + virtual ~GPUBackend(){}; + + virtual GPUContext *context_alloc(void *ghost_window) = 0; +}; + +GPUBackend *gpu_backend_get(void); diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index c3c0863f6cd..9707c32cede 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -28,6 +28,9 @@ * - free can be called from any thread */ +/* TODO Create cmake option. */ +#define WITH_OPENGL_BACKEND 1 + #include "BLI_assert.h" #include "BLI_utildefines.h" @@ -36,63 +39,25 @@ #include "GHOST_C-api.h" +#include "gpu_backend.hh" #include "gpu_batch_private.h" #include "gpu_context_private.h" #include "gpu_matrix_private.h" +#ifdef WITH_OPENGL_BACKEND +# include "gl_backend.hh" +# include "gl_context.hh" +#endif + #include -#include -#include -#include #include -#if TRUST_NO_ONE -# if 0 -extern "C" { -extern int BLI_thread_is_main(void); /* Blender-specific function */ -} - -static bool thread_is_main() -{ - /* "main" here means the GL context's thread */ - return BLI_thread_is_main(); -} -# endif -#endif - static std::vector orphaned_buffer_ids; static std::vector orphaned_texture_ids; static std::mutex orphans_mutex; static std::mutex main_context_mutex; -struct GPUContext { - GLuint default_vao; - GLuint default_framebuffer; - GPUFrameBuffer *current_fbo; - std::unordered_set batches; /* Batches that have VAOs from this context */ -#ifdef DEBUG - std::unordered_set - framebuffers; /* Framebuffers that have FBO from this context */ -#endif - struct GPUMatrixState *matrix_state; - std::vector orphaned_vertarray_ids; - std::vector orphaned_framebuffer_ids; - std::mutex orphans_mutex; /* todo: try spinlock instead */ -#if TRUST_NO_ONE - pthread_t thread; /* Thread on which this context is active. */ - bool thread_is_used; -#endif - - GPUContext() - { -#if TRUST_NO_ONE - thread_is_used = false; -#endif - current_fbo = 0; - } -}; - static thread_local GPUContext *active_ctx = NULL; static void orphans_add(GPUContext *ctx, std::vector *orphan_list, GLuint id) @@ -142,8 +107,12 @@ static void orphans_clear(GPUContext *ctx) GPUContext *GPU_context_create(void *ghost_window) { - /* BLI_assert(thread_is_main()); */ - GPUContext *ctx = new GPUContext; + if (gpu_backend_get() == NULL) { + /* TODO move where it make sense. */ + GPU_backend_init(GPU_BACKEND_OPENGL); + } + + GPUContext *ctx = gpu_backend_get()->context_alloc(ghost_window); glGenVertexArrays(1, &ctx->default_vao); if (ghost_window != NULL) { ctx->default_framebuffer = GHOST_GetDefaultOpenGLFramebuffer((GHOST_WindowHandle)ghost_window); @@ -364,3 +333,37 @@ void GPU_context_main_unlock(void) { main_context_mutex.unlock(); } + +/* -------------------------------------------------------------------- */ +/** \name Backend selection + * \{ */ + +static GPUBackend *g_backend; + +void GPU_backend_init(eGPUBackendType backend_type) +{ + BLI_assert(g_backend == NULL); + + switch (backend_type) { +#if WITH_OPENGL_BACKEND + case GPU_BACKEND_OPENGL: + g_backend = new GLBackend; + break; +#endif + default: + BLI_assert(0); + break; + } +} + +void GPU_backend_exit(void) +{ + delete g_backend; +} + +GPUBackend *gpu_backend_get(void) +{ + return g_backend; +} + +/** \} */ diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h index 08fbefe3b3f..374a05bc25f 100644 --- a/source/blender/gpu/intern/gpu_context_private.h +++ b/source/blender/gpu/intern/gpu_context_private.h @@ -27,12 +27,52 @@ #include "GPU_context.h" +/* TODO cleanup this ifdef */ #ifdef __cplusplus -extern "C" { -#endif + +# include +# include +# include +# include +# include struct GPUFrameBuffer; +struct GPUContext { + GLuint default_vao; + GLuint default_framebuffer; + GPUFrameBuffer *current_fbo; + std::unordered_set batches; /* Batches that have VAOs from this context */ +# ifdef DEBUG + std::unordered_set + framebuffers; /* Framebuffers that have FBO from this context */ +# endif + struct GPUMatrixState *matrix_state; + std::vector orphaned_vertarray_ids; + std::vector orphaned_framebuffer_ids; + std::mutex orphans_mutex; /* todo: try spinlock instead */ +# if TRUST_NO_ONE + pthread_t thread; /* Thread on which this context is active. */ + bool thread_is_used; +# endif + + GPUContext() + { +# if TRUST_NO_ONE + thread_is_used = false; +# endif + current_fbo = 0; + }; + + virtual ~GPUContext(){}; +}; + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + GLuint GPU_vao_default(void); GLuint GPU_framebuffer_default(void); diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index c5061ec9ba3..462a1d395c2 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -26,6 +26,7 @@ #include "BLI_sys_types.h" #include "GPU_batch.h" #include "GPU_buffers.h" +#include "GPU_context.h" #include "GPU_immediate.h" #include "intern/gpu_codegen.h" @@ -92,6 +93,8 @@ void GPU_exit(void) gpu_extensions_exit(); gpu_platform_exit(); /* must come last */ + GPU_backend_exit(); + initialized = false; } diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh new file mode 100644 index 00000000000..25400a55394 --- /dev/null +++ b/source/blender/gpu/opengl/gl_backend.hh @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "gpu_backend.hh" + +#include "gl_context.hh" + +class GLBackend : public GPUBackend { + public: + GPUContext *context_alloc(void *ghost_window) + { + return new GLContext(ghost_window); + }; +}; diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc new file mode 100644 index 00000000000..9fe283131fd --- /dev/null +++ b/source/blender/gpu/opengl/gl_context.cc @@ -0,0 +1,53 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "BLI_assert.h" +#include "BLI_utildefines.h" + +#include "GPU_framebuffer.h" + +#include "GHOST_C-api.h" + +#include "gpu_context_private.h" + +#include "gl_context.hh" + +// TODO(fclem) this requires too much refactor for now. +// using namespace blender::gpu; + +/* -------------------------------------------------------------------- */ +/** \name Constructor / Destructor + * \{ */ + +GLContext::GLContext(void *ghost_window) : GPUContext() +{ + default_framebuffer_ = ghost_window ? + GHOST_GetDefaultOpenGLFramebuffer((GHOST_WindowHandle)ghost_window) : + 0; +} + +GLContext::~GLContext() +{ +} + +/** \} */ diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh new file mode 100644 index 00000000000..5daf793910c --- /dev/null +++ b/source/blender/gpu/opengl/gl_context.hh @@ -0,0 +1,50 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "gpu_context_private.h" + +#include "glew-mx.h" + +#include +#include +#include +#include + +// TODO(fclem) this requires too much refactor for now. +// namespace blender { +// namespace gpu { + +class GLContext : public GPUContext { + public: + GLContext(void *ghost_window); + ~GLContext(); + + private: + /** Default framebuffer object for some GL implementation. */ + GLuint default_framebuffer_; +}; + +// } // namespace gpu +// } // namespace blender -- cgit v1.2.3