diff --git a/src/xrt/ipc/CMakeLists.txt b/src/xrt/ipc/CMakeLists.txt index 0dbfb583f..041581e3e 100644 --- a/src/xrt/ipc/CMakeLists.txt +++ b/src/xrt/ipc/CMakeLists.txt @@ -66,7 +66,9 @@ add_library( client/ipc_client_device.c client/ipc_client_hmd.c client/ipc_client_instance.c + client/ipc_client_session.c client/ipc_client_space_overseer.c + client/ipc_client_system.c client/ipc_client_system_devices.c ) target_include_directories( diff --git a/src/xrt/ipc/client/ipc_client.h b/src/xrt/ipc/client/ipc_client.h index 9507282a1..1458856f1 100644 --- a/src/xrt/ipc/client/ipc_client.h +++ b/src/xrt/ipc/client/ipc_client.h @@ -220,8 +220,14 @@ ipc_client_hmd_create(struct ipc_connection *ipc_c, struct xrt_tracking_origin * struct xrt_device * ipc_client_device_create(struct ipc_connection *ipc_c, struct xrt_tracking_origin *xtrack, uint32_t device_id); +struct xrt_system * +ipc_client_system_create(struct ipc_connection *ipc_c, struct xrt_system_compositor *xsysc); + struct xrt_space_overseer * ipc_client_space_overseer_create(struct ipc_connection *ipc_c); struct xrt_system_devices * ipc_client_system_devices_create(struct ipc_connection *ipc_c); + +struct xrt_session * +ipc_client_session_create(struct ipc_connection *ipc_c); diff --git a/src/xrt/ipc/client/ipc_client_session.c b/src/xrt/ipc/client/ipc_client_session.c new file mode 100644 index 000000000..0432cddb9 --- /dev/null +++ b/src/xrt/ipc/client/ipc_client_session.c @@ -0,0 +1,83 @@ +// Copyright 2020-2023, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Client side wrapper of @ref xrt_session. + * @author Jakob Bornecrantz + * @ingroup ipc_client + */ + +#include "xrt/xrt_defines.h" +#include "xrt/xrt_session.h" + +#include "ipc_client_generated.h" + + +/*! + * IPC client implementation of @ref xrt_session. + * + * @implements xrt_session. + * @ingroup ipc_client + */ +struct ipc_client_session +{ + struct xrt_session base; + + struct ipc_connection *ipc_c; +}; + + +/* + * + * Helpers + * + */ + +static inline struct ipc_client_session * +ipc_session(struct xrt_session *xs) +{ + return (struct ipc_client_session *)xs; +} + + +/* + * + * Member functions. + * + */ + +static xrt_result_t +ipc_client_session_poll_events(struct xrt_session *xs, union xrt_session_event *out_xse) +{ + struct ipc_client_session *ics = ipc_session(xs); + xrt_result_t xret; + + xret = ipc_call_session_poll_events(ics->ipc_c, out_xse); + IPC_CHK_ALWAYS_RET(ics->ipc_c, xret, "ipc_call_session_poll_events"); +} + +static void +ipc_client_session_destroy(struct xrt_session *xs) +{ + struct ipc_client_session *ics = ipc_session(xs); + + free(ics); +} + + +/* + * + * 'Exported' functions. + * + */ + +struct xrt_session * +ipc_client_session_create(struct ipc_connection *ipc_c) +{ + struct ipc_client_session *ics = U_TYPED_CALLOC(struct ipc_client_session); + ics->base.poll_events = ipc_client_session_poll_events; + ics->base.destroy = ipc_client_session_destroy; + ics->ipc_c = ipc_c; + + return &ics->base; +} diff --git a/src/xrt/ipc/client/ipc_client_system.c b/src/xrt/ipc/client/ipc_client_system.c new file mode 100644 index 000000000..4247774a7 --- /dev/null +++ b/src/xrt/ipc/client/ipc_client_system.c @@ -0,0 +1,115 @@ +// Copyright 2020-2023, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Client side wrapper of @ref xrt_system. + * @author Jakob Bornecrantz + * @ingroup ipc_client + */ + +#include "xrt/xrt_defines.h" +#include "xrt/xrt_system.h" +#include "xrt/xrt_session.h" + +#include "ipc_client_generated.h" + + +/*! + * IPC client implementation of @ref xrt_system. + * + * @implements xrt_system. + * @ingroup ipc_client + */ +struct ipc_client_system +{ + struct xrt_system base; + + struct ipc_connection *ipc_c; + + struct xrt_system_compositor *xsysc; +}; + + +/* + * + * Helpers + * + */ + +static inline struct ipc_client_system * +ipc_system(struct xrt_system *xsys) +{ + return (struct ipc_client_system *)xsys; +} + + +/* + * + * Member functions. + * + */ + +static xrt_result_t +ipc_client_system_create_session(struct xrt_system *xsys, + const struct xrt_session_info *xsi, + struct xrt_session **out_xs, + struct xrt_compositor_native **out_xcn) +{ + struct ipc_client_system *icsys = ipc_system(xsys); + xrt_result_t xret = XRT_SUCCESS; + + if (out_xcn != NULL && icsys->xsysc == NULL) { + U_LOG_E("No system compositor in system, can't create native compositor."); + return XRT_ERROR_COMPOSITOR_NOT_SUPPORTED; + } + + struct xrt_session *xs = ipc_client_session_create(icsys->ipc_c); + + // Skip making a native compositor if not asked for. + if (out_xcn == NULL) { + goto out_session; + } + + xret = xrt_syscomp_create_native_compositor( // + icsys->xsysc, // + xsi, // + out_xcn); // + if (xret != XRT_SUCCESS) { + goto err; + } + +out_session: + *out_xs = xs; + + return XRT_SUCCESS; + +err: + return xret; +} + +static void +ipc_client_system_destroy(struct xrt_system *xsys) +{ + struct ipc_client_system *icsys = ipc_system(xsys); + + free(icsys); +} + + +/* + * + * 'Exported' functions. + * + */ + +struct xrt_system * +ipc_client_system_create(struct ipc_connection *ipc_c, struct xrt_system_compositor *xsysc) +{ + struct ipc_client_system *icsys = U_TYPED_CALLOC(struct ipc_client_system); + icsys->base.create_session = ipc_client_system_create_session; + icsys->base.destroy = ipc_client_system_destroy; + icsys->ipc_c = ipc_c; + icsys->xsysc = xsysc; + + return &icsys->base; +} diff --git a/src/xrt/ipc/server/ipc_server.h b/src/xrt/ipc/server/ipc_server.h index 9d2e99602..1a1a54ca3 100644 --- a/src/xrt/ipc/server/ipc_server.h +++ b/src/xrt/ipc/server/ipc_server.h @@ -82,6 +82,9 @@ struct ipc_client_state //! Link back to the main server. struct ipc_server *server; + //! Session for this client. + struct xrt_session *xs; + //! Compositor for this client. struct xrt_compositor *xc; @@ -420,7 +423,7 @@ ipc_server_client_thread(void *_ics); * created from it, like all of the swapchains. */ void -ipc_server_client_destroy_compositor(volatile struct ipc_client_state *ics); +ipc_server_client_destroy_session_and_compositor(volatile struct ipc_client_state *ics); /*! * @defgroup ipc_server_internals Server Internals diff --git a/src/xrt/ipc/server/ipc_server_handler.c b/src/xrt/ipc/server/ipc_server_handler.c index 09f7e04bf..02ea30b26 100644 --- a/src/xrt/ipc/server/ipc_server_handler.c +++ b/src/xrt/ipc/server/ipc_server_handler.c @@ -231,6 +231,17 @@ ipc_handle_session_create(volatile struct ipc_client_state *ics, const struct xr return XRT_SUCCESS; } +xrt_result_t +ipc_handle_session_poll_events(volatile struct ipc_client_state *ics, union xrt_session_event *out_xse) +{ + // Have we created the session? + if (ics->xs == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + return xrt_session_poll_events(ics->xs, out_xse); +} + xrt_result_t ipc_handle_session_begin(volatile struct ipc_client_state *ics) { @@ -272,7 +283,7 @@ ipc_handle_session_destroy(volatile struct ipc_client_state *ics) return XRT_ERROR_IPC_SESSION_NOT_CREATED; } - ipc_server_client_destroy_compositor(ics); + ipc_server_client_destroy_session_and_compositor(ics); return XRT_SUCCESS; } diff --git a/src/xrt/ipc/server/ipc_server_per_client_thread.c b/src/xrt/ipc/server/ipc_server_per_client_thread.c index 3c09d10dc..d97cfc902 100644 --- a/src/xrt/ipc/server/ipc_server_per_client_thread.c +++ b/src/xrt/ipc/server/ipc_server_per_client_thread.c @@ -59,7 +59,7 @@ common_shutdown(volatile struct ipc_client_state *ics) */ // If the session hasn't been stopped, destroy the compositor. - ipc_server_client_destroy_compositor(ics); + ipc_server_client_destroy_session_and_compositor(ics); // Make sure undestroyed spaces are unreferenced for (uint32_t i = 0; i < IPC_MAX_CLIENT_SPACES; i++) { @@ -294,7 +294,7 @@ client_loop(volatile struct ipc_client_state *ics) */ void -ipc_server_client_destroy_compositor(volatile struct ipc_client_state *ics) +ipc_server_client_destroy_session_and_compositor(volatile struct ipc_client_state *ics) { // Multiple threads might be looking at these fields. os_mutex_lock(&ics->server->global_state.lock); @@ -319,6 +319,9 @@ ipc_server_client_destroy_compositor(volatile struct ipc_client_state *ics) // Cast away volatile. xrt_comp_destroy((struct xrt_compositor **)&ics->xc); + + // Cast away volatile. + xrt_session_destroy((struct xrt_session **)&ics->xs); } void * diff --git a/src/xrt/ipc/shared/ipc_protocol.h b/src/xrt/ipc/shared/ipc_protocol.h index 8341d63ed..42fa753df 100644 --- a/src/xrt/ipc/shared/ipc_protocol.h +++ b/src/xrt/ipc/shared/ipc_protocol.h @@ -16,6 +16,7 @@ #include "xrt/xrt_results.h" #include "xrt/xrt_defines.h" #include "xrt/xrt_system.h" +#include "xrt/xrt_session.h" #include "xrt/xrt_instance.h" #include "xrt/xrt_compositor.h" #include "xrt/xrt_device.h" diff --git a/src/xrt/ipc/shared/proto.json b/src/xrt/ipc/shared/proto.json index f6ace8b02..39f2b6200 100644 --- a/src/xrt/ipc/shared/proto.json +++ b/src/xrt/ipc/shared/proto.json @@ -68,6 +68,12 @@ ] }, + "session_poll_events": { + "out": [ + {"name": "event", "type": "union xrt_session_event"} + ] + }, + "session_begin": {}, "session_end": {},