The open source OpenXR runtime
at main 153 lines 3.6 kB view raw
1// Copyright 2020-2023, Collabora, Ltd. 2// Copyright 2025, NVIDIA CORPORATION. 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief Client side wrapper of @ref xrt_system. 7 * @author Jakob Bornecrantz <jakob@collabora.com> 8 * @ingroup ipc_client 9 */ 10 11#include "xrt/xrt_defines.h" 12#include "xrt/xrt_system.h" 13#include "xrt/xrt_session.h" 14 15#include "ipc_client_generated.h" 16 17#include <assert.h> 18 19/*! 20 * IPC client implementation of @ref xrt_system. 21 * 22 * @implements xrt_system 23 * @ingroup ipc_client 24 */ 25struct ipc_client_system 26{ 27 struct xrt_system base; 28 29 struct ipc_connection *ipc_c; 30 31 struct xrt_system_compositor *xsysc; 32}; 33 34 35/* 36 * 37 * Helpers 38 * 39 */ 40 41static inline struct ipc_client_system * 42ipc_system(struct xrt_system *xsys) 43{ 44 return (struct ipc_client_system *)xsys; 45} 46 47static inline xrt_result_t 48create_headless(struct ipc_client_system *icsys, const struct xrt_session_info *xsi, struct xrt_session **out_xs) 49{ 50 xrt_result_t xret = XRT_SUCCESS; 51 52 // We create the session ourselves. 53 xret = ipc_call_session_create( // 54 icsys->ipc_c, // ipc_c 55 xsi, // xsi 56 false); // create_native_compositor 57 IPC_CHK_AND_RET(icsys->ipc_c, xret, "ipc_call_session_create"); 58 59 struct xrt_session *xs = ipc_client_session_create(icsys->ipc_c); 60 assert(xs != NULL); 61 62 *out_xs = xs; 63 64 return XRT_SUCCESS; 65} 66 67static inline xrt_result_t 68create_with_comp(struct ipc_client_system *icsys, 69 const struct xrt_session_info *xsi, 70 struct xrt_session **out_xs, 71 struct xrt_compositor_native **out_xcn) 72{ 73 xrt_result_t xret = XRT_SUCCESS; 74 75 assert(icsys->xsysc != NULL); 76 77 // The native compositor creates the session. 78 xret = ipc_client_create_native_compositor( // 79 icsys->xsysc, // 80 xsi, // 81 out_xcn); // 82 IPC_CHK_AND_RET(icsys->ipc_c, xret, "ipc_client_create_native_compositor"); 83 84 struct xrt_session *xs = ipc_client_session_create(icsys->ipc_c); 85 assert(xs != NULL); 86 87 *out_xs = xs; 88 89 return XRT_SUCCESS; 90} 91 92 93/* 94 * 95 * Member functions. 96 * 97 */ 98 99static xrt_result_t 100ipc_client_system_create_session(struct xrt_system *xsys, 101 const struct xrt_session_info *xsi, 102 struct xrt_session **out_xs, 103 struct xrt_compositor_native **out_xcn) 104{ 105 struct ipc_client_system *icsys = ipc_system(xsys); 106 107 if (out_xcn != NULL && icsys->xsysc == NULL) { 108 U_LOG_E("No system compositor in system, can't create native compositor."); 109 return XRT_ERROR_COMPOSITOR_NOT_SUPPORTED; 110 } 111 112 // Skip making a native compositor if not asked for. 113 if (out_xcn == NULL) { 114 return create_headless(icsys, xsi, out_xs); 115 } else { 116 return create_with_comp(icsys, xsi, out_xs, out_xcn); 117 } 118} 119 120static void 121ipc_client_system_destroy(struct xrt_system *xsys) 122{ 123 struct ipc_client_system *icsys = ipc_system(xsys); 124 125 free(icsys); 126} 127 128 129/* 130 * 131 * 'Exported' functions. 132 * 133 */ 134 135struct xrt_system * 136ipc_client_system_create(struct ipc_connection *ipc_c, struct xrt_system_compositor *xsysc) 137{ 138 struct ipc_client_system *icsys = U_TYPED_CALLOC(struct ipc_client_system); 139 140 xrt_result_t xret = ipc_call_system_get_properties(ipc_c, &icsys->base.properties); 141 IPC_CHK_ONLY_PRINT(ipc_c, xret, "ipc_call_system_get_properties"); 142 if (xret != XRT_SUCCESS) { 143 free(icsys); 144 return NULL; 145 } 146 147 icsys->base.create_session = ipc_client_system_create_session; 148 icsys->base.destroy = ipc_client_system_destroy; 149 icsys->ipc_c = ipc_c; 150 icsys->xsysc = xsysc; 151 152 return &icsys->base; 153}