The open source OpenXR runtime
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}