diff options
author | Julian Eisel <julian@blender.org> | 2020-06-23 18:19:00 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-06-23 18:28:53 +0300 |
commit | 2dd60e6c2cbdf3e39ed3451ee0f67a5b00a7a5bc (patch) | |
tree | f49fd69364dfe0a045c6df0081f51d559cefb80a /source | |
parent | 1e0426da7c735b5d59f23b2b9303d9c1d72ca7f8 (diff) |
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.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/windowmanager/intern/wm_surface.c | 14 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_surface.h | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/xr/intern/wm_xr_session.c | 6 |
3 files changed, 21 insertions, 4 deletions
diff --git a/source/blender/windowmanager/intern/wm_surface.c b/source/blender/windowmanager/intern/wm_surface.c index e8850693d69..12e55790259 100644 --- a/source/blender/windowmanager/intern/wm_surface.c +++ b/source/blender/windowmanager/intern/wm_surface.c @@ -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); diff --git a/source/blender/windowmanager/wm_surface.h b/source/blender/windowmanager/wm_surface.h index e1b00ae1ade..bc1cc825e4b 100644 --- a/source/blender/windowmanager/wm_surface.h +++ b/source/blender/windowmanager/wm_surface.h @@ -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 */ diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c index e9ff38c5a92..2f72b2b25a5 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_session.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c @@ -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(); |