DRW: Move GPU context lock out of the DST variable.
This doesnt remove the locking but isolate the `GPUContext` lock to oustide the `DrawManager` class. This has no functional change. Pull Request: https://projects.blender.org/blender/blender/pulls/135189
This commit is contained in:
committed by
Clément Foucault
parent
1fc2daf3e2
commit
583e2b7240
@@ -81,6 +81,7 @@ struct DrawEngineType {
|
||||
};
|
||||
|
||||
/* Shaders */
|
||||
/** IMPORTANT: Modify the currently bound context. */
|
||||
void DRW_shader_init();
|
||||
void DRW_shader_exit();
|
||||
|
||||
|
||||
@@ -111,6 +111,26 @@
|
||||
|
||||
static CLG_LogRef LOG = {"draw.manager"};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Settings
|
||||
*
|
||||
* A global GPUContext is used for rendering every viewports (even on different windows).
|
||||
* This is because some resources cannot be shared between contexts (GPUFramebuffers, GPUBatch).
|
||||
* \{ */
|
||||
|
||||
/** Unique ghost context used by Viewports. */
|
||||
static void *system_gpu_context = nullptr;
|
||||
/** GPUContext associated to the system_gpu_context. */
|
||||
static GPUContext *blender_gpu_context = nullptr;
|
||||
/**
|
||||
* GPUContext cannot be used concurrently. This isn't required at the moment since viewports
|
||||
* aren't rendered in parallel but this could happen in the future. The old implementation of DRW
|
||||
* was also locking so this is a bit of a preventive measure. Could eventually be removed.
|
||||
*/
|
||||
static TicketMutex *system_gpu_context_mutex = nullptr;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** Render State: No persistent data between draw calls. */
|
||||
DRWManager DST = {nullptr};
|
||||
|
||||
@@ -121,7 +141,7 @@ static struct {
|
||||
|
||||
static void drw_state_prepare_clean_for_draw(DRWManager *dst)
|
||||
{
|
||||
memset(dst, 0x0, offsetof(DRWManager, system_gpu_context));
|
||||
memset(dst, 0x0, offsetof(DRWManager, debug));
|
||||
}
|
||||
|
||||
/* This function is used to reset draw manager to a state
|
||||
@@ -131,7 +151,7 @@ static void drw_state_prepare_clean_for_draw(DRWManager *dst)
|
||||
#ifndef NDEBUG
|
||||
static void drw_state_ensure_not_reused(DRWManager *dst)
|
||||
{
|
||||
memset(dst, 0xff, offsetof(DRWManager, system_gpu_context));
|
||||
memset(dst, 0xff, offsetof(DRWManager, debug));
|
||||
}
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
@@ -1128,7 +1148,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
|
||||
* Check for recursive lock which can deadlock. This should not
|
||||
* happen, but in case there is a bug where depsgraph update is called
|
||||
* during drawing we try not to hang Blender. */
|
||||
if (!BLI_ticket_mutex_lock_check_recursive(DST.system_gpu_context_mutex)) {
|
||||
if (!BLI_ticket_mutex_lock_check_recursive(system_gpu_context_mutex)) {
|
||||
CLOG_ERROR(&LOG, "GPU context already bound");
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
@@ -1168,7 +1188,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
|
||||
|
||||
drw_manager_exit(&DST);
|
||||
|
||||
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_unlock(system_gpu_context_mutex);
|
||||
}
|
||||
|
||||
/* update a viewport which belongs to a GPUOffscreen */
|
||||
@@ -2815,7 +2835,7 @@ void DRW_engines_free()
|
||||
using namespace blender::draw;
|
||||
drw_registered_engines_free();
|
||||
|
||||
if (DST.system_gpu_context == nullptr) {
|
||||
if (system_gpu_context == nullptr) {
|
||||
/* Nothing has been setup. Nothing to clear.
|
||||
* Otherwise, DRW_gpu_context_enable can
|
||||
* create a context in background mode. (see #62355) */
|
||||
@@ -2837,7 +2857,7 @@ void DRW_engines_free()
|
||||
|
||||
void DRW_render_context_enable(Render *render)
|
||||
{
|
||||
if (G.background && DST.system_gpu_context == nullptr) {
|
||||
if (G.background && system_gpu_context == nullptr) {
|
||||
WM_init_gpu();
|
||||
}
|
||||
|
||||
@@ -2895,57 +2915,61 @@ void DRW_render_context_disable(Render *render)
|
||||
|
||||
void DRW_gpu_context_create()
|
||||
{
|
||||
BLI_assert(DST.system_gpu_context == nullptr); /* Ensure it's called once */
|
||||
BLI_assert(system_gpu_context == nullptr); /* Ensure it's called once */
|
||||
|
||||
DST.system_gpu_context_mutex = BLI_ticket_mutex_alloc();
|
||||
/* This changes the active context. */
|
||||
DST.system_gpu_context = WM_system_gpu_context_create();
|
||||
WM_system_gpu_context_activate(DST.system_gpu_context);
|
||||
/* Be sure to create blender_gpu_context too. */
|
||||
DST.blender_gpu_context = GPU_context_create(nullptr, DST.system_gpu_context);
|
||||
/* Setup compilation context. */
|
||||
/* Setup compilation context. Called first as it changes the active GPUContext. */
|
||||
DRW_shader_init();
|
||||
/* Activate the window's context afterwards. */
|
||||
|
||||
system_gpu_context_mutex = BLI_ticket_mutex_alloc();
|
||||
/* This changes the active context. */
|
||||
system_gpu_context = WM_system_gpu_context_create();
|
||||
WM_system_gpu_context_activate(system_gpu_context);
|
||||
/* Be sure to create blender_gpu_context too. */
|
||||
blender_gpu_context = GPU_context_create(nullptr, system_gpu_context);
|
||||
/* Some part of the code assumes no context is left bound. */
|
||||
GPU_context_active_set(nullptr);
|
||||
WM_system_gpu_context_release(system_gpu_context);
|
||||
/* Activate the window's context if any. */
|
||||
wm_window_reset_drawable();
|
||||
}
|
||||
|
||||
void DRW_gpu_context_destroy()
|
||||
{
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
if (DST.system_gpu_context != nullptr) {
|
||||
if (system_gpu_context != nullptr) {
|
||||
DRW_shader_exit();
|
||||
WM_system_gpu_context_activate(DST.system_gpu_context);
|
||||
GPU_context_active_set(DST.blender_gpu_context);
|
||||
GPU_context_discard(DST.blender_gpu_context);
|
||||
WM_system_gpu_context_dispose(DST.system_gpu_context);
|
||||
BLI_ticket_mutex_free(DST.system_gpu_context_mutex);
|
||||
WM_system_gpu_context_activate(system_gpu_context);
|
||||
GPU_context_active_set(blender_gpu_context);
|
||||
GPU_context_discard(blender_gpu_context);
|
||||
WM_system_gpu_context_dispose(system_gpu_context);
|
||||
BLI_ticket_mutex_free(system_gpu_context_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_gpu_context_enable_ex(bool /*restore*/)
|
||||
{
|
||||
if (DST.system_gpu_context != nullptr) {
|
||||
if (system_gpu_context != nullptr) {
|
||||
/* IMPORTANT: We don't support immediate mode in render mode!
|
||||
* This shall remain in effect until immediate mode supports
|
||||
* multiple threads. */
|
||||
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_lock(system_gpu_context_mutex);
|
||||
GPU_render_begin();
|
||||
WM_system_gpu_context_activate(DST.system_gpu_context);
|
||||
GPU_context_active_set(DST.blender_gpu_context);
|
||||
GPU_context_begin_frame(DST.blender_gpu_context);
|
||||
WM_system_gpu_context_activate(system_gpu_context);
|
||||
GPU_context_active_set(blender_gpu_context);
|
||||
GPU_context_begin_frame(blender_gpu_context);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_gpu_context_disable_ex(bool restore)
|
||||
{
|
||||
if (DST.system_gpu_context != nullptr) {
|
||||
GPU_context_end_frame(DST.blender_gpu_context);
|
||||
if (system_gpu_context != nullptr) {
|
||||
GPU_context_end_frame(blender_gpu_context);
|
||||
|
||||
if (BLI_thread_is_main() && restore) {
|
||||
wm_window_reset_drawable();
|
||||
}
|
||||
else {
|
||||
WM_system_gpu_context_release(DST.system_gpu_context);
|
||||
WM_system_gpu_context_release(system_gpu_context);
|
||||
GPU_context_active_set(nullptr);
|
||||
}
|
||||
|
||||
@@ -2953,7 +2977,7 @@ void DRW_gpu_context_disable_ex(bool restore)
|
||||
* called outside of an existing render loop. */
|
||||
GPU_render_end();
|
||||
|
||||
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_unlock(system_gpu_context_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2961,7 +2985,7 @@ void DRW_gpu_context_enable()
|
||||
{
|
||||
/* TODO: should be replace by a more elegant alternative. */
|
||||
|
||||
if (G.background && DST.system_gpu_context == nullptr) {
|
||||
if (G.background && system_gpu_context == nullptr) {
|
||||
WM_init_gpu();
|
||||
}
|
||||
DRW_gpu_context_enable_ex(true);
|
||||
@@ -2977,16 +3001,14 @@ void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
|
||||
/* If thread is main you should use DRW_gpu_context_enable(). */
|
||||
BLI_assert(!BLI_thread_is_main());
|
||||
|
||||
/* TODO: get rid of the blocking. Only here because of the static global DST. */
|
||||
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_lock(system_gpu_context_mutex);
|
||||
WM_system_gpu_context_activate(re_system_gpu_context);
|
||||
}
|
||||
|
||||
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context)
|
||||
{
|
||||
WM_system_gpu_context_release(re_system_gpu_context);
|
||||
/* TODO: get rid of the blocking. */
|
||||
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_unlock(system_gpu_context_mutex);
|
||||
}
|
||||
|
||||
void DRW_blender_gpu_render_context_enable(void *re_gpu_context)
|
||||
@@ -3018,28 +3040,28 @@ void *DRW_system_gpu_context_get()
|
||||
* have to work from the main thread, which is tricky to get working too. The preferable solution
|
||||
* would be using a separate thread for VR drawing where a single context can stay active. */
|
||||
|
||||
return DST.system_gpu_context;
|
||||
return system_gpu_context;
|
||||
}
|
||||
|
||||
void *DRW_xr_blender_gpu_context_get()
|
||||
{
|
||||
/* XXX: See comment on #DRW_system_gpu_context_get(). */
|
||||
|
||||
return DST.blender_gpu_context;
|
||||
return blender_gpu_context;
|
||||
}
|
||||
|
||||
void DRW_xr_drawing_begin()
|
||||
{
|
||||
/* XXX: See comment on #DRW_system_gpu_context_get(). */
|
||||
|
||||
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_lock(system_gpu_context_mutex);
|
||||
}
|
||||
|
||||
void DRW_xr_drawing_end()
|
||||
{
|
||||
/* XXX: See comment on #DRW_system_gpu_context_get(). */
|
||||
|
||||
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
|
||||
BLI_ticket_mutex_unlock(system_gpu_context_mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3095,7 +3117,7 @@ bool DRW_gpu_context_release()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GPU_context_active_get() != DST.blender_gpu_context) {
|
||||
if (GPU_context_active_get() != blender_gpu_context) {
|
||||
/* Context release is requested from the outside of the draw manager main draw loop, indicate
|
||||
* this to the `DRW_gpu_context_activate()` so that it restores drawable of the window.
|
||||
*/
|
||||
@@ -3103,7 +3125,7 @@ bool DRW_gpu_context_release()
|
||||
}
|
||||
|
||||
GPU_context_active_set(nullptr);
|
||||
WM_system_gpu_context_release(DST.system_gpu_context);
|
||||
WM_system_gpu_context_release(system_gpu_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3115,8 +3137,8 @@ void DRW_gpu_context_activate(bool drw_state)
|
||||
}
|
||||
|
||||
if (drw_state) {
|
||||
WM_system_gpu_context_activate(DST.system_gpu_context);
|
||||
GPU_context_active_set(DST.blender_gpu_context);
|
||||
WM_system_gpu_context_activate(system_gpu_context);
|
||||
GPU_context_active_set(blender_gpu_context);
|
||||
}
|
||||
else {
|
||||
wm_window_reset_drawable();
|
||||
|
||||
@@ -139,14 +139,6 @@ struct DRWManager {
|
||||
|
||||
/* ---------- Nothing after this point is cleared after use ----------- */
|
||||
|
||||
/* system_gpu_context serves as the offset for clearing only
|
||||
* the top portion of the struct so DO NOT MOVE IT! */
|
||||
/** Unique ghost context used by the draw manager. */
|
||||
void *system_gpu_context;
|
||||
GPUContext *blender_gpu_context;
|
||||
/** Mutex to lock the drw manager and avoid concurrent context usage. */
|
||||
TicketMutex *system_gpu_context_mutex;
|
||||
|
||||
DRWDebugModule *debug;
|
||||
};
|
||||
|
||||
|
||||
@@ -193,9 +193,10 @@ void DRW_shader_init()
|
||||
compiler_data().system_gpu_context = WM_system_gpu_context_create();
|
||||
compiler_data().blender_gpu_context = GPU_context_create(nullptr,
|
||||
compiler_data().system_gpu_context);
|
||||
|
||||
/* Some part of the code assumes no context is left bound. */
|
||||
GPU_context_active_set(nullptr);
|
||||
WM_system_gpu_context_activate(DST.system_gpu_context);
|
||||
GPU_context_active_set(DST.blender_gpu_context);
|
||||
WM_system_gpu_context_release(compiler_data().system_gpu_context);
|
||||
|
||||
BLI_threadpool_init(&compilation_threadpool(), drw_deferred_shader_compilation_exec, 1);
|
||||
BLI_threadpool_insert(&compilation_threadpool(), nullptr);
|
||||
|
||||
Reference in New Issue
Block a user