ipc: Impelement xrt_compositor_semaphore interfaces

This commit is contained in:
Jakob Bornecrantz 2022-03-04 16:20:41 +00:00
parent ca7526a3e2
commit ef373662f2
5 changed files with 284 additions and 0 deletions

View file

@ -89,6 +89,26 @@ struct ipc_client_swapchain
uint32_t id;
};
/*!
* Client proxy for an xrt_compositor_semaphore implementation over IPC.
* @implements xrt_compositor_semaphore
*/
struct ipc_client_compositor_semaphore
{
struct xrt_compositor_semaphore base;
struct ipc_client_compositor *icc;
uint32_t id;
};
/*
*
* Helper functions.
*
*/
static inline struct ipc_client_compositor *
ipc_client_compositor(struct xrt_compositor *xc)
{
@ -101,6 +121,12 @@ ipc_client_swapchain(struct xrt_swapchain *xs)
return (struct ipc_client_swapchain *)xs;
}
static inline struct ipc_client_compositor_semaphore *
ipc_client_compositor_semaphore(struct xrt_compositor_semaphore *xcsem)
{
return (struct ipc_client_compositor_semaphore *)xcsem;
}
/*
*
@ -190,6 +216,35 @@ ipc_compositor_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index
}
/*
*
* Compositor semaphore functions.
*
*/
static xrt_result_t
ipc_client_compositor_semaphore_wait(struct xrt_compositor_semaphore *xcsem, uint64_t value, uint64_t timeout_ns)
{
struct ipc_client_compositor_semaphore *iccs = ipc_client_compositor_semaphore(xcsem);
struct ipc_client_compositor *icc = iccs->icc;
IPC_ERROR(icc->ipc_c, "Can not call wait on client side!");
return XRT_ERROR_IPC_FAILURE;
}
static void
ipc_client_compositor_semaphore_destroy(struct xrt_compositor_semaphore *xcsem)
{
struct ipc_client_compositor_semaphore *iccs = ipc_client_compositor_semaphore(xcsem);
struct ipc_client_compositor *icc = iccs->icc;
IPC_CALL_CHK(ipc_call_compositor_semaphore_destroy(icc->ipc_c, iccs->id));
free(iccs);
}
/*
*
* Compositor functions.
@ -350,6 +405,30 @@ ipc_compositor_swapchain_import(struct xrt_compositor *xc,
return swapchain_server_import(icc, info, native_images, image_count, out_xsc);
}
static xrt_result_t
ipc_compositor_semaphore_create(struct xrt_compositor *xc,
xrt_graphics_sync_handle_t *out_handle,
struct xrt_compositor_semaphore **out_xcsem)
{
struct ipc_client_compositor *icc = ipc_client_compositor(xc);
uint32_t id = 0;
xrt_graphics_sync_handle_t handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID;
IPC_CALL_CHK(ipc_call_compositor_semaphore_create(icc->ipc_c, &id, &handle, 1));
struct ipc_client_compositor_semaphore *iccs = U_TYPED_CALLOC(struct ipc_client_compositor_semaphore);
iccs->base.reference.count = 1;
iccs->base.wait = ipc_client_compositor_semaphore_wait;
iccs->base.destroy = ipc_client_compositor_semaphore_destroy;
iccs->id = id;
iccs->icc = icc;
*out_handle = handle;
*out_xcsem = &iccs->base;
return XRT_SUCCESS;
}
static xrt_result_t
ipc_compositor_poll_events(struct xrt_compositor *xc, union xrt_compositor_event *out_xce)
{
@ -648,6 +727,35 @@ ipc_compositor_layer_commit(struct xrt_compositor *xc, int64_t frame_id, xrt_gra
return res;
}
static xrt_result_t
ipc_compositor_layer_commit_with_semaphore(struct xrt_compositor *xc,
int64_t frame_id,
struct xrt_compositor_semaphore *xcsem,
uint64_t value)
{
struct ipc_client_compositor *icc = ipc_client_compositor(xc);
struct ipc_client_compositor_semaphore *iccs = ipc_client_compositor_semaphore(xcsem);
struct ipc_shared_memory *ism = icc->ipc_c->ism;
struct ipc_layer_slot *slot = &ism->slots[icc->layers.slot_id];
// Last bit of data to put in the shared memory area.
slot->layer_count = icc->layers.layer_count;
IPC_CALL_CHK(ipc_call_compositor_layer_sync_with_semaphore( //
icc->ipc_c, //
frame_id, //
icc->layers.slot_id, //
iccs->id, //
value, //
&icc->layers.slot_id)); //
// Reset.
icc->layers.layer_count = 0;
return res;
}
static xrt_result_t
ipc_compositor_discard_frame(struct xrt_compositor *xc, int64_t frame_id)
{
@ -675,6 +783,7 @@ ipc_compositor_init(struct ipc_client_compositor *icc, struct xrt_compositor_nat
{
icc->base.base.create_swapchain = ipc_compositor_swapchain_create;
icc->base.base.import_swapchain = ipc_compositor_swapchain_import;
icc->base.base.create_semaphore = ipc_compositor_semaphore_create;
icc->base.base.begin_session = ipc_compositor_begin_session;
icc->base.base.end_session = ipc_compositor_end_session;
icc->base.base.wait_frame = ipc_compositor_wait_frame;
@ -689,6 +798,7 @@ ipc_compositor_init(struct ipc_client_compositor *icc, struct xrt_compositor_nat
icc->base.base.layer_equirect1 = ipc_compositor_layer_equirect1;
icc->base.base.layer_equirect2 = ipc_compositor_layer_equirect2;
icc->base.base.layer_commit = ipc_compositor_layer_commit;
icc->base.base.layer_commit_with_semaphore = ipc_compositor_layer_commit_with_semaphore;
icc->base.base.destroy = ipc_compositor_destroy;
icc->base.base.poll_events = ipc_compositor_poll_events;

View file

@ -45,6 +45,7 @@ extern "C" {
*/
#define IPC_SERVER_NUM_XDEVS 8
#define IPC_MAX_CLIENT_SEMAPHORES 8
#define IPC_MAX_CLIENT_SWAPCHAINS 32
//#define IPC_MAX_CLIENTS 8
@ -93,6 +94,12 @@ struct ipc_client_state
//! Data for the swapchains.
struct ipc_swapchain_data swapchain_data[IPC_MAX_CLIENT_SWAPCHAINS];
//! Number of compositor semaphores in use by client
uint32_t compositor_semaphore_count;
//! Ptrs to the semaphores.
struct xrt_compositor_semaphore *xcsems[IPC_MAX_CLIENT_SEMAPHORES];
//! Socket fd used for client comms
struct ipc_message_channel imc;

View file

@ -558,6 +558,63 @@ ipc_handle_compositor_layer_sync(volatile struct ipc_client_state *ics,
return XRT_SUCCESS;
}
xrt_result_t
ipc_handle_compositor_layer_sync_with_semaphore(volatile struct ipc_client_state *ics,
int64_t frame_id,
uint32_t slot_id,
uint32_t semaphore_id,
uint64_t semaphore_value,
uint32_t *out_free_slot_id)
{
IPC_TRACE_MARKER();
if (ics->xc == NULL) {
return XRT_ERROR_IPC_SESSION_NOT_CREATED;
}
if (semaphore_id >= IPC_MAX_CLIENT_SEMAPHORES) {
IPC_ERROR(ics->server, "Invalid semaphore_id");
return XRT_ERROR_IPC_FAILURE;
}
if (ics->xcsems[semaphore_id] == NULL) {
IPC_ERROR(ics->server, "Semaphore of id %u not created!", semaphore_id);
return XRT_ERROR_IPC_FAILURE;
}
struct xrt_compositor_semaphore *xcsem = ics->xcsems[semaphore_id];
struct ipc_shared_memory *ism = ics->server->ism;
struct ipc_layer_slot *slot = &ism->slots[slot_id];
// Copy current slot data.
struct ipc_layer_slot copy = *slot;
/*
* Transfer data to underlying compositor.
*/
xrt_comp_layer_begin(ics->xc, frame_id, copy.display_time_ns, copy.env_blend_mode);
_update_layers(ics, ics->xc, &copy);
xrt_comp_layer_commit_with_semaphore(ics->xc, frame_id, xcsem, semaphore_value);
/*
* Manage shared state.
*/
os_mutex_lock(&ics->server->global_state.lock);
*out_free_slot_id = (ics->server->current_slot_index + 1) % IPC_MAX_SLOTS;
ics->server->current_slot_index = *out_free_slot_id;
os_mutex_unlock(&ics->server->global_state.lock);
return XRT_SUCCESS;
}
xrt_result_t
ipc_handle_compositor_poll_events(volatile struct ipc_client_state *ics, union xrt_compositor_event *out_xce)
{
@ -843,6 +900,85 @@ ipc_handle_swapchain_destroy(volatile struct ipc_client_state *ics, uint32_t id)
return XRT_SUCCESS;
}
/*
*
* Compositor semaphore function..
*
*/
xrt_result_t
ipc_handle_compositor_semaphore_create(volatile struct ipc_client_state *ics,
uint32_t *out_id,
uint32_t max_handle_count,
xrt_graphics_sync_handle_t *out_handles,
uint32_t *out_handle_count)
{
xrt_result_t xret;
if (ics->xc == NULL) {
return XRT_ERROR_IPC_SESSION_NOT_CREATED;
}
int id = 0;
for (; id < IPC_MAX_CLIENT_SEMAPHORES; id++) {
if (ics->xcsems[id] == NULL) {
break;
}
}
if (id == IPC_MAX_CLIENT_SEMAPHORES) {
IPC_ERROR(ics->server, "Too many compositor semaphores alive!");
return XRT_ERROR_IPC_FAILURE;
}
struct xrt_compositor_semaphore *xcsem = NULL;
xrt_graphics_sync_handle_t handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID;
xret = xrt_comp_create_semaphore(ics->xc, &handle, &xcsem);
if (xret != XRT_SUCCESS) {
IPC_ERROR(ics->server, "Failed to create compositor semaphore!");
return XRT_SUCCESS;
}
// Set it directly, no need to use reference here.
ics->xcsems[id] = xcsem;
// Set out parameters.
*out_id = id;
out_handles[0] = handle;
*out_handle_count = 1;
return XRT_SUCCESS;
}
xrt_result_t
ipc_handle_compositor_semaphore_destroy(volatile struct ipc_client_state *ics, uint32_t id)
{
if (ics->xc == NULL) {
return XRT_ERROR_IPC_SESSION_NOT_CREATED;
}
if (ics->xcsems[id] == NULL) {
IPC_ERROR(ics->server, "Client tried to delete non-existent compositor semaphore!");
return XRT_ERROR_IPC_FAILURE;
}
ics->compositor_semaphore_count--;
// Drop our reference, does NULL checking. Cast away volatile.
xrt_compositor_semaphore_reference((struct xrt_compositor_semaphore **)&ics->xcsems[id], NULL);
return XRT_SUCCESS;
}
/*
*
* Device functions.
*
*/
xrt_result_t
ipc_handle_device_update_input(volatile struct ipc_client_state *ics, uint32_t id)
{

View file

@ -163,6 +163,12 @@ ipc_server_client_destroy_compositor(volatile struct ipc_client_state *ics)
IPC_TRACE(ics->server, "Destroyed swapchain %d.", j);
}
for (uint32_t j = 0; j < IPC_MAX_CLIENT_SEMAPHORES; j++) {
// Drop our reference, does NULL checking. Cast away volatile.
xrt_compositor_semaphore_reference((struct xrt_compositor_semaphore **)&ics->xcsems[j], NULL);
IPC_TRACE(ics->server, "Destroyed compositor semaphore %d.", j);
}
os_mutex_unlock(&ics->server->global_state.lock);
// Cast away volatile.

View file

@ -112,6 +112,18 @@
]
},
"compositor_layer_sync_with_semaphore": {
"in": [
{"name": "frame_id", "type": "int64_t"},
{"name": "slot_id", "type": "uint32_t"},
{"name": "semaphore_id", "type": "uint32_t"},
{"name": "semaphore_value", "type": "uint64_t"}
],
"out": [
{"name": "free_slot_id", "type": "uint32_t"}
]
},
"compositor_poll_events": {
"out": [
{"name": "event", "type": "union xrt_compositor_event"}
@ -172,6 +184,19 @@
]
},
"compositor_semaphore_create": {
"out": [
{"name": "id", "type": "uint32_t"}
],
"out_handles": {"type": "xrt_graphics_sync_handle_t"}
},
"compositor_semaphore_destroy": {
"in": [
{"name": "id", "type": "uint32_t"}
]
},
"device_update_input": {
"in": [
{"name": "id", "type": "uint32_t"}