[Bf-blender-cvs] [7bdd12e20c2] vr_scene_inspection: Fix multiple issues when closing session from OpenXR runtime

Julian Eisel noreply at git.blender.org
Mon Mar 16 11:22:36 CET 2020


Commit: 7bdd12e20c2a6c1081864c76cf44e63f187e99bb
Author: Julian Eisel
Date:   Sun Mar 15 02:54:59 2020 +0100
Branches: vr_scene_inspection
https://developer.blender.org/rB7bdd12e20c2a6c1081864c76cf44e63f187e99bb

Fix multiple issues when closing session from OpenXR runtime

We only managed Ghost-XR data then, not Blender side data. E.g. if there
was a VR mirror, its 3D View would remain locked then (disallowing
navigation).

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

M	intern/ghost/GHOST_Types.h
M	intern/ghost/intern/GHOST_XrContext.cpp
M	intern/ghost/intern/GHOST_XrContext.h
M	intern/ghost/intern/GHOST_XrSession.cpp
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/intern/wm_xr.c
M	source/blender/windowmanager/wm.h

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

diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 79c9b129fad..7fb9ef3bc61 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -598,6 +598,19 @@ typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_T
 
 #ifdef WITH_XR_OPENXR
 
+struct GHOST_XrError;
+struct GHOST_XrDrawViewInfo;
+enum GHOST_TXrGraphicsBinding;
+
+typedef void (*GHOST_XrErrorHandlerFn)(const struct GHOST_XrError *);
+
+typedef void (*GHOST_XrSessionExitFn)(void *customdata);
+
+typedef void *(*GHOST_XrGraphicsContextBindFn)(enum GHOST_TXrGraphicsBinding graphics_lib);
+typedef void (*GHOST_XrGraphicsContextUnbindFn)(enum GHOST_TXrGraphicsBinding graphics_lib,
+                                                GHOST_ContextHandle graphics_context);
+typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata);
+
 /**
  * The XR view (i.e. the OpenXR runtime) may require a different graphics library than OpenGL. An
  * offscreen texture of the viewport will then be drawn into using OpenGL, but the final texture
@@ -605,7 +618,7 @@ typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_T
  *
  * This enum defines the possible graphics bindings to attempt to enable.
  */
-typedef enum {
+typedef enum GHOST_TXrGraphicsBinding {
   GHOST_kXrGraphicsUnknown = 0,
   GHOST_kXrGraphicsOpenGL,
 #  ifdef WIN32
@@ -638,9 +651,12 @@ typedef struct {
 
 typedef struct {
   GHOST_XrPose base_pose;
+
+  GHOST_XrSessionExitFn exit_fn;
+  void *exit_customdata;
 } GHOST_XrSessionBeginInfo;
 
-typedef struct {
+typedef struct GHOST_XrDrawViewInfo {
   int ofsx, ofsy;
   int width, height;
 
@@ -656,19 +672,12 @@ typedef struct {
   char expects_srgb_buffer;
 } GHOST_XrDrawViewInfo;
 
-typedef struct {
+typedef struct GHOST_XrError {
   const char *user_message;
 
   void *customdata;
 } GHOST_XrError;
 
-typedef void (*GHOST_XrErrorHandlerFn)(const GHOST_XrError *);
-
-typedef void *(*GHOST_XrGraphicsContextBindFn)(GHOST_TXrGraphicsBinding graphics_lib);
-typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_TXrGraphicsBinding graphics_lib,
-                                                void *graphics_context);
-typedef void (*GHOST_XrDrawViewFn)(const GHOST_XrDrawViewInfo *draw_view, void *customdata);
-
 #endif
 
 #endif  // __GHOST_TYPES_H__
diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp
index 410837e9805..d7b83114c85 100644
--- a/intern/ghost/intern/GHOST_XrContext.cpp
+++ b/intern/ghost/intern/GHOST_XrContext.cpp
@@ -454,10 +454,12 @@ GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToEnable(
 
 void GHOST_XrContext::startSession(const GHOST_XrSessionBeginInfo *begin_info)
 {
+  m_custom_funcs.session_exit_fn = begin_info->exit_fn;
+  m_custom_funcs.session_exit_customdata = begin_info->exit_customdata;
+
   if (m_session == nullptr) {
     m_session = std::unique_ptr<GHOST_XrSession>(new GHOST_XrSession(this));
   }
-
   m_session->start(begin_info);
 }
 
diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h
index b361fb5caf8..5140ad7ea27 100644
--- a/intern/ghost/intern/GHOST_XrContext.h
+++ b/intern/ghost/intern/GHOST_XrContext.h
@@ -33,6 +33,9 @@ struct GHOST_XrCustomFuncs {
   /** Function to release (possibly free) a graphics context. */
   GHOST_XrGraphicsContextUnbindFn gpu_ctx_unbind_fn = nullptr;
 
+  GHOST_XrSessionExitFn session_exit_fn = nullptr;
+  void *session_exit_customdata = nullptr;
+
   /** Custom per-view draw function for Blender side drawing. */
   GHOST_XrDrawViewFn draw_view_fn = nullptr;
 };
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 3f653da44d6..a85bde3cab6 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -82,6 +82,8 @@ GHOST_XrSession::~GHOST_XrSession()
 
   m_oxr->session = XR_NULL_HANDLE;
   m_oxr->session_state = XR_SESSION_STATE_UNKNOWN;
+
+  m_context->getCustomFuncs().session_exit_fn(m_context->getCustomFuncs().session_exit_customdata);
 }
 
 /**
@@ -499,7 +501,8 @@ void GHOST_XrSession::unbindGraphicsContext()
 {
   const GHOST_XrCustomFuncs &custom_funcs = m_context->getCustomFuncs();
   if (custom_funcs.gpu_ctx_unbind_fn) {
-    custom_funcs.gpu_ctx_unbind_fn(m_context->getGraphicsBindingType(), m_gpu_ctx);
+    custom_funcs.gpu_ctx_unbind_fn(m_context->getGraphicsBindingType(),
+                                   (GHOST_ContextHandle)m_gpu_ctx);
   }
   m_gpu_ctx = nullptr;
 }
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 2e6e1856461..da53da9ae14 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3647,9 +3647,9 @@ static void WM_OT_stereo3d_set(wmOperatorType *ot)
 
 #ifdef WITH_XR_OPENXR
 
-static void wm_xr_session_update_mirror_views(Main *bmain, wmWindowManager *wm)
+static void wm_xr_session_update_mirror_views(Main *bmain, const wmXrData *xr_data)
 {
-  const bool enable = WM_xr_session_was_started(&wm->xr);
+  const bool enable = WM_xr_session_was_started(xr_data);
 
   for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
     for (ScrArea *area = screen->areabase.first; area; area = area->next) {
@@ -3666,8 +3666,14 @@ static void wm_xr_session_update_mirror_views(Main *bmain, wmWindowManager *wm)
   }
 }
 
+static void wm_xr_session_exit_cb(const wmXrData *xr_data, void *customdata)
+{
+  wm_xr_session_update_mirror_views(customdata, xr_data);
+}
+
 static int wm_xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
 {
+  Main *bmain = CTX_data_main(C);
   wmWindowManager *wm = CTX_wm_manager(C);
 
   /* Lazy-create xr context - tries to dynlink to the runtime, reading active_runtime.json. */
@@ -3675,9 +3681,8 @@ static int wm_xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
     return OPERATOR_CANCELLED;
   }
 
-  wm_xr_session_toggle(wm);
-
-  wm_xr_session_update_mirror_views(CTX_data_main(C), wm);
+  wm_xr_session_toggle(wm, wm_xr_session_exit_cb, bmain);
+  wm_xr_session_update_mirror_views(bmain, &wm->xr);
 
   WM_event_add_notifier(C, NC_WM | ND_XR_DATA_CHANGED, NULL);
 
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index 2d67dd25a8f..c3343be3036 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -97,6 +97,8 @@ typedef struct wmXrRuntimeData {
 
   /* Although this struct is internal, RNA gets a handle to this for state information queries. */
   wmXrSessionState session_state;
+  wmXrSessionExitFn exit_fn;
+  void *exit_customdata;
 } wmXrRuntimeData;
 
 typedef struct wmXrDrawData {
@@ -411,7 +413,7 @@ void *wm_xr_session_gpu_binding_context_create(GHOST_TXrGraphicsBinding graphics
 }
 
 void wm_xr_session_gpu_binding_context_destroy(GHOST_TXrGraphicsBinding UNUSED(graphics_lib),
-                                               void *UNUSED(context))
+                                               GHOST_ContextHandle UNUSED(context))
 {
   if (g_xr_surface) { /* Might have been freed already */
     wm_surface_remove(g_xr_surface);
@@ -424,25 +426,46 @@ void wm_xr_session_gpu_binding_context_destroy(GHOST_TXrGraphicsBinding UNUSED(g
   WM_main_add_notifier(NC_WM | ND_XR_DATA_CHANGED, NULL);
 }
 
-static void wm_xr_session_begin_info_create(const wmXrRuntimeData *UNUSED(runtime),
-                                            GHOST_XrSessionBeginInfo *UNUSED(r_begin_info))
+static void wm_xr_session_exit_cb(void *customdata)
 {
+  wmXrData *xr_data = customdata;
+
+  xr_data->runtime->session_state.is_started = false;
+  if (xr_data->runtime->exit_fn) {
+    xr_data->runtime->exit_fn(xr_data, xr_data->runtime->exit_customdata);
+  }
+
+  /* Free the entire runtime data (including session state and context), to play safe. */
+  wm_xr_runtime_data_free(&xr_data->runtime);
+}
+
+static void wm_xr_session_begin_info_create(wmXrData *xr_data,
+                                            GHOST_XrSessionBeginInfo *r_begin_info)
+{
+  /* WM-XR exit function, does some own stuff and calls callback passed to wm_xr_session_toggle(),
+   * to allow external code to execute its own session-exit logic. */
+  r_begin_info->exit_fn = wm_xr_session_exit_cb;
+  r_begin_info->exit_customdata = xr_data;
 }
 
-void wm_xr_session_toggle(wmWindowManager *wm)
+void wm_xr_session_toggle(wmWindowManager *wm,
+                          wmXrSessionExitFn session_exit_fn,
+                          void *session_exit_customdata)
 {
   wmXrData *xr_data = &wm->xr;
 
   if (WM_xr_session_was_started(xr_data)) {
     GHOST_XrSessionEnd(xr_data->runtime->context);
-    /* Free the entire runtime data (including session state and context), to play safe. */
-    wm_xr_runtime_data_free(&xr_data->runtime);
   }
   else {
     GHOST_XrSessionBeginInfo begin_info;
-    wm_xr_session_begin_info_create(xr_data->runtime, &begin_info);
-    GHOST_XrSessionStart(xr_data->runtime->context, &begin_info);
+
     xr_data->runtime->session_state.is_started = true;
+    xr_data->runtime->exit_fn = session_exit_fn;
+    xr_data->runtime->exit_customdata = session_exit_customdata;
+
+    wm_xr_session_begin_info_create(xr_data, &begin_info);
+    GHOST_XrSessionStart(xr_data->runtime->context, &begin_info);
   }
 }
 
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index d53fa48273b..47aa68aee96 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -99,10 +99,14 @@ void wm_open_init_load_ui(wmOperator *op, bool use_prefs);
 void wm_open_init_use_scripts(wmOperator *op, bool use_prefs);
 
 #ifdef WITH_XR_OPENXR
+typedef void (*wmXrSessionExitFn)(const wmXrData *xr_data, void *customdata);
+
 /* wm_xr.c */
 bool wm_xr_init(wmWindowManager *wm);
 void wm_xr_exit(wmWindowManager *wm);
-void wm_xr_session_toggle(wmWindowManager *wm);
+void wm_xr_session_toggle(wmWindowManager *wm,
+                          wmXrSessionExitFn session_exit_fn,
+                          voi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list