st/oxr: Separate out dynamic roles and associated profiles

Separates the role xdev indices and associated interaction
profile (names) from dynamic roles so that interaction profiles
can be method active and have action (set) attachements updated
without bindings and no requirement for an xrt-device for
a particular hand.

E.g. driver can make left & right with a paritcular profile (name) and
have either both not have an xrt-device ready/unassigned but OpenXR apps
can still sync/query actions states on the not read/unassigned hands,
this also fixes CTS action tests when the hand is constrained to certain
hand, in particular the right hand.

Co-authored-by: Robbie Bridgewater <ebridgewater@magicleap.com>
This commit is contained in:
Korcan Hussein 2023-12-13 21:56:56 +00:00 committed by Simon Zeni
parent 36d5d4224c
commit 59b8d3a955
5 changed files with 81 additions and 12 deletions

View file

@ -657,6 +657,8 @@ struct xrt_relation_chain
*/
enum xrt_device_name
{
XRT_DEVICE_INVALID = 0,
XRT_DEVICE_GENERIC_HMD = 1,
// Vive stuff.

View file

@ -5,6 +5,7 @@
* @file
* @brief Header for system objects.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Korcan Hussein <korcan.hussein@collabora.com>
* @ingroup xrt_iface
*/
@ -171,6 +172,12 @@ struct xrt_system_roles
* device, or negative if none available.
*/
int32_t gamepad;
enum xrt_device_name left_profile;
enum xrt_device_name right_profile;
enum xrt_device_name gamepad_profile;
};
/*!
@ -182,7 +189,7 @@ struct xrt_system_roles
*/
#define XRT_SYSTEM_ROLES_INIT \
{ \
0, -1, -1, -1 \
0, -1, -1, -1, XRT_DEVICE_INVALID, XRT_DEVICE_INVALID, XRT_DEVICE_INVALID, \
}

View file

@ -342,11 +342,11 @@ get_identifier_str_in_profile(struct oxr_logger *log,
return str;
}
static void
get_profile_for_device_name(struct oxr_logger *log,
struct oxr_session *sess,
enum xrt_device_name name,
struct oxr_interaction_profile **out_p)
void
oxr_get_profile_for_device_name(struct oxr_logger *log,
struct oxr_session *sess,
enum xrt_device_name name,
struct oxr_interaction_profile **out_p)
{
struct oxr_instance *inst = sess->sys->inst;
/*
@ -407,7 +407,7 @@ oxr_find_profile_for_device(struct oxr_logger *log,
}
// Have bindings for this device's interaction profile been suggested?
get_profile_for_device_name(log, sess, xdev->name, out_p);
oxr_get_profile_for_device_name(log, sess, xdev->name, out_p);
if (*out_p != NULL) {
return;
}
@ -415,7 +415,7 @@ oxr_find_profile_for_device(struct oxr_logger *log,
// Check if bindings for any of this device's alternative interaction profiles have been suggested.
for (size_t i = 0; i < xdev->binding_profile_count; i++) {
struct xrt_binding_profile *xbp = &xdev->binding_profiles[i];
get_profile_for_device_name(log, sess, xbp->name, out_p);
oxr_get_profile_for_device_name(log, sess, xbp->name, out_p);
if (*out_p != NULL) {
return;
}

View file

@ -747,6 +747,25 @@ struct oxr_profiles_per_subaction
#undef PROFILE_MEMBER
};
static void
oxr_find_profiles_from_roles(struct oxr_logger *log,
struct oxr_session *sess,
struct oxr_profiles_per_subaction *out_profiles)
{
#define FIND_PROFILE(X) \
{ \
struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, X); \
if (xdev != NULL) { \
oxr_find_profile_for_device(log, sess, xdev, &out_profiles->X); \
} else { \
oxr_get_profile_for_device_name(log, sess, GET_PROFILE_NAME_BY_ROLE(sess->sys, X), \
&out_profiles->X); \
} \
}
OXR_FOR_EACH_VALID_SUBACTION_PATH(FIND_PROFILE)
#undef FIND_PROFILE
}
/*!
* @public @memberof oxr_action_attachment
*/
@ -1661,10 +1680,7 @@ XrResult
oxr_session_update_action_bindings(struct oxr_logger *log, struct oxr_session *sess)
{
struct oxr_profiles_per_subaction profiles = {0};
#define FIND_PROFILE(X) oxr_find_profile_for_device(log, sess, GET_XDEV_BY_ROLE(sess->sys, X), &profiles.X);
OXR_FOR_EACH_VALID_SUBACTION_PATH(FIND_PROFILE)
#undef FIND_PROFILE
oxr_find_profiles_from_roles(log, sess, &profiles);
for (size_t i = 0; i < sess->action_set_attachment_count; i++) {
struct oxr_action_set_attachment *act_set_attached = &sess->act_set_attachments[i];

View file

@ -564,6 +564,12 @@ oxr_find_profile_for_device(struct oxr_logger *log,
struct xrt_device *xdev,
struct oxr_interaction_profile **out_p);
void
oxr_get_profile_for_device_name(struct oxr_logger *log,
struct oxr_session *sess,
enum xrt_device_name name,
struct oxr_interaction_profile **out_p);
struct oxr_interaction_profile *
oxr_clone_profile(const struct oxr_interaction_profile *src_profile);
@ -1395,6 +1401,44 @@ MAKE_GET_DYN_ROLES_FN(gamepad)
#define GET_XDEV_BY_ROLE(SYS, ROLE) (get_role_##ROLE((SYS)))
static inline enum xrt_device_name
get_role_profile_head(struct oxr_system *sys)
{
return XRT_DEVICE_INVALID;
}
static inline enum xrt_device_name
get_role_profile_eyes(struct oxr_system *sys)
{
return XRT_DEVICE_INVALID;
}
static inline enum xrt_device_name
get_role_profile_hand_tracking_left(struct oxr_system *sys)
{
return XRT_DEVICE_INVALID;
}
static inline enum xrt_device_name
get_role_profile_hand_tracking_right(struct oxr_system *sys)
{
return XRT_DEVICE_INVALID;
}
#define MAKE_GET_DYN_ROLE_PROFILE_FN(ROLE) \
static inline enum xrt_device_name get_role_profile_##ROLE(struct oxr_system *sys) \
{ \
const bool is_locked = 0 == os_mutex_trylock(&sys->sync_actions_mutex); \
const enum xrt_device_name profile_name = sys->dynamic_roles_cache.ROLE##_profile; \
if (is_locked) { \
os_mutex_unlock(&sys->sync_actions_mutex); \
} \
return profile_name; \
}
MAKE_GET_DYN_ROLE_PROFILE_FN(left)
MAKE_GET_DYN_ROLE_PROFILE_FN(right)
MAKE_GET_DYN_ROLE_PROFILE_FN(gamepad)
#undef MAKE_GET_DYN_ROLES_FN
#define GET_PROFILE_NAME_BY_ROLE(SYS, ROLE) (get_role_profile_##ROLE((SYS)))
/*
* Extensions helpers.
*/