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