mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-16 10:40:06 +00:00
st/oxr: Clone profiles to session on action sets attachment.
Co-authored-by: Jakob Bornecrantz <jakob@collabora.com>
This commit is contained in:
parent
d033955678
commit
f60ffe5af7
src/xrt/state_trackers/oxr
|
@ -45,13 +45,16 @@ setup_paths(struct oxr_logger *log,
|
|||
}
|
||||
|
||||
static bool
|
||||
interaction_profile_find(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath path,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
interaction_profile_find_in_array(struct oxr_logger *log,
|
||||
const size_t profile_count,
|
||||
struct oxr_interaction_profile **profiles,
|
||||
XrPath path,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
{
|
||||
for (size_t x = 0; x < inst->profile_count; x++) {
|
||||
struct oxr_interaction_profile *p = inst->profiles[x];
|
||||
if (profiles == NULL)
|
||||
return false;
|
||||
for (size_t x = 0; x < profile_count; x++) {
|
||||
struct oxr_interaction_profile *p = profiles[x];
|
||||
if (p->path != path) {
|
||||
continue;
|
||||
}
|
||||
|
@ -63,6 +66,34 @@ interaction_profile_find(struct oxr_logger *log,
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
interaction_profile_find_in_instance(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath path,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
{
|
||||
return interaction_profile_find_in_array( //
|
||||
log, //
|
||||
inst->profile_count, //
|
||||
inst->profiles, //
|
||||
path, //
|
||||
out_p); //
|
||||
}
|
||||
|
||||
static inline bool
|
||||
internaction_profile_find_in_session(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
XrPath path,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
{
|
||||
return interaction_profile_find_in_array( //
|
||||
log, //
|
||||
sess->profiles_on_attachment_size, //
|
||||
sess->profiles_on_attachment, //
|
||||
path, //
|
||||
out_p); //
|
||||
}
|
||||
|
||||
static bool
|
||||
get_subaction_path_from_path(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
|
@ -70,12 +101,12 @@ get_subaction_path_from_path(struct oxr_logger *log,
|
|||
enum oxr_subaction_path *out_subaction_path);
|
||||
|
||||
static bool
|
||||
interaction_profile_find_or_create(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath path,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
interaction_profile_find_or_create_in_instance(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath path,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
{
|
||||
if (interaction_profile_find(log, inst, path, out_p)) {
|
||||
if (interaction_profile_find_in_instance(log, inst, path, out_p)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -313,15 +344,16 @@ get_identifier_str_in_profile(struct oxr_logger *log,
|
|||
|
||||
static void
|
||||
get_profile_for_device_name(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
struct oxr_session *sess,
|
||||
enum xrt_device_name name,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
{
|
||||
struct oxr_instance *inst = sess->sys->inst;
|
||||
/*
|
||||
* Map xrt_device_name to an interaction profile XrPath.
|
||||
* Set *out_p to an oxr_interaction_profile if bindings for that interaction profile XrPath have been suggested.
|
||||
*/
|
||||
#define FIND_PROFILE(PATH) interaction_profile_find(log, inst, inst->path_cache.PATH, out_p)
|
||||
#define FIND_PROFILE(PATH) internaction_profile_find_in_session(log, sess, inst->path_cache.PATH, out_p)
|
||||
|
||||
switch (name) {
|
||||
case XRT_DEVICE_PSMV: FIND_PROFILE(mndx_ball_on_a_stick_controller); return;
|
||||
|
@ -366,7 +398,7 @@ get_profile_for_device_name(struct oxr_logger *log,
|
|||
|
||||
void
|
||||
oxr_find_profile_for_device(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
struct oxr_session *sess,
|
||||
struct xrt_device *xdev,
|
||||
struct oxr_interaction_profile **out_p)
|
||||
{
|
||||
|
@ -375,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, inst, xdev->name, out_p);
|
||||
get_profile_for_device_name(log, sess, xdev->name, out_p);
|
||||
if (*out_p != NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -383,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, inst, xbp->name, out_p);
|
||||
get_profile_for_device_name(log, sess, xbp->name, out_p);
|
||||
if (*out_p != NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -425,11 +457,91 @@ oxr_binding_find_bindings_from_key(struct oxr_logger *log,
|
|||
*binding_count = num;
|
||||
}
|
||||
|
||||
void
|
||||
oxr_binding_destroy_all(struct oxr_logger *log, struct oxr_instance *inst)
|
||||
struct oxr_interaction_profile *
|
||||
oxr_clone_profile(const struct oxr_interaction_profile *src_profile)
|
||||
{
|
||||
for (size_t x = 0; x < inst->profile_count; x++) {
|
||||
struct oxr_interaction_profile *p = inst->profiles[x];
|
||||
if (src_profile == NULL)
|
||||
return NULL;
|
||||
|
||||
struct oxr_interaction_profile *dst_profile = U_TYPED_CALLOC(struct oxr_interaction_profile);
|
||||
|
||||
*dst_profile = *src_profile;
|
||||
|
||||
dst_profile->binding_count = 0;
|
||||
dst_profile->bindings = NULL;
|
||||
if (src_profile->bindings && src_profile->binding_count > 0) {
|
||||
|
||||
dst_profile->binding_count = src_profile->binding_count;
|
||||
dst_profile->bindings = U_TYPED_ARRAY_CALLOC(struct oxr_binding, src_profile->binding_count);
|
||||
|
||||
for (size_t binding_idx = 0; binding_idx < src_profile->binding_count; ++binding_idx) {
|
||||
struct oxr_binding *dst_binding = dst_profile->bindings + binding_idx;
|
||||
const struct oxr_binding *src_binding = src_profile->bindings + binding_idx;
|
||||
|
||||
*dst_binding = *src_binding;
|
||||
|
||||
dst_binding->path_count = 0;
|
||||
dst_binding->paths = NULL;
|
||||
if (src_binding->paths && src_binding->path_count > 0) {
|
||||
dst_binding->path_count = src_binding->path_count;
|
||||
dst_binding->paths = U_TYPED_ARRAY_CALLOC(XrPath, src_binding->path_count);
|
||||
memcpy(dst_binding->paths, src_binding->paths,
|
||||
sizeof(XrPath) * src_binding->path_count);
|
||||
}
|
||||
|
||||
dst_binding->key_count = 0;
|
||||
dst_binding->keys = NULL;
|
||||
dst_binding->preferred_binding_path_index = NULL;
|
||||
if (src_binding->keys && src_binding->key_count > 0) {
|
||||
dst_binding->key_count = src_binding->key_count;
|
||||
dst_binding->keys = U_TYPED_ARRAY_CALLOC(uint32_t, src_binding->key_count);
|
||||
memcpy(dst_binding->keys, src_binding->keys, sizeof(uint32_t) * src_binding->key_count);
|
||||
}
|
||||
if (src_binding->preferred_binding_path_index && src_binding->key_count > 0) {
|
||||
assert(dst_binding->key_count == src_binding->key_count);
|
||||
dst_binding->preferred_binding_path_index =
|
||||
U_TYPED_ARRAY_CALLOC(uint32_t, src_binding->key_count);
|
||||
memcpy(dst_binding->preferred_binding_path_index,
|
||||
src_binding->preferred_binding_path_index,
|
||||
sizeof(uint32_t) * src_binding->key_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dst_profile->dpad_count = 0;
|
||||
dst_profile->dpads = NULL;
|
||||
if (src_profile->dpads && src_profile->dpad_count > 0) {
|
||||
|
||||
dst_profile->dpad_count = src_profile->dpad_count;
|
||||
dst_profile->dpads = U_TYPED_ARRAY_CALLOC(struct oxr_dpad_emulation, src_profile->dpad_count);
|
||||
|
||||
for (size_t dpad_index = 0; dpad_index < src_profile->dpad_count; ++dpad_index) {
|
||||
struct oxr_dpad_emulation *dst_dpad = dst_profile->dpads + dpad_index;
|
||||
const struct oxr_dpad_emulation *src_dpad = src_profile->dpads + dpad_index;
|
||||
|
||||
*dst_dpad = *src_dpad;
|
||||
|
||||
dst_dpad->path_count = 0;
|
||||
dst_dpad->paths = NULL;
|
||||
if (src_dpad->paths && src_dpad->path_count > 0) {
|
||||
dst_dpad->path_count = src_dpad->path_count;
|
||||
dst_dpad->paths = U_TYPED_ARRAY_CALLOC(XrPath, src_dpad->path_count);
|
||||
memcpy(dst_dpad->paths, src_dpad->paths, sizeof(XrPath) * src_dpad->path_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dst_profile;
|
||||
}
|
||||
|
||||
static void
|
||||
oxr_destroy_profiles(struct oxr_interaction_profile **profiles, const size_t profile_count)
|
||||
{
|
||||
if (profiles == NULL)
|
||||
return;
|
||||
|
||||
for (size_t x = 0; x < profile_count; x++) {
|
||||
struct oxr_interaction_profile *p = profiles[x];
|
||||
|
||||
for (size_t y = 0; y < p->binding_count; y++) {
|
||||
struct oxr_binding *b = &p->bindings[y];
|
||||
|
@ -451,11 +563,24 @@ oxr_binding_destroy_all(struct oxr_logger *log, struct oxr_instance *inst)
|
|||
free(p);
|
||||
}
|
||||
|
||||
free(inst->profiles);
|
||||
free(profiles);
|
||||
}
|
||||
|
||||
void
|
||||
oxr_binding_destroy_all(struct oxr_logger *log, struct oxr_instance *inst)
|
||||
{
|
||||
oxr_destroy_profiles(inst->profiles, inst->profile_count);
|
||||
inst->profiles = NULL;
|
||||
inst->profile_count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
oxr_session_binding_destroy_all(struct oxr_logger *log, struct oxr_session *sess)
|
||||
{
|
||||
oxr_destroy_profiles(sess->profiles_on_attachment, sess->profiles_on_attachment_size);
|
||||
sess->profiles_on_attachment = NULL;
|
||||
sess->profiles_on_attachment_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -473,7 +598,7 @@ oxr_action_suggest_interaction_profile_bindings(struct oxr_logger *log,
|
|||
|
||||
// Path already validated.
|
||||
XrPath path = suggestedBindings->interactionProfile;
|
||||
interaction_profile_find_or_create(log, inst, path, &p);
|
||||
interaction_profile_find_or_create_in_instance(log, inst, path, &p);
|
||||
|
||||
// Valid path, but not used.
|
||||
if (p == NULL) {
|
||||
|
@ -559,7 +684,7 @@ oxr_action_get_input_source_localized_name(struct oxr_logger *log,
|
|||
// Find the interaction profile.
|
||||
struct oxr_interaction_profile *oip = NULL;
|
||||
//! @todo: If we ever rebind a profile that has not been suggested by the client, it will not be found.
|
||||
interaction_profile_find(log, sess->sys->inst, path, &oip);
|
||||
internaction_profile_find_in_session(log, sess, path, &oip);
|
||||
if (oip == NULL) {
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "no interaction profile found");
|
||||
}
|
||||
|
|
|
@ -1522,14 +1522,36 @@ oxr_handle_base_get_num_children(struct oxr_handle_base *hb)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
oxr_clone_profiles_to_session(struct oxr_logger *log, struct oxr_instance *inst, struct oxr_session *sess)
|
||||
{
|
||||
|
||||
if (inst == NULL || sess == NULL)
|
||||
return;
|
||||
|
||||
oxr_session_binding_destroy_all(log, sess);
|
||||
|
||||
if (inst->profiles == NULL || inst->profile_count == 0)
|
||||
return;
|
||||
|
||||
sess->profiles_on_attachment_size = inst->profile_count;
|
||||
sess->profiles_on_attachment = U_TYPED_ARRAY_CALLOC(struct oxr_interaction_profile *, inst->profile_count);
|
||||
|
||||
for (size_t profile_idx = 0; profile_idx < inst->profile_count; ++profile_idx) {
|
||||
sess->profiles_on_attachment[profile_idx] = oxr_clone_profile(inst->profiles[profile_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
XrResult
|
||||
oxr_session_attach_action_sets(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
const XrSessionActionSetsAttachInfo *bindInfo)
|
||||
{
|
||||
struct oxr_instance *inst = sess->sys->inst;
|
||||
oxr_clone_profiles_to_session(log, inst, sess);
|
||||
|
||||
struct oxr_profiles_per_subaction profiles = {0};
|
||||
#define FIND_PROFILE(X) oxr_find_profile_for_device(log, inst, GET_XDEV_BY_ROLE(sess->sys, X), &profiles.X);
|
||||
#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
|
||||
|
||||
|
|
|
@ -555,10 +555,13 @@ oxr_hand_tracker_create(struct oxr_logger *log,
|
|||
*/
|
||||
void
|
||||
oxr_find_profile_for_device(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
struct oxr_session *sess,
|
||||
struct xrt_device *xdev,
|
||||
struct oxr_interaction_profile **out_p);
|
||||
|
||||
struct oxr_interaction_profile *
|
||||
oxr_clone_profile(const struct oxr_interaction_profile *src_profile);
|
||||
|
||||
/*!
|
||||
* Free all memory allocated by the binding system.
|
||||
*
|
||||
|
@ -567,6 +570,14 @@ oxr_find_profile_for_device(struct oxr_logger *log,
|
|||
void
|
||||
oxr_binding_destroy_all(struct oxr_logger *log, struct oxr_instance *inst);
|
||||
|
||||
/*!
|
||||
* Free all memory allocated by the binding system.
|
||||
*
|
||||
* @public @memberof oxr_instance
|
||||
*/
|
||||
void
|
||||
oxr_session_binding_destroy_all(struct oxr_logger *log, struct oxr_session *sess);
|
||||
|
||||
/*!
|
||||
* Find all bindings that is the given action key is bound to.
|
||||
* @public @memberof oxr_interaction_profile
|
||||
|
@ -1521,6 +1532,12 @@ struct oxr_session
|
|||
*/
|
||||
struct u_hashmap_int *act_attachments_by_key;
|
||||
|
||||
/*!
|
||||
* Clone of all suggested binding profiles at the point of action set/session attachment.
|
||||
* ref to @oxr_session_attach_action_sets
|
||||
*/
|
||||
size_t profiles_on_attachment_size;
|
||||
struct oxr_interaction_profile **profiles_on_attachment;
|
||||
|
||||
/*!
|
||||
* Currently bound interaction profile.
|
||||
|
|
|
@ -651,6 +651,8 @@ oxr_session_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
|||
|
||||
XrResult ret = oxr_event_remove_session_events(log, sess);
|
||||
|
||||
oxr_session_binding_destroy_all(log, sess);
|
||||
|
||||
for (size_t i = 0; i < sess->action_set_attachment_count; ++i) {
|
||||
oxr_action_set_attachment_teardown(&sess->act_set_attachments[i]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue