[Bf-blender-cvs] [3a2e459f588] soc-2019-openxr: Show useful error reports in case of errors.
Julian Eisel
noreply at git.blender.org
Fri Jul 12 19:51:51 CEST 2019
Commit: 3a2e459f588851ca8c9553c803735d49bc3902de
Author: Julian Eisel
Date: Fri Jul 12 19:44:46 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB3a2e459f588851ca8c9553c803735d49bc3902de
Show useful error reports in case of errors.
E.g. with an active OpenXR runtime installed, but no HMD plugged in,
Blender will now show: "Failed to get device information. Is a device
plugged in?".
In case of such errors, the VR-session will be cleanly exited, with
no side effects to the rest of Blender (at least if there are no bugs).
The GHOST_Xr API now allows setting a custom error handling callback
which may cleanly destroy all GHOST_Xr data.
===================================================================
M intern/ghost/GHOST_C-api.h
M intern/ghost/GHOST_Types.h
M intern/ghost/intern/GHOST_Xr.cpp
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_C-api.h b/intern/ghost/GHOST_C-api.h
index c86902de3b1..84bad87e654 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -981,6 +981,13 @@ extern void GHOST_EndIME(GHOST_WindowHandle windowhandle);
#ifdef WITH_OPENXR
/* xr-context */
+
+/**
+ * Set a custom callback to be executed whenever an error occurs. Should be set before calling
+ * #GHOST_XrContextCreate().
+ */
+void GHOST_XrErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata);
+
GHOST_XrContextHandle GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info);
void GHOST_XrContextDestroy(GHOST_XrContextHandle xr_context);
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 06bd5ca8180..78bb3deeb1a 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -616,6 +616,17 @@ typedef struct {
} fov;
} GHOST_XrDrawViewInfo;
+typedef struct {
+ const char *user_message;
+
+ /** File path and line number the error was found at. */
+ const char *source_location;
+
+ 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);
diff --git a/intern/ghost/intern/GHOST_Xr.cpp b/intern/ghost/intern/GHOST_Xr.cpp
index f23b156248f..0028a2c65ec 100644
--- a/intern/ghost/intern/GHOST_Xr.cpp
+++ b/intern/ghost/intern/GHOST_Xr.cpp
@@ -54,3 +54,8 @@ void GHOST_XrContextDestroy(GHOST_XrContextHandle xr_contexthandle)
{
delete (GHOST_XrContext *)xr_contexthandle;
}
+
+void GHOST_XrErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
+{
+ GHOST_XrContext::setErrorHandler(handler_fn, customdata);
+}
diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp
index c94b911fc8b..2e49c6ec85a 100644
--- a/intern/ghost/intern/GHOST_XrContext.cpp
+++ b/intern/ghost/intern/GHOST_XrContext.cpp
@@ -21,6 +21,7 @@
*/
#include <cassert>
+#include <sstream>
#include <string>
#include "GHOST_Types.h"
@@ -47,6 +48,9 @@ PFN_xrCreateDebugUtilsMessengerEXT OpenXRInstanceData::s_xrCreateDebugUtilsMesse
PFN_xrDestroyDebugUtilsMessengerEXT OpenXRInstanceData::s_xrDestroyDebugUtilsMessengerEXT_fn =
nullptr;
+GHOST_XrErrorHandlerFn GHOST_XrContext::s_error_handler = nullptr;
+void *GHOST_XrContext::s_error_handler_customdata = nullptr;
+
/* -------------------------------------------------------------------- */
/** \name Create, Initialize and Destruct
*
@@ -66,6 +70,7 @@ GHOST_XrContext::~GHOST_XrContext()
}
if (m_oxr->instance != XR_NULL_HANDLE) {
xrDestroyInstance(m_oxr->instance);
+ m_oxr->instance = XR_NULL_HANDLE;
}
}
@@ -196,17 +201,44 @@ void GHOST_XrContext::initDebugMessenger()
}
}
+/** \} */ /* Debug Printing */
+
+/* -------------------------------------------------------------------- */
+/** \name Error handling
+ *
+ * \{ */
+
void GHOST_XrContext::dispatchErrorMessage(const GHOST_XrException *exception) const
{
- // TODO dummy
- printf("Error: %s %i (%s:%i)\n",
- exception->m_msg,
- exception->m_res,
- exception->m_file,
- exception->m_line);
+ std::ostringstream stream_err_location;
+ std::string str_err_location;
+ GHOST_XrError error;
+
+ stream_err_location << exception->m_file << ":" << exception->m_line;
+ str_err_location = stream_err_location.str();
+
+ error.user_message = exception->m_msg;
+ error.source_location = str_err_location.c_str();
+ error.customdata = s_error_handler_customdata;
+
+ XR_DEBUG_ONLY_CALL(this,
+ fprintf(stderr,
+ "Error: \t%s\n\tOpenXR error value: %i\n\tSource: (%s)\n",
+ error.user_message,
+ exception->m_res,
+ error.source_location));
+
+ /* Potentially destroys GHOST_XrContext */
+ s_error_handler(&error);
}
-/** \} */ /* Debug Printing */
+void GHOST_XrContext::setErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
+{
+ s_error_handler = handler_fn;
+ s_error_handler_customdata = customdata;
+}
+
+/** \} */ /* Error handling */
/* -------------------------------------------------------------------- */
/** \name OpenXR API-Layers and Extensions
diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h
index b4df6689463..3e878bfa1d6 100644
--- a/intern/ghost/intern/GHOST_XrContext.h
+++ b/intern/ghost/intern/GHOST_XrContext.h
@@ -46,13 +46,14 @@ class GHOST_XrContext : public GHOST_IXrContext {
public:
GHOST_XrContext(const GHOST_XrContextCreateInfo *create_info);
~GHOST_XrContext();
-
void initialize(const GHOST_XrContextCreateInfo *create_info);
+
void startSession(const GHOST_XrSessionBeginInfo *begin_info) override;
void endSession() override;
bool isSessionRunning() const override;
void drawSessionViews(void *draw_customdata) override;
+ static void setErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata);
void dispatchErrorMessage(const class GHOST_XrException *exception) const override;
void setGraphicsContextBindFuncs(GHOST_XrGraphicsContextBindFn bind_fn,
@@ -80,6 +81,8 @@ class GHOST_XrContext : public GHOST_IXrContext {
/** Names of enabled API-layers */
std::vector<const char *> m_enabled_layers;
+ static GHOST_XrErrorHandlerFn s_error_handler;
+ static void *s_error_handler_customdata;
GHOST_XrCustomFuncs m_custom_funcs;
/** Enable debug message prints and OpenXR API validation layers */
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 634a92987e0..8ff812be1ce 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -62,8 +62,6 @@ GHOST_XrSession::GHOST_XrSession(GHOST_XrContext *xr_context)
GHOST_XrSession::~GHOST_XrSession()
{
- assert(m_oxr->session != XR_NULL_HANDLE);
-
// TODO OpenXR calls here can fail, but we should not throw an exception in the destructor.
for (XrSwapchain &swapchain : m_oxr->swapchains) {
@@ -73,7 +71,9 @@ GHOST_XrSession::~GHOST_XrSession()
if (m_oxr->reference_space != XR_NULL_HANDLE) {
xrDestroySpace(m_oxr->reference_space);
}
- xrDestroySession(m_oxr->session);
+ if (m_oxr->session != XR_NULL_HANDLE) {
+ xrDestroySession(m_oxr->session);
+ }
m_oxr->session = XR_NULL_HANDLE;
m_oxr->session_state = XR_SESSION_STATE_UNKNOWN;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 89567765760..4ff58f2a867 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3516,7 +3516,7 @@ static int wm_xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
wmWindowManager *wm = CTX_wm_manager(C);
/* Lazy-create xr context - tries to dynlink to the runtime, reading active_runtime.json. */
- if (wm_xr_context_ensure(wm) == false) {
+ if (wm_xr_context_ensure(C, wm) == false) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index 1a783df9376..237040a3db3 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -21,6 +21,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_report.h"
#include "BKE_screen.h"
#include "BLI_math_geom.h"
@@ -43,6 +44,8 @@
#include "MEM_guardedalloc.h"
+#include "UI_interface.h"
+
#include "WM_types.h"
#include "WM_api.h"
@@ -60,27 +63,57 @@ typedef struct {
GHOST_TXrGraphicsBinding gpu_binding_type;
} XrSurfaceData;
-bool wm_xr_context_ensure(wmWindowManager *wm)
+typedef struct {
+ wmWindowManager *wm;
+ bContext *evil_C;
+} wmXrErrorHandlerData;
+
+static void wm_xr_error_handler(const GHOST_XrError *error)
+{
+ wmXrErrorHandlerData *handler_data = error->customdata;
+ wmWindowManager *wm = handler_data->wm;
+
+ BKE_reports_clear(&wm->reports);
+ WM_report(RPT_ERROR, error->user_message);
+ WM_report_banner_show();
+ UI_popup_menu_reports(handler_data->evil_C, &wm->reports);
+
+ if (wm->xr_context) {
+ /* Just play safe and destroy the entire context. */
+ GHOST_XrContextDestroy(wm->xr_context);
+ wm->xr_context = NULL;
+ }
+}
+
+bool wm_xr_context_ensure(bContext *C, wmWindowManager *wm)
{
if (wm->xr_context) {
return true;
}
+ static wmXrErrorHandlerData error_customdata;
+
+ /* Set up error handling */
+ error_customdata.wm = wm;
+ error_customdata.evil_C = C;
+ GHOST_XrErrorHandler(wm_xr_error_handler, &error_customdata);
- const GHOST_TXrGraphicsBinding gpu_bindings_candidates[] = {
- GHOST_kXrGraphicsOpenGL,
+ {
+ const GHOST_TXrGraphicsBinding gpu_bindings_candidates[] = {
+ GHOST_kXrGraphicsOpenGL,
#ifdef WIN32
- GHOST_kXrGraphicsD3D11,
+ GHOST_kXrGraphicsD3D11,
#endif
- };
- GHOST_XrContextCreateInfo create_info = {
- .gpu_binding_candidates = gpu_bindings_candidates,
- .gpu_binding_candidates_count = ARRAY_SIZE(gpu_bindings_candidates)};
+ };
+ GHOST_XrContextCreateInfo create_info = {
+ .gpu_binding_candidates = gpu_bindings_candidates,
+ .gpu_binding_candidates_count = ARRAY_SIZE(gpu_bindings_candidates)};
- if (G.debug & G_DEBUG_XR) {
- create_info.context_flag |= GHOST_kXrContextDebug;
- }
+ if (G.debug & G_DEBUG_XR) {
+ create_info.context_flag |= GHOST_kXrContextDebug;
+ }
- wm->xr_context = GHOST_XrContextCreate(&create_info);
+ wm->xr_context = GHOST_XrContextCreate(&create_info);
+ }
return wm->xr_context != NULL;
}
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index e1d2d186af3..f28552916f2 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -102,7 +102,7 @@ void wm_draw_upside_down(int sizex, int sizey);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list