diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2019-06-28 14:28:53 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2019-06-28 14:38:34 +0300 |
commit | cf4799e299b89fb9fb7d4b1293e0074c2b1dd6ae (patch) | |
tree | 4488f5d56186e013d6f7622d361392ecff6a8c9a /source/blender/windowmanager/intern/wm_xr.c | |
parent | 57d9f004aa55ecb0f564b2e4199a1821d69fbbc6 (diff) |
Add wmSurface for non-Window offscreen VR session drawing
Adds a wmSurface type which acts as a container for non-Window (offscreen)
draw surfaces. Ideally wmWindow would of course also just do C-style
inheritance from wmSurface, but I guess they can co-exist too.
For the VR session a surface is created on Linux and passed to the
graphics binding to use.
Note this is not used on Windows yet, it still opens a window there.
Diffstat (limited to 'source/blender/windowmanager/intern/wm_xr.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_xr.c | 106 |
1 files changed, 103 insertions, 3 deletions
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c index 3a6f181eafa..e02aee7beb2 100644 --- a/source/blender/windowmanager/intern/wm_xr.c +++ b/source/blender/windowmanager/intern/wm_xr.c @@ -22,15 +22,115 @@ #include "GHOST_C-api.h" +#include "GPU_context.h" +#include "GPU_draw.h" + +#include "MEM_guardedalloc.h" + #include "WM_types.h" #include "WM_api.h" #include "wm.h" +#include "wm_window.h" +#include "wm_surface.h" + +static wmSurface *global_xr_surface = NULL; + +typedef struct { + GHOST_TXrGraphicsBinding gpu_binding_type; +} XrSurfaceData; + +bool wm_xr_context_ensure(wmWindowManager *wm) +{ + if (wm->xr_context) { + return true; + } + + const GHOST_TXrGraphicsBinding gpu_bindings_candidates[] = { + GHOST_kXrGraphicsOpenGL, +#ifdef WIN32 + GHOST_kXrGraphicsD3D11, +#endif + }; + const GHOST_XrContextCreateInfo create_info = { + .gpu_binding_candidates = gpu_bindings_candidates, + .gpu_binding_candidates_count = ARRAY_SIZE(gpu_bindings_candidates)}; + + wm->xr_context = GHOST_XrContextCreate(&create_info); -void wm_xr_session_draw(bContext *C, struct GHOST_XrContext *xr_context) + return wm->xr_context != NULL; +} + +static void wm_xr_session_surface_draw(bContext *C) { - if (!GHOST_XrSessionIsRunning(xr_context)) { + wmWindowManager *wm = CTX_wm_manager(C); + + if (!GHOST_XrSessionIsRunning(wm->xr_context)) { return; } - GHOST_XrSessionDrawViews(xr_context, C); + GHOST_XrSessionDrawViews(wm->xr_context, C); +} + +static void wm_xr_session_free_data(wmSurface *surface) +{ + WM_opengl_context_dispose(surface->ghost_ctx); + GPU_context_active_set(surface->gpu_ctx); + GPU_context_discard(surface->gpu_ctx); + MEM_freeN(surface->customdata); + + global_xr_surface = NULL; +} + +wmSurface *wm_xr_session_surface_create(wmWindowManager *wm, unsigned int gpu_binding_type) +{ + if (global_xr_surface) { + BLI_assert(false); + return global_xr_surface; + } + + wmSurface *surface = MEM_callocN(sizeof(*surface), __func__); + XrSurfaceData *data = MEM_callocN(sizeof(*data), "XrSurfaceData"); + unsigned int default_fb; + +#ifndef WIN32 + BLI_assert(gpu_binding_type == GHOST_kXrGraphicsOpenGL); +#endif + + surface->draw = wm_xr_session_surface_draw; + surface->free_data = wm_xr_session_free_data; + + data->gpu_binding_type = gpu_binding_type; + surface->customdata = data; + + wm_window_clear_drawable(wm); + wm_surface_clear_drawable(); + + switch (gpu_binding_type) { + case GHOST_kXrGraphicsOpenGL: + surface->ghost_ctx = WM_opengl_context_create(); + WM_opengl_context_activate(surface->ghost_ctx); + break; +#ifdef WIN32 + case GHOST_kXrGraphicsD3D11: + break; +#endif + } + + default_fb = GHOST_GetContextDefaultOpenGLFramebuffer(surface->ghost_ctx); + surface->gpu_ctx = GPU_context_create(default_fb); + + wm_surface_set_drawable(surface, false); + GHOST_SwapContextBuffers(surface->ghost_ctx); + GPU_state_init(); + + wm_surface_clear_drawable(); + + global_xr_surface = surface; + + return surface; +} + +wmSurface *wm_xr_session_surface_get(void) +{ + return global_xr_surface; } |