[Bf-blender-cvs] [146ef0dd1e1] soc-2019-openxr: Properly end VR sessions fixing crash on next session start

Julian Eisel noreply at git.blender.org
Wed Jul 3 21:06:16 CEST 2019


Commit: 146ef0dd1e1430a3a6c3e3039475dde814c5a2c8
Author: Julian Eisel
Date:   Wed Jul 3 21:01:58 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB146ef0dd1e1430a3a6c3e3039475dde814c5a2c8

Properly end VR sessions fixing crash on next session start

Previously, you had to restart Blender to start another session.

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

M	intern/ghost/intern/GHOST_Xr.cpp
M	intern/ghost/intern/GHOST_XrEvent.cpp
M	intern/ghost/intern/GHOST_XrSession.cpp
M	intern/ghost/intern/GHOST_Xr_intern.h
M	source/blender/windowmanager/intern/wm_xr.c

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

diff --git a/intern/ghost/intern/GHOST_Xr.cpp b/intern/ghost/intern/GHOST_Xr.cpp
index 9e77443edb0..20c8b4ceb76 100644
--- a/intern/ghost/intern/GHOST_Xr.cpp
+++ b/intern/ghost/intern/GHOST_Xr.cpp
@@ -253,16 +253,10 @@ void GHOST_XrContextDestroy(GHOST_XrContext *xr_context)
 {
   OpenXRData *oxr = &xr_context->oxr;
 
-  /* Unbinding may involve destruction, so call here too */
-  GHOST_XrGraphicsContextUnbind(*xr_context);
-
-  for (auto &swapchain_image : oxr->swapchain_images) {
-    xrDestroySwapchain(swapchain_image.first);
-  }
-
   if (oxr->session != XR_NULL_HANDLE) {
-    xrDestroySession(oxr->session);
+    GHOST_XrSessionDestroy(xr_context);
   }
+
   if (oxr->instance != XR_NULL_HANDLE) {
     xrDestroyInstance(oxr->instance);
   }
diff --git a/intern/ghost/intern/GHOST_XrEvent.cpp b/intern/ghost/intern/GHOST_XrEvent.cpp
index b3ea35194f7..93058cbf349 100644
--- a/intern/ghost/intern/GHOST_XrEvent.cpp
+++ b/intern/ghost/intern/GHOST_XrEvent.cpp
@@ -37,7 +37,7 @@ GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContext *xr_context)
   OpenXRData *oxr = &xr_context->oxr;
   XrEventDataBuffer event_buffer; /* structure big enought to hold all possible events */
 
-  if ((xr_context == NULL) || (oxr->session == XR_NULL_HANDLE)) {
+  if (xr_context == NULL) {
     return GHOST_kFailure;
   }
 
@@ -46,7 +46,7 @@ GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContext *xr_context)
 
     switch (event.type) {
       case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
-        GHOST_XrSessionStateChange(oxr, (XrEventDataSessionStateChanged &)event);
+        GHOST_XrSessionStateChange(xr_context, (XrEventDataSessionStateChanged &)event);
         return GHOST_kSuccess;
 
       default:
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index fbf6d5d857a..83152e247dc 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -185,16 +185,51 @@ void GHOST_XrSessionStart(GHOST_XrContext *xr_context)
   prepare_drawing(xr_context);
 }
 
-void GHOST_XrSessionEnd(GHOST_XrContext *xr_context)
+void GHOST_XrSessionEndNoDestroy(GHOST_XrContext *xr_context)
+{
+  OpenXRData *oxr = &xr_context->oxr;
+
+  assert(oxr->session != XR_NULL_HANDLE);
+
+  xrEndSession(oxr->session);
+}
+
+void GHOST_XrSessionDestroy(GHOST_XrContext *xr_context)
 {
-  xrEndSession(xr_context->oxr.session);
+  OpenXRData *oxr = &xr_context->oxr;
+
+  assert(oxr->session != XR_NULL_HANDLE);
+
   GHOST_XrGraphicsContextUnbind(*xr_context);
+
+  for (XrSwapchain &swapchain : oxr->swapchains) {
+    xrDestroySwapchain(swapchain);
+  }
+  oxr->swapchains.clear();
+  xrDestroySession(oxr->session);
+
+  oxr->session = XR_NULL_HANDLE;
+  /* Requery on next launch (allows changing devices/system). */
+  oxr->system_id = XR_NULL_SYSTEM_ID;
+  oxr->session_state = XR_SESSION_STATE_UNKNOWN;
+}
+
+void GHOST_XrSessionEnd(GHOST_XrContext *xr_context)
+{
+  GHOST_XrSessionEndNoDestroy(xr_context);
+  GHOST_XrSessionDestroy(xr_context);
 }
 
-void GHOST_XrSessionStateChange(OpenXRData *oxr, const XrEventDataSessionStateChanged &lifecycle)
+void GHOST_XrSessionStateChange(GHOST_XrContext *xr_context,
+                                const XrEventDataSessionStateChanged &lifecycle)
 {
+  OpenXRData *oxr = &xr_context->oxr;
+
   oxr->session_state = lifecycle.state;
 
+  /* Runtime may send events for apparently destroyed session. Our handle should be NULL then. */
+  assert((oxr->session == XR_NULL_HANDLE) || (oxr->session == lifecycle.session));
+
   switch (lifecycle.state) {
     case XR_SESSION_STATE_READY: {
       XrSessionBeginInfo begin_info{};
@@ -204,10 +239,13 @@ void GHOST_XrSessionStateChange(OpenXRData *oxr, const XrEventDataSessionStateCh
       xrBeginSession(oxr->session, &begin_info);
       break;
     }
-    case XR_SESSION_STATE_STOPPING: {
-      assert(oxr->session != XR_NULL_HANDLE);
-      xrEndSession(oxr->session);
-    }
+    case XR_SESSION_STATE_STOPPING:
+      /* Runtime will change state to STATE_EXITING, don't destruct session yet. */
+      GHOST_XrSessionEndNoDestroy(xr_context);
+      break;
+    case XR_SESSION_STATE_EXITING:
+      GHOST_XrSessionDestroy(xr_context);
+      break;
     default:
       break;
   }
@@ -363,4 +401,5 @@ void GHOST_XrSessionDrawViews(GHOST_XrContext *xr_context, void *draw_customdata
   }
 
   frame_drawing_end(xr_context, &layers);
+  xrDestroySpace(space);
 }
diff --git a/intern/ghost/intern/GHOST_Xr_intern.h b/intern/ghost/intern/GHOST_Xr_intern.h
index fb7ee92ba14..969eddabed9 100644
--- a/intern/ghost/intern/GHOST_Xr_intern.h
+++ b/intern/ghost/intern/GHOST_Xr_intern.h
@@ -74,6 +74,8 @@ struct GHOST_XrDrawFrame {
 void GHOST_XrGraphicsContextBind(GHOST_XrContext &xr_context);
 void GHOST_XrGraphicsContextUnbind(GHOST_XrContext &xr_context);
 
-void GHOST_XrSessionStateChange(OpenXRData *oxr, const XrEventDataSessionStateChanged &lifecycle);
+void GHOST_XrSessionDestroy(GHOST_XrContext *xr_context);
+void GHOST_XrSessionStateChange(GHOST_XrContext *xr_context,
+                                const XrEventDataSessionStateChanged &lifecycle);
 
 #endif /* __GHOST_XR_INTERN_H__ */
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index ccd8a94464c..369272a60bf 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -263,6 +263,8 @@ static void wm_xr_session_gpu_binding_context_destroy(
     wm_surface_remove(g_xr_surface);
   }
 #endif
+
+  wm_window_reset_drawable();
 }
 
 void wm_xr_session_toggle(struct GHOST_XrContext *xr_context)



More information about the Bf-blender-cvs mailing list