[Bf-blender-cvs] [231dbd53bf3] soc-2019-openxr: Support Window-less (offscreen) VR session on Windows

Julian Eisel noreply at git.blender.org
Fri Jun 28 16:44:46 CEST 2019


Commit: 231dbd53bf30f59c0dfc8cd928e0e046c57d87d2
Author: Julian Eisel
Date:   Fri Jun 28 16:24:24 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB231dbd53bf30f59c0dfc8cd928e0e046c57d87d2

Support Window-less (offscreen) VR session on Windows

Uses the new wmSurface type (non-window drawable container) to manage
the OpenGL, DirectX and GPU module contexts. The draw callback of the XR
surface calls the GHOST_Xr session drawing routines.

What you should see when starting a VR session now (using the WMR
runtime): The Windows Mixed Reality Portal pops up, and a blue
background is drawn on the HMD. This is from the blue color clear call
we do in the drawing preparations of the GHOST_Xr session drawing.

===================================================================

M	intern/ghost/GHOST_C-api.h
M	intern/ghost/GHOST_ISystem.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_System.cpp
M	intern/ghost/intern/GHOST_System.h
M	release/scripts/addons
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/intern/wm_window.c
M	source/blender/windowmanager/intern/wm_xr.c
M	source/blender/windowmanager/wm_surface.h
M	source/tools

===================================================================

diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index a7fcb46211c..305c6ce5282 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -193,6 +193,25 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha
 extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
                                                  GHOST_ContextHandle contexthandle);
 
+#ifdef WIN32
+/**
+ * Create a new offscreen context.
+ * Never explicitly delete the context, use disposeContext() instead.
+ * \param systemhandle The handle to the system
+ * \return A handle to the new context ( == NULL if creation failed).
+ */
+GHOST_ContextHandle GHOST_CreateDirectXContext(GHOST_SystemHandle systemhandle);
+
+/**
+ * Dispose of a context.
+ * \param systemhandle The handle to the system
+ * \param contexthandle Handle to the context to be disposed.
+ * \return Indication of success.
+ */
+GHOST_TSuccess GHOST_DisposeDirectXContext(GHOST_SystemHandle systemhandle,
+                                           GHOST_ContextHandle contexthandle);
+#endif
+
 GHOST_TSuccess GHOST_BlitOpenGLOffscreenContext(GHOST_WindowHandle windowhandle,
                                                 GHOST_ContextHandle offscreen_contexthandle);
 
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 3721955ae6b..124d78a75d8 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -268,15 +268,7 @@ class GHOST_ISystem {
    * Overload to allow requesting a different context type. By default only OpenGL is supported.
    * However by explicitly overloading this a system may add support for others.
    */
-  virtual GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type)
-  {
-    switch (type) {
-      case GHOST_kDrawingContextTypeOpenGL:
-        return createOffscreenContext();
-      default:
-        return NULL;
-    }
-  }
+  virtual GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type) = 0;
 
   /**
    * Dispose of a context.
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 7cb2326a919..ddd364d63ec 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -127,6 +127,25 @@ GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
   return system->disposeContext(context);
 }
 
+#ifdef WIN32
+GHOST_ContextHandle GHOST_CreateDirectXContext(GHOST_SystemHandle systemhandle)
+{
+  GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+
+  return (GHOST_ContextHandle)system->createOffscreenContext(GHOST_kDrawingContextTypeD3D);
+}
+
+GHOST_TSuccess GHOST_DisposeDirectXContext(GHOST_SystemHandle systemhandle,
+                                           GHOST_ContextHandle contexthandle)
+{
+  GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+  GHOST_IContext *context = (GHOST_IContext *)contexthandle;
+
+  return system->disposeContext(context);
+}
+
+#endif
+
 GHOST_TSuccess GHOST_BlitOpenGLOffscreenContext(GHOST_WindowHandle windowhandle,
                                                 GHOST_ContextHandle offscreen_contexthandle)
 {
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 21935abed9c..224f0fab90c 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -121,6 +121,16 @@ GHOST_TSuccess GHOST_System::disposeWindow(GHOST_IWindow *window)
   return success;
 }
 
+GHOST_IContext *GHOST_System::createOffscreenContext(GHOST_TDrawingContextType type)
+{
+  switch (type) {
+    case GHOST_kDrawingContextTypeOpenGL:
+      return createOffscreenContext();
+    default:
+      return NULL;
+  }
+}
+
 bool GHOST_System::validWindow(GHOST_IWindow *window)
 {
   return m_windowManager->getWindowFound(window);
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index fbf8af01e59..bea61f42674 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -119,6 +119,19 @@ class GHOST_System : public GHOST_ISystem {
    */
   GHOST_TSuccess disposeWindow(GHOST_IWindow *window);
 
+  /**
+   * Create a new offscreen context.
+   * Never explicitly delete the context, use disposeContext() instead.
+   * \return  The new context (or 0 if creation failed).
+   */
+  virtual GHOST_IContext *createOffscreenContext() = 0;
+
+  /**
+   * Overload to allow requesting a different context type. By default only OpenGL is supported.
+   * However by explicitly overloading this a system may add support for others.
+   */
+  GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type);
+
   /**
    * Returns whether a window is valid.
    * \param   window Pointer to the window to be checked.
diff --git a/release/scripts/addons b/release/scripts/addons
index 3687f02a662..0e53a9a3867 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 3687f02a662d6c258cb72e36127cff1fb7fe3236
+Subproject commit 0e53a9a38672790d5fbb9a1d4a935980824d4a84
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index df3766904da..b6450be280f 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -154,6 +154,10 @@ void *WM_opengl_context_create(void);
 void WM_opengl_context_dispose(void *context);
 void WM_opengl_context_activate(void *context);
 void WM_opengl_context_release(void *context);
+#ifdef WIN32
+void *WM_directx_context_create(void);
+void WM_directx_context_dispose(void *context);
+#endif
 
 /* defines for 'type' WM_window_open_temp */
 enum {
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 8ef243b8bfb..da0fc8318bb 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3540,15 +3540,19 @@ static void WM_OT_stereo3d_set(wmOperatorType *ot)
 }
 
 #ifdef WITH_OPENXR
+
+#  ifdef WIN32
+//#    define USE_FORCE_WINDOWED_SESSION
+#  endif
+
 static void *xr_session_gpu_binding_context_create(GHOST_TXrGraphicsBinding graphics_binding)
 {
-#  ifndef WIN32
+#  ifndef USE_FORCE_WINDOWED_SESSION
   wmSurface *surface = wm_xr_session_surface_create(G_MAIN->wm.first, graphics_binding);
 
   wm_surface_add(surface);
 
-  return surface->ghost_ctx;
-
+  return surface->secondary_ghost_ctx ? surface->secondary_ghost_ctx : surface->ghost_ctx;
 #  else
 #    ifdef WIN32
   if (graphics_binding == GHOST_kXrGraphicsD3D11) {
@@ -3559,16 +3563,16 @@ static void *xr_session_gpu_binding_context_create(GHOST_TXrGraphicsBinding grap
         return GHOST_GetWindowContext(win->ghostwin);
       }
     }
-    return NULL;
   }
 #    endif
+  return NULL;
 #  endif
 }
 
 static void xr_session_gpu_binding_context_destroy(GHOST_TXrGraphicsBinding UNUSED(graphics_lib),
                                                    void *UNUSED(context))
 {
-#  ifndef WIN32
+#  ifndef USE_FORCE_WINDOWED_SESSION
   wmSurface *surface = wm_xr_session_surface_get();
 
   if (surface) { /* Might have been freed already */
@@ -3577,7 +3581,7 @@ static void xr_session_gpu_binding_context_destroy(GHOST_TXrGraphicsBinding UNUS
 #  endif
 }
 
-#  ifdef WIN32
+#  if defined(WIN32) && defined(USE_FORCE_WINDOWED_SESSION)
 static void xr_session_window_create(bContext *C)
 {
   Main *bmain = CTX_data_main(C);
@@ -3635,7 +3639,7 @@ static void xr_session_window_create(bContext *C)
     CTX_wm_window_set(C, win_prev);
   }
 }
-#  endif /* WIN32 */
+#  endif /* WIN32 && USE_FORCE_WINDOWED_SESSION */
 
 static void wm_xr_draw_view_fn(const GHOST_XrDrawViewInfo *UNUSED(draw_view), void *customdata)
 {
@@ -3656,7 +3660,7 @@ static int wm_xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
     GHOST_XrSessionEnd(wm->xr_context);
   }
   else {
-#  if defined(WIN32)
+#  if defined(WIN32) && defined(USE_FORCE_WINDOWED_SESSION)
     xr_session_window_create(C);
 #  endif
 
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index b48186ae226..83dbe531715 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -2462,3 +2462,24 @@ void WM_opengl_context_release(void *context)
 }
 
 /** \} */
+
+#ifdef WIN32
+/* -------------------------------------------------------------------- */
+/** \name Direct DirectX Context Management
+ * \{ */
+
+void *WM_directx_context_create(void)
+{
+  BLI_assert(GPU_framebuffer_active_get() == NULL);
+  return GHOST_CreateDirectXContext(g_system);
+}
+
+void WM_directx_context_dispose(void *context)
+{
+  BLI_assert(GPU_framebuffer_active_get() == NULL);
+  GHOST_DisposeDirectXContext(g_system, context);
+}
+
+/** \} */
+
+#endif
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index e02aee7beb2..cad02fc20c2 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -104,14 +104,15 @@ wmSurface *wm_xr_session_surface_create(wmWindowManager *wm, unsigned int gpu_bi
 
   wm_window_clear_drawable(wm);
   wm_surface_clear_drawable();
+  surface->ghost_ctx = WM_opengl_context_create();
+  WM_opengl_context_activate(surface->ghost_ctx);
 
   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:
+      surface->secondary_ghost_ctx = WM_directx_context_create();
       break;
 #endif
   }
diff --git a/source/blender/windowmanager/wm_surface.h b/source/blender/windowmanager/wm_surface.h
index a8d0e547c1d..438663f0259 100644
--- a/source/blender/windowmanager/wm_surface.h
+++ b/source/blender/windowmanager/wm_surface.h
@@ -27,6 +27,9 @@ typedef struct wmSurface {
   struct wmSurface *next, *prev;
 
   GHOST_ContextHandle ghost_ctx;
+  /** Some surfaces may want to use a secondary context. E.g. a DirectX one to draw OpenGL
+   * resources using DirectX (compatibility layer us

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list