Fix T77830: Crash in VR session when opening material preview
Draw-manager mutex has to be set before activating OpenGL/GPU context. Otherwise, parallel jobs (like preview rendering) may try to activate the context from another thread. Also: Use WM wrappers for activating/releasing OpenGL context, which have an additional assert check. Suggest to backport this for 2.83.1.
This commit is contained in:
parent
1e0426da7c
commit
2dd60e6c2c
Notes:
blender-bot
2023-02-14 07:31:32 +01:00
Referenced by issue #77830, Crash in VR Session when opening the Material Tab Referenced by issue #77348, Blender LTS: Maintenance Task 2.83
|
@ -53,10 +53,17 @@ void wm_surfaces_iter(bContext *C, void (*cb)(bContext *C, wmSurface *))
|
|||
void wm_surface_clear_drawable(void)
|
||||
{
|
||||
if (g_drawable) {
|
||||
WM_opengl_context_release(g_drawable->ghost_ctx);
|
||||
GPU_context_active_set(NULL);
|
||||
|
||||
BLF_batch_reset();
|
||||
gpu_batch_presets_reset();
|
||||
immDeactivate();
|
||||
|
||||
if (g_drawable->deactivate) {
|
||||
g_drawable->deactivate();
|
||||
}
|
||||
|
||||
g_drawable = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +74,10 @@ void wm_surface_set_drawable(wmSurface *surface, bool activate)
|
|||
|
||||
g_drawable = surface;
|
||||
if (activate) {
|
||||
GHOST_ActivateOpenGLContext(surface->ghost_ctx);
|
||||
if (surface->activate) {
|
||||
surface->activate();
|
||||
}
|
||||
WM_opengl_context_activate(surface->ghost_ctx);
|
||||
}
|
||||
|
||||
GPU_context_active_set(surface->gpu_ctx);
|
||||
|
@ -109,6 +119,8 @@ void wm_surface_remove(wmSurface *surface)
|
|||
|
||||
void wm_surfaces_free(void)
|
||||
{
|
||||
wm_surface_clear_drawable();
|
||||
|
||||
for (wmSurface *surf = global_surface_list.first, *surf_next; surf; surf = surf_next) {
|
||||
surf_next = surf->next;
|
||||
wm_surface_remove(surf);
|
||||
|
|
|
@ -38,6 +38,11 @@ typedef struct wmSurface {
|
|||
void (*draw)(struct bContext *);
|
||||
/** Free customdata, not the surface itself (done by wm_surface API) */
|
||||
void (*free_data)(struct wmSurface *);
|
||||
|
||||
/** Called when surface is activated for drawing (made drawable). */
|
||||
void (*activate)(void);
|
||||
/** Called when surface is deactivated for drawing (current drawable cleared). */
|
||||
void (*deactivate)(void);
|
||||
} wmSurface;
|
||||
|
||||
/* Create/Free */
|
||||
|
|
|
@ -315,12 +315,9 @@ static void wm_xr_session_surface_draw(bContext *C)
|
|||
wm_xr_session_draw_data_populate(
|
||||
&wm->xr, CTX_data_scene(C), CTX_data_ensure_evaluated_depsgraph(C), &draw_data);
|
||||
|
||||
DRW_xr_drawing_begin();
|
||||
|
||||
GHOST_XrSessionDrawViews(wm->xr.runtime->context, &draw_data);
|
||||
|
||||
GPU_offscreen_unbind(surface_data->offscreen, false);
|
||||
DRW_xr_drawing_end();
|
||||
}
|
||||
|
||||
bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data,
|
||||
|
@ -391,6 +388,9 @@ static wmSurface *wm_xr_session_surface_create(void)
|
|||
|
||||
surface->draw = wm_xr_session_surface_draw;
|
||||
surface->free_data = wm_xr_session_surface_free_data;
|
||||
surface->activate = DRW_xr_drawing_begin;
|
||||
surface->deactivate = DRW_xr_drawing_end;
|
||||
|
||||
surface->ghost_ctx = DRW_xr_opengl_context_get();
|
||||
surface->gpu_ctx = DRW_xr_gpu_context_get();
|
||||
|
||||
|
|
Loading…
Reference in New Issue