mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
ipc: Impelement xrt_compositor_semaphore interfaces
This commit is contained in:
parent
ca7526a3e2
commit
ef373662f2
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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, ©);
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"}
|
||||
|
|
Loading…
Reference in a new issue