[Bf-blender-cvs] [6904ab10f48] soc-2019-openxr: Add GHOST_XrSession class for cleaner & safer session management

Julian Eisel noreply at git.blender.org
Mon Jul 8 14:13:50 CEST 2019


Commit: 6904ab10f4897fe3f82748e7f22833a2ac990d2a
Author: Julian Eisel
Date:   Sun Jul 7 01:13:42 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB6904ab10f4897fe3f82748e7f22833a2ac990d2a

Add GHOST_XrSession class for cleaner & safer session management

Session code and data structures are now localized. But also, this
enables sessions to use deterministic destruction to end itself cleanly.
So whenever an error occurs, we can use stack unwinding which will cause
graceful ending of the session.

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

M	intern/ghost/CMakeLists.txt
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_Xr.cpp
M	intern/ghost/intern/GHOST_XrEvent.cpp
M	intern/ghost/intern/GHOST_XrSession.cpp
A	intern/ghost/intern/GHOST_XrSession.h
M	intern/ghost/intern/GHOST_Xr_intern.h
M	source/blender/windowmanager/intern/wm_xr.c

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

diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 7e47b7eab08..d40583977be 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -357,7 +357,7 @@ if(WITH_OPENXR)
     intern/GHOST_Xr_intern.h
     intern/GHOST_Xr_openxr_includes.h
     intern/GHOST_IXrGraphicsBinding.h
-#    intern/GHOST_XrSession.h
+    intern/GHOST_XrSession.h
   )
   list(APPEND INC
   )
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 74e244e79e8..c190b8fc885 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -31,6 +31,7 @@
 #include "GHOST_IEvent.h"
 #include "GHOST_IEventConsumer.h"
 #include "intern/GHOST_CallbackEventConsumer.h"
+#include "intern/GHOST_XrSession.h"
 
 GHOST_SystemHandle GHOST_CreateSystem(void)
 {
diff --git a/intern/ghost/intern/GHOST_Xr.cpp b/intern/ghost/intern/GHOST_Xr.cpp
index 20c8b4ceb76..914d8236154 100644
--- a/intern/ghost/intern/GHOST_Xr.cpp
+++ b/intern/ghost/intern/GHOST_Xr.cpp
@@ -244,8 +244,6 @@ GHOST_XrContext *GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_i
   openxr_instance_create(xr_context);
   openxr_instance_log_print(oxr);
 
-  oxr->session_state = XR_SESSION_STATE_UNKNOWN;
-
   return xr_context;
 }
 
@@ -253,9 +251,7 @@ void GHOST_XrContextDestroy(GHOST_XrContext *xr_context)
 {
   OpenXRData *oxr = &xr_context->oxr;
 
-  if (oxr->session != XR_NULL_HANDLE) {
-    GHOST_XrSessionDestroy(xr_context);
-  }
+  xr_context->session = nullptr;
 
   if (oxr->instance != XR_NULL_HANDLE) {
     xrDestroyInstance(oxr->instance);
@@ -264,6 +260,44 @@ void GHOST_XrContextDestroy(GHOST_XrContext *xr_context)
   delete xr_context;
 }
 
+void GHOST_XrSessionStart(GHOST_XrContext *xr_context)
+{
+  if (xr_context->session == nullptr) {
+    xr_context->session = std::unique_ptr<GHOST_XrSession>(new GHOST_XrSession(xr_context));
+  }
+
+  xr_context->session->start();
+}
+
+void GHOST_XrSessionEnd(GHOST_XrContext *xr_context)
+{
+  xr_context->session->end();
+  xr_context->session = nullptr;
+}
+
+GHOST_TSuccess GHOST_XrSessionIsRunning(const GHOST_XrContext *xr_context)
+{
+  return (xr_context->session && xr_context->session->isRunning()) ? GHOST_kSuccess :
+                                                                     GHOST_kFailure;
+}
+
+void GHOST_XrSessionDrawViews(GHOST_XrContext *xr_context, void *draw_customdata)
+{
+  xr_context->session->draw(draw_customdata);
+}
+
+/**
+ * Delegates event to session, allowing context to destruct the session if needed.
+ */
+void GHOST_XrSessionStateChange(GHOST_XrContext *xr_context,
+                                const XrEventDataSessionStateChanged *lifecycle)
+{
+  if (xr_context->session &&
+      xr_context->session->handleStateChangeEvent(lifecycle) == GHOST_XrSession::SESSION_DESTROY) {
+    xr_context->session = nullptr;
+  }
+}
+
 /**
  * Set context for binding and unbinding a graphics context for a session. The binding callback may
  * create a new context thereby. In fact that's the sole reason for this callback approach to
@@ -276,26 +310,13 @@ void GHOST_XrGraphicsContextBindFuncs(GHOST_XrContext *xr_context,
                                       GHOST_XrGraphicsContextBindFn bind_fn,
                                       GHOST_XrGraphicsContextUnbindFn unbind_fn)
 {
-  GHOST_XrGraphicsContextUnbind(*xr_context);
+  if (xr_context->session) {
+    xr_context->session->unbindGraphicsContext();
+  }
   xr_context->gpu_ctx_bind_fn = bind_fn;
   xr_context->gpu_ctx_unbind_fn = unbind_fn;
 }
 
-void GHOST_XrGraphicsContextBind(GHOST_XrContext &xr_context)
-{
-  assert(xr_context.gpu_ctx_bind_fn);
-  xr_context.gpu_ctx = static_cast<GHOST_Context *>(
-      xr_context.gpu_ctx_bind_fn(xr_context.gpu_binding_type));
-}
-
-void GHOST_XrGraphicsContextUnbind(GHOST_XrContext &xr_context)
-{
-  if (xr_context.gpu_ctx_unbind_fn) {
-    xr_context.gpu_ctx_unbind_fn(xr_context.gpu_binding_type, xr_context.gpu_ctx);
-  }
-  xr_context.gpu_ctx = nullptr;
-}
-
 void GHOST_XrDrawViewFunc(struct GHOST_XrContext *xr_context, GHOST_XrDrawViewFn draw_view_fn)
 {
   xr_context->draw_view_fn = draw_view_fn;
diff --git a/intern/ghost/intern/GHOST_XrEvent.cpp b/intern/ghost/intern/GHOST_XrEvent.cpp
index 93058cbf349..99cb9e7c1d0 100644
--- a/intern/ghost/intern/GHOST_XrEvent.cpp
+++ b/intern/ghost/intern/GHOST_XrEvent.cpp
@@ -42,15 +42,15 @@ GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContext *xr_context)
   }
 
   while (GHOST_XrEventPollNext(oxr, event_buffer)) {
-    XrEventDataBaseHeader &event = (XrEventDataBaseHeader &)event_buffer; /* base event struct */
+    XrEventDataBaseHeader *event = (XrEventDataBaseHeader *)&event_buffer; /* base event struct */
 
-    switch (event.type) {
+    switch (event->type) {
       case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
-        GHOST_XrSessionStateChange(xr_context, (XrEventDataSessionStateChanged &)event);
+        GHOST_XrSessionStateChange(xr_context, (XrEventDataSessionStateChanged *)event);
         return GHOST_kSuccess;
 
       default:
-        printf("Unhandled event: %i\n", event.type);
+        printf("Unhandled event: %i\n", event->type);
         return GHOST_kFailure;
     }
   }
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 83152e247dc..854a883fdb2 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -25,34 +25,70 @@
 #include "GHOST_C-api.h"
 
 #include "GHOST_IXrGraphicsBinding.h"
-
+#include "GHOST_XrSession.h"
 #include "GHOST_Xr_intern.h"
 
-GHOST_TSuccess GHOST_XrSessionIsRunning(const GHOST_XrContext *xr_context)
+struct OpenXRSessionData {
+  XrSystemId system_id{XR_NULL_SYSTEM_ID};
+  XrSession session{XR_NULL_HANDLE};
+  XrSessionState session_state{XR_SESSION_STATE_UNKNOWN};
+
+  // Only stereo rendering supported now.
+  const XrViewConfigurationType view_type{XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO};
+  std::vector<XrView> views;
+  std::vector<XrSwapchain> swapchains;
+  std::map<XrSwapchain, std::vector<XrSwapchainImageBaseHeader *>> swapchain_images;
+  int32_t swapchain_image_width, swapchain_image_height;
+};
+
+struct GHOST_XrDrawFrame {
+  XrFrameState frame_state;
+};
+
+GHOST_XrSession::GHOST_XrSession(GHOST_XrContext *xr_context)
+    : m_context(xr_context), m_oxr(new OpenXRSessionData())
 {
-  if ((xr_context == nullptr) || (xr_context->oxr.session == XR_NULL_HANDLE)) {
-    return GHOST_kFailure;
+}
+
+GHOST_XrSession::~GHOST_XrSession()
+{
+  assert(m_oxr->session != XR_NULL_HANDLE);
+
+  for (XrSwapchain &swapchain : m_oxr->swapchains) {
+    xrDestroySwapchain(swapchain);
   }
-  switch (xr_context->oxr.session_state) {
+  m_oxr->swapchains.clear();
+  xrDestroySession(m_oxr->session);
+
+  m_oxr->session = XR_NULL_HANDLE;
+  m_oxr->session_state = XR_SESSION_STATE_UNKNOWN;
+}
+
+bool GHOST_XrSession::isRunning()
+{
+  if (m_oxr->session == XR_NULL_HANDLE) {
+    return false;
+  }
+  switch (m_oxr->session_state) {
     case XR_SESSION_STATE_RUNNING:
     case XR_SESSION_STATE_VISIBLE:
     case XR_SESSION_STATE_FOCUSED:
-      return GHOST_kSuccess;
+      return true;
     default:
-      return GHOST_kFailure;
+      return false;
   }
 }
-static GHOST_TSuccess GHOST_XrSessionIsVisible(const GHOST_XrContext *xr_context)
+bool GHOST_XrSession::isVisible()
 {
-  if ((xr_context == nullptr) || (xr_context->oxr.session == XR_NULL_HANDLE)) {
-    return GHOST_kFailure;
+  if (m_oxr->session == XR_NULL_HANDLE) {
+    return false;
   }
-  switch (xr_context->oxr.session_state) {
+  switch (m_oxr->session_state) {
     case XR_SESSION_STATE_VISIBLE:
     case XR_SESSION_STATE_FOCUSED:
-      return GHOST_kSuccess;
+      return true;
     default:
-      return GHOST_kFailure;
+      return false;
   }
 }
 
@@ -60,16 +96,30 @@ static GHOST_TSuccess GHOST_XrSessionIsVisible(const GHOST_XrContext *xr_context
  * A system in OpenXR the combination of some sort of HMD plus controllers and whatever other
  * devices are managed through OpenXR. So this attempts to init the HMD and the other devices.
  */
-static void GHOST_XrSystemInit(OpenXRData *oxr)
+void GHOST_XrSession::initSystem()
 {
-  assert(oxr->instance != XR_NULL_HANDLE);
-  assert(oxr->system_id == XR_NULL_SYSTEM_ID);
+  assert(m_context->oxr.instance != XR_NULL_HANDLE);
+  assert(m_oxr->system_id == XR_NULL_SYSTEM_ID);
 
   XrSystemGetInfo system_info{};
   system_info.type = XR_TYPE_SYSTEM_GET_INFO;
   system_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
 
-  xrGetSystem(oxr->instance, &system_info, &oxr->system_id);
+  xrGetSystem(m_context->oxr.instance, &system_info, &m_oxr->system_id);
+}
+
+void GHOST_XrSession::bindGraphicsContext()
+{
+  assert(m_context->gpu_ctx_bind_fn);
+  m_gpu_ctx = static_cast<GHOST_Context *>(
+      m_context->gpu_ctx_bind_fn(m_context->gpu_binding_type));
+}
+void GHOST_XrSession::unbindGraphicsContext()
+{
+  if (m_context->gpu_ctx_unbind_fn) {
+    m_context->gpu_ctx_unbind_fn(m_context->gpu_binding_type, m_gpu_ctx);
+  }
+  m_gpu_ctx = nullptr;
 }
 
 static std::vector<XrSwapchainImageBaseHeader *> swapchain_images_create(
@@ -119,42 +169,39 @@ static XrSwapchain swapchain_create(const XrSession session,
   return swapchain;
 }
 
-void prepare_drawing(GHOST_XrContext *xr_context)
+void GHOST_XrSession::prepareDrawing()
 {
-  OpenXRData *oxr = &xr_context->oxr;
   std::vector<XrViewConfigurationView> view_configs;
   uint32_t view_count;
 
   xrEnumerateViewConfigurationViews(
-      oxr->instance, oxr->system_id, oxr->view_type, 0, &view_count, nullptr);
+      m_context->oxr.instance, m_oxr->system_id, m_oxr->view_type, 0, &view_count, nullptr);
   view_configs.resize(view_count, {XR_TYPE_VIEW_CONFIGURATION_VIEW});
-  xrEnumerateViewConfigurationViews(oxr->instance,
-                                    oxr->system_id,
-                                    oxr->view_type,
+  xrEnumerateViewConfigurationViews(m_context->oxr.instance,
+                                    m_oxr->system_id,
+                                    m_oxr->view_type,
                                     view_configs.size(),
                                     &view_count,
    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list