Support muti-localspace on server side

client can have independent localspace to use

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2130>
This commit is contained in:
Shijian 2024-01-26 18:35:41 +08:00 committed by Marge Bot
parent a60e24ef01
commit 0f07c05426
5 changed files with 122 additions and 3 deletions

View file

@ -802,6 +802,23 @@ err_unlock:
return XRT_ERROR_RECENTERING_NOT_SUPPORTED;
}
static xrt_result_t
create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space)
{
assert(xso->semantic.root != NULL);
struct xrt_space *xs = NULL;
struct xrt_space_relation xsr;
int64_t timestamp_ns = os_monotonic_get_ns();
xrt_device_get_tracked_pose(xso->head, XRT_INPUT_GENERIC_HEAD_POSE, timestamp_ns, &xsr);
xsr.pose.orientation.x = 0;
xsr.pose.orientation.z = 0;
math_quat_normalize(&xsr.pose.orientation);
create_offset_space(xso, xso->semantic.root, &xsr.pose, &xs);
*out_space = xs;
U_LOG_D("u_space_overseer create_local_space!");
return XRT_SUCCESS;
}
static void
destroy(struct xrt_space_overseer *xso)
{
@ -818,6 +835,11 @@ destroy(struct xrt_space_overseer *xso)
u_hashmap_int_clear_and_call_for_each(uso->xdev_map, hashmap_unreference_space_items, uso);
u_hashmap_int_destroy(&uso->xdev_map);
for (int id = 0; id < XRT_MAX_CLIENT_SPACES; id++) {
struct xrt_space *xslocal = xso->localspace[id];
xrt_space_reference(&xslocal, NULL);
}
pthread_rwlock_destroy(&uso->lock);
free(uso);
@ -834,6 +856,7 @@ struct u_space_overseer *
u_space_overseer_create(struct xrt_session_event_sink *broadcast)
{
struct u_space_overseer *uso = U_TYPED_CALLOC(struct u_space_overseer);
uso->base.create_local_space = create_local_space;
uso->base.create_offset_space = create_offset_space;
uso->base.create_pose_space = create_pose_space;
uso->base.locate_space = locate_space;
@ -919,6 +942,8 @@ u_space_overseer_legacy_setup(struct u_space_overseer *uso,
xrt_space_reference(&uso->base.semantic.unbounded, uso->base.semantic.root);
}
uso->base.head = head;
// Set local to the local offset.
u_space_overseer_create_offset_space(uso, uso->base.semantic.root, local_offset, &uso->base.semantic.local);

View file

@ -15,7 +15,7 @@
extern "C" {
#endif
#define XRT_MAX_CLIENT_SPACES 128
struct xrt_device;
/*!
@ -107,6 +107,10 @@ struct xrt_space_overseer
*/
} semantic;
//! Ptrs to the localspace
struct xrt_space *localspace[XRT_MAX_CLIENT_SPACES];
struct xrt_device *head;
/*!
* Create a space with a fixed offset to the parent space.
*
@ -236,6 +240,14 @@ struct xrt_space_overseer
*/
xrt_result_t (*recenter_local_spaces)(struct xrt_space_overseer *xso);
/*!
* Create a localspace.
*
* @param[in] xso Owning space overseer.
* @param[out] out_space The newly created localspace.
*/
xrt_result_t (*create_local_space)(struct xrt_space_overseer *xso, struct xrt_space **out_space);
/*!
* Destroy function.
*
@ -373,6 +385,19 @@ xrt_space_overseer_recenter_local_spaces(struct xrt_space_overseer *xso)
return xso->recenter_local_spaces(xso);
}
/*!
* @copydoc xrt_space_overseer::create_localspace_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)
{
return xso->create_local_space(xso, out_space);
}
/*!
* Helper for calling through the function pointer: does a null check and sets
* xc_ptr to null if freed.

View file

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

View file

@ -154,6 +154,62 @@ 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)
{
// Our handle is just the index for now.
uint32_t index = 0;
for (; index < IPC_MAX_CLIENT_SPACES; index++) {
if (ics->server->xso->localspace[index] == NULL) {
break;
}
}
if (index >= IPC_MAX_CLIENT_SPACES) {
IPC_ERROR(ics->server, "Too many localspaces!");
return XRT_ERROR_IPC_FAILURE;
}
ics->local_space_overseer_index = index;
index = 0;
for (; index < IPC_MAX_CLIENT_SPACES; index++) {
if (ics->xspcs[index] == NULL) {
break;
}
}
if (index >= IPC_MAX_CLIENT_SPACES) {
IPC_ERROR(ics->server, "Too many spaces!");
return XRT_ERROR_IPC_FAILURE;
}
ics->local_space_index = index;
*out_id = index;
return XRT_SUCCESS;
}
static xrt_result_t
create_localspace(volatile struct ipc_client_state *ics, uint32_t *out_local_id)
{
uint32_t id = UINT32_MAX;
xrt_result_t xret = get_new_localspace_id(ics, &id);
if (xret != XRT_SUCCESS) {
return xret;
}
struct xrt_space *xs = NULL;
struct xrt_space_overseer *xso = ics->server->xso;
struct xrt_space **xs_ptr = (struct xrt_space **)&ics->xspcs[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;
return XRT_SUCCESS;
}
/*
*
* Handle functions.
@ -366,13 +422,12 @@ ipc_handle_space_create_semantic_ids(volatile struct ipc_client_state *ics,
CREATE(root);
CREATE(view);
CREATE(local);
CREATE(local_floor);
CREATE(stage);
CREATE(unbounded);
#undef CREATE
create_localspace(ics, out_local_id);
return XRT_SUCCESS;
}
@ -647,6 +702,11 @@ ipc_handle_space_destroy(volatile struct ipc_client_state *ics, uint32_t space_i
struct xrt_space **xs_ptr = (struct xrt_space **)&ics->xspcs[space_id];
xrt_space_reference(xs_ptr, NULL);
if (space_id == ics->local_space_index) {
struct xrt_space *xslocal_ptr = ics->server->xso->localspace[ics->local_space_overseer_index];
xrt_space_reference(&xslocal_ptr, NULL);
}
return XRT_SUCCESS;
}

View file

@ -67,6 +67,11 @@ common_shutdown(volatile struct ipc_client_state *ics)
xrt_space_reference((struct xrt_space **)&ics->xspcs[i], NULL);
}
if (ics->local_space_overseer_index < IPC_MAX_CLIENT_SPACES && ics->local_space_overseer_index >= 0) {
struct xrt_space *xslocal = ics->server->xso->localspace[ics->local_space_overseer_index];
xrt_space_reference(&xslocal, 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];