a/util,ipc,xrt: Support multi-local_floor space

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2252>
This commit is contained in:
Yu Li 2024-06-17 13:28:10 +08:00 committed by Marge Bot
parent 3b7f85cd8c
commit b00a37be18
5 changed files with 106 additions and 21 deletions

View file

@ -827,7 +827,9 @@ err_unlock:
}
static xrt_result_t
create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space)
create_local_space(struct xrt_space_overseer *xso,
struct xrt_space **out_local_space,
struct xrt_space **out_local_floor_space)
{
assert(xso->semantic.root != NULL);
@ -847,7 +849,31 @@ create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space)
xsr.pose.orientation.z = 0;
math_quat_normalize(&xsr.pose.orientation);
return create_offset_space(xso, xso->semantic.root, &xsr.pose, out_space);
xrt_result_t xret = XRT_SUCCESS;
if (out_local_space != NULL) {
xret = create_offset_space(xso, xso->semantic.root, &xsr.pose, out_local_space);
if (xret != XRT_SUCCESS) {
U_LOG_E("Failed to create offset space LOCAL!");
return xret;
}
}
if (out_local_floor_space != NULL) {
if (xso->semantic.stage != NULL) {
struct u_space *ustage = u_space(xso->semantic.stage);
xsr.pose.position.y = ustage->offset.pose.position.y;
} else {
xsr.pose.position.y = 0;
}
xret = create_offset_space(xso, xso->semantic.root, &xsr.pose, out_local_floor_space);
if (xret != XRT_SUCCESS) {
U_LOG_E("Failed to create offset space LOCAL_FLOOR!");
return xret;
}
}
return xret;
}
static xrt_result_t
@ -1018,6 +1044,9 @@ destroy(struct xrt_space_overseer *xso)
for (int id = 0; id < XRT_MAX_CLIENT_SPACES; id++) {
struct xrt_space **xslocal_ptr = (struct xrt_space **)&xso->localspace[id];
xrt_space_reference(xslocal_ptr, NULL);
struct xrt_space **xslocalfloor_ptr = (struct xrt_space **)&xso->localfloorspace[id];
xrt_space_reference(xslocalfloor_ptr, NULL);
}
pthread_rwlock_destroy(&uso->lock);

View file

@ -110,6 +110,8 @@ struct xrt_space_overseer
//! Ptrs to the localspace
struct xrt_space *localspace[XRT_MAX_CLIENT_SPACES];
//! Ptrs to the localfloorspace
struct xrt_space *localfloorspace[XRT_MAX_CLIENT_SPACES];
/*!
* Create a space with a fixed offset to the parent space.
@ -291,12 +293,15 @@ struct xrt_space_overseer
const struct xrt_pose *offset);
/*!
* Create a localspace.
* Create a localspace and a localfloorspace.
*
* @param[in] xso Owning space overseer.
* @param[out] out_space The newly created localspace.
* @param[out] out_local_space The newly created localspace.
* @param[out] out_local_floor_space The newly created localfloorspace.
*/
xrt_result_t (*create_local_space)(struct xrt_space_overseer *xso, struct xrt_space **out_space);
xrt_result_t (*create_local_space)(struct xrt_space_overseer *xso,
struct xrt_space **out_local_space,
struct xrt_space **out_local_floor_space);
/*!
* Destroy function.
@ -496,16 +501,18 @@ xrt_space_overseer_set_reference_space_offset(struct xrt_space_overseer *xso,
}
/*!
* @copydoc xrt_space_overseer::create_localspace_space
* @copydoc xrt_space_overseer::create_local_space
*
* Helper for calling through the function pointer.
*
* @public @memberof xrt_space_overseer
*/
static inline xrt_result_t
xrt_space_overseer_create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space)
xrt_space_overseer_create_local_space(struct xrt_space_overseer *xso,
struct xrt_space **out_local_space,
struct xrt_space **out_local_floor_space)
{
return xso->create_local_space(xso, out_space);
return xso->create_local_space(xso, out_local_space, out_local_floor_space);
}
/*!

View file

@ -120,6 +120,10 @@ struct ipc_client_state
uint32_t local_space_index;
//! Index of localspace in space overseer.
uint32_t local_space_overseer_index;
//! Index of localfloorspace in ipc client.
uint32_t local_floor_space_index;
//! Index of localfloorspace in space overseer.
uint32_t local_floor_space_overseer_index;
//! Ptrs to the spaces.
struct xrt_space *xspcs[IPC_MAX_CLIENT_SPACES];

View file

@ -174,7 +174,7 @@ track_space(volatile struct ipc_client_state *ics, struct xrt_space *xs, uint32_
static xrt_result_t
get_new_localspace_id(volatile struct ipc_client_state *ics, uint32_t *out_id)
get_new_localspace_id(volatile struct ipc_client_state *ics, uint32_t *out_local_id, uint32_t *out_local_floor_id)
{
// Our handle is just the index for now.
uint32_t index = 0;
@ -203,27 +203,61 @@ get_new_localspace_id(volatile struct ipc_client_state *ics, uint32_t *out_id)
}
ics->local_space_index = index;
*out_id = index;
*out_local_id = index;
for (index = 0; index < IPC_MAX_CLIENT_SPACES; index++) {
if (ics->server->xso->localfloorspace[index] == NULL) {
break;
}
}
if (index >= IPC_MAX_CLIENT_SPACES) {
IPC_ERROR(ics->server, "Too many localfloorspaces!");
return XRT_ERROR_IPC_FAILURE;
}
ics->local_floor_space_overseer_index = index;
for (index = 0; index < IPC_MAX_CLIENT_SPACES; index++) {
if (ics->xspcs[index] == NULL && index != ics->local_space_index) {
break;
}
}
if (index >= IPC_MAX_CLIENT_SPACES) {
IPC_ERROR(ics->server, "Too many spaces!");
return XRT_ERROR_IPC_FAILURE;
}
ics->local_floor_space_index = index;
*out_local_floor_id = index;
return XRT_SUCCESS;
}
static xrt_result_t
create_localspace(volatile struct ipc_client_state *ics, uint32_t *out_local_id)
create_localspace(volatile struct ipc_client_state *ics, uint32_t *out_local_id, uint32_t *out_local_floor_id)
{
uint32_t id = UINT32_MAX;
xrt_result_t xret = get_new_localspace_id(ics, &id);
uint32_t local_id = UINT32_MAX;
uint32_t local_floor_id = UINT32_MAX;
xrt_result_t xret = get_new_localspace_id(ics, &local_id, &local_floor_id);
if (xret != XRT_SUCCESS) {
return xret;
}
struct xrt_space_overseer *xso = ics->server->xso;
struct xrt_space **xs_ptr = (struct xrt_space **)&ics->xspcs[id];
struct xrt_space **xslocal_ptr = (struct xrt_space **)&ics->xspcs[local_id];
struct xrt_space **xslocalfloor_ptr = (struct xrt_space **)&ics->xspcs[local_floor_id];
xrt_space_overseer_create_local_space(xso, &xso->localspace[ics->local_space_overseer_index]);
xrt_space_reference(xs_ptr, xso->localspace[ics->local_space_overseer_index]);
*out_local_id = id;
xret = xrt_space_overseer_create_local_space(xso, &xso->localspace[ics->local_space_overseer_index],
&xso->localfloorspace[ics->local_floor_space_overseer_index]);
if (xret != XRT_SUCCESS) {
return xret;
}
xrt_space_reference(xslocal_ptr, xso->localspace[ics->local_space_overseer_index]);
xrt_space_reference(xslocalfloor_ptr, xso->localfloorspace[ics->local_floor_space_overseer_index]);
*out_local_id = local_id;
*out_local_floor_id = local_floor_id;
return XRT_SUCCESS;
}
@ -444,13 +478,11 @@ ipc_handle_space_create_semantic_ids(volatile struct ipc_client_state *ics,
CREATE(root);
CREATE(view);
CREATE(local_floor);
CREATE(stage);
CREATE(unbounded);
#undef CREATE
create_localspace(ics, out_local_id);
return XRT_SUCCESS;
return create_localspace(ics, out_local_id, out_local_floor_id);
}
xrt_result_t
@ -730,6 +762,12 @@ ipc_handle_space_destroy(volatile struct ipc_client_state *ics, uint32_t space_i
xrt_space_reference(xslocal_ptr, NULL);
}
if (space_id == ics->local_floor_space_index) {
struct xrt_space **xslocalfloor_ptr =
(struct xrt_space **)&ics->server->xso->localfloorspace[ics->local_floor_space_overseer_index];
xrt_space_reference(xslocalfloor_ptr, NULL);
}
return XRT_SUCCESS;
}

View file

@ -72,6 +72,13 @@ common_shutdown(volatile struct ipc_client_state *ics)
NULL);
}
if (ics->local_floor_space_overseer_index < IPC_MAX_CLIENT_SPACES && //
ics->local_floor_space_overseer_index >= 0) {
xrt_space_reference(
(struct xrt_space **)&ics->server->xso->localfloorspace[ics->local_floor_space_overseer_index],
NULL);
}
// Mark an still in use reference spaces as no longer used.
for (uint32_t i = 0; i < ARRAY_SIZE(ics->ref_space_used); i++) {
bool used = ics->ref_space_used[i];