The open source OpenXR runtime
at main 206 lines 4.7 kB view raw
1// Copyright 2020-2024, Collabora, Ltd. 2// Copyright 2025, NVIDIA CORPORATION. 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief Shared default implementation of the instance with compositor. 7 * @author Jakob Bornecrantz <jakob@collabora.com> 8 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 9 */ 10 11#include "xrt/xrt_space.h" 12#include "xrt/xrt_system.h" 13#include "xrt/xrt_config_build.h" 14#include "xrt/xrt_config_os.h" 15 16 17#include "os/os_time.h" 18 19#include "util/u_debug.h" 20#include "util/u_system.h" 21#include "util/u_trace_marker.h" 22#include "util/u_system_helpers.h" 23 24#ifdef XRT_MODULE_COMPOSITOR_MAIN 25#include "main/comp_main_interface.h" 26#endif 27 28#include "target_instance_parts.h" 29 30#include <assert.h> 31 32#ifdef XRT_OS_ANDROID 33#include "android/android_instance_base.h" 34#endif 35 36#ifdef XRT_MODULE_COMPOSITOR_MAIN 37#define USE_NULL_DEFAULT (false) 38#else 39#define USE_NULL_DEFAULT (true) 40#endif 41 42DEBUG_GET_ONCE_BOOL_OPTION(use_null, "XRT_COMPOSITOR_NULL", USE_NULL_DEFAULT) 43 44xrt_result_t 45null_compositor_create_system(struct xrt_device *xdev, struct xrt_system_compositor **out_xsysc); 46 47 48 49/* 50 * 51 * Internal functions. 52 * 53 */ 54 55static xrt_result_t 56t_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} 66 67static xrt_result_t 68t_instance_create_system(struct xrt_instance *xinst, 69 struct xrt_system **out_xsys, 70 struct xrt_system_devices **out_xsysd, 71 struct xrt_space_overseer **out_xso, 72 struct xrt_system_compositor **out_xsysc) 73{ 74 XRT_TRACE_MARKER(); 75 76 assert(out_xsys != NULL); 77 assert(*out_xsys == NULL); 78 assert(out_xsysd != NULL); 79 assert(*out_xsysd == NULL); 80 assert(out_xso != NULL); 81 assert(*out_xso == NULL); 82 assert(out_xsysc == NULL || *out_xsysc == NULL); 83 84 struct u_system *usys = NULL; 85 struct xrt_system_compositor *xsysc = NULL; 86 struct xrt_space_overseer *xso = NULL; 87 struct xrt_system_devices *xsysd = NULL; 88 xrt_result_t xret = XRT_SUCCESS; 89 90 usys = u_system_create(); 91 assert(usys != NULL); // Should never fail. 92 93 xret = u_system_devices_create_from_prober( // 94 xinst, // xinst 95 &usys->broadcast, // broadcast 96 &xsysd, // out_xsysd 97 &xso); // out_xso 98 if (xret != XRT_SUCCESS) { 99 return xret; 100 } 101 102 // Early out if we only want devices. 103 if (out_xsysc == NULL) { 104 goto out; 105 } 106 107 struct xrt_device *head = xsysd->static_roles.head; 108 u_system_fill_properties(usys, head->str); 109 110 bool use_null = debug_get_bool_option_use_null(); 111 112#ifdef XRT_MODULE_COMPOSITOR_NULL 113 if (use_null) { 114 xret = null_compositor_create_system(head, &xsysc); 115 } 116#else 117 if (use_null) { 118 U_LOG_E("The null compositor is not compiled in!"); 119 xret = XRT_ERROR_VULKAN; 120 } 121#endif 122 123#ifdef XRT_MODULE_COMPOSITOR_MAIN 124 if (xret == XRT_SUCCESS && xsysc == NULL) { 125 xret = comp_main_create_system_compositor(head, NULL, NULL, &xsysc); 126 } 127#else 128 if (!use_null) { 129 U_LOG_E("Explicitly didn't request the null compositor, but the main compositor hasn't been built!"); 130 xret = XRT_ERROR_VULKAN; 131 } 132#endif 133 134 if (xret != XRT_SUCCESS) { 135 goto err_destroy; 136 } 137 138out: 139 *out_xsys = &usys->base; 140 *out_xsysd = xsysd; 141 *out_xso = xso; 142 143 if (xsysc != NULL) { 144 // Tell the system about the system compositor. 145 u_system_set_system_compositor(usys, xsysc); 146 147 assert(out_xsysc != NULL); 148 *out_xsysc = xsysc; 149 } 150 151 return xret; 152 153 154err_destroy: 155 xrt_space_overseer_destroy(&xso); 156 xrt_system_devices_destroy(&xsysd); 157 u_system_destroy(&usys); 158 159 return xret; 160} 161 162 163/* 164 * 165 * Exported function(s). 166 * 167 */ 168 169xrt_result_t 170xrt_instance_create(struct xrt_instance_info *ii, struct xrt_instance **out_xinst) 171{ 172 struct xrt_prober *xp = NULL; 173 174 u_trace_marker_init(); 175 176 XRT_TRACE_MARKER(); 177 178 int ret = xrt_prober_create_with_lists(&xp, &target_lists); 179 if (ret < 0) { 180 return XRT_ERROR_PROBER_CREATION_FAILED; 181 } 182 183 struct t_instance *tinst = U_TYPED_CALLOC(struct t_instance); 184 tinst->base.is_system_available = t_instance_is_system_available; 185 tinst->base.create_system = t_instance_create_system; 186 tinst->base.get_prober = t_instance_get_prober; 187 tinst->base.destroy = t_instance_destroy; 188 tinst->xp = xp; 189 190 tinst->base.startup_timestamp = os_monotonic_get_ns(); 191 192#ifdef XRT_OS_ANDROID 193 if (ii != NULL) { 194 ret = android_instance_base_init(&tinst->android, &tinst->base, ii); 195 if (ret < 0) { 196 xrt_prober_destroy(&xp); 197 free(tinst); 198 return ret; 199 } 200 } 201#endif // XRT_OS_ANDROID 202 203 *out_xinst = &tinst->base; 204 205 return XRT_SUCCESS; 206}