Monado OpenXR Runtime
Loading...
Searching...
No Matches
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 "util/u_device_id.h"
16#include "g_catch_guard.hpp"
17#include "g_traits.hpp"
18
19#include <type_traits>
20
21
22namespace xrt::util {
23
24/*!
25 * Selects which functions that the @ref DeviceBase wrapper should set.
26 */
28{
29 /*!
30 * @ref xrt_device::get_view_poses
31 * @ref xrt_device::is_form_factor_available
32 */
33 bool hmd{false};
34
35 //! @ref xrt_device::compute_distortion
36 bool distortion{false};
37
38 //! @ref xrt_device::get_visibility_mask
39 bool visibility_mask{false};
40
41 //! @ref xrt_device::update_inputs
42 bool update_inputs{false};
43
44 //! @ref xrt_device::set_output
45 bool output{false};
46
47 //! @ref xrt_device::get_output_limits
48 bool output_limits{false};
49
50 //! @ref xrt_device::get_hand_tracking
51 bool hand_tracking{false};
52
53 //! @ref xrt_device::get_face_tracking
54 bool face_tracking{false};
55
56 //! @ref xrt_device::get_face_calibration_state_android
58
59 /*!
60 * @ref xrt_device::get_body_skeleton
61 * @ref xrt_device::get_body_joints
62 * @ref xrt_device::reset_body_tracking_calibration_meta
63 * @ref xrt_device::set_body_tracking_calibration_override_meta
64 */
65 bool body_tracking{false};
66
67 /*!
68 * @ref xrt_device::begin_plane_detection_ext
69 * @ref xrt_device::destroy_plane_detection_ext
70 * @ref xrt_device::get_plane_detection_state_ext
71 * @ref xrt_device::get_plane_detections_ext
72 */
73 bool plane_detection{false};
74
75 //! @ref xrt_device::ref_space_usage
76 bool reference_space{false};
77
78 //! @ref xrt_device::get_battery_status
79 bool battery{false};
80
81 /*!
82 * @ref xrt_device::get_brightness
83 * @ref xrt_device::set_brightness
84 */
85 bool brightness{false};
86
87 //! @ref xrt_device::get_compositor_info
88 bool compositor_info{false};
89
90 /*!
91 * @ref xrt_device::begin_feature
92 * @ref xrt_device::end_feature
93 */
94 bool features{false};
95};
96
97/*!
98 * CRTP glue wrapper for @ref xrt_device. Relies on standard layout to recover
99 * the derived object from the C struct, and has some requirements and
100 * limitations because of that. See @ref cpp-glue-wrappers for the guide and
101 * conventions for these wrappers.
102 *
103 * Unlike the other wrappers it wires function pointers selectively: the
104 * `functions` @ref DeviceFunctions bitmask decides which C function pointers
105 * are installed, so `T` only has to implement C++ methods for the features it
106 * turns on.
107 */
108template <class T, DeviceFunctions functions> class DeviceBase
109{
110public: // Members
111 /*!
112 * Fully resets and sets function pointers on @ref xrt_device.
113 */
114 DeviceBase() noexcept
115 {
116 static_assert(std::is_standard_layout_v<DeviceBase>,
117 "glue base must be standard layout for pointer recovery");
118 static_assert(is_non_virtual_base_v<DeviceBase, T>,
119 "glue base must be a non-virtual base of T for pointer recovery");
120
121 // Setup function for the device.
122 auto &xdev = *getXDev();
123
124 u_device_id_assign(&xdev);
125
126 // Inits all functions, some are replaced below.
127 u_device_populate_function_pointers(&xdev, getTrackedPoseWrap, destroyDeviceWrap);
128
129 if constexpr (functions.hmd) {
130 xdev.get_view_poses = getViewPosesWrap;
131 xdev.is_form_factor_available = isFormFactorAvailableWrap;
132 }
133
134 if constexpr (functions.distortion) {
135 xdev.compute_distortion = computeDistortionWrap;
136 }
137
138 if constexpr (functions.visibility_mask) {
139 xdev.get_visibility_mask = getVisibilityMaskWrap;
140 }
141
142 if constexpr (functions.update_inputs) {
143 xdev.update_inputs = updateInputsWrap;
144 }
145
146 if constexpr (functions.output) {
147 xdev.set_output = setOutputWrap;
148 }
149
150 if constexpr (functions.output_limits) {
151 xdev.get_output_limits = getOutputLimitsWrap;
152 }
153
154 if constexpr (functions.hand_tracking) {
155 xdev.get_hand_tracking = getHandTrackingWrap;
156 }
157
158 if constexpr (functions.face_tracking) {
159 xdev.get_face_tracking = getFaceTrackingWrap;
160 }
161
162 if constexpr (functions.face_calibration_android) {
163 xdev.get_face_calibration_state_android = getFaceCalibrationStateAndroidWrap;
164 }
165
166 if constexpr (functions.body_tracking) {
167 xdev.get_body_skeleton = getBodySkeletonWrap;
168 xdev.get_body_joints = getBodyJointsWrap;
169 xdev.reset_body_tracking_calibration_meta = resetBodyTrackingCalibrationMetaWrap;
170 xdev.set_body_tracking_calibration_override_meta = setBodyTrackingCalibrationOverrideMetaWrap;
171 }
172
173 if constexpr (functions.plane_detection) {
174 xdev.begin_plane_detection_ext = beginPlaneDetectionExtWrap;
175 xdev.destroy_plane_detection_ext = destroyPlaneDetectionExtWrap;
176 xdev.get_plane_detection_state_ext = getPlaneDetectionStateExtWrap;
177 xdev.get_plane_detections_ext = getPlaneDetectionsExtWrap;
178 }
179
180 if constexpr (functions.reference_space) {
181 xdev.ref_space_usage = refSpaceUsageWrap;
182 }
183
184 if constexpr (functions.battery) {
185 xdev.get_battery_status = getBatteryStatusWrap;
186 }
187
188 if constexpr (functions.brightness) {
189 xdev.get_brightness = getBrightnessWrap;
190 xdev.set_brightness = setBrightnessWrap;
191 }
192
193 if constexpr (functions.compositor_info) {
194 xdev.get_compositor_info = getCompositorInfoWrap;
195 }
196
197 if constexpr (functions.features) {
198 xdev.begin_feature = beginFeatureWrap;
199 xdev.end_feature = endFeatureWrap;
200 }
201 }
202
203 /*!
204 * Destructor
205 */
206 ~DeviceBase() noexcept = default;
207
208 const T &
209 derived() const noexcept
210 {
211 return static_cast<const T &>(*this);
212 }
213
214 T &
215 derived() noexcept
216 {
217 return static_cast<T &>(*this);
218 }
219
220 //! Gets the pointer to the derived class from a @ref xrt_device.
221 static const T *
222 fromXDev(const xrt_device *xdev) noexcept
223 {
224 return &(reinterpret_cast<const DeviceBase *>(xdev)->derived());
225 }
226
227 //! Gets the pointer to the derived class from a @ref xrt_device.
228 static T *
229 fromXDev(xrt_device *xdev) noexcept
230 {
231 return &(reinterpret_cast<DeviceBase *>(xdev)->derived());
232 }
233
234 //! Gets the underlying xrt_device pointer.
235 const xrt_device *
236 getXDev() const noexcept
237 {
238 return &mDevice;
239 }
240
241 //! Gets the underlying xrt_device pointer.
242 xrt_device *
243 getXDev() noexcept
244 {
245 return &mDevice;
246 }
247
248
249private: // Fields
250 /*!
251 * Wrapped @ref xrt_device. Must be the first data member: a pointer to it is
252 * then interconvertible with a pointer to this standard-layout base, which
253 * lets the glue cast a C pointer back to the derived C++ class. See
254 * @ref cpp-glue-wrappers.
255 */
256 xrt_device mDevice = {};
257
258
259private: // Functions
260#define GET(xdev) (fromXDev(xdev)->derived())
261
262 static xrt_result_t
263 updateInputsWrap(struct xrt_device *xdev) noexcept
264 try {
265 return GET(xdev).updateInputs();
266 }
267 G_CATCH_GUARDS
268
269 static xrt_result_t
270 getTrackedPoseWrap(struct xrt_device *xdev,
271 enum xrt_input_name name,
272 int64_t at_timestamp_ns,
273 struct xrt_space_relation *out_relation) noexcept
274 try {
275 return GET(xdev).getTrackedPose(name, at_timestamp_ns, out_relation);
276 }
277 G_CATCH_GUARDS
278
279 static xrt_result_t
280 getHandTrackingWrap(struct xrt_device *xdev,
281 enum xrt_input_name name,
282 int64_t desired_timestamp_ns,
283 struct xrt_hand_joint_set *out_value,
284 int64_t *out_timestamp_ns) noexcept
285 try {
286 return GET(xdev).getHandTracking(name, desired_timestamp_ns, out_value, out_timestamp_ns);
287 }
288 G_CATCH_GUARDS
289
290 static xrt_result_t
291 getFaceTrackingWrap(struct xrt_device *xdev,
292 enum xrt_input_name facial_expression_type,
293 int64_t at_timestamp_ns,
294 struct xrt_facial_expression_set *out_value) noexcept
295 try {
296 return GET(xdev).getFaceTracking(facial_expression_type, at_timestamp_ns, out_value);
297 }
298 G_CATCH_GUARDS
299
300 static xrt_result_t
301 getFaceCalibrationStateAndroidWrap(struct xrt_device *xdev, bool *out_face_is_calibrated) noexcept
302 try {
303 return GET(xdev).getFaceCalibrationStateAndroid(out_face_is_calibrated);
304 }
305 G_CATCH_GUARDS
306
307 static xrt_result_t
308 getBodySkeletonWrap(struct xrt_device *xdev,
309 enum xrt_input_name body_tracking_type,
310 struct xrt_body_skeleton *out_value) noexcept
311 try {
312 return GET(xdev).getBodySkeleton(body_tracking_type, out_value);
313 }
314 G_CATCH_GUARDS
315
316 static xrt_result_t
317 getBodyJointsWrap(struct xrt_device *xdev,
318 enum xrt_input_name body_tracking_type,
319 int64_t desired_timestamp_ns,
320 struct xrt_body_joint_set *out_value) noexcept
321 try {
322 return GET(xdev).getBodyJoints(body_tracking_type, desired_timestamp_ns, out_value);
323 }
324 G_CATCH_GUARDS
325
326 static xrt_result_t
327 resetBodyTrackingCalibrationMetaWrap(struct xrt_device *xdev) noexcept
328 try {
329 return GET(xdev).resetBodyTrackingCalibrationMeta();
330 }
331 G_CATCH_GUARDS
332
333 static xrt_result_t
334 setBodyTrackingCalibrationOverrideMetaWrap(struct xrt_device *xdev, float new_body_height) noexcept
335 try {
336 return GET(xdev).setBodyTrackingCalibrationOverrideMeta(new_body_height);
337 }
338 G_CATCH_GUARDS
339
340 static xrt_result_t
341 setOutputWrap(struct xrt_device *xdev, enum xrt_output_name name, const struct xrt_output_value *value) noexcept
342 try {
343 return GET(xdev).setOutput(name, value);
344 }
345 G_CATCH_GUARDS
346
347 static xrt_result_t
348 getOutputLimitsWrap(struct xrt_device *xdev, struct xrt_output_limits *limits) noexcept
349 try {
350 return GET(xdev).getOutputLimits(limits);
351 }
352 G_CATCH_GUARDS
353
354 static xrt_result_t
355 beginPlaneDetectionExtWrap(struct xrt_device *xdev,
356 const struct xrt_plane_detector_begin_info_ext *begin_info,
357 uint64_t plane_detection_id,
358 uint64_t *out_plane_detection_id) noexcept
359 try {
360 return GET(xdev).beginPlaneDetectionExt(begin_info, plane_detection_id, out_plane_detection_id);
361 }
362 G_CATCH_GUARDS
363
364 static xrt_result_t
365 destroyPlaneDetectionExtWrap(struct xrt_device *xdev, uint64_t plane_detection_id) noexcept
366 try {
367 return GET(xdev).destroyPlaneDetectionExt(plane_detection_id);
368 }
369 G_CATCH_GUARDS
370
371 static xrt_result_t
372 getPlaneDetectionStateExtWrap(struct xrt_device *xdev,
373 uint64_t plane_detection_id,
374 enum xrt_plane_detector_state_ext *out_state) noexcept
375 try {
376 return GET(xdev).getPlaneDetectionStateExt(plane_detection_id, out_state);
377 }
378 G_CATCH_GUARDS
379
380 static xrt_result_t
381 getPlaneDetectionsExtWrap(struct xrt_device *xdev,
382 uint64_t plane_detection_id,
383 struct xrt_plane_detections_ext *out_detections) noexcept
384 try {
385 return GET(xdev).getPlaneDetectionsExt(plane_detection_id, out_detections);
386 }
387 G_CATCH_GUARDS
388
389 static xrt_result_t
390 getViewPosesWrap(struct xrt_device *xdev,
391 const struct xrt_vec3 *default_eye_relation,
392 int64_t at_timestamp_ns,
393 enum xrt_view_type view_type,
394 uint32_t view_count,
395 struct xrt_space_relation *out_head_relation,
396 struct xrt_fov *out_fovs,
397 struct xrt_pose *out_poses) noexcept
398 try {
399 return GET(xdev).getViewPoses(default_eye_relation, at_timestamp_ns, view_type, view_count,
400 out_head_relation, out_fovs, out_poses);
401 }
402 G_CATCH_GUARDS
403
404 static xrt_result_t
405 computeDistortionWrap(
406 struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *out_result) noexcept
407 try {
408 return GET(xdev).computeDistortion(view, u, v, out_result);
409 }
410 G_CATCH_GUARDS
411
412 static xrt_result_t
413 getVisibilityMaskWrap(struct xrt_device *xdev,
414 enum xrt_visibility_mask_type type,
415 uint32_t view_index,
416 struct xrt_visibility_mask **out_mask) noexcept
417 try {
418 return GET(xdev).getVisibilityMask(type, view_index, out_mask);
419 }
420 G_CATCH_GUARDS
421
422 static xrt_result_t
423 refSpaceUsageWrap(struct xrt_device *xdev,
424 enum xrt_reference_space_type type,
425 enum xrt_input_name name,
426 bool used) noexcept
427 try {
428 return GET(xdev).refSpaceUsage(type, name, used);
429 }
430 G_CATCH_GUARDS
431
432 static xrt_result_t
433 isFormFactorAvailableWrap(struct xrt_device *xdev,
434 enum xrt_form_factor form_factor,
435 bool *out_available) noexcept
436 try {
437 return GET(xdev).isFormFactorAvailable(form_factor, out_available);
438 }
439 G_CATCH_GUARDS
440
441 static xrt_result_t
442 getBatteryStatusWrap(struct xrt_device *xdev, bool *out_present, bool *out_charging, float *out_charge) noexcept
443 try {
444 return GET(xdev).getBatteryStatus(out_present, out_charging, out_charge);
445 }
446 G_CATCH_GUARDS
447
448 static xrt_result_t
449 getBrightnessWrap(struct xrt_device *xdev, float *out_brightness) noexcept
450 try {
451 return GET(xdev).getBrightness(out_brightness);
452 }
453 G_CATCH_GUARDS
454
455 static xrt_result_t
456 setBrightnessWrap(struct xrt_device *xdev, float brightness, bool relative) noexcept
457 try {
458 return GET(xdev).setBrightness(brightness, relative);
459 }
460 G_CATCH_GUARDS
461
462 static xrt_result_t
463 getCompositorInfoWrap(struct xrt_device *xdev,
464 const struct xrt_device_compositor_mode *mode,
465 struct xrt_device_compositor_info *out_info) noexcept
466 try {
467 return GET(xdev).getCompositorInfo(mode, out_info);
468 }
469 G_CATCH_GUARDS
470
471 static xrt_result_t
472 beginFeatureWrap(struct xrt_device *xdev, enum xrt_device_feature_type type) noexcept
473 try {
474 return GET(xdev).beginFeature(type);
475 }
476 G_CATCH_GUARDS
477
478 static xrt_result_t
479 endFeatureWrap(struct xrt_device *xdev, enum xrt_device_feature_type type) noexcept
480 try {
481 return GET(xdev).endFeature(type);
482 }
483 G_CATCH_GUARDS
484
485 static void
486 destroyDeviceWrap(struct xrt_device *xdev) noexcept
487 try {
488 T::destroyDevice(xdev);
489 }
490 G_CATCH_GUARDS_VOID
491
492
493#undef GET
494};
495
496} // namespace xrt::util
CRTP glue wrapper for xrt_device.
Definition g_device.hpp:109
DeviceBase() noexcept
Fully resets and sets function pointers on xrt_device.
Definition g_device.hpp:114
xrt_device * getXDev() noexcept
Gets the underlying xrt_device pointer.
Definition g_device.hpp:243
static T * fromXDev(xrt_device *xdev) noexcept
Gets the pointer to the derived class from a xrt_device.
Definition g_device.hpp:229
static const T * fromXDev(const xrt_device *xdev) noexcept
Gets the pointer to the derived class from a xrt_device.
Definition g_device.hpp:222
~DeviceBase() noexcept=default
Destructor.
const xrt_device * getXDev() const noexcept
Gets the underlying xrt_device pointer.
Definition g_device.hpp:236
Catch guards for glue classes.
Shared type traits 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:599
void u_device_id_assign(struct xrt_device *xdev)
Assign a newly generated ID to the given device.
Definition u_device_id.c:31
xrt_visibility_mask_type
Visibility mask, mirror of XrVisibilityMaskKHR.
Definition xrt_defines.h:2468
xrt_form_factor
What form factor is this device, mostly maps onto OpenXR's XrFormFactor.
Definition xrt_defines.h:2408
xrt_input_name
Every internal input source known to monado with a baked in type.
Definition xrt_defines.h:930
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:625
xrt_output_name
Name of a output with a baked in type.
Definition xrt_defines.h:1612
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:28
bool body_tracking
xrt_device::get_body_skeleton xrt_device::get_body_joints xrt_device::reset_body_tracking_calibration...
Definition g_device.hpp:65
bool reference_space
xrt_device::ref_space_usage
Definition g_device.hpp:76
bool plane_detection
xrt_device::begin_plane_detection_ext xrt_device::destroy_plane_detection_ext xrt_device::get_plane_d...
Definition g_device.hpp:73
bool output_limits
xrt_device::get_output_limits
Definition g_device.hpp:48
bool visibility_mask
xrt_device::get_visibility_mask
Definition g_device.hpp:39
bool update_inputs
xrt_device::update_inputs
Definition g_device.hpp:42
bool compositor_info
xrt_device::get_compositor_info
Definition g_device.hpp:88
bool hmd
xrt_device::get_view_poses xrt_device::is_form_factor_available
Definition g_device.hpp:33
bool output
xrt_device::set_output
Definition g_device.hpp:45
bool battery
xrt_device::get_battery_status
Definition g_device.hpp:79
bool brightness
xrt_device::get_brightness xrt_device::set_brightness
Definition g_device.hpp:85
bool hand_tracking
xrt_device::get_hand_tracking
Definition g_device.hpp:51
bool face_tracking
xrt_device::get_face_tracking
Definition g_device.hpp:54
bool distortion
xrt_device::compute_distortion
Definition g_device.hpp:36
bool features
xrt_device::begin_feature xrt_device::end_feature
Definition g_device.hpp:94
bool face_calibration_android
xrt_device::get_face_calibration_state_android
Definition g_device.hpp:57
Definition xrt_defines.h:2301
Definition xrt_defines.h:2198
Compositor information for a device.
Definition xrt_device.h:110
Compositor mode information for a device.
Definition xrt_device.h:126
A single HMD or input device.
Definition xrt_device.h:340
Definition xrt_defines.h:1967
Describes a projection matrix fov.
Definition xrt_defines.h:512
Joint set type used for hand tracking.
Definition xrt_defines.h:1521
Output limits of a particular device.
Definition xrt_device.h:288
A union of all output types.
Definition xrt_defines.h:2386
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:492
A relation with two spaces, includes velocity and acceleration.
Definition xrt_defines.h:683
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.
Generator for per-process unique xrt_device_id values.
xrt_view_type
View type to be rendered to by the compositor.
Definition xrt_defines.h:2417
Header defining an xrt display or controller device.
xrt_device_feature_type
Higher level features for devices.
Definition xrt_device.h:276