| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup gpu | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | /* TODO Create cmake option. */ | 
					
						
							|  |  |  | #define WITH_OPENGL_BACKEND 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | #include "BLI_assert.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #include "GPU_context.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | #include "GPU_framebuffer.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-06 04:30:38 +02:00
										 |  |  | #include "GHOST_C-api.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | #include "gpu_backend.hh"
 | 
					
						
							| 
									
										
										
										
											2020-08-09 01:21:34 +02:00
										 |  |  | #include "gpu_batch_private.hh"
 | 
					
						
							| 
									
										
										
										
											2020-08-08 03:01:45 +02:00
										 |  |  | #include "gpu_context_private.hh"
 | 
					
						
							| 
									
										
										
										
											2019-08-14 15:27:10 +02:00
										 |  |  | #include "gpu_matrix_private.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | #ifdef WITH_OPENGL_BACKEND
 | 
					
						
							|  |  |  | #  include "gl_backend.hh"
 | 
					
						
							|  |  |  | #  include "gl_context.hh"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | #include <mutex>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | using namespace blender::gpu; | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | static thread_local Context *active_ctx = NULL; | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | /** \name gpu::Context methods
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  |  * \{ */ | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | namespace blender::gpu { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Context::Context() | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   thread_ = pthread_self(); | 
					
						
							|  |  |  |   is_active_ = false; | 
					
						
							|  |  |  |   matrix_state = GPU_matrix_state_create(); | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | Context::~Context() | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  |   GPU_matrix_state_discard(matrix_state); | 
					
						
							| 
									
										
										
										
											2020-08-17 00:34:06 +02:00
										 |  |  |   delete state_manager; | 
					
						
							| 
									
										
										
										
											2020-08-31 15:13:26 +02:00
										 |  |  |   delete front_left; | 
					
						
							|  |  |  |   delete back_left; | 
					
						
							|  |  |  |   delete front_right; | 
					
						
							|  |  |  |   delete back_right; | 
					
						
							| 
									
										
										
										
											2020-08-31 15:14:47 +02:00
										 |  |  |   delete imm; | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | bool Context::is_active_on_thread() | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return (this == active_ctx) && pthread_equal(pthread_self(), thread_); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | Context *Context::get() | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return active_ctx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace blender::gpu
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | /** \} */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-06 04:30:38 +02:00
										 |  |  | GPUContext *GPU_context_create(void *ghost_window) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-08 15:24:52 +02:00
										 |  |  |   if (GPUBackend::get() == NULL) { | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  |     /* TODO move where it make sense. */ | 
					
						
							|  |  |  |     GPU_backend_init(GPU_BACKEND_OPENGL); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context *ctx = GPUBackend::get()->context_alloc(ghost_window); | 
					
						
							| 
									
										
										
										
											2020-08-06 04:30:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   GPU_context_active_set(wrap(ctx)); | 
					
						
							|  |  |  |   return wrap(ctx); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | /* to be called after GPU_context_active_set(ctx_to_destroy) */ | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | void GPU_context_discard(GPUContext *ctx_) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context *ctx = unwrap(ctx_); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   delete ctx; | 
					
						
							|  |  |  |   active_ctx = NULL; | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | /* ctx can be NULL */ | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  | void GPU_context_active_set(GPUContext *ctx_) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   Context *ctx = unwrap(ctx_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (active_ctx) { | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  |     active_ctx->deactivate(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   active_ctx = ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (ctx) { | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  |     ctx->activate(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-19 23:50:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 16:06:37 +10:00
										 |  |  | GPUContext *GPU_context_active_get(void) | 
					
						
							| 
									
										
										
										
											2018-07-17 14:46:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:12:12 +02:00
										 |  |  |   return wrap(Context::get()); | 
					
						
							| 
									
										
										
										
											2019-08-14 15:27:10 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Main context global mutex
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Used to avoid crash on some old drivers. | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static std::mutex main_context_mutex; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-05 15:26:49 +02:00
										 |  |  | void GPU_context_main_lock(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   main_context_mutex.lock(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GPU_context_main_unlock(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   main_context_mutex.unlock(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 01:18:18 +02:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-11 14:58:01 -04:00
										 |  |  |   /* TODO assert no resource left. Currently UI textures are still not freed in their context
 | 
					
						
							|  |  |  |    * correctly. */ | 
					
						
							|  |  |  |   delete g_backend; | 
					
						
							| 
									
										
										
										
											2020-09-08 10:40:30 +02:00
										 |  |  |   g_backend = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 13:18:48 +01:00
										 |  |  | GPUBackend *GPUBackend::get() | 
					
						
							| 
									
										
										
										
											2020-08-07 17:00:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return g_backend; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |