Blender  V3.3
wm_xr.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
11 #include "BKE_global.h"
12 #include "BKE_idprop.h"
13 #include "BKE_main.h"
14 #include "BKE_report.h"
15 
16 #include "DEG_depsgraph.h"
17 
18 #include "DNA_scene_types.h"
20 
21 #include "ED_screen.h"
22 
23 #include "GHOST_C-api.h"
24 
25 #include "GPU_platform.h"
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "WM_api.h"
30 
31 #include "wm_surface.h"
32 #include "wm_xr_intern.h"
33 
34 typedef struct {
37 
38 /* -------------------------------------------------------------------- */
39 
40 static void wm_xr_error_handler(const GHOST_XrError *error)
41 {
42  wmXrErrorHandlerData *handler_data = error->customdata;
43  wmWindowManager *wm = handler_data->wm;
44 
46  WM_report(RPT_ERROR, error->user_message);
48 
49  if (wm->xr.runtime) {
50  /* Just play safe and destroy the entire runtime data, including context. */
52  }
53 }
54 
56 {
57  if (wm->xr.runtime && wm->xr.runtime->context) {
58  return true;
59  }
60  static wmXrErrorHandlerData error_customdata;
61 
62  /* Set up error handling */
63  error_customdata.wm = wm;
64  GHOST_XrErrorHandler(wm_xr_error_handler, &error_customdata);
65 
66  {
67  const GHOST_TXrGraphicsBinding gpu_bindings_candidates[] = {
68  GHOST_kXrGraphicsOpenGL,
69 #ifdef WIN32
70  GHOST_kXrGraphicsD3D11,
71 #endif
72  };
73  GHOST_XrContextCreateInfo create_info = {
74  .gpu_binding_candidates = gpu_bindings_candidates,
75  .gpu_binding_candidates_count = ARRAY_SIZE(gpu_bindings_candidates),
76  };
77  GHOST_XrContextHandle context;
78 
79  if (G.debug & G_DEBUG_XR) {
80  create_info.context_flag |= GHOST_kXrContextDebug;
81  }
82  if (G.debug & G_DEBUG_XR_TIME) {
83  create_info.context_flag |= GHOST_kXrContextDebugTime;
84  }
85 #ifdef WIN32
87  create_info.context_flag |= GHOST_kXrContextGpuNVIDIA;
88  }
89 #endif
90 
91  if (!(context = GHOST_XrContextCreate(&create_info))) {
92  return false;
93  }
94 
95  /* Set up context callbacks */
96  GHOST_XrGraphicsContextBindFuncs(context,
99  GHOST_XrDrawViewFunc(context, wm_xr_draw_view);
100 
101  if (!wm->xr.runtime) {
103  wm->xr.runtime->context = context;
104  }
105  }
106  BLI_assert(wm->xr.runtime && wm->xr.runtime->context);
107 
108  return true;
109 }
110 
112 {
113  if (wm->xr.runtime != NULL) {
115  }
116  if (wm->xr.session_settings.shading.prop) {
119  }
120 }
121 
123 {
124  if (wm->xr.runtime && wm->xr.runtime->context) {
126 
127  /* Process OpenXR action events. */
128  if (WM_xr_session_is_ready(&wm->xr)) {
130  }
131 
132  /* wm_window_process_events() uses the return value to determine if it can put the main thread
133  * to sleep for some milliseconds. We never want that to happen while the VR session runs on
134  * the main thread. So always return true. */
135  return true;
136  }
137  return false;
138 }
139 
140 /* -------------------------------------------------------------------- */
145 {
146  wmXrRuntimeData *runtime = MEM_callocN(sizeof(*runtime), __func__);
147  return runtime;
148 }
149 
151 {
152  /* Note that this function may be called twice, because of an indirect recursion: If a session is
153  * running while WM-XR calls this function, calling GHOST_XrContextDestroy() will call this
154  * again, because it's also set as the session exit callback. So NULL-check and NULL everything
155  * that is freed here. */
156 
157  /* We free all runtime XR data here, so if the context is still alive, destroy it. */
158  if ((*runtime)->context != NULL) {
159  GHOST_XrContextHandle context = (*runtime)->context;
160  /* Prevent recursive GHOST_XrContextDestroy() call by NULL'ing the context pointer before the
161  * first call, see comment above. */
162  (*runtime)->context = NULL;
163 
164  if ((*runtime)->area) {
165  wmWindowManager *wm = G_MAIN->wm.first;
167  ED_area_offscreen_free(wm, win, (*runtime)->area);
168  (*runtime)->area = NULL;
169  }
170  wm_xr_session_data_free(&(*runtime)->session_state);
171  WM_xr_actionmaps_clear(*runtime);
172 
174  }
175  MEM_SAFE_FREE(*runtime);
176 }
177  /* XR Runtime Data */
#define G_MAIN
Definition: BKE_global.h:267
@ G_DEBUG_XR
Definition: BKE_global.h:196
@ G_DEBUG_XR_TIME
Definition: BKE_global.h:197
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1093
void BKE_reports_clear(ReportList *reports)
Definition: report.c:63
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define ARRAY_SIZE(arr)
void ED_area_offscreen_free(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area)
Definition: area.c:2035
GHOST C-API function and type declarations.
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_contexthandle)
GHOST_XrContextHandle GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info)
Definition: GHOST_Xr.cpp:18
void GHOST_XrContextDestroy(GHOST_XrContextHandle xr_contexthandle)
Definition: GHOST_Xr.cpp:36
void GHOST_XrErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
Definition: GHOST_Xr.cpp:41
@ GPU_DRIVER_ANY
Definition: GPU_platform.h:47
@ GPU_OS_WIN
Definition: GPU_platform.h:37
@ GPU_DEVICE_NVIDIA
Definition: GPU_platform.h:24
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
static void error(const char *str)
Definition: meshlaplacian.c:51
struct IDProperty * prop
struct View3DShading shading
Definition: DNA_xr_types.h:19
struct ReportList reports
XrSessionSettings session_settings
struct wmXrRuntimeData * runtime
wmWindowManager * wm
Definition: wm_xr.c:35
GHOST_XrContextHandle context
Definition: wm_xr_intern.h:65
void WM_report(eReportType type, const char *message)
void WM_report_banner_show(void)
bool wm_xr_init(wmWindowManager *wm)
Definition: wm_xr.c:55
static void wm_xr_error_handler(const GHOST_XrError *error)
Definition: wm_xr.c:40
void wm_xr_runtime_data_free(wmXrRuntimeData **runtime)
Definition: wm_xr.c:150
wmXrRuntimeData * wm_xr_runtime_data_create(void)
Definition: wm_xr.c:144
bool wm_xr_events_handle(wmWindowManager *wm)
Definition: wm_xr.c:122
void wm_xr_exit(wmWindowManager *wm)
Definition: wm_xr.c:111
void WM_xr_actionmaps_clear(wmXrRuntimeData *runtime)
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
Draw a viewport for a single eye.
Definition: wm_xr_draw.c:128
void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle context)
void wm_xr_session_actions_update(wmWindowManager *wm)
wmWindow * wm_xr_session_root_window_or_fallback_get(const wmWindowManager *wm, const wmXrRuntimeData *runtime_data)
void * wm_xr_session_gpu_binding_context_create(void)
void wm_xr_session_data_free(wmXrSessionState *state)
Definition: wm_xr_session.c:85
bool WM_xr_session_is_ready(const wmXrData *xr)