The open source OpenXR runtime
1// Copyright 2022-2023, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Fallback builder the old method of probing devices.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup xrt_iface
8 */
9
10#include "xrt/xrt_config_drivers.h"
11#include "xrt/xrt_prober.h"
12
13#include "util/u_misc.h"
14#include "util/u_device.h"
15#include "util/u_builders.h"
16#include "util/u_system_helpers.h"
17
18#include "target_builder_interface.h"
19
20#include <assert.h>
21
22static const char *driver_list[] = {
23#ifdef XRT_BUILD_DRIVER_HYDRA
24 "hydra",
25#endif
26
27#ifdef XRT_BUILD_DRIVER_HDK
28 "hdk",
29#endif
30
31#ifdef XRT_BUILD_DRIVER_ULV2
32 "ulv2",
33#endif
34
35#ifdef XRT_BUILD_DRIVER_DEPTHAI
36 "depthai",
37#endif
38
39#ifdef XRT_BUILD_DRIVER_WMR
40 "wmr",
41#endif
42
43#ifdef XRT_BUILD_DRIVER_ARDUINO
44 "arduino",
45#endif
46
47#ifdef XRT_BUILD_DRIVER_DAYDREAM
48 "daydream",
49#endif
50
51#ifdef XRT_BUILD_DRIVER_OHMD
52 "oh",
53#endif
54
55#ifdef XRT_BUILD_DRIVER_NS
56 "ns",
57#endif
58
59#ifdef XRT_BUILD_DRIVER_ANDROID
60 "android",
61#endif
62
63#ifdef XRT_BUILD_DRIVER_ILLIXR
64 "illixr",
65#endif
66
67#ifdef XRT_BUILD_DRIVER_REALSENSE
68 "rs",
69#endif
70
71#ifdef XRT_BUILD_DRIVER_EUROC
72 "euroc",
73#endif
74
75#ifdef XRT_BUILD_DRIVER_QWERTY
76 "qwerty",
77#endif
78
79#if defined(XRT_BUILD_DRIVER_HANDTRACKING) && defined(XRT_BUILD_DRIVER_DEPTHAI)
80 "ht",
81#endif
82
83#if defined(XRT_BUILD_DRIVER_SIMULATED)
84 "simulated",
85#endif
86 NULL,
87};
88
89
90/*
91 *
92 * Member functions.
93 *
94 */
95
96static xrt_result_t
97legacy_estimate_system(struct xrt_builder *xb,
98 cJSON *config,
99 struct xrt_prober *xp,
100 struct xrt_builder_estimate *estimate)
101{
102 // If no driver is enabled, there is no way to create a HMD
103 bool may_create_hmd = xb->driver_identifier_count > 0;
104
105 estimate->maybe.head = may_create_hmd;
106 estimate->maybe.left = may_create_hmd;
107 estimate->maybe.right = may_create_hmd;
108 estimate->priority = -20;
109
110 return XRT_SUCCESS;
111}
112
113static xrt_result_t
114legacy_open_system_impl(struct xrt_builder *xb,
115 cJSON *config,
116 struct xrt_prober *xp,
117 struct xrt_tracking_origin *origin,
118 struct xrt_system_devices *xsysd,
119 struct xrt_frame_context *xfctx,
120 struct u_builder_roles_helper *ubrh)
121{
122 xrt_result_t xret;
123 int ret;
124
125
126 /*
127 * Create the devices.
128 */
129
130 xret = xrt_prober_probe(xp);
131 if (xret != XRT_SUCCESS) {
132 return xret;
133 }
134
135 ret = xrt_prober_select(xp, xsysd->xdevs, ARRAY_SIZE(xsysd->xdevs));
136 if (ret < 0) {
137 return XRT_ERROR_DEVICE_CREATION_FAILED;
138 }
139
140 // Count the xdevs.
141 for (uint32_t i = 0; i < ARRAY_SIZE(xsysd->xdevs); i++) {
142 if (xsysd->xdevs[i] == NULL) {
143 break;
144 }
145
146 xsysd->xdev_count++;
147 }
148
149
150 /*
151 * Setup the roles.
152 */
153
154 int head_idx, left_idx, right_idx, gamepad_idx;
155 u_device_assign_xdev_roles(xsysd->xdevs, xsysd->xdev_count, &head_idx, &left_idx, &right_idx, &gamepad_idx);
156
157 struct xrt_device *head = NULL;
158 struct xrt_device *left = NULL, *right = NULL, *gamepad = NULL;
159 struct xrt_device *unobstructed_left_ht = NULL, *unobstructed_right_ht = NULL;
160 struct xrt_device *conforming_left_ht = NULL, *conforming_right_ht = NULL;
161
162 if (head_idx >= 0) {
163 head = xsysd->xdevs[head_idx];
164 }
165 if (left_idx >= 0) {
166 left = xsysd->xdevs[left_idx];
167 }
168 if (right_idx >= 0) {
169 right = xsysd->xdevs[right_idx];
170 }
171 if (gamepad_idx >= 0) {
172 gamepad = xsysd->xdevs[gamepad_idx];
173 }
174
175 // Find hand tracking devices.
176 unobstructed_left_ht = u_system_devices_get_ht_device_unobstructed_left(xsysd);
177 unobstructed_right_ht = u_system_devices_get_ht_device_unobstructed_right(xsysd);
178
179 conforming_left_ht = u_system_devices_get_ht_device_conforming_left(xsysd);
180 conforming_right_ht = u_system_devices_get_ht_device_conforming_right(xsysd);
181
182 // Assign to role(s).
183 ubrh->head = head;
184 ubrh->left = left;
185 ubrh->right = right;
186 ubrh->gamepad = gamepad;
187 ubrh->hand_tracking.unobstructed.left = unobstructed_left_ht;
188 ubrh->hand_tracking.unobstructed.right = unobstructed_right_ht;
189 ubrh->hand_tracking.conforming.left = conforming_left_ht;
190 ubrh->hand_tracking.conforming.right = conforming_right_ht;
191
192 return XRT_SUCCESS;
193}
194
195static void
196legacy_destroy(struct xrt_builder *xb)
197{
198 free(xb);
199}
200
201
202/*
203 *
204 * 'Exported' functions.
205 *
206 */
207
208struct xrt_builder *
209t_builder_legacy_create(void)
210{
211 struct u_builder *ub = U_TYPED_CALLOC(struct u_builder);
212
213 // xrt_builder fields.
214 ub->base.estimate_system = legacy_estimate_system;
215 ub->base.open_system = u_builder_open_system_static_roles;
216 ub->base.destroy = legacy_destroy;
217 ub->base.identifier = "legacy";
218 ub->base.name = "Legacy probing system";
219 ub->base.driver_identifiers = driver_list;
220 ub->base.driver_identifier_count = ARRAY_SIZE(driver_list) - 1;
221
222 // u_builder fields.
223 ub->open_system_static_roles = legacy_open_system_impl;
224
225 return &ub->base;
226}