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:
authorClément Foucault <foucault.clem@gmail.com>2020-08-08 02:18:18 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-08-08 02:30:33 +0300
commitcb7ea2ccfbb5d81083313c21d6b85a9c85db67d4 (patch)
treeaf7baa1dc3438da8f349bd38c2a65f9caad50bf3 /source/blender/gpu
parent1dd737759639c63d3279be774202585de778dac5 (diff)
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. # Conflicts: # source/blender/gpu/intern/gpu_context.cc
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_context.cc178
-rw-r--r--source/blender/gpu/intern/gpu_context_private.h49
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c2
-rw-r--r--source/blender/gpu/opengl/gl_backend.hh23
-rw-r--r--source/blender/gpu/opengl/gl_context.cc191
-rw-r--r--source/blender/gpu/opengl/gl_context.hh65
6 files changed, 341 insertions, 167 deletions
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index 9707c32cede..d9f435ce1a9 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -52,58 +52,34 @@
#include <mutex>
#include <vector>
-static std::vector<GLuint> orphaned_buffer_ids;
-static std::vector<GLuint> orphaned_texture_ids;
-
-static std::mutex orphans_mutex;
-static std::mutex main_context_mutex;
+using namespace blender::gpu;
static thread_local GPUContext *active_ctx = NULL;
-static void orphans_add(GPUContext *ctx, std::vector<GLuint> *orphan_list, GLuint id)
-{
- std::mutex *mutex = (ctx) ? &ctx->orphans_mutex : &orphans_mutex;
+/* -------------------------------------------------------------------- */
+/** \name GPUContext methods
+ * \{ */
- mutex->lock();
- orphan_list->emplace_back(id);
- mutex->unlock();
+GPUContext::GPUContext()
+{
+ thread_ = pthread_self();
+ is_active_ = false;
+ matrix_state = GPU_matrix_state_create();
}
-static void orphans_clear(GPUContext *ctx)
+GPUContext::~GPUContext()
{
- /* need at least an active context */
- BLI_assert(ctx);
-
- /* context has been activated by another thread! */
- BLI_assert(pthread_equal(pthread_self(), ctx->thread));
+ GPU_matrix_state_discard(matrix_state);
+}
- ctx->orphans_mutex.lock();
- if (!ctx->orphaned_vertarray_ids.empty()) {
- uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size();
- glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data());
- ctx->orphaned_vertarray_ids.clear();
- }
- if (!ctx->orphaned_framebuffer_ids.empty()) {
- uint orphan_len = (uint)ctx->orphaned_framebuffer_ids.size();
- glDeleteFramebuffers(orphan_len, ctx->orphaned_framebuffer_ids.data());
- ctx->orphaned_framebuffer_ids.clear();
- }
+bool GPUContext::is_active_on_thread(void)
+{
+ return (this == active_ctx) && pthread_equal(pthread_self(), thread_);
+}
- ctx->orphans_mutex.unlock();
+/** \} */
- orphans_mutex.lock();
- if (!orphaned_buffer_ids.empty()) {
- uint orphan_len = (uint)orphaned_buffer_ids.size();
- glDeleteBuffers(orphan_len, orphaned_buffer_ids.data());
- orphaned_buffer_ids.clear();
- }
- if (!orphaned_texture_ids.empty()) {
- uint orphan_len = (uint)orphaned_texture_ids.size();
- glDeleteTextures(orphan_len, orphaned_texture_ids.data());
- orphaned_texture_ids.clear();
- }
- orphans_mutex.unlock();
-}
+/* -------------------------------------------------------------------- */
GPUContext *GPU_context_create(void *ghost_window)
{
@@ -113,15 +89,7 @@ GPUContext *GPU_context_create(void *ghost_window)
}
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);
- }
- else {
- ctx->default_framebuffer = 0;
- }
- ctx->matrix_state = GPU_matrix_state_create();
GPU_context_active_set(ctx);
return ctx;
}
@@ -129,21 +97,6 @@ GPUContext *GPU_context_create(void *ghost_window)
/* to be called after GPU_context_active_set(ctx_to_destroy) */
void GPU_context_discard(GPUContext *ctx)
{
- /* Make sure no other thread has locked it. */
- BLI_assert(ctx == active_ctx);
- BLI_assert(pthread_equal(pthread_self(), ctx->thread));
- BLI_assert(ctx->orphaned_vertarray_ids.empty());
-#ifdef DEBUG
- /* For now don't allow GPUFrameBuffers to be reuse in another ctx. */
- BLI_assert(ctx->framebuffers.empty());
-#endif
- /* delete remaining vaos */
- while (!ctx->batches.empty()) {
- /* this removes the array entry */
- GPU_batch_vao_cache_clear(*ctx->batches.begin());
- }
- GPU_matrix_state_discard(ctx->matrix_state);
- glDeleteVertexArrays(1, &ctx->default_vao);
delete ctx;
active_ctx = NULL;
}
@@ -151,22 +104,15 @@ void GPU_context_discard(GPUContext *ctx)
/* ctx can be NULL */
void GPU_context_active_set(GPUContext *ctx)
{
-#if TRUST_NO_ONE
if (active_ctx) {
- active_ctx->thread_is_used = false;
+ active_ctx->deactivate();
}
- /* Make sure no other context is already bound to this thread. */
- if (ctx) {
- /* Make sure no other thread has locked it. */
- assert(ctx->thread_is_used == false);
- ctx->thread = pthread_self();
- ctx->thread_is_used = true;
- }
-#endif
+
+ active_ctx = ctx;
+
if (ctx) {
- orphans_clear(ctx);
+ ctx->activate();
}
- active_ctx = ctx;
}
GPUContext *GPU_context_active_get(void)
@@ -177,23 +123,18 @@ GPUContext *GPU_context_active_get(void)
GLuint GPU_vao_default(void)
{
BLI_assert(active_ctx); /* need at least an active context */
- BLI_assert(pthread_equal(
- pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */
- return active_ctx->default_vao;
+ return static_cast<GLContext *>(active_ctx)->default_vao_;
}
GLuint GPU_framebuffer_default(void)
{
BLI_assert(active_ctx); /* need at least an active context */
- BLI_assert(pthread_equal(
- pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */
- return active_ctx->default_framebuffer;
+ return static_cast<GLContext *>(active_ctx)->default_framebuffer_;
}
GLuint GPU_vao_alloc(void)
{
GLuint new_vao_id = 0;
- orphans_clear(active_ctx);
glGenVertexArrays(1, &new_vao_id);
return new_vao_id;
}
@@ -201,7 +142,6 @@ GLuint GPU_vao_alloc(void)
GLuint GPU_fbo_alloc(void)
{
GLuint new_fbo_id = 0;
- orphans_clear(active_ctx);
glGenFramebuffers(1, &new_fbo_id);
return new_fbo_id;
}
@@ -209,7 +149,6 @@ GLuint GPU_fbo_alloc(void)
GLuint GPU_buf_alloc(void)
{
GLuint new_buffer_id = 0;
- orphans_clear(active_ctx);
glGenBuffers(1, &new_buffer_id);
return new_buffer_id;
}
@@ -217,51 +156,32 @@ GLuint GPU_buf_alloc(void)
GLuint GPU_tex_alloc(void)
{
GLuint new_texture_id = 0;
- orphans_clear(active_ctx);
glGenTextures(1, &new_texture_id);
return new_texture_id;
}
void GPU_vao_free(GLuint vao_id, GPUContext *ctx)
{
- BLI_assert(ctx);
- if (ctx == active_ctx) {
- glDeleteVertexArrays(1, &vao_id);
- }
- else {
- orphans_add(ctx, &ctx->orphaned_vertarray_ids, vao_id);
- }
+ static_cast<GLContext *>(ctx)->vao_free(vao_id);
}
void GPU_fbo_free(GLuint fbo_id, GPUContext *ctx)
{
- BLI_assert(ctx);
- if (ctx == active_ctx) {
- glDeleteFramebuffers(1, &fbo_id);
- }
- else {
- orphans_add(ctx, &ctx->orphaned_framebuffer_ids, fbo_id);
- }
+ static_cast<GLContext *>(ctx)->fbo_free(fbo_id);
}
void GPU_buf_free(GLuint buf_id)
{
- if (active_ctx) {
- glDeleteBuffers(1, &buf_id);
- }
- else {
- orphans_add(NULL, &orphaned_buffer_ids, buf_id);
- }
+ /* TODO avoid using backend */
+ GPUBackend *backend = gpu_backend_get();
+ static_cast<GLBackend *>(backend)->buf_free(buf_id);
}
void GPU_tex_free(GLuint tex_id)
{
- if (active_ctx) {
- glDeleteTextures(1, &tex_id);
- }
- else {
- orphans_add(NULL, &orphaned_texture_ids, tex_id);
- }
+ /* TODO avoid using backend */
+ GPUBackend *backend = gpu_backend_get();
+ static_cast<GLBackend *>(backend)->tex_free(tex_id);
}
/* GPUBatch & GPUFrameBuffer contains respectively VAO & FBO indices
@@ -271,26 +191,20 @@ void GPU_tex_free(GLuint tex_id)
void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch)
{
BLI_assert(ctx);
- ctx->orphans_mutex.lock();
- ctx->batches.emplace(batch);
- ctx->orphans_mutex.unlock();
+ static_cast<GLContext *>(ctx)->batch_register(batch);
}
void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch)
{
BLI_assert(ctx);
- ctx->orphans_mutex.lock();
- ctx->batches.erase(batch);
- ctx->orphans_mutex.unlock();
+ static_cast<GLContext *>(ctx)->batch_unregister(batch);
}
void gpu_context_add_framebuffer(GPUContext *ctx, GPUFrameBuffer *fb)
{
#ifdef DEBUG
BLI_assert(ctx);
- ctx->orphans_mutex.lock();
- ctx->framebuffers.emplace(fb);
- ctx->orphans_mutex.unlock();
+ static_cast<GLContext *>(ctx)->framebuffer_register(fb);
#else
UNUSED_VARS(ctx, fb);
#endif
@@ -300,9 +214,7 @@ void gpu_context_remove_framebuffer(GPUContext *ctx, GPUFrameBuffer *fb)
{
#ifdef DEBUG
BLI_assert(ctx);
- ctx->orphans_mutex.lock();
- ctx->framebuffers.erase(fb);
- ctx->orphans_mutex.unlock();
+ static_cast<GLContext *>(ctx)->framebuffer_unregister(fb);
#else
UNUSED_VARS(ctx, fb);
#endif
@@ -324,6 +236,14 @@ struct GPUMatrixState *gpu_context_active_matrix_state_get()
return active_ctx->matrix_state;
}
+/* -------------------------------------------------------------------- */
+/** \name Main context global mutex
+ *
+ * Used to avoid crash on some old drivers.
+ * \{ */
+
+static std::mutex main_context_mutex;
+
void GPU_context_main_lock(void)
{
main_context_mutex.lock();
@@ -334,6 +254,8 @@ void GPU_context_main_unlock(void)
main_context_mutex.unlock();
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Backend selection
* \{ */
@@ -358,7 +280,11 @@ void GPU_backend_init(eGPUBackendType backend_type)
void GPU_backend_exit(void)
{
- delete g_backend;
+ if (g_backend) {
+ /* TODO assert no resource left. Currently UI textures are still not freed in their context
+ * correctly. */
+ delete g_backend;
+ }
}
GPUBackend *gpu_backend_get(void)
diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h
index 374a05bc25f..37bf110665f 100644
--- a/source/blender/gpu/intern/gpu_context_private.h
+++ b/source/blender/gpu/intern/gpu_context_private.h
@@ -25,6 +25,8 @@
#pragma once
+#include "MEM_guardedalloc.h"
+
#include "GPU_context.h"
/* TODO cleanup this ifdef */
@@ -37,34 +39,29 @@
# include <vector>
struct GPUFrameBuffer;
+struct GPUMatrixState;
struct GPUContext {
- GLuint default_vao;
- GLuint default_framebuffer;
- GPUFrameBuffer *current_fbo;
- std::unordered_set<GPUBatch *> batches; /* Batches that have VAOs from this context */
-# ifdef DEBUG
- std::unordered_set<GPUFrameBuffer *>
- framebuffers; /* Framebuffers that have FBO from this context */
-# endif
- struct GPUMatrixState *matrix_state;
- std::vector<GLuint> orphaned_vertarray_ids;
- std::vector<GLuint> 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(){};
+ public:
+ /** State managment */
+ GPUFrameBuffer *current_fbo = NULL;
+ GPUMatrixState *matrix_state = NULL;
+
+ protected:
+ /** Thread on which this context is active. */
+ pthread_t thread_;
+ bool is_active_;
+
+ public:
+ GPUContext();
+ virtual ~GPUContext();
+
+ virtual void activate(void) = 0;
+ virtual void deactivate(void) = 0;
+
+ bool is_active_on_thread(void);
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("GPUContext")
};
#endif
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 462a1d395c2..ba0da95eb9d 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -93,8 +93,6 @@ 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
index 25400a55394..f7c01b2f184 100644
--- a/source/blender/gpu/opengl/gl_backend.hh
+++ b/source/blender/gpu/opengl/gl_backend.hh
@@ -25,12 +25,33 @@
#include "gpu_backend.hh"
+#include "BLI_vector.hh"
+
#include "gl_context.hh"
+namespace blender {
+namespace gpu {
+
class GLBackend : public GPUBackend {
+ private:
+ GLSharedOrphanLists shared_orphan_list_;
+
public:
GPUContext *context_alloc(void *ghost_window)
{
- return new GLContext(ghost_window);
+ return new GLContext(ghost_window, shared_orphan_list_);
};
+
+ /* TODO remove */
+ void buf_free(GLuint buf_id);
+ void tex_free(GLuint tex_id);
+ void orphans_add(Vector<GLuint> &orphan_list, std::mutex &list_mutex, unsigned int id)
+ {
+ list_mutex.lock();
+ orphan_list.append(id);
+ list_mutex.unlock();
+ }
};
+
+} // namespace gpu
+} // namespace blender
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc
index 9fe283131fd..696603ab070 100644
--- a/source/blender/gpu/opengl/gl_context.cc
+++ b/source/blender/gpu/opengl/gl_context.cc
@@ -30,24 +30,209 @@
#include "gpu_context_private.h"
+#include "gl_backend.hh" /* TODO remove */
#include "gl_context.hh"
-// TODO(fclem) this requires too much refactor for now.
-// using namespace blender::gpu;
+using namespace blender::gpu;
/* -------------------------------------------------------------------- */
/** \name Constructor / Destructor
* \{ */
-GLContext::GLContext(void *ghost_window) : GPUContext()
+GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list)
+ : shared_orphan_list_(shared_orphan_list)
{
default_framebuffer_ = ghost_window ?
GHOST_GetDefaultOpenGLFramebuffer((GHOST_WindowHandle)ghost_window) :
0;
+
+ glGenVertexArrays(1, &default_vao_);
+
+ float data[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ glGenBuffers(1, &default_attr_vbo_);
+ glBindBuffer(GL_ARRAY_BUFFER, default_attr_vbo_);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
}
GLContext::~GLContext()
{
+ BLI_assert(orphaned_framebuffers_.is_empty());
+ BLI_assert(orphaned_vertarrays_.is_empty());
+ /* For now don't allow GPUFrameBuffers to be reuse in another context. */
+ BLI_assert(framebuffers_.is_empty());
+ /* Delete vaos so the batch can be reused in another context. */
+ for (GPUBatch *batch : batches_) {
+ GPU_batch_vao_cache_clear(batch);
+ }
+ glDeleteVertexArrays(1, &default_vao_);
+ glDeleteBuffers(1, &default_attr_vbo_);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Activate / Deactivate context
+ * \{ */
+
+void GLContext::activate(void)
+{
+ /* Make sure no other context is already bound to this thread. */
+ BLI_assert(is_active_ == false);
+
+ is_active_ = true;
+ thread_ = pthread_self();
+
+ /* Clear accumulated orphans. */
+ orphans_clear();
+}
+
+void GLContext::deactivate(void)
+{
+ is_active_ = false;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Safe object deletion
+ *
+ * GPU objects can be freed when the context is not bound.
+ * In this case we delay the deletion until the context is bound again.
+ * \{ */
+
+void GLSharedOrphanLists::orphans_clear(void)
+{
+ /* Check if any context is active on this thread! */
+ BLI_assert(GPU_context_active_get());
+
+ lists_mutex.lock();
+ if (!buffers.is_empty()) {
+ glDeleteBuffers((uint)buffers.size(), buffers.data());
+ buffers.clear();
+ }
+ if (!textures.is_empty()) {
+ glDeleteTextures((uint)textures.size(), textures.data());
+ textures.clear();
+ }
+ lists_mutex.unlock();
+};
+
+void GLContext::orphans_clear(void)
+{
+ /* Check if context has been activated by another thread! */
+ BLI_assert(this->is_active_on_thread());
+
+ lists_mutex_.lock();
+ if (!orphaned_vertarrays_.is_empty()) {
+ glDeleteVertexArrays((uint)orphaned_vertarrays_.size(), orphaned_vertarrays_.data());
+ orphaned_vertarrays_.clear();
+ }
+ if (!orphaned_framebuffers_.is_empty()) {
+ glDeleteFramebuffers((uint)orphaned_framebuffers_.size(), orphaned_framebuffers_.data());
+ orphaned_framebuffers_.clear();
+ }
+ lists_mutex_.unlock();
+
+ shared_orphan_list_.orphans_clear();
+};
+
+void GLContext::orphans_add(Vector<GLuint> &orphan_list, std::mutex &list_mutex, GLuint id)
+{
+ list_mutex.lock();
+ orphan_list.append(id);
+ list_mutex.unlock();
+}
+
+void GLContext::vao_free(GLuint vao_id)
+{
+ if (this == GPU_context_active_get()) {
+ glDeleteVertexArrays(1, &vao_id);
+ }
+ else {
+ orphans_add(orphaned_vertarrays_, lists_mutex_, vao_id);
+ }
+}
+
+void GLContext::fbo_free(GLuint fbo_id)
+{
+ if (this == GPU_context_active_get()) {
+ glDeleteFramebuffers(1, &fbo_id);
+ }
+ else {
+ orphans_add(orphaned_framebuffers_, lists_mutex_, fbo_id);
+ }
+}
+
+void GLBackend::buf_free(GLuint buf_id)
+{
+ /* Any context can free. */
+ if (GPU_context_active_get()) {
+ glDeleteBuffers(1, &buf_id);
+ }
+ else {
+ orphans_add(shared_orphan_list_.buffers, shared_orphan_list_.lists_mutex, buf_id);
+ }
+}
+
+void GLBackend::tex_free(GLuint tex_id)
+{
+ /* Any context can free. */
+ if (GPU_context_active_get()) {
+ glDeleteTextures(1, &tex_id);
+ }
+ else {
+ orphans_add(shared_orphan_list_.textures, shared_orphan_list_.lists_mutex, tex_id);
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Linked object deletion
+ *
+ * These objects contain data that are stored per context. We
+ * need to do some cleanup if they are used accross context or if context
+ * is discarded.
+ * \{ */
+
+void GLContext::batch_register(struct GPUBatch *batch)
+{
+ lists_mutex_.lock();
+ batches_.add(batch);
+ lists_mutex_.unlock();
+}
+
+void GLContext::batch_unregister(struct GPUBatch *batch)
+{
+ /* vao_cache_clear() can acquire lists_mutex_ so avoid deadlock. */
+ // reinterpret_cast<GLBatch *>(batch)->vao_cache_clear();
+
+ lists_mutex_.lock();
+ batches_.remove(batch);
+ lists_mutex_.unlock();
+}
+
+void GLContext::framebuffer_register(struct GPUFrameBuffer *fb)
+{
+#ifdef DEBUG
+ lists_mutex_.lock();
+ framebuffers_.add(fb);
+ lists_mutex_.unlock();
+#else
+ UNUSED_VARS(fb);
+#endif
+}
+
+void GLContext::framebuffer_unregister(struct GPUFrameBuffer *fb)
+{
+#ifdef DEBUG
+ lists_mutex_.lock();
+ framebuffers_.remove(fb);
+ lists_mutex_.unlock();
+#else
+ UNUSED_VARS(fb);
+#endif
}
/** \} */
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 5daf793910c..5da288a265f 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -25,6 +25,9 @@
#include "gpu_context_private.h"
+#include "BLI_vector.hh"
+#include "BLI_set.hh"
+
#include "glew-mx.h"
#include <iostream>
@@ -32,19 +35,63 @@
#include <unordered_set>
#include <vector>
-// TODO(fclem) this requires too much refactor for now.
-// namespace blender {
-// namespace gpu {
+namespace blender {
+namespace gpu {
-class GLContext : public GPUContext {
+class GLSharedOrphanLists {
public:
- GLContext(void *ghost_window);
- ~GLContext();
+ /** Mutex for the bellow structures. */
+ std::mutex lists_mutex;
+ /** Buffers and textures are shared across context. Any context can free them. */
+ Vector<GLuint> textures;
+ Vector<GLuint> buffers;
+
+ public:
+ void orphans_clear(void);
+};
- private:
+class GLContext : public GPUContext {
+ /* TODO(fclem) these needs to become private. */
+ public:
+ /** Default VAO for procedural draw calls. */
+ GLuint default_vao_;
/** Default framebuffer object for some GL implementation. */
GLuint default_framebuffer_;
+ /** VBO for missing vertex attrib binding. Avoid undefined behavior on some implementation. */
+ GLuint default_attr_vbo_;
+ /**
+ * GPUBatch & GPUFramebuffer have references to the context they are from, in the case the
+ * context is destroyed, we need to remove any reference to it.
+ */
+ Set<GPUBatch *> batches_;
+ Set<GPUFrameBuffer *> framebuffers_;
+ /** Mutex for the bellow structures. */
+ std::mutex lists_mutex_;
+ /** VertexArrays and framebuffers are not shared across context. */
+ Vector<GLuint> orphaned_vertarrays_;
+ Vector<GLuint> orphaned_framebuffers_;
+ /** GLBackend onws this data. */
+ GLSharedOrphanLists &shared_orphan_list_;
+
+ public:
+ GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list);
+ ~GLContext();
+
+ void activate(void) override;
+ void deactivate(void) override;
+
+ /* TODO(fclem) these needs to become private. */
+ public:
+ void orphans_add(Vector<GLuint> &orphan_list, std::mutex &list_mutex, GLuint id);
+ void orphans_clear(void);
+
+ void vao_free(GLuint vao_id);
+ void fbo_free(GLuint fbo_id);
+ void batch_register(struct GPUBatch *batch);
+ void batch_unregister(struct GPUBatch *batch);
+ void framebuffer_register(struct GPUFrameBuffer *fb);
+ void framebuffer_unregister(struct GPUFrameBuffer *fb);
};
-// } // namespace gpu
-// } // namespace blender
+} // namespace gpu
+} // namespace blender