The open source OpenXR runtime

xrt: Add add_device function to space overseer

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2627>

Changed files
+119 -16
src
xrt
auxiliary
include
ipc
+65 -16
src/xrt/auxiliary/util/u_space_overseer.c
··· 1 1 // Copyright 2023, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 474 475 475 476 /* 476 477 * 478 + * Device helpers. 479 + * 480 + */ 481 + 482 + /*! 483 + * Helper function to add a device to the space overseer. This function 484 + * handles creating or finding a space for the device's tracking origin 485 + * and linking the device to that space. 486 + */ 487 + static xrt_result_t 488 + add_device_helper(struct u_space_overseer *uso, struct xrt_device *xdev) 489 + { 490 + struct xrt_tracking_origin *torig = xdev->tracking_origin; 491 + assert(torig != NULL); 492 + 493 + struct xrt_space *root = uso->base.semantic.root; 494 + uint64_t key = (uint64_t)(intptr_t)torig; 495 + struct xrt_space *xs = NULL; 496 + 497 + // Need to take the write lock. 498 + pthread_rwlock_wrlock(&uso->lock); 499 + 500 + // Does this tracking origin already have space. 501 + void *ptr = NULL; 502 + u_hashmap_int_find(uso->xto_map, key, &ptr); 503 + 504 + if (ptr != NULL) { 505 + xs = (struct xrt_space *)ptr; 506 + } else { 507 + /* 508 + * If we ever make u_space_overseer sub-classable maek sure 509 + * this calls the right function, can't call interface function 510 + * as the lock is held here. 511 + */ 512 + xs = (struct xrt_space *)create_space(U_SPACE_TYPE_OFFSET, u_space(root)); 513 + 514 + update_offset_write_locked(u_space(xs), &torig->initial_offset); 515 + 516 + u_hashmap_int_insert(uso->xto_map, key, xs); 517 + } 518 + 519 + pthread_rwlock_unlock(&uso->lock); 520 + 521 + u_space_overseer_link_space_to_device(uso, xs, xdev); 522 + 523 + return XRT_SUCCESS; 524 + } 525 + 526 + 527 + /* 528 + * 477 529 * Member functions. 478 530 * 479 531 */ ··· 1033 1085 return xret; 1034 1086 } 1035 1087 1088 + static xrt_result_t 1089 + add_device(struct xrt_space_overseer *xso, struct xrt_device *xdev) 1090 + { 1091 + struct u_space_overseer *uso = u_space_overseer(xso); 1092 + 1093 + return add_device_helper(uso, xdev); 1094 + } 1095 + 1036 1096 static void 1037 1097 destroy(struct xrt_space_overseer *xso) 1038 1098 { ··· 1089 1149 uso->base.set_tracking_origin_offset = set_tracking_origin_offset; 1090 1150 uso->base.get_reference_space_offset = get_reference_space_offset; 1091 1151 uso->base.set_reference_space_offset = set_reference_space_offset; 1152 + uso->base.add_device = add_device; 1092 1153 uso->base.destroy = destroy; 1093 1154 uso->broadcast = broadcast; 1094 1155 ··· 1117 1178 bool root_is_unbounded, 1118 1179 bool per_app_local_spaces) 1119 1180 { 1120 - struct xrt_space *root = uso->base.semantic.root; // Convenience 1121 1181 uso->per_app_local_spaces = per_app_local_spaces; 1122 1182 1183 + // Add all devices to the space overseer. 1123 1184 for (uint32_t i = 0; i < xdev_count; i++) { 1124 - struct xrt_device *xdev = xdevs[i]; 1125 - struct xrt_tracking_origin *torig = xdev->tracking_origin; 1126 - uint64_t key = (uint64_t)(intptr_t)torig; 1127 - struct xrt_space *xs = NULL; 1128 - 1129 - void *ptr = NULL; 1130 - u_hashmap_int_find(uso->xto_map, key, &ptr); 1131 - 1132 - if (ptr != NULL) { 1133 - xs = (struct xrt_space *)ptr; 1134 - } else { 1135 - u_space_overseer_create_offset_space(uso, root, &torig->initial_offset, &xs); 1136 - u_hashmap_int_insert(uso->xto_map, key, xs); 1185 + xrt_result_t xret = add_device_helper(uso, xdevs[i]); 1186 + if (xret != XRT_SUCCESS) { 1187 + U_LOG_E("Failed to add device '%s' to space overseer!", xdevs[i]->str); 1137 1188 } 1138 - 1139 - u_space_overseer_link_space_to_device(uso, xs, xdev); 1140 1189 } 1141 1190 1142 1191 // If these are set something is probably wrong, but just in case unset them.
+47
src/xrt/include/xrt/xrt_space.h
··· 1 1 // Copyright 2019-2023, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 303 304 struct xrt_space **out_local_space, 304 305 struct xrt_space **out_local_floor_space); 305 306 307 + /* 308 + * 309 + * Special inter-monado component functions. 310 + * 311 + */ 312 + 313 + /*! 314 + * Add a new device to be tracked by the space overseer. The exact 315 + * semantic of the space is determined by the implementation of the 316 + * space overseer. And may be outright rejected by the implementation. 317 + * 318 + * After this call completes successfully, the device can be passed 319 + * into the @ref xrt_space_overseer::locate_device function, but may 320 + * not be locatable immediately. 321 + * 322 + * This function is not intended to be called by the OpenXR state 323 + * tracker, but by other monado components that need to add devices 324 + * but does not own the space overseer. Components like the fixer 325 + * uppers or for push devices. 326 + * 327 + * @param[in] xso The space overseer. 328 + * @param[in] xdev The device to be tracked. 329 + * @return XRT_SUCCESS if added, otherwise an error code. 330 + */ 331 + xrt_result_t (*add_device)(struct xrt_space_overseer *xso, struct xrt_device *xdev); 332 + 333 + 334 + /* 335 + * 336 + * Destroy function always comes last. 337 + * 338 + */ 339 + 306 340 /*! 307 341 * Destroy function. 308 342 * ··· 513 547 struct xrt_space **out_local_floor_space) 514 548 { 515 549 return xso->create_local_space(xso, out_local_space, out_local_floor_space); 550 + } 551 + 552 + /*! 553 + * @copydoc xrt_space_overseer::add_device 554 + * 555 + * Helper for calling through the function pointer. 556 + * 557 + * @public @memberof xrt_space_overseer 558 + */ 559 + static inline xrt_result_t 560 + xrt_space_overseer_add_device(struct xrt_space_overseer *xso, struct xrt_device *xdev) 561 + { 562 + return xso->add_device(xso, xdev); 516 563 } 517 564 518 565 /*!
+7
src/xrt/ipc/client/ipc_client_space_overseer.c
··· 318 318 return ipc_call_space_set_reference_space_offset(icspo->ipc_c, type, offset); 319 319 } 320 320 321 + static xrt_result_t 322 + add_device(struct xrt_space_overseer *xso, struct xrt_device *xdev) 323 + { 324 + return XRT_ERROR_NOT_IMPLEMENTED; 325 + } 326 + 321 327 static void 322 328 destroy(struct xrt_space_overseer *xso) 323 329 { ··· 374 380 icspo->base.set_tracking_origin_offset = set_tracking_origin_offset; 375 381 icspo->base.get_reference_space_offset = get_reference_space_offset; 376 382 icspo->base.set_reference_space_offset = set_reference_space_offset; 383 + icspo->base.add_device = add_device; 377 384 icspo->base.destroy = destroy; 378 385 icspo->ipc_c = ipc_c; 379 386