Monado OpenXR Runtime
g_device.hpp
Go to the documentation of this file.
1// Copyright 2024-2026, NVIDIA CORPORATION.
2// Copyright 2026, Collabora, Ltd.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief Header for glue classes to wrap XRT device interfaces.
7 * @author Jakob Bornecrantz <tbornecrantz@nvidia.com>
8 * @ingroup aux_util
9 */
10
11#pragma once
12
13#include "xrt/xrt_device.h"
14#include "util/u_device.h"
15#include "g_catch_guard.hpp"
16
17
18namespace xrt::util {
19
20/*!
21 * Selects which functions that the @ref DeviceBase wrapper should set.
22 */
24{
25 /*!
26 * @ref xrt_device::get_view_poses
27 * @ref xrt_device::is_form_factor_available
28 */
29 bool hmd{false};
30
31 //! @ref xrt_device::compute_distortion
32 bool distortion{false};
33
34 //! @ref xrt_device::get_visibility_mask
35 bool visibility_mask{false};
36
37 //! @ref xrt_device::update_inputs
38 bool update_inputs{false};
39
40 //! @ref xrt_device::set_output
41 bool output{false};
42
43 //! @ref xrt_device::get_output_limits
44 bool output_limits{false};
45
46 //! @ref xrt_device::get_hand_tracking
47 bool hand_tracking{false};
48
49 //! @ref xrt_device::get_face_tracking
50 bool face_tracking{false};
51
52 //! @ref xrt_device::get_face_calibration_state_android
54
55 /*!
56 * @ref xrt_device::get_body_skeleton
57 * @ref xrt_device::get_body_joints
58 * @ref xrt_device::reset_body_tracking_calibration_meta
59 * @ref xrt_device::set_body_tracking_calibration_override_meta
60 */
61 bool body_tracking{false};
62
63 /*!
64 * @ref xrt_device::begin_plane_detection_ext
65 * @ref xrt_device::destroy_plane_detection_ext
66 * @ref xrt_device::get_plane_detection_state_ext
67 * @ref xrt_device::get_plane_detections_ext
68 */
69 bool plane_detection{false};
70
71 //! @ref xrt_device::get_presence
72 bool presence{false};
73
74 //! @ref xrt_device::ref_space_usage
75 bool reference_space{false};
76
77 //! @ref xrt_device::get_battery_status
78 bool battery{false};
79
80 /*!
81 * @ref xrt_device::get_brightness
82 * @ref xrt_device::set_brightness
83 */
84 bool brightness{false};
85
86 //! @ref xrt_device::get_compositor_info
87 bool compositor_info{false};
88
89 /*!
90 * @ref xrt_device::begin_feature
91 * @ref xrt_device::end_feature
92 */
93 bool features{false};
94};
95
96/*!
97 * Helper wrapper for @ref xrt_device, Monado has C style inheritance where the
98 * first field is the base class. In order to safely cast the from the parent
99 * to the child class it needs to have a standard layout, it is very easy to
100 * not have that. So this class, which has standard layout, goes via itself to
101 * then using a static_cast to go to the derived class.
102 *
103 * https://en.cppreference.com/w/cpp/types/is_standard_layout
104 */
105template <class T, DeviceFunctions functions> class DeviceBase
106{
107public: // Members
108 /*!
109 * Fully resets and sets function pointers on @ref xrt_device.
110 */
111 DeviceBase() noexcept
112 {
113 // Setup function for the device.
114 auto &xdev = *getXDev();
115
116 // Inits all functions, some are replaced below.
117 u_device_populate_function_pointers(&xdev, getTrackedPoseWrap, destroyDeviceWrap);
118
119 if constexpr (functions.hmd) {
120 xdev.get_view_poses = getViewPosesWrap;
121 xdev.is_form_factor_available = isFormFactorAvailableWrap;
122 }
123
124 if constexpr (functions.distortion) {
125 xdev.compute_distortion = computeDistortionWrap;
126 }
127
128 if constexpr (functions.visibility_mask) {
129 xdev.get_visibility_mask = getVisibilityMaskWrap;
130 }
131
132 if constexpr (functions.update_inputs) {
133 xdev.update_inputs = updateInputsWrap;
134 }
135
136 if constexpr (functions.output) {
137 xdev.set_output = setOutputWrap;
138 }
139
140 if constexpr (functions.output_limits) {
141 xdev.get_output_limits = getOutputLimitsWrap;
142 }
143
144 if constexpr (functions.hand_tracking) {
145 xdev.get_hand_tracking = getHandTrackingWrap;
146 }
147
148 if constexpr (functions.face_tracking) {
149 xdev.get_face_tracking = getFaceTrackingWrap;
150 }
151
152 if constexpr (functions.face_calibration_android) {
153 xdev.get_face_calibration_state_android = getFaceCalibrationStateAndroidWrap;
154 }
155
156 if constexpr (functions.body_tracking) {
157 xdev.get_body_skeleton = getBodySkeletonWrap;
158 xdev.get_body_joints = getBodyJointsWrap;
159 xdev.reset_body_tracking_calibration_meta = resetBodyTrackingCalibrationMetaWrap;
160 xdev.set_body_tracking_calibration_override_meta = setBodyTrackingCalibrationOverrideMetaWrap;
161 }
162
163 if constexpr (functions.plane_detection) {
164 xdev.begin_plane_detection_ext = beginPlaneDetectionExtWrap;
165 xdev.destroy_plane_detection_ext = destroyPlaneDetectionExtWrap;
166 xdev.get_plane_detection_state_ext = getPlaneDetectionStateExtWrap;
167 xdev.get_plane_detections_ext = getPlaneDetectionsExtWrap;
168 }
169
170 if constexpr (functions.presence) {
171 xdev.get_presence = getPresenceWrap;
172 }
173
174 if constexpr (functions.reference_space) {
175 xdev.ref_space_usage = refSpaceUsageWrap;
176 }
177
178 if constexpr (functions.battery) {
179 xdev.get_battery_status = getBatteryStatusWrap;
180 }
181
182 if constexpr (functions.brightness) {
183 xdev.get_brightness = getBrightnessWrap;
184 xdev.set_brightness = setBrightnessWrap;
185 }
186
187 if constexpr (functions.compositor_info) {
188 xdev.get_compositor_info = getCompositorInfoWrap;
189 }
190
191 if constexpr (functions.features) {
192 xdev.begin_feature = beginFeatureWrap;
193 xdev.end_feature = endFeatureWrap;
194 }
195 }
196
197 /*!
198 * Destructor
199 */
200 ~DeviceBase() noexcept = default;
201
202 const T &
203 derived() const noexcept
204 {
205 return static_cast<const T &>(*this);
206 }
207
208 T &
209 derived() noexcept
210 {
211 return static_cast<T &>(*this);
212 }
213
214 //! Gets the pointer to the derived class from a @ref xrt_device.
215 static const T *
216 fromXDev(const xrt_device *xdev) noexcept
217 {
218 return &(reinterpret_cast<const DeviceBase *>(xdev)->derived());
219 }
220
221 //! Gets the pointer to the derived class from a @ref xrt_device.
222 static T *
223 fromXDev(xrt_device *xdev) noexcept
224 {
225 return &(reinterpret_cast<DeviceBase *>(xdev)->derived());
226 }
227
228 //! Gets the underlying xrt_device pointer.
229 const xrt_device *
230 getXDev() const noexcept
231 {
232 return &mDevice;
233 }
234
235 //! Gets the underlying xrt_device pointer.
236 xrt_device *
237 getXDev() noexcept
238 {
239 return &mDevice;
240 }
241
242
243private: // Fields
244 /*!
245 * C style inheritance, this object has to be first.
246 *
247 * We have to do it this way because when we add a field to this class
248 * and we do C++ style inheritance we lose our standard layout status.
249 */
250 xrt_device mDevice = {};
251
252
253private: // Functions
254#define GET(xdev) (fromXDev(xdev)->derived())
255
256 static xrt_result_t
257 updateInputsWrap(struct xrt_device *xdev) noexcept
258 try {
259 return GET(xdev).updateInputs();
260 }
261 G_CATCH_GUARDS
262
263 static xrt_result_t
264 getTrackedPoseWrap(struct xrt_device *xdev,
265 enum xrt_input_name name,
266 int64_t at_timestamp_ns,
267 struct xrt_space_relation *out_relation) noexcept
268 try {
269 return GET(xdev).getTrackedPose(name, at_timestamp_ns, out_relation);
270 }
271 G_CATCH_GUARDS
272
273 static xrt_result_t
274 getHandTrackingWrap(struct xrt_device *xdev,
275 enum xrt_input_name name,
276 int64_t desired_timestamp_ns,
277 struct xrt_hand_joint_set *out_value,
278 int64_t *out_timestamp_ns) noexcept
279 try {
280 return GET(xdev).getHandTracking(name, desired_timestamp_ns, out_value, out_timestamp_ns);
281 }
282 G_CATCH_GUARDS
283
284 static xrt_result_t
285 getFaceTrackingWrap(struct xrt_device *xdev,
286 enum xrt_input_name facial_expression_type,
287 int64_t at_timestamp_ns,
288 struct xrt_facial_expression_set *out_value) noexcept
289 try {
290 return GET(xdev).getFaceTracking(facial_expression_type, at_timestamp_ns, out_value);
291 }
292 G_CATCH_GUARDS
293
294 static xrt_result_t
295 getFaceCalibrationStateAndroidWrap(struct xrt_device *xdev, bool *out_face_is_calibrated) noexcept
296 try {
297 return GET(xdev).getFaceCalibrationStateAndroid(out_face_is_calibrated);
298 }
299 G_CATCH_GUARDS
300
301 static xrt_result_t
302 getBodySkeletonWrap(struct xrt_device *xdev,
303 enum xrt_input_name body_tracking_type,
304 struct xrt_body_skeleton *out_value) noexcept
305 try {
306 return GET(xdev).getBodySkeleton(body_tracking_type, out_value);
307 }
308 G_CATCH_GUARDS
309
310 static xrt_result_t
311 getBodyJointsWrap(struct xrt_device *xdev,
312 enum xrt_input_name body_tracking_type,
313 int64_t desired_timestamp_ns,
314 struct xrt_body_joint_set *out_value) noexcept
315 try {
316 return GET(xdev).getBodyJoints(body_tracking_type, desired_timestamp_ns, out_value);
317 }
318 G_CATCH_GUARDS
319
320 static xrt_result_t
321 resetBodyTrackingCalibrationMetaWrap(struct xrt_device *xdev) noexcept
322 try {
323 return GET(xdev).resetBodyTrackingCalibrationMeta();
324 }
325 G_CATCH_GUARDS
326
327 static xrt_result_t
328 setBodyTrackingCalibrationOverrideMetaWrap(struct xrt_device *xdev, float new_body_height) noexcept
329 try {
330 return GET(xdev).setBodyTrackingCalibrationOverrideMeta(new_body_height);
331 }
332 G_CATCH_GUARDS
333
334 static xrt_result_t
335 setOutputWrap(struct xrt_device *xdev, enum xrt_output_name name, const struct xrt_output_value *value) noexcept
336 try {
337 return GET(xdev).setOutput(name, value);
338 }
339 G_CATCH_GUARDS
340
341 static xrt_result_t
342 getOutputLimitsWrap(struct xrt_device *xdev, struct xrt_output_limits *limits) noexcept
343 try {
344 return GET(xdev).getOutputLimits(limits);
345 }
346 G_CATCH_GUARDS
347
348 static xrt_result_t
349 getPresenceWrap(struct xrt_device *xdev, bool *presence) noexcept
350 try {
351 return GET(xdev).getPresence(presence);
352 }
353 G_CATCH_GUARDS
354
355 static xrt_result_t
356 beginPlaneDetectionExtWrap(struct xrt_device *xdev,
357 const struct xrt_plane_detector_begin_info_ext *begin_info,
358 uint64_t plane_detection_id,
359 uint64_t *out_plane_detection_id) noexcept
360 try {
361 return GET(xdev).beginPlaneDetectionExt(begin_info, plane_detection_id, out_plane_detection_id);
362 }
363 G_CATCH_GUARDS
364
365 static xrt_result_t
366 destroyPlaneDetectionExtWrap(struct xrt_device *xdev, uint64_t plane_detection_id) noexcept
367 try {
368 return GET(xdev).destroyPlaneDetectionExt(plane_detection_id);
369 }
370 G_CATCH_GUARDS
371
372 static xrt_result_t
373 getPlaneDetectionStateExtWrap(struct xrt_device *xdev,
374 uint64_t plane_detection_id,
375 enum xrt_plane_detector_state_ext *out_state) noexcept
376 try {
377 return GET(xdev).getPlaneDetectionStateExt(plane_detection_id, out_state);
378 }
379 G_CATCH_GUARDS
380
381 static xrt_result_t
382 getPlaneDetectionsExtWrap(struct xrt_device *xdev,
383 uint64_t plane_detection_id,
384 struct xrt_plane_detections_ext *out_detections) noexcept
385 try {
386 return GET(xdev).getPlaneDetectionsExt(plane_detection_id, out_detections);
387 }
388 G_CATCH_GUARDS
389
390 static xrt_result_t
391 getViewPosesWrap(struct xrt_device *xdev,
392 const struct xrt_vec3 *default_eye_relation,
393 int64_t at_timestamp_ns,
394 enum xrt_view_type view_type,
395 uint32_t view_count,
396 struct xrt_space_relation *out_head_relation,
397 struct xrt_fov *out_fovs,
398 struct xrt_pose *out_poses) noexcept
399 try {
400 return GET(xdev).getViewPoses(default_eye_relation, at_timestamp_ns, view_type, view_count,
401 out_head_relation, out_fovs, out_poses);
402 }
403 G_CATCH_GUARDS
404
405 static xrt_result_t
406 computeDistortionWrap(
407 struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *out_result) noexcept
408 try {
409 return GET(xdev).computeDistortion(view, u, v, out_result);
410 }
411 G_CATCH_GUARDS
412
413 static xrt_result_t
414 getVisibilityMaskWrap(struct xrt_device *xdev,
415 enum xrt_visibility_mask_type type,
416 uint32_t view_index,
417 struct xrt_visibility_mask **out_mask) noexcept
418 try {
419 return GET(xdev).getVisibilityMask(type, view_index, out_mask);
420 }
421 G_CATCH_GUARDS
422
423 static xrt_result_t
424 refSpaceUsageWrap(struct xrt_device *xdev,
425 enum xrt_reference_space_type type,
426 enum xrt_input_name name,
427 bool used) noexcept
428 try {
429 return GET(xdev).refSpaceUsage(type, name, used);
430 }
431 G_CATCH_GUARDS
432
433 static bool
434 isFormFactorAvailableWrap(struct xrt_device *xdev, enum xrt_form_factor form_factor) noexcept
435 try {
436 return GET(xdev).isFormFactorAvailable(form_factor);
437 }
438 G_CATCH_GUARDS_WITH_RETURN(false)
439
440 static xrt_result_t
441 getBatteryStatusWrap(struct xrt_device *xdev, bool *out_present, bool *out_charging, float *out_charge) noexcept
442 try {
443 return GET(xdev).getBatteryStatus(out_present, out_charging, out_charge);
444 }
445 G_CATCH_GUARDS
446
447 static xrt_result_t
448 getBrightnessWrap(struct xrt_device *xdev, float *out_brightness) noexcept
449 try {
450 return GET(xdev).getBrightness(out_brightness);
451 }
452 G_CATCH_GUARDS
453
454 static xrt_result_t
455 setBrightnessWrap(struct xrt_device *xdev, float brightness, bool relative) noexcept
456 try {
457 return GET(xdev).setBrightness(brightness, relative);
458 }
459 G_CATCH_GUARDS
460
461 static xrt_result_t
462 getCompositorInfoWrap(struct xrt_device *xdev,
463 const struct xrt_device_compositor_mode *mode,
464 struct xrt_device_compositor_info *out_info) noexcept
465 try {
466 return GET(xdev).getCompositorInfo(mode, out_info);
467 }
468 G_CATCH_GUARDS
469
470 static xrt_result_t
471 beginFeatureWrap(struct xrt_device *xdev, enum xrt_device_feature_type type) noexcept
472 try {
473 return GET(xdev).beginFeature(type);
474 }
475 G_CATCH_GUARDS
476
477 static xrt_result_t
478 endFeatureWrap(struct xrt_device *xdev, enum xrt_device_feature_type type) noexcept
479 try {
480 return GET(xdev).endFeature(type);
481 }
482 G_CATCH_GUARDS
483
484 static void
485 destroyDeviceWrap(struct xrt_device *xdev) noexcept
486 try {
487 T::destroyDevice(xdev);
488 }
489 G_CATCH_GUARDS_VOID
490
491
492#undef GET
493};
494
495} // namespace xrt::util
Helper wrapper for xrt_device, Monado has C style inheritance where the first field is the base class...
Definition: g_device.hpp:106
DeviceBase() noexcept
Fully resets and sets function pointers on xrt_device.
Definition: g_device.hpp:111
xrt_device * getXDev() noexcept
Gets the underlying xrt_device pointer.
Definition: g_device.hpp:237
static T * fromXDev(xrt_device *xdev) noexcept
Gets the pointer to the derived class from a xrt_device.
Definition: g_device.hpp:223
static const T * fromXDev(const xrt_device *xdev) noexcept
Gets the pointer to the derived class from a xrt_device.
Definition: g_device.hpp:216
~DeviceBase() noexcept=default
Destructor.
const xrt_device * getXDev() const noexcept
Gets the underlying xrt_device pointer.
Definition: g_device.hpp:230
Catch guards for glue classes.
void u_device_populate_function_pointers(struct xrt_device *xdev, u_device_get_tracked_pose_function_t get_tracked_pose_fn, u_device_destroy_function_t destroy_fn)
Populate the device's function pointers with default implementations.
Definition: u_device.c:595
xrt_visibility_mask_type
Visibility mask, mirror of XrVisibilityMaskKHR.
Definition: xrt_defines.h:2424
xrt_form_factor
What form factor is this device, mostly maps onto OpenXR's XrFormFactor.
Definition: xrt_defines.h:2365
xrt_input_name
Every internal input source known to monado with a baked in type.
Definition: xrt_defines.h:915
enum xrt_result xrt_result_t
Result type used across Monado.
xrt_reference_space_type
Type of a OpenXR mapped reference space, maps to the semantic spaces on the xrt_space_overseer struct...
Definition: xrt_defines.h:612
xrt_output_name
Name of a output with a baked in type.
Definition: xrt_defines.h:1582
xrt_plane_detector_state_ext
State of a plane detector, see xrt_device.
Definition: xrt_plane_detector.h:83
Selects which functions that the DeviceBase wrapper should set.
Definition: g_device.hpp:24
bool body_tracking
xrt_device::get_body_skeleton xrt_device::get_body_joints xrt_device::reset_body_tracking_calibration...
Definition: g_device.hpp:61
bool reference_space
xrt_device::ref_space_usage
Definition: g_device.hpp:75
bool plane_detection
xrt_device::begin_plane_detection_ext xrt_device::destroy_plane_detection_ext xrt_device::get_plane_d...
Definition: g_device.hpp:69
bool output_limits
xrt_device::get_output_limits
Definition: g_device.hpp:44
bool visibility_mask
xrt_device::get_visibility_mask
Definition: g_device.hpp:35
bool update_inputs
xrt_device::update_inputs
Definition: g_device.hpp:38
bool compositor_info
xrt_device::get_compositor_info
Definition: g_device.hpp:87
bool hmd
xrt_device::get_view_poses xrt_device::is_form_factor_available
Definition: g_device.hpp:29
bool output
xrt_device::set_output
Definition: g_device.hpp:41
bool battery
xrt_device::get_battery_status
Definition: g_device.hpp:78
bool brightness
xrt_device::get_brightness xrt_device::set_brightness
Definition: g_device.hpp:84
bool hand_tracking
xrt_device::get_hand_tracking
Definition: g_device.hpp:47
bool face_tracking
xrt_device::get_face_tracking
Definition: g_device.hpp:50
bool distortion
xrt_device::compute_distortion
Definition: g_device.hpp:32
bool features
xrt_device::begin_feature xrt_device::end_feature
Definition: g_device.hpp:93
bool face_calibration_android
xrt_device::get_face_calibration_state_android
Definition: g_device.hpp:53
bool presence
xrt_device::get_presence
Definition: g_device.hpp:72
Definition: xrt_defines.h:2258
Definition: xrt_defines.h:2158
Compositor information for a device.
Definition: xrt_device.h:88
Compositor mode information for a device.
Definition: xrt_device.h:104
A single HMD or input device.
Definition: xrt_device.h:310
Definition: xrt_defines.h:1934
Describes a projection matrix fov.
Definition: xrt_defines.h:499
Joint set type used for hand tracking.
Definition: xrt_defines.h:1491
Output limits of a particular device.
Definition: xrt_device.h:266
A union of all output types.
Definition: xrt_defines.h:2343
Each plane has n polygons; ultimately plane metadata from xrt_plane_detections_ext::locations and xrt...
Definition: xrt_plane_detector.h:172
A query for a plane.
Definition: xrt_plane_detector.h:97
A pose composed of a position and orientation.
Definition: xrt_defines.h:479
A relation with two spaces, includes velocity and acceleration.
Definition: xrt_defines.h:670
Represents a uv triplet for distortion, basically just three xrt_vec2.
Definition: xrt_defines.h:279
A 3 element vector with single floats.
Definition: xrt_defines.h:289
Visibility mask helper, the indices and vertices are tightly packed after this struct.
Definition: xrt_visibility_mask.h:26
Misc helpers for device drivers.
xrt_view_type
View type to be rendered to by the compositor.
Definition: xrt_defines.h:2374
Header defining an xrt display or controller device.
xrt_device_feature_type
Higher level features for devices.
Definition: xrt_device.h:254