The open source OpenXR runtime
1// Copyright 2023, Collabora, Ltd.
2// Copyright 2025, NVIDIA CORPORATION.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief IPC Client system devices.
7 * @author Korcan Hussein <korcan.hussein@collabora.com>
8 * @author Jakob Bornecrantz <jakob@collabora.com>
9 * @ingroup ipc_client
10 */
11
12#include "ipc_client.h"
13#include "ipc_client_generated.h"
14
15#include "util/u_system_helpers.h"
16#include "util/u_var.h"
17
18
19/*
20 *
21 * Helpers
22 *
23 */
24
25static inline struct ipc_client_system_devices *
26ipc_system_devices(struct xrt_system_devices *xsysd)
27{
28 return (struct ipc_client_system_devices *)xsysd;
29}
30
31
32/*
33 *
34 * Member functions.
35 *
36 */
37
38static xrt_result_t
39ipc_client_system_devices_get_roles(struct xrt_system_devices *xsysd, struct xrt_system_roles *out_roles)
40{
41 struct ipc_client_system_devices *usysd = ipc_system_devices(xsysd);
42
43 return ipc_call_system_devices_get_roles(usysd->ipc_c, out_roles);
44}
45
46static xrt_result_t
47ipc_client_system_devices_feature_inc(struct xrt_system_devices *xsysd, enum xrt_device_feature_type type)
48{
49 struct ipc_client_system_devices *usysd = ipc_system_devices(xsysd);
50 xrt_result_t xret;
51
52 assert(type < XRT_DEVICE_FEATURE_MAX_ENUM);
53
54 // If it wasn't zero nothing to do.
55 if (!xrt_reference_inc_and_was_zero(&usysd->feature_use[type])) {
56 return XRT_SUCCESS;
57 }
58
59 xret = ipc_call_system_devices_begin_feature(usysd->ipc_c, type);
60 IPC_CHK_ALWAYS_RET(usysd->ipc_c, xret, "ipc_call_system_devices_begin_feature");
61}
62
63static xrt_result_t
64ipc_client_system_devices_feature_dec(struct xrt_system_devices *xsysd, enum xrt_device_feature_type type)
65{
66 struct ipc_client_system_devices *usysd = ipc_system_devices(xsysd);
67 xrt_result_t xret;
68
69 assert(type < XRT_DEVICE_FEATURE_MAX_ENUM);
70
71 // If it is not zero we are done.
72 if (!xrt_reference_dec_and_is_zero(&usysd->feature_use[type])) {
73 return XRT_SUCCESS;
74 }
75
76 xret = ipc_call_system_devices_end_feature(usysd->ipc_c, type);
77 IPC_CHK_ALWAYS_RET(usysd->ipc_c, xret, "ipc_call_system_devices_end_feature");
78}
79
80
81static void
82ipc_client_system_devices_destroy(struct xrt_system_devices *xsysd)
83{
84 struct ipc_client_system_devices *usysd = ipc_system_devices(xsysd);
85
86 for (size_t i = 0; i < usysd->xtrack_count; i++) {
87 u_var_remove_root(usysd->xtracks[i]);
88 free(usysd->xtracks[i]);
89 usysd->xtracks[i] = NULL;
90 }
91 usysd->xtrack_count = 0;
92
93 u_system_devices_close(&usysd->base.base);
94
95 free(usysd);
96}
97
98
99/*
100 *
101 * 'Exported' functions.
102 *
103 */
104
105struct ipc_client_system_devices *
106ipc_client_system_devices_create(struct ipc_connection *ipc_c)
107{
108 struct ipc_client_system_devices *icsd = U_TYPED_CALLOC(struct ipc_client_system_devices);
109 icsd->base.base.get_roles = ipc_client_system_devices_get_roles;
110 icsd->base.base.destroy = ipc_client_system_devices_destroy;
111 icsd->base.base.feature_inc = ipc_client_system_devices_feature_inc;
112 icsd->base.base.feature_dec = ipc_client_system_devices_feature_dec;
113 icsd->ipc_c = ipc_c;
114
115 return icsd;
116}