mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-29 18:08:29 +00:00
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:
parent
a60e24ef01
commit
0f07c05426
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue