[Bf-blender-cvs] [41406fcacf7] tmp-gpu-context-isolation: GPU: Hide GL context specificitied behind class methods
Clément Foucault
noreply at git.blender.org
Fri Jul 31 18:58:25 CEST 2020
Commit: 41406fcacf74b7aad7f1c842cb9fa19eb886caac
Author: Clément Foucault
Date: Fri Jul 31 11:56:29 2020 +0200
Branches: tmp-gpu-context-isolation
https://developer.blender.org/rB41406fcacf74b7aad7f1c842cb9fa19eb886caac
GPU: Hide GL context specificitied behind class methods
===================================================================
M source/blender/gpu/CMakeLists.txt
M source/blender/gpu/intern/gpu_batch.cc
M source/blender/gpu/intern/gpu_context.cc
D source/blender/gpu/intern/gpu_context_private.h
A source/blender/gpu/intern/gpu_context_private.hh
M source/blender/gpu/intern/gpu_element.cc
M source/blender/gpu/intern/gpu_framebuffer.cc
M source/blender/gpu/intern/gpu_immediate.cc
M source/blender/gpu/intern/gpu_matrix.cc
M source/blender/gpu/intern/gpu_shader_interface.cc
M source/blender/gpu/intern/gpu_texture.cc
M source/blender/gpu/intern/gpu_uniformbuffer.cc
M source/blender/gpu/intern/gpu_vertex_buffer.cc
A source/blender/gpu/opengl/gl_batch.cc
A source/blender/gpu/opengl/gl_context.cc
A source/blender/gpu/opengl/gl_context.hh
===================================================================
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 3ea18f72166..c18fa5f508c 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -28,6 +28,7 @@ endif()
set(INC
.
+ ./opengl
../blenkernel
../blenlib
../bmesh
@@ -85,6 +86,12 @@ set(SRC
intern/gpu_vertex_format.cc
intern/gpu_viewport.c
+ # opengl/ogl_context.cc
+ opengl/gl_context.hh
+
+ # vulkan/vk_context.cc
+ # vulkan/vk_context.hh
+
GPU_attr_binding.h
GPU_batch.h
GPU_batch_presets.h
@@ -118,7 +125,7 @@ set(SRC
intern/gpu_attr_binding_private.h
intern/gpu_batch_private.h
intern/gpu_codegen.h
- intern/gpu_context_private.h
+ intern/gpu_context_private.hh
intern/gpu_material_library.h
intern/gpu_matrix_private.h
intern/gpu_node_graph.h
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index 9f9adcacfa6..d354d828044 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -34,7 +34,7 @@
#include "GPU_shader.h"
#include "gpu_batch_private.h"
-#include "gpu_context_private.h"
+#include "gpu_context_private.hh"
#include "gpu_primitive_private.h"
#include "gpu_shader_private.h"
#include "gpu_vertex_format_private.h"
@@ -81,7 +81,7 @@ void GPU_batch_vao_cache_clear(GPUBatch *batch)
batch->static_vaos.vao_ids[i] = 0;
batch->static_vaos.interfaces[i] = NULL;
}
- gpu_context_remove_batch(batch->context, batch);
+ batch->context->batch_remove(batch);
batch->context = NULL;
}
@@ -294,7 +294,7 @@ static GLuint batch_vao_get(GPUBatch *batch)
* Until then it can only be drawn with this context. */
if (batch->context == NULL) {
batch->context = GPU_context_active_get();
- gpu_context_add_batch(batch->context, batch);
+ batch->context->batch_add(batch);
}
#if TRUST_NO_ONE
else {
@@ -634,16 +634,6 @@ void GPU_batch_uniform_mat4(GPUBatch *batch, const char *name, const float data[
glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data);
}
-static void *elem_offset(const GPUIndexBuf *el, int v_first)
-{
-#if GPU_TRACK_INDEX_RANGE
- if (el->index_type == GPU_INDEX_U16) {
- return (GLushort *)0 + v_first + el->index_start;
- }
-#endif
- return (GLuint *)0 + v_first + el->index_start;
-}
-
/* Use when drawing with GPU_batch_draw_advanced */
void GPU_batch_bind(GPUBatch *batch)
{
@@ -704,90 +694,13 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
return;
}
- /* Verify there is enough data do draw. */
- /* TODO(fclem) Nice to have but this is invalid when using procedural draw-calls.
- * The right assert would be to check if there is an enabled attribute from each VBO
- * and check their length. */
- // BLI_assert(i_first + i_count <= (batch->inst ? batch->inst->vertex_len : INT_MAX));
- // BLI_assert(v_first + v_count <=
- // (batch->elem ? batch->elem->index_len : batch->verts[0]->vertex_len));
-
-#ifdef __APPLE__
- GLuint vao = 0;
-#endif
-
- if (!GPU_arb_base_instance_is_supported()) {
- if (i_first > 0) {
-#ifdef __APPLE__
- /**
- * There seems to be a nasty bug when drawing using the same VAO reconfiguring. (see T71147)
- * We just use a throwaway VAO for that. Note that this is likely to degrade performance.
- **/
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
-#else
- /* If using offset drawing with instancing, we must
- * use the default VAO and redo bindings. */
- glBindVertexArray(GPU_vao_default());
-#endif
- batch_update_program_bindings(batch, i_first);
- }
- else {
- /* Previous call could have bind the default vao
- * see above. */
- glBindVertexArray(batch->vao_id);
- }
- }
-
- if (batch->elem) {
- const GPUIndexBuf *el = batch->elem;
- GLenum index_type = INDEX_TYPE(el);
- GLint base_index = BASE_INDEX(el);
- void *v_first_ofs = elem_offset(el, v_first);
-
- if (GPU_arb_base_instance_is_supported()) {
- glDrawElementsInstancedBaseVertexBaseInstance(
- batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index, i_first);
- }
- else {
- glDrawElementsInstancedBaseVertex(
- batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index);
- }
- }
- else {
-#ifdef __APPLE__
- glDisable(GL_PRIMITIVE_RESTART);
-#endif
- if (GPU_arb_base_instance_is_supported()) {
- glDrawArraysInstancedBaseInstance(batch->gl_prim_type, v_first, v_count, i_count, i_first);
- }
- else {
- glDrawArraysInstanced(batch->gl_prim_type, v_first, v_count, i_count);
- }
-#ifdef __APPLE__
- glEnable(GL_PRIMITIVE_RESTART);
-#endif
- }
-
-#ifdef __APPLE__
- if (vao != 0) {
- glDeleteVertexArrays(1, &vao);
- }
-#endif
+ GPU_ctx()->draw_batch(batch, v_first, v_count, i_first, i_count);
}
/* just draw some vertices and let shader place them where we want. */
void GPU_draw_primitive(GPUPrimType prim_type, int v_count)
{
- /* we cannot draw without vao ... annoying ... */
- glBindVertexArray(GPU_vao_default());
-
- GLenum type = convert_prim_type_to_gl(prim_type);
- glDrawArrays(type, 0, v_count);
-
- /* Performance hog if you are drawing with the same vao multiple time.
- * Only activate for debugging.*/
- // glBindVertexArray(0);
+ GPU_ctx()->draw_primitive(prim_type, v_count);
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index 0b9104e5349..16e52cab0bd 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -35,137 +35,46 @@
#include "GPU_framebuffer.h"
#include "gpu_batch_private.h"
-#include "gpu_context_private.h"
+#include "gpu_context_private.hh"
#include "gpu_matrix_private.h"
+#include "gl_context.hh"
+
#include <mutex>
#include <pthread.h>
#include <string.h>
#include <unordered_set>
#include <vector>
-#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<GLuint> orphaned_buffer_ids;
-static std::vector<GLuint> orphaned_texture_ids;
-
-static std::mutex orphans_mutex;
-
-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;
- }
-};
+// TODO
+// using namespace blender::gpu;
static thread_local GPUContext *active_ctx = NULL;
-static void orphans_add(GPUContext *ctx, std::vector<GLuint> *orphan_list, GLuint id)
+GPUContext::GPUContext()
{
- std::mutex *mutex = (ctx) ? &ctx->orphans_mutex : &orphans_mutex;
-
- mutex->lock();
- orphan_list->emplace_back(id);
- mutex->unlock();
+ thread_ = pthread_self();
+ matrix_state = GPU_matrix_state_create();
}
-static void orphans_clear(GPUContext *ctx)
+GPUContext *GPU_context_create(GLuint)
{
- /* need at least an active context */
- BLI_assert(ctx);
-
- /* context has been activated by another thread! */
- BLI_assert(pthread_equal(pthread_self(), ctx->thread));
-
- 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();
- }
-
- 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 *ctx = new GLContext();
+ GPU_context_active_set(ctx);
+ return ctx;
}
-GPUContext *GPU_context_create(GLuint default_framebuffer)
+bool GPUContext::is_active_on_thread(void)
{
- /* BLI_assert(thread_is_main()); */
- GPUContext *ctx = new GPUContext;
- glGenVertexArrays(1, &ctx->default_vao);
- ctx->default_framebuffer = default_framebuffer;
- ctx->matrix_state = GPU_matrix_state_create();
- GPU_context_active_set(ctx);
- return ctx;
+ return (this == active_ctx) && pthread_equal(pthread_self(), thread_);
}
/* 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);
+ BLI_assert(ctx->is_active_on_thread());
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list