The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

xrt: server can use xrt_instance::is_system_available to delay system creation

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

authored by

Andrei Aristarkhov and committed by
Jakob Bornecrantz
803e8168 6417c181

+164 -18
+20
src/xrt/include/xrt/xrt_instance.h
··· 1 1 // Copyright 2020-2024, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 126 127 */ 127 128 128 129 /*! 130 + * Checks if the system can be created with create_system(). 131 + */ 132 + xrt_result_t (*is_system_available)(struct xrt_instance *xinst, bool *out_available); 133 + 134 + /*! 129 135 * Creates all of the system resources like the devices and system 130 136 * compositor. The system compositor is optional. 131 137 * ··· 198 204 */ 199 205 struct xrt_instance_android *android_instance; 200 206 }; 207 + 208 + 209 + /*! 210 + * @copydoc xrt_instance::create_system 211 + * 212 + * Helper for calling through the function pointer. 213 + * 214 + * @public @memberof xrt_instance 215 + */ 216 + static inline xrt_result_t 217 + xrt_instance_is_system_available(struct xrt_instance *xinst, bool *out_available) 218 + { 219 + return xinst->is_system_available(xinst, out_available); 220 + } 201 221 202 222 /*! 203 223 * @copydoc xrt_instance::create_system
+9
src/xrt/ipc/client/ipc_client_instance.c
··· 131 131 */ 132 132 133 133 static xrt_result_t 134 + ipc_client_instance_is_system_available(struct xrt_instance *xinst, bool *out_available) 135 + { 136 + struct ipc_client_instance *ii = ipc_client_instance(xinst); 137 + xrt_result_t xret = ipc_call_instance_is_system_available(&ii->ipc_c, out_available); 138 + IPC_CHK_ALWAYS_RET(&ii->ipc_c, xret, "ipc_call_instance_is_system_available"); 139 + } 140 + 141 + static xrt_result_t 134 142 ipc_client_instance_create_system(struct xrt_instance *xinst, 135 143 struct xrt_system **out_xsys, 136 144 struct xrt_system_devices **out_xsysd, ··· 284 292 ipc_instance_create(const struct xrt_instance_info *i_info, struct xrt_instance **out_xinst) 285 293 { 286 294 struct ipc_client_instance *ii = U_TYPED_CALLOC(struct ipc_client_instance); 295 + ii->base.is_system_available = ipc_client_instance_is_system_available; 287 296 ii->base.create_system = ipc_client_instance_create_system; 288 297 ii->base.get_prober = ipc_client_instance_get_prober; 289 298 ii->base.destroy = ipc_client_instance_destroy;
+13
src/xrt/ipc/server/ipc_server.h
··· 1 1 // Copyright 2020-2023, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 89 90 { 90 91 //! Link back to the main server. 91 92 struct ipc_server *server; 93 + 94 + //! Has the system part of the shm initialized. 95 + bool has_init_shm_system; 92 96 93 97 //! Session for this client. 94 98 struct xrt_session *xs; ··· 409 413 } global_state; 410 414 }; 411 415 416 + /*! 417 + * Finish setting up the server by creating the system, compositor and devices. 418 + * 419 + * @ingroup ipc_server 420 + */ 421 + xrt_result_t 422 + ipc_server_init_system_if_available_locked(struct ipc_server *s, 423 + volatile struct ipc_client_state *ics, 424 + bool *out_available); 412 425 413 426 /*! 414 427 * Get the current state of a client.
+19
src/xrt/ipc/server/ipc_server_handler.c
··· 400 400 } 401 401 402 402 xrt_result_t 403 + ipc_handle_instance_is_system_available(volatile struct ipc_client_state *ics, bool *out_available) 404 + { 405 + IPC_TRACE_MARKER(); 406 + 407 + xrt_result_t xret = XRT_SUCCESS; 408 + 409 + struct ipc_server *s = ics->server; 410 + 411 + os_mutex_lock(&s->global_state.lock); 412 + 413 + xret = ipc_server_init_system_if_available_locked(s, ics, out_available); 414 + IPC_CHK_WITH_GOTO(s, xret, "ipc_server_init_system_if_available_locked", cleanup); 415 + 416 + cleanup: 417 + os_mutex_unlock(&s->global_state.lock); 418 + return xret; 419 + } 420 + 421 + xrt_result_t 403 422 ipc_handle_system_compositor_get_info(volatile struct ipc_client_state *ics, 404 423 struct xrt_system_compositor_info *out_info) 405 424 {
+68 -18
src/xrt/ipc/server/ipc_server_process.c
··· 279 279 } 280 280 281 281 XRT_CHECK_RESULT static xrt_result_t 282 - init_shm(struct ipc_server *s, volatile struct ipc_client_state *cs) 282 + init_shm_and_instance_state(struct ipc_server *s, volatile struct ipc_client_state *ics) 283 283 { 284 284 const size_t size = sizeof(struct ipc_shared_memory); 285 285 xrt_shmem_handle_t handle; 286 286 287 - xrt_result_t xret = ipc_shmem_create(size, &handle, (void **)&s->isms[cs->server_thread_index]); 287 + xrt_result_t xret = ipc_shmem_create(size, &handle, (void **)&s->isms[ics->server_thread_index]); 288 288 IPC_CHK_AND_RET(s, xret, "ipc_shmem_create"); 289 289 290 290 // we have a filehandle, we will pass this to our client 291 - cs->ism_handle = handle; 291 + ics->ism_handle = handle; 292 + 293 + // Convenience 294 + struct ipc_shared_memory *ism = s->isms[ics->server_thread_index]; 292 295 296 + // Clients expect git version info and timestamp available upon connect. 297 + snprintf(ism->u_git_tag, IPC_VERSION_NAME_LEN, "%s", u_git_tag); 293 298 299 + // Used to synchronize all client's xrt_instance::startup_timestamp. 300 + ism->startup_timestamp = os_monotonic_get_ns(); 301 + 302 + return XRT_SUCCESS; 303 + } 304 + 305 + static void 306 + init_system_shm_state(struct ipc_server *s, volatile struct ipc_client_state *cs) 307 + { 294 308 /* 295 309 * 296 310 * Setup the shared memory state. ··· 299 313 300 314 uint32_t count = 0; 301 315 struct ipc_shared_memory *ism = s->isms[cs->server_thread_index]; 302 - 303 - ism->startup_timestamp = os_monotonic_get_ns(); 304 316 305 317 // Setup the tracking origins. 306 318 count = 0; ··· 423 435 ism->roles.eyes = find_xdev_index(s, s->xsysd->static_roles.eyes); 424 436 ism->roles.face = find_xdev_index(s, s->xsysd->static_roles.face); 425 437 ism->roles.body = find_xdev_index(s, s->xsysd->static_roles.body); 438 + 426 439 #define SET_HT_ROLE(SRC) \ 427 440 ism->roles.hand_tracking.SRC.left = find_xdev_index(s, s->xsysd->static_roles.hand_tracking.SRC.left); \ 428 441 ism->roles.hand_tracking.SRC.right = find_xdev_index(s, s->xsysd->static_roles.hand_tracking.SRC.right); 429 442 SET_HT_ROLE(unobstructed) 430 443 SET_HT_ROLE(conforming) 431 444 #undef SET_HT_ROLE 432 - 433 - // Fill out git version info. 434 - snprintf(ism->u_git_tag, IPC_VERSION_NAME_LEN, "%s", u_git_tag); 435 - 436 - return XRT_SUCCESS; 437 445 } 438 446 439 447 static void ··· 487 495 488 496 xret = xrt_instance_create(NULL, &s->xinst); 489 497 IPC_CHK_WITH_GOTO(s, xret, "xrt_instance_create", error); 490 - 491 - xret = xrt_instance_create_system(s->xinst, &s->xsys, &s->xsysd, &s->xso, &s->xsysc); 492 - IPC_CHK_WITH_GOTO(s, xret, "xrt_instance_create_system", error); 493 - 494 - // Always succeeds. 495 - init_idevs(s); 496 - init_tracking_origins(s); 497 498 498 499 ret = ipc_server_mainloop_init(&s->ml); 499 500 if (ret < 0) { ··· 806 807 */ 807 808 808 809 xrt_result_t 810 + ipc_server_init_system_if_available_locked(struct ipc_server *s, 811 + volatile struct ipc_client_state *ics, 812 + bool *out_available) 813 + { 814 + xrt_result_t xret = XRT_SUCCESS; 815 + 816 + bool available = false; 817 + 818 + if (s->xsys) { 819 + available = true; 820 + } else { 821 + xret = xrt_instance_is_system_available(s->xinst, &available); 822 + IPC_CHK_WITH_GOTO(s, xret, "xrt_instance_is_system_available", error); 823 + 824 + if (available) { 825 + xret = xrt_instance_create_system(s->xinst, &s->xsys, &s->xsysd, &s->xso, &s->xsysc); 826 + IPC_CHK_WITH_GOTO(s, xret, "xrt_instance_create_system", error); 827 + 828 + // Always succeeds. 829 + init_idevs(s); 830 + init_tracking_origins(s); 831 + } 832 + } 833 + 834 + if (available && ics != NULL && !ics->has_init_shm_system) { 835 + init_system_shm_state(s, ics); 836 + ics->has_init_shm_system = true; 837 + } 838 + 839 + if (out_available) { 840 + *out_available = available; 841 + } 842 + 843 + return XRT_SUCCESS; 844 + 845 + error: 846 + return xret; 847 + } 848 + 849 + xrt_result_t 809 850 ipc_server_get_client_app_state(struct ipc_server *s, uint32_t client_id, struct ipc_app_state *out_ias) 810 851 { 811 852 os_mutex_lock(&s->global_state.lock); ··· 982 1023 ics->plane_detection_ids = NULL; 983 1024 ics->plane_detection_xdev = NULL; 984 1025 985 - xrt_result_t xret = init_shm(vs, ics); 1026 + xrt_result_t xret = init_shm_and_instance_state(vs, ics); 986 1027 if (xret != XRT_SUCCESS) { 987 1028 988 1029 // Unlock when we are done. ··· 1048 1089 1049 1090 // Tell the callbacks we are entering the main-loop. 1050 1091 callbacks->mainloop_entering(s, s->xinst, data); 1092 + 1093 + // Early init the system. If not available now, will try again per client request. 1094 + xret = ipc_server_init_system_if_available_locked( // 1095 + s, // 1096 + NULL, // optional - ics 1097 + NULL); // optional - out_available 1098 + if (xret != XRT_SUCCESS) { 1099 + U_LOG_CHK_ONLY_PRINT(log_level, xret, "ipc_server_init_system_if_available_locked"); 1100 + } 1051 1101 1052 1102 // Main loop. 1053 1103 ret = main_loop(s);
+6
src/xrt/ipc/shared/proto.json
··· 11 11 ] 12 12 }, 13 13 14 + "instance_is_system_available": { 15 + "out": [ 16 + {"name": "available", "type": "bool"} 17 + ] 18 + }, 19 + 14 20 "system_get_properties": { 15 21 "out": [ 16 22 {"name": "properties", "type": "struct xrt_system_properties"}
+15
src/xrt/state_trackers/oxr/oxr_instance.c
··· 479 479 xrt_result_t xret; 480 480 XrResult ret; 481 481 482 + bool available = false; 483 + xret = xrt_instance_is_system_available(inst->xinst, &available); 484 + if (xret != XRT_SUCCESS) { 485 + struct u_pp_sink_stack_only sink; 486 + u_pp_delegate_t dg = u_pp_sink_stack_only_init(&sink); 487 + u_pp(dg, "Call to xrt_instance_is_system_available failed: "); 488 + u_pp_xrt_result(dg, xret); 489 + ret = oxr_error(log, xret == XRT_ERROR_IPC_FAILURE ? XR_ERROR_INSTANCE_LOST : XR_ERROR_RUNTIME_FAILURE, 490 + "%s", sink.buffer); 491 + return ret; 492 + } 493 + if (!available) { 494 + return XR_ERROR_FORM_FACTOR_UNAVAILABLE; 495 + } 496 + 482 497 // Create the compositor if we are not headless, currently always create it. 483 498 bool should_create_compositor = true /* !inst->extensions.MND_headless */; 484 499
+14
src/xrt/targets/common/target_instance.c
··· 1 1 // Copyright 2020-2024, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 50 51 * Internal functions. 51 52 * 52 53 */ 54 + 55 + static xrt_result_t 56 + t_instance_is_system_available(struct xrt_instance *xinst, bool *out_available) 57 + { 58 + XRT_TRACE_MARKER(); 59 + 60 + assert(out_available != NULL); 61 + 62 + *out_available = true; 63 + 64 + return XRT_SUCCESS; 65 + } 53 66 54 67 static xrt_result_t 55 68 t_instance_create_system(struct xrt_instance *xinst, ··· 168 181 } 169 182 170 183 struct t_instance *tinst = U_TYPED_CALLOC(struct t_instance); 184 + tinst->base.is_system_available = t_instance_is_system_available; 171 185 tinst->base.create_system = t_instance_create_system; 172 186 tinst->base.get_prober = t_instance_get_prober; 173 187 tinst->base.destroy = t_instance_destroy;