The open source OpenXR runtime
0
fork

Configure Feed

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

st/oxr: delay ipc client system creation until xrGetSystem call

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

authored by

Andrei Aristarkhov and committed by
Jakob Bornecrantz
6417c181 b8b4cfad

+100 -56
+14 -2
src/xrt/state_trackers/oxr/oxr_api_system.c
··· 65 65 struct oxr_system *systems[1] = {&inst->system}; 66 66 uint32_t system_count = ARRAY_SIZE(systems); 67 67 68 - XrResult ret = oxr_system_select(&log, systems, system_count, getInfo->formFactor, &selected); 68 + /* 69 + * This lock is needed to make sure that xrGetSystem can be called from 70 + * multiple threads. This happens in the CTS. 71 + */ 72 + os_mutex_lock(&inst->system_init_lock); 73 + XrResult ret = oxr_instance_init_system_locked(&log, inst); 74 + os_mutex_unlock(&inst->system_init_lock); 75 + 69 76 if (ret != XR_SUCCESS) { 70 - return ret; 77 + return ret; // Already logged 78 + } 79 + 80 + ret = oxr_system_select(&log, systems, system_count, getInfo->formFactor, &selected); 81 + if (ret != XR_SUCCESS) { 82 + return ret; // Already logged 71 83 } 72 84 73 85 *systemId = selected->systemId;
+75 -54
src/xrt/state_trackers/oxr/oxr_instance.c
··· 91 91 inst->system.visibility_mask[i] = NULL; 92 92 } 93 93 94 + os_mutex_destroy(&inst->system_init_lock); 95 + 94 96 xrt_space_overseer_destroy(&inst->system.xso); 95 97 os_mutex_destroy(&inst->system.sync_actions_mutex); 96 98 xrt_system_devices_destroy(&inst->system.xsysd); ··· 258 260 return ret; 259 261 } 260 262 263 + m_ret = os_mutex_init(&inst->system_init_lock); 264 + if (m_ret < 0) { 265 + ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Failed to init system init mutex"); 266 + return ret; 267 + } 268 + 269 + 261 270 #ifdef XRT_FEATURE_CLIENT_DEBUG_GUI 262 271 struct u_debug_gui_create_info udgci = { 263 272 .window_title = "Monado! ✨⚡🔥", ··· 371 380 } 372 381 #endif // XRT_OS_ANDROID 373 382 374 - struct oxr_system *sys = &inst->system; 375 - 376 - // Create the compositor if we are not headless, currently always create it. 377 - bool should_create_compositor = true /* !inst->extensions.MND_headless */; 378 - 379 - // Create the system. 380 - if (should_create_compositor) { 381 - xret = xrt_instance_create_system(inst->xinst, &sys->xsys, &sys->xsysd, &sys->xso, &sys->xsysc); 382 - } else { 383 - xret = xrt_instance_create_system(inst->xinst, &sys->xsys, &sys->xsysd, &sys->xso, NULL); 384 - } 385 - 386 - if (xret != XRT_SUCCESS) { 387 - ret = oxr_error(log, XR_ERROR_INITIALIZATION_FAILED, "Failed to create the system '%i'", xret); 388 - oxr_instance_destroy(log, &inst->handle); 389 - return ret; 390 - } 391 - 392 - ret = XR_SUCCESS; 393 - if (sys->xsysd == NULL) { 394 - ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Huh?! Field sys->xsysd was NULL?"); 395 - } else if (should_create_compositor && sys->xsysc == NULL) { 396 - ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Huh?! Field sys->xsysc was NULL?"); 397 - } else if (!should_create_compositor && sys->xsysc != NULL) { 398 - ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Huh?! Field sys->xsysc was not NULL?"); 399 - } 400 - 401 - if (ret != XR_SUCCESS) { 402 - oxr_instance_destroy(log, &inst->handle); 403 - return ret; 404 - } 405 - 406 - // Did we find any HMD 407 - // @todo Headless with only controllers? 408 - struct xrt_device *dev = GET_XDEV_BY_ROLE(sys, head); 409 - if (dev == NULL) { 410 - ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Failed to find any HMD device"); 411 - oxr_instance_destroy(log, &inst->handle); 412 - return ret; 413 - } 414 - uint32_t view_count = dev->hmd->view_count; 415 - ret = oxr_system_fill_in(log, inst, XRT_SYSTEM_ID, view_count, &inst->system); 416 - if (ret != XR_SUCCESS) { 417 - oxr_instance_destroy(log, &inst->handle); 418 - return ret; 419 - } 420 - 421 383 inst->timekeeping = time_state_create(inst->xinst->startup_timestamp); 422 384 423 385 //! @todo check if this (and other creates) failed? ··· 430 392 431 393 u_var_add_root((void *)inst, "XrInstance", true); 432 394 433 - #ifdef XRT_FEATURE_CLIENT_DEBUG_GUI 434 - u_debug_gui_start(inst->debug_ui, inst->xinst, sys->xsysd); 435 - #endif 436 - 437 395 oxr_log(log, 438 396 "Instance created\n" 439 397 "\tcreateInfo->applicationInfo.applicationName: %s\n" ··· 465 423 inst->quirks.skip_end_session ? "true" : "false", // 466 424 inst->quirks.parallel_views ? "true" : "false" // 467 425 ); // 468 - 469 - debug_print_devices(log, sys); 470 - 471 426 472 427 #ifdef XRT_FEATURE_RENDERDOC 473 428 ··· 509 464 #endif 510 465 511 466 *out_instance = inst; 467 + 468 + return XR_SUCCESS; 469 + } 470 + 471 + XrResult 472 + oxr_instance_init_system_locked(struct oxr_logger *log, struct oxr_instance *inst) 473 + { 474 + struct oxr_system *sys = &inst->system; 475 + if (sys->xsys) { 476 + return XR_SUCCESS; 477 + } 478 + 479 + xrt_result_t xret; 480 + XrResult ret; 481 + 482 + // Create the compositor if we are not headless, currently always create it. 483 + bool should_create_compositor = true /* !inst->extensions.MND_headless */; 484 + 485 + // Create the system. 486 + if (should_create_compositor) { 487 + xret = xrt_instance_create_system(inst->xinst, &sys->xsys, &sys->xsysd, &sys->xso, &sys->xsysc); 488 + } else { 489 + xret = xrt_instance_create_system(inst->xinst, &sys->xsys, &sys->xsysd, &sys->xso, NULL); 490 + } 491 + 492 + if (xret != XRT_SUCCESS) { 493 + struct u_pp_sink_stack_only sink; 494 + u_pp_delegate_t dg = u_pp_sink_stack_only_init(&sink); 495 + u_pp(dg, "Call to xrt_instance_create_system failed: "); 496 + u_pp_xrt_result(dg, xret); 497 + ret = oxr_error(log, XR_ERROR_INITIALIZATION_FAILED, "%s", sink.buffer); 498 + return ret; 499 + } 500 + 501 + #ifdef XRT_FEATURE_CLIENT_DEBUG_GUI 502 + // Do this after creating the system. 503 + u_debug_gui_start(inst->debug_ui, inst->xinst, sys->xsysd); 504 + #endif 505 + 506 + ret = XR_SUCCESS; 507 + if (sys->xsysd == NULL) { 508 + ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Huh?! Field sys->xsysd was NULL?"); 509 + } else if (should_create_compositor && sys->xsysc == NULL) { 510 + ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Huh?! Field sys->xsysc was NULL?"); 511 + } else if (!should_create_compositor && sys->xsysc != NULL) { 512 + ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Huh?! Field sys->xsysc was not NULL?"); 513 + } 514 + 515 + if (ret != XR_SUCCESS) { 516 + return ret; 517 + } 518 + 519 + // Did we find any HMD 520 + // @todo Headless with only controllers? 521 + struct xrt_device *dev = GET_XDEV_BY_ROLE(sys, head); 522 + if (dev == NULL) { 523 + ret = oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Failed to find any HMD device"); 524 + return ret; 525 + } 526 + uint32_t view_count = (uint32_t)dev->hmd->view_count; 527 + ret = oxr_system_fill_in(log, inst, XRT_SYSTEM_ID, view_count, &inst->system); 528 + if (ret != XR_SUCCESS) { 529 + return ret; 530 + } 531 + 532 + debug_print_devices(log, sys); 512 533 513 534 return XR_SUCCESS; 514 535 }
+11
src/xrt/state_trackers/oxr/oxr_objects.h
··· 252 252 struct oxr_instance **out_inst); 253 253 254 254 /*! 255 + * Must be called with oxr_instance::system_init_lock held. 256 + * 257 + * @public @memberof oxr_instance 258 + */ 259 + XrResult 260 + oxr_instance_init_system_locked(struct oxr_logger *log, struct oxr_instance *inst); 261 + 262 + /*! 255 263 * @public @memberof oxr_instance 256 264 */ 257 265 XrResult ··· 1694 1702 //! Stores only major.minor version. Simplifies comparisons for e.g. "at least OpenXR 1.1". 1695 1703 XrVersion major_minor; 1696 1704 } openxr_version; 1705 + 1706 + // Protects the function oxr_instance_init_system_locked. 1707 + struct os_mutex system_init_lock; 1697 1708 1698 1709 // Hardcoded single system. 1699 1710 struct oxr_system system;