Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2019-06-28 14:28:53 +0300
committerJulian Eisel <eiseljulian@gmail.com>2019-06-28 14:38:34 +0300
commitcf4799e299b89fb9fb7d4b1293e0074c2b1dd6ae (patch)
tree4488f5d56186e013d6f7622d361392ecff6a8c9a /source/blender/windowmanager/intern/wm_xr.c
parent57d9f004aa55ecb0f564b2e4199a1821d69fbbc6 (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.c106
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;
}