From 5037dd8abdf9335e998141336d4e15f81580c491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 19 Jul 2018 15:48:13 +0200 Subject: GPU: Add GC to FBOs and UBOs and centralize all GCs GPUFrameBuffers were being free when no context was attached or in the wrong gl context. This make sure this does not happen again. You can now safely free any gl resource from any thread (well as long as it's not used anymore!). --- source/blender/draw/DRW_engine.h | 4 + source/blender/draw/intern/draw_manager.c | 20 +- source/blender/gpu/CMakeLists.txt | 6 +- source/blender/gpu/GPU_buffer_id.h | 53 ---- source/blender/gpu/GPU_material.h | 5 - source/blender/gpu/GPU_texture.h | 5 - source/blender/gpu/GPU_vertex_array_id.h | 55 ---- source/blender/gpu/intern/gpu_batch.c | 3 +- source/blender/gpu/intern/gpu_batch_private.h | 3 - source/blender/gpu/intern/gpu_buffer_id.cpp | 90 ------ source/blender/gpu/intern/gpu_context.cpp | 315 +++++++++++++++++++++ source/blender/gpu/intern/gpu_context_private.h | 68 +++++ source/blender/gpu/intern/gpu_element.c | 7 +- source/blender/gpu/intern/gpu_framebuffer.c | 15 +- source/blender/gpu/intern/gpu_immediate.c | 7 +- source/blender/gpu/intern/gpu_init_exit.c | 5 - source/blender/gpu/intern/gpu_material.c | 39 +-- source/blender/gpu/intern/gpu_private.h | 3 + source/blender/gpu/intern/gpu_shader.c | 2 + source/blender/gpu/intern/gpu_shader_interface.c | 6 +- source/blender/gpu/intern/gpu_texture.c | 58 +--- source/blender/gpu/intern/gpu_uniformbuffer.c | 7 +- source/blender/gpu/intern/gpu_vertex_array_id.cpp | 196 ------------- source/blender/gpu/intern/gpu_vertex_buffer.c | 8 +- source/blender/windowmanager/intern/wm_init_exit.c | 5 +- source/blender/windowmanager/intern/wm_window.c | 2 - 26 files changed, 458 insertions(+), 529 deletions(-) delete mode 100644 source/blender/gpu/GPU_buffer_id.h delete mode 100644 source/blender/gpu/GPU_vertex_array_id.h delete mode 100644 source/blender/gpu/intern/gpu_buffer_id.cpp create mode 100644 source/blender/gpu/intern/gpu_context.cpp create mode 100644 source/blender/gpu/intern/gpu_context_private.h delete mode 100644 source/blender/gpu/intern/gpu_vertex_array_id.cpp (limited to 'source/blender') diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index eb037d081e1..4d4b486d247 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -136,6 +136,10 @@ void DRW_opengl_context_destroy(void); void DRW_opengl_context_enable(void); void DRW_opengl_context_disable(void); +/* Never use this. Only for closing blender. */ +void DRW_opengl_context_enable_ex(bool restore); +void DRW_opengl_context_disable_ex(bool restore); + void DRW_opengl_render_context_enable(void *re_gl_context); void DRW_opengl_render_context_disable(void *re_gl_context); void DRW_gawain_render_context_enable(void *re_gpu_context); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2793410cd8e..cc4f8ec7947 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2374,21 +2374,21 @@ void DRW_opengl_context_destroy(void) } } -void DRW_opengl_context_enable(void) +void DRW_opengl_context_enable_ex(bool restore) { if (DST.gl_context != NULL) { /* IMPORTANT: We dont support immediate mode in render mode! * This shall remain in effect until immediate mode supports * multiple threads. */ BLI_ticket_mutex_lock(DST.gl_context_mutex); - if (BLI_thread_is_main()) { + if (BLI_thread_is_main() && restore) { if (!G.background) { immDeactivate(); } } WM_opengl_context_activate(DST.gl_context); GPU_context_active_set(DST.gpu_context); - if (BLI_thread_is_main()) { + if (BLI_thread_is_main() && restore) { if (!G.background) { immActivate(); } @@ -2397,7 +2397,7 @@ void DRW_opengl_context_enable(void) } } -void DRW_opengl_context_disable(void) +void DRW_opengl_context_disable_ex(bool restore) { if (DST.gl_context != NULL) { #ifdef __APPLE__ @@ -2406,7 +2406,7 @@ void DRW_opengl_context_disable(void) glFlush(); #endif - if (BLI_thread_is_main()) { + if (BLI_thread_is_main() && restore) { wm_window_reset_drawable(); } else { @@ -2418,6 +2418,16 @@ void DRW_opengl_context_disable(void) } } +void DRW_opengl_context_enable(void) +{ + DRW_opengl_context_enable_ex(true); +} + +void DRW_opengl_context_disable(void) +{ + DRW_opengl_context_disable_ex(true); +} + void DRW_opengl_render_context_enable(void *re_gl_context) { /* If thread is main you should use DRW_opengl_context_enable(). */ diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 58295ae9329..8273f3f1992 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -62,9 +62,9 @@ set(SRC intern/gpu_batch.c intern/gpu_batch_presets.c intern/gpu_batch_utils.c - intern/gpu_buffer_id.cpp intern/gpu_buffers.c intern/gpu_codegen.c + intern/gpu_context.cpp intern/gpu_debug.c intern/gpu_draw.c intern/gpu_element.c @@ -84,7 +84,6 @@ set(SRC intern/gpu_state.c intern/gpu_texture.c intern/gpu_uniformbuffer.c - intern/gpu_vertex_array_id.cpp intern/gpu_vertex_buffer.c intern/gpu_vertex_format.c intern/gpu_viewport.c @@ -113,7 +112,6 @@ set(SRC GPU_attr_binding.h GPU_basic_shader.h GPU_batch.h - GPU_buffer_id.h GPU_buffers.h GPU_common.h GPU_debug.h @@ -135,7 +133,6 @@ set(SRC GPU_state.h GPU_texture.h GPU_uniformbuffer.h - GPU_vertex_array_id.h GPU_vertex_buffer.h GPU_vertex_format.h GPU_viewport.h @@ -143,6 +140,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_primitive_private.h intern/gpu_private.h intern/gpu_select_private.h diff --git a/source/blender/gpu/GPU_buffer_id.h b/source/blender/gpu/GPU_buffer_id.h deleted file mode 100644 index 4615e9e2c66..00000000000 --- a/source/blender/gpu/GPU_buffer_id.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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. - * - * The Original Code is Copyright (C) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/GPU_buffer_id.h - * \ingroup gpu - * - * GPU buffer IDs - */ - -#ifndef __GPU_BUFFER_ID_H__ -#define __GPU_BUFFER_ID_H__ - -/* Manage GL buffer IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from main thread - * - free can be called from any thread */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "GPU_common.h" - -GLuint GPU_buf_id_alloc(void); -void GPU_buf_id_free(GLuint buffer_id); - -#ifdef __cplusplus -} -#endif - -#endif /* __GPU_BUFFER_ID_H__ */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 4e264defbd4..f2c029f643e 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -254,11 +254,6 @@ void GPU_material_free(struct ListBase *gpumaterial); void GPU_materials_free(struct Main *bmain); -void GPU_material_orphans_init(void); -void GPU_material_orphans_exit(void); -/* This has to be called from a thread with an ogl context bound. */ -void GPU_material_orphans_delete(void); - struct Scene *GPU_material_scene(GPUMaterial *material); GPUMatType GPU_Material_get_type(GPUMaterial *material); struct GPUPass *GPU_material_get_pass(GPUMaterial *material); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index e3db18f1358..1ddf801e166 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -198,11 +198,6 @@ void GPU_invalid_tex_free(void); void GPU_texture_free(GPUTexture *tex); -void GPU_texture_orphans_init(void); -void GPU_texture_orphans_exit(void); -/* This has to be called from a thread with an ogl context bound. */ -void GPU_texture_orphans_delete(void); - void GPU_texture_ref(GPUTexture *tex); void GPU_texture_bind(GPUTexture *tex, int number); void GPU_texture_unbind(GPUTexture *tex); diff --git a/source/blender/gpu/GPU_vertex_array_id.h b/source/blender/gpu/GPU_vertex_array_id.h deleted file mode 100644 index ff84a290a5a..00000000000 --- a/source/blender/gpu/GPU_vertex_array_id.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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. - * - * The Original Code is Copyright (C) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/GPU_vertex_array_id.h - * \ingroup gpu - * - * Manage GL vertex array IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from a thread that is bound - * to the context that will be used for drawing with - * this vao. - * - free can be called from any thread - */ - -#ifndef __GPU_VERTEX_ARRAY_ID_H__ -#define __GPU_VERTEX_ARRAY_ID_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "GPU_common.h" -#include "GPU_context.h" - -GLuint GPU_vao_default(void); -GLuint GPU_vao_alloc(void); -void GPU_vao_free(GLuint vao_id, GPUContext *); - -#ifdef __cplusplus -} -#endif - -#endif /* __GPU_VERTEX_ARRAY_ID_H__ */ diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index a11eefee078..9b433a37a72 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -32,12 +32,11 @@ #include "GPU_batch.h" #include "GPU_batch_presets.h" -#include "GPU_buffer_id.h" #include "GPU_matrix.h" #include "GPU_shader.h" -#include "GPU_vertex_array_id.h" #include "gpu_batch_private.h" +#include "gpu_context_private.h" #include "gpu_primitive_private.h" #include "gpu_shader_private.h" diff --git a/source/blender/gpu/intern/gpu_batch_private.h b/source/blender/gpu/intern/gpu_batch_private.h index 51040ff751a..3a05e243065 100644 --- a/source/blender/gpu/intern/gpu_batch_private.h +++ b/source/blender/gpu/intern/gpu_batch_private.h @@ -43,9 +43,6 @@ extern "C" { void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface); -void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch); -void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); - #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_buffer_id.cpp b/source/blender/gpu/intern/gpu_buffer_id.cpp deleted file mode 100644 index f3faba9c766..00000000000 --- a/source/blender/gpu/intern/gpu_buffer_id.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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. - * - * The Original Code is Copyright (C) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gpu_buffer_id.cpp - * \ingroup gpu - * - * GPU buffer IDs - */ - -#include "GPU_buffer_id.h" - -#include -#include - -#define ORPHAN_DEBUG 0 - -#if ORPHAN_DEBUG -# include -#endif - -static std::vector orphaned_buffer_ids; - -static std::mutex orphan_mutex; - -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(); -} - -GLuint GPU_buf_id_alloc() -{ - /* delete orphaned IDs */ - orphan_mutex.lock(); - if (!orphaned_buffer_ids.empty()) { - const auto orphaned_buffer_len = (uint)orphaned_buffer_ids.size(); -#if ORPHAN_DEBUG - printf("deleting %u orphaned VBO%s\n", orphaned_buffer_len, orphaned_buffer_len == 1 ? "" : "s"); -#endif - glDeleteBuffers(orphaned_buffer_len, orphaned_buffer_ids.data()); - orphaned_buffer_ids.clear(); - } - orphan_mutex.unlock(); - - GLuint new_buffer_id = 0; - glGenBuffers(1, &new_buffer_id); - return new_buffer_id; -} - -void GPU_buf_id_free(GLuint buffer_id) -{ - if (thread_is_main()) { - glDeleteBuffers(1, &buffer_id); - } - else { - /* add this ID to the orphaned list */ - orphan_mutex.lock(); -#if ORPHAN_DEBUG - printf("orphaning VBO %u\n", buffer_id); -#endif - orphaned_buffer_ids.emplace_back(buffer_id); - orphan_mutex.unlock(); - } -} diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp new file mode 100644 index 00000000000..6a42552c2fd --- /dev/null +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -0,0 +1,315 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gpu_vertex_array_id.cpp + * \ingroup gpu + * + * Manage GL vertex array IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from a thread that is bound + * to the context that will be used for drawing with + * this vao. + * - free can be called from any thread + */ + +#include "BLI_assert.h" +#include "BLI_utildefines.h" + +#include "GPU_context.h" +#include "GPU_framebuffer.h" + +#include "gpu_batch_private.h" +#include "gpu_context_private.h" + +#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; + +struct GPUContext { + GLuint default_vao; + 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 + 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; + + GPUContext() { + thread_is_used = false; + } +#endif +}; + +#if defined(_MSC_VER) && (_MSC_VER == 1800) +#define thread_local __declspec(thread) +thread_local GPUContext *active_ctx = NULL; +#else +static thread_local GPUContext *active_ctx = NULL; +#endif + +static void orphans_add(GPUContext *ctx, std::vector *orphan_list, GLuint id) +{ + std::mutex *mutex = (ctx) ? &ctx->orphans_mutex : &orphans_mutex; + + mutex->lock(); + orphan_list->emplace_back(id); + mutex->unlock(); +} + +static void orphans_clear(GPUContext *ctx) +{ + BLI_assert(ctx); /* need at least an active context */ + BLI_assert(pthread_equal(pthread_self(), ctx->thread)); /* context has been activated by another 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 *GPU_context_create(void) +{ + /* BLI_assert(thread_is_main()); */ + GPUContext *ctx = new GPUContext; + glGenVertexArrays(1, &ctx->default_vao); + GPU_context_active_set(ctx); + return ctx; +} + +/* 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()); + /* For now don't allow GPUFrameBuffers to be reuse in another ctx. */ + BLI_assert(ctx->framebuffers.empty()); + /* delete remaining vaos */ + while (!ctx->batches.empty()) { + /* this removes the array entry */ + GPU_batch_vao_cache_clear(*ctx->batches.begin()); + } + glDeleteVertexArrays(1, &ctx->default_vao); + delete ctx; + active_ctx = NULL; +} + +/* ctx can be NULL */ +void GPU_context_active_set(GPUContext *ctx) +{ +#if TRUST_NO_ONE + if (active_ctx) { + active_ctx->thread_is_used = false; + } + /* 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 + if (ctx) { + orphans_clear(ctx); + } + active_ctx = ctx; +} + +GPUContext *GPU_context_active_get(void) +{ + return active_ctx; +} + +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; +} + +GLuint GPU_vao_alloc(void) +{ + GLuint new_vao_id = 0; + orphans_clear(active_ctx); + glGenVertexArrays(1, &new_vao_id); + return new_vao_id; +} + +GLuint GPU_fbo_alloc(void) +{ + GLuint new_fbo_id = 0; + orphans_clear(active_ctx); + glGenFramebuffers(1, &new_fbo_id); + return new_fbo_id; +} + +GLuint GPU_buf_alloc(void) +{ + GLuint new_buffer_id = 0; + orphans_clear(active_ctx); + glGenBuffers(1, &new_buffer_id); + return new_buffer_id; +} + +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); + } +} + +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); + } +} + +void GPU_buf_free(GLuint buf_id) +{ + if (active_ctx) { + glDeleteBuffers(1, &buf_id); + } + else { + orphans_add(NULL, &orphaned_buffer_ids, 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); + } +} + +/* GPUBatch & GPUFrameBuffer contains respectively VAO & FBO indices + * which are not shared across contexts. So we need to keep track of + * ownership. */ + +void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch) +{ + BLI_assert(ctx); + ctx->orphans_mutex.lock(); + ctx->batches.emplace(batch); + ctx->orphans_mutex.unlock(); +} + +void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch) +{ + BLI_assert(ctx); + ctx->orphans_mutex.lock(); + ctx->batches.erase(batch); + ctx->orphans_mutex.unlock(); +} + +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(); +#else + UNUSED_VARS(ctx, fb); +#endif +} + +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(); +#else + UNUSED_VARS(ctx, fb); +#endif +} diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h new file mode 100644 index 00000000000..4881a892e38 --- /dev/null +++ b/source/blender/gpu/intern/gpu_context_private.h @@ -0,0 +1,68 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gpu_context_private.h + * \ingroup gpu + * + * This interface allow GPU to manage GL objects for mutiple context and threads. + */ + +#ifndef __GPU_CONTEXT_PRIVATE_H__ +#define __GPU_CONTEXT_PRIVATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "GPU_context.h" + +struct GPUFrameBuffer; + +GLuint GPU_vao_default(void); + +/* These require a gl ctx bound. */ +GLuint GPU_buf_alloc(void); +GLuint GPU_tex_alloc(void); +GLuint GPU_vao_alloc(void); +GLuint GPU_fbo_alloc(void); + +/* These can be called any threads even without gl ctx. */ +void GPU_buf_free(GLuint buf_id); +void GPU_tex_free(GLuint tex_id); +/* These two need the ctx the id was created with. */ +void GPU_vao_free(GLuint vao_id, GPUContext *ctx); +void GPU_fbo_free(GLuint fbo_id, GPUContext *ctx); + +void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch); +void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); + +void gpu_context_add_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); +void gpu_context_remove_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); + +#ifdef __cplusplus +} +#endif + +#endif /* __GPU_CONTEXT_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 9abfed2db05..901e09443d1 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -30,7 +30,8 @@ */ #include "GPU_element.h" -#include "GPU_buffer_id.h" + +#include "gpu_context_private.h" #include @@ -279,7 +280,7 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) #endif if (elem->vbo_id == 0) { - elem->vbo_id = GPU_buf_id_alloc(); + elem->vbo_id = GPU_buf_alloc(); } /* send data to GPU */ /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, @@ -302,7 +303,7 @@ void GPU_indexbuf_use(GPUIndexBuf *elem) void GPU_indexbuf_discard(GPUIndexBuf *elem) { if (elem->vbo_id) { - GPU_buf_id_free(elem->vbo_id); + GPU_buf_free(elem->vbo_id); } free(elem); } diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index d28b82ac3cd..ba8dcb04269 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -42,7 +42,8 @@ #include "GPU_shader.h" #include "GPU_texture.h" -#include "intern/gpu_private.h" +#include "gpu_private.h" +#include "gpu_context_private.h" static ThreadLocal(void *) g_currentfb; @@ -69,6 +70,7 @@ typedef enum { #define GPU_FB_ATTACHEMENT_SET_DIRTY(flag, type) (flag |= (1 << type)) struct GPUFrameBuffer { + GPUContext *ctx; GLuint object; GPUAttachment attachments[GPU_FB_MAX_ATTACHEMENT]; uint16_t dirty_flag; @@ -196,7 +198,9 @@ GPUFrameBuffer *GPU_framebuffer_create(void) static void gpu_framebuffer_init(GPUFrameBuffer *fb) { - glGenFramebuffers(1, &fb->object); + fb->object = GPU_fbo_alloc(); + fb->ctx = GPU_context_active_get(); + gpu_context_add_framebuffer(fb->ctx, fb); } void GPU_framebuffer_free(GPUFrameBuffer *fb) @@ -207,8 +211,11 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb) } } - /* This restores the framebuffer if it was bound */ - glDeleteFramebuffers(1, &fb->object); + if (fb->object != 0) { + /* This restores the framebuffer if it was bound */ + GPU_fbo_free(fb->object, fb->ctx); + gpu_context_remove_framebuffer(fb->ctx, fb); + } if (gpu_framebuffer_current_get() == fb->object) { gpu_framebuffer_current_set(0); diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 66a467e339e..9674cf0b9f7 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -32,11 +32,10 @@ #include "UI_resources.h" #include "GPU_attr_binding.h" -#include "GPU_buffer_id.h" #include "GPU_immediate.h" -#include "GPU_vertex_array_id.h" #include "gpu_attr_binding_private.h" +#include "gpu_context_private.h" #include "gpu_primitive_private.h" #include "gpu_shader_private.h" #include "gpu_vertex_format_private.h" @@ -91,7 +90,7 @@ void immInit(void) #endif memset(&imm, 0, sizeof(Immediate)); - imm.vbo_id = GPU_buf_id_alloc(); + imm.vbo_id = GPU_buf_alloc(); glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); @@ -127,7 +126,7 @@ void immDeactivate(void) void immDestroy(void) { - GPU_buf_id_free(imm.vbo_id); + GPU_buf_free(imm.vbo_id); initialized = false; } diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 78d4f491b66..55d0466c929 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -57,8 +57,6 @@ void GPU_init(void) gpu_extensions_init(); /* must come first */ - GPU_texture_orphans_init(); - GPU_material_orphans_init(); gpu_codegen_init(); gpu_framebuffer_module_init(); @@ -84,9 +82,6 @@ void GPU_exit(void) gpu_batch_exit(); - GPU_texture_orphans_exit(); - GPU_material_orphans_exit(); - if (G.debug & G_DEBUG_GPU) gpu_debug_exit(); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9566f091ada..92aff91da32 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -75,9 +75,6 @@ # include "BKE_DerivedMesh.h" #endif -static ListBase g_orphaned_mat = {NULL, NULL}; -static ThreadMutex g_orphan_lock; - /* Structs */ struct GPUMaterial { @@ -175,44 +172,12 @@ void GPU_material_free(ListBase *gpumaterial) { for (LinkData *link = gpumaterial->first; link; link = link->next) { GPUMaterial *material = link->data; - - /* TODO(fclem): Check if the thread has an ogl context. */ - if (BLI_thread_is_main()) { - gpu_material_free_single(material); - MEM_freeN(material); - } - else { - BLI_mutex_lock(&g_orphan_lock); - BLI_addtail(&g_orphaned_mat, BLI_genericNodeN(material)); - BLI_mutex_unlock(&g_orphan_lock); - } + gpu_material_free_single(material); + MEM_freeN(material); } BLI_freelistN(gpumaterial); } -void GPU_material_orphans_init(void) -{ - BLI_mutex_init(&g_orphan_lock); -} - -void GPU_material_orphans_delete(void) -{ - BLI_mutex_lock(&g_orphan_lock); - LinkData *link; - while ((link = BLI_pophead(&g_orphaned_mat))) { - gpu_material_free_single((GPUMaterial *)link->data); - MEM_freeN(link->data); - MEM_freeN(link); - } - BLI_mutex_unlock(&g_orphan_lock); -} - -void GPU_material_orphans_exit(void) -{ - GPU_material_orphans_delete(); - BLI_mutex_end(&g_orphan_lock); -} - GPUBuiltin GPU_get_material_builtins(GPUMaterial *material) { return material->builtins; diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h index 996ba9c63a1..df55f7922b3 100644 --- a/source/blender/gpu/intern/gpu_private.h +++ b/source/blender/gpu/intern/gpu_private.h @@ -25,6 +25,9 @@ #ifndef __GPU_PRIVATE_H__ #define __GPU_PRIVATE_H__ +struct GPUContext; +struct GPUFrameBuffer; + /* call this before running any of the functions below */ void gpu_extensions_init(void); void gpu_extensions_exit(void); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 1eae073d9c0..04b43d03c83 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -38,6 +38,7 @@ #include "DNA_space_types.h" #include "GPU_extensions.h" +#include "GPU_context.h" #include "GPU_matrix.h" #include "GPU_shader.h" #include "GPU_texture.h" @@ -572,6 +573,7 @@ void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) void GPU_shader_free(GPUShader *shader) { + BLI_assert(GPU_context_active_get() != NULL); BLI_assert(shader); if (shader->vertex) diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index 4b8413d0cc3..54c5f41bbd3 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -29,9 +29,11 @@ * GPU shader interface (C --> GLSL) */ -#include "gpu_batch_private.h" #include "GPU_shader_interface.h" -#include "GPU_vertex_array_id.h" + +#include "gpu_batch_private.h" +#include "gpu_context_private.h" + #include #include #include diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 4465136dd0f..5ac746ec9c1 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -38,22 +38,22 @@ #include "BKE_global.h" #include "GPU_batch.h" +#include "GPU_context.h" #include "GPU_debug.h" #include "GPU_draw.h" #include "GPU_extensions.h" -#include "GPU_framebuffer.h" #include "GPU_glew.h" +#include "GPU_framebuffer.h" #include "GPU_texture.h" +#include "gpu_context_private.h" + static struct GPUTextureGlobal { GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */ GPUTexture *invalid_tex_2D; GPUTexture *invalid_tex_3D; } GG = {NULL, NULL, NULL}; -static ListBase g_orphaned_tex = {NULL, NULL}; -static ThreadMutex g_orphan_lock; - /* Maximum number of FBOs a texture can be attached to. */ #define GPU_TEX_MAX_FBO_ATTACHED 8 @@ -535,7 +535,7 @@ GPUTexture *GPU_texture_create_nD( gpu_texture_memory_footprint_add(tex); /* Generate Texture object */ - glGenTextures(1, &tex->bindcode); + tex->bindcode = GPU_tex_alloc(); if (!tex->bindcode) { if (err_out) @@ -668,7 +668,7 @@ static GPUTexture *GPU_texture_cube_create( gpu_texture_memory_footprint_add(tex); /* Generate Texture object */ - glGenTextures(1, &tex->bindcode); + tex->bindcode = GPU_tex_alloc(); if (!tex->bindcode) { if (err_out) @@ -752,7 +752,7 @@ GPUTexture *GPU_texture_create_buffer(GPUTextureFormat tex_format, const GLuint } /* Generate Texture object */ - glGenTextures(1, &tex->bindcode); + tex->bindcode = GPU_tex_alloc(); if (!tex->bindcode) { fprintf(stderr, "GPUTexture: texture create failed\n"); @@ -1301,17 +1301,6 @@ void GPU_texture_filters(GPUTexture *tex, GPUFilterFunction min_filter, GPUFilte glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, gpu_get_gl_filterfunction(mag_filter)); } - -static void gpu_texture_delete(GPUTexture *tex) -{ - if (tex->bindcode) - glDeleteTextures(1, &tex->bindcode); - - gpu_texture_memory_footprint_remove(tex); - - MEM_freeN(tex); -} - void GPU_texture_free(GPUTexture *tex) { tex->refcount--; @@ -1326,38 +1315,13 @@ void GPU_texture_free(GPUTexture *tex) } } - /* TODO(fclem): Check if the thread has an ogl context. */ - if (BLI_thread_is_main()) { - gpu_texture_delete(tex); - } - else { - BLI_mutex_lock(&g_orphan_lock); - BLI_addtail(&g_orphaned_tex, BLI_genericNodeN(tex)); - BLI_mutex_unlock(&g_orphan_lock); - } - } -} + if (tex->bindcode) + GPU_tex_free(tex->bindcode); -void GPU_texture_orphans_init(void) -{ - BLI_mutex_init(&g_orphan_lock); -} + gpu_texture_memory_footprint_remove(tex); -void GPU_texture_orphans_delete(void) -{ - BLI_mutex_lock(&g_orphan_lock); - LinkData *link; - while ((link = BLI_pophead(&g_orphaned_tex))) { - gpu_texture_delete((GPUTexture *)link->data); - MEM_freeN(link); + MEM_freeN(tex); } - BLI_mutex_unlock(&g_orphan_lock); -} - -void GPU_texture_orphans_exit(void) -{ - GPU_texture_orphans_delete(); - BLI_mutex_end(&g_orphan_lock); } void GPU_texture_ref(GPUTexture *tex) diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c index 1e39b2ea5b7..9b8441efd08 100644 --- a/source/blender/gpu/intern/gpu_uniformbuffer.c +++ b/source/blender/gpu/intern/gpu_uniformbuffer.c @@ -35,6 +35,7 @@ #include "BLI_blenlib.h" #include "gpu_codegen.h" +#include "gpu_context_private.h" #include "GPU_extensions.h" #include "GPU_glew.h" @@ -88,7 +89,7 @@ GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_ ubo->bindpoint = -1; /* Generate Buffer object */ - glGenBuffers(1, &ubo->bindcode); + ubo->bindcode = GPU_buf_alloc(); if (!ubo->bindcode) { if (err_out) @@ -127,7 +128,7 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou ubo->flag = GPU_UBO_FLAG_DIRTY; /* Generate Buffer object. */ - glGenBuffers(1, &ubo->buffer.bindcode); + ubo->buffer.bindcode = GPU_buf_alloc(); if (!ubo->buffer.bindcode) { if (err_out) @@ -190,7 +191,7 @@ void GPU_uniformbuffer_free(GPUUniformBuffer *ubo) gpu_uniformbuffer_dynamic_free(ubo); } - glDeleteBuffers(1, &ubo->bindcode); + GPU_buf_free(ubo->bindcode); MEM_freeN(ubo); } diff --git a/source/blender/gpu/intern/gpu_vertex_array_id.cpp b/source/blender/gpu/intern/gpu_vertex_array_id.cpp deleted file mode 100644 index 64f704bb107..00000000000 --- a/source/blender/gpu/intern/gpu_vertex_array_id.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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. - * - * The Original Code is Copyright (C) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation, Clément Foucault - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gpu_vertex_array_id.cpp - * \ingroup gpu - * - * Manage GL vertex array IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from a thread that is bound - * to the context that will be used for drawing with - * this vao. - * - free can be called from any thread - */ - -#include "gpu_batch_private.h" -#include "GPU_vertex_array_id.h" -#include "GPU_context.h" -#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 - -struct GPUContext { - GLuint default_vao; - std::unordered_set batches; /* Batches that have VAOs from this context */ - std::vector orphaned_vertarray_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; - - GPUContext() { - thread_is_used = false; - } -#endif -}; - -#if defined(_MSC_VER) && (_MSC_VER == 1800) -#define thread_local __declspec(thread) -thread_local GPUContext *active_ctx = NULL; -#else -static thread_local GPUContext *active_ctx = NULL; -#endif - -static void clear_orphans(GPUContext *ctx) -{ - 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(); - } - ctx->orphans_mutex.unlock(); -} - -GPUContext *GPU_context_create(void) -{ -#if TRUST_NO_ONE - /* assert(thread_is_main()); */ -#endif - GPUContext *ctx = new GPUContext; - glGenVertexArrays(1, &ctx->default_vao); - GPU_context_active_set(ctx); - return ctx; -} - -/* to be called after GPU_context_active_set(ctx_to_destroy) */ -void GPU_context_discard(GPUContext *ctx) -{ -#if TRUST_NO_ONE - /* Make sure no other thread has locked it. */ - assert(ctx == active_ctx); - assert(pthread_equal(pthread_self(), ctx->thread)); - assert(ctx->orphaned_vertarray_ids.empty()); -#endif - /* delete remaining vaos */ - while (!ctx->batches.empty()) { - /* this removes the array entry */ - GPU_batch_vao_cache_clear(*ctx->batches.begin()); - } - glDeleteVertexArrays(1, &ctx->default_vao); - delete ctx; - active_ctx = NULL; -} - -/* ctx can be NULL */ -void GPU_context_active_set(GPUContext *ctx) -{ -#if TRUST_NO_ONE - if (active_ctx) { - active_ctx->thread_is_used = false; - } - /* 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 - if (ctx) { - clear_orphans(ctx); - } - active_ctx = ctx; -} - -GPUContext *GPU_context_active_get(void) -{ - return active_ctx; -} - -GLuint GPU_vao_default(void) -{ -#if TRUST_NO_ONE - assert(active_ctx); /* need at least an active context */ - assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ -#endif - return active_ctx->default_vao; -} - -GLuint GPU_vao_alloc(void) -{ -#if TRUST_NO_ONE - assert(active_ctx); /* need at least an active context */ - assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ -#endif - clear_orphans(active_ctx); - - GLuint new_vao_id = 0; - glGenVertexArrays(1, &new_vao_id); - return new_vao_id; -} - -/* this can be called from multiple thread */ -void GPU_vao_free(GLuint vao_id, GPUContext *ctx) -{ -#if TRUST_NO_ONE - assert(ctx); -#endif - if (ctx == active_ctx) { - glDeleteVertexArrays(1, &vao_id); - } - else { - ctx->orphans_mutex.lock(); - ctx->orphaned_vertarray_ids.emplace_back(vao_id); - ctx->orphans_mutex.unlock(); - } -} - -void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch) -{ - ctx->batches.emplace(batch); -} - -void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch) -{ - ctx->orphans_mutex.lock(); - ctx->batches.erase(batch); - ctx->orphans_mutex.unlock(); -} diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index b25d9fc3a2c..d605378bf0e 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -30,8 +30,10 @@ */ #include "GPU_vertex_buffer.h" -#include "GPU_buffer_id.h" + +#include "gpu_context_private.h" #include "gpu_vertex_format_private.h" + #include #include @@ -88,7 +90,7 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts, const GPUVertFormat *for void GPU_vertbuf_discard(GPUVertBuf *verts) { if (verts->vbo_id) { - GPU_buf_id_free(verts->vbo_id); + GPU_buf_free(verts->vbo_id); #if VRAM_USAGE vbo_memory_usage -= GPU_vertbuf_size_get(verts); #endif @@ -117,7 +119,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) #endif /* only create the buffer the 1st time */ if (verts->vbo_id == 0) { - verts->vbo_id = GPU_buf_id_alloc(); + verts->vbo_id = GPU_buf_alloc(); } /* discard previous data if any */ if (verts->data) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 0c7c85e0d94..f7d6561e17f 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -119,6 +119,7 @@ #include "GPU_material.h" #include "GPU_draw.h" +#include "GPU_immediate.h" #include "GPU_init_exit.h" #include "BKE_sound.h" @@ -515,9 +516,11 @@ void WM_exit_ext(bContext *C, const bool do_python) BLF_exit(); if (opengl_is_init) { + DRW_opengl_context_enable_ex(false); GPU_pass_cache_free(); - DRW_opengl_context_destroy(); GPU_exit(); + DRW_opengl_context_disable_ex(false); + DRW_opengl_context_destroy(); } #ifdef WITH_INTERNATIONAL diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index b87ae7e076c..c1006db34ef 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1921,8 +1921,6 @@ void wm_window_raise(wmWindow *win) void wm_window_swap_buffers(wmWindow *win) { - GPU_texture_orphans_delete(); /* XXX should be done elsewhere. */ - GPU_material_orphans_delete(); /* XXX Amen to that. */ GHOST_SwapWindowBuffers(win->ghostwin); } -- cgit v1.2.3