mirror of
https://github.com/lbgos/rift-s-linux.git
synced 2026-10-28 03:01:29 +01:00
st/oxr: Add oxr_session_action_context
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2761>
This commit is contained in:
1 parent
8ff0ba352d
commit
6d503d082f
10 files changed
+395
-177
No files matched your search
@@ -33,6 +33,8 @@ add_library(
|
||||
actions/oxr_instance_path_cache.h
|
||||
actions/oxr_interaction_profile_array.c
|
||||
actions/oxr_interaction_profile_array.h
|
||||
actions/oxr_session_action_context.c
|
||||
actions/oxr_session_action_context.h
|
||||
actions/oxr_set_haptic.c
|
||||
actions/oxr_set_haptic.h
|
||||
common/oxr_defines.h
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "oxr_input.h"
|
||||
#include "oxr_binding.h"
|
||||
#include "oxr_haptic.h"
|
||||
#include "oxr_session_action_context.h"
|
||||
|
||||
#include "../oxr_api_verify.h"
|
||||
#include "../oxr_objects.h"
|
||||
@@ -178,7 +179,7 @@ oxr_xrAttachSessionActionSets(XrSession session, const XrSessionActionSetsAttach
|
||||
OXR_VERIFY_SESSION_NOT_LOST(&log, sess);
|
||||
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, bindInfo, XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO);
|
||||
|
||||
if (sess->act_set_attachments != NULL) {
|
||||
if (oxr_session_action_context_has_attached_act_sets(&sess->action_context)) {
|
||||
return oxr_error(&log, XR_ERROR_ACTIONSETS_ALREADY_ATTACHED,
|
||||
"(session) has already had action sets "
|
||||
"attached, can only attach action sets once.");
|
||||
@@ -423,10 +424,12 @@ oxr_xrGetCurrentInteractionProfile(XrSession session,
|
||||
str);
|
||||
}
|
||||
|
||||
OXR_SESSION_CHECK_ATTACHED_AND_RET(sess, &log);
|
||||
|
||||
XrResult ret = oxr_action_get_current_interaction_profile( //
|
||||
&log, //
|
||||
&inst->path_cache, //
|
||||
sess, //
|
||||
&sess->action_context, //
|
||||
topLevelUserPath, //
|
||||
interactionProfile); //
|
||||
if (ret == XR_SUCCESS) {
|
||||
@@ -454,10 +457,7 @@ oxr_xrGetInputSourceLocalizedName(XrSession session,
|
||||
// Short hand.
|
||||
inst = sess->sys->inst;
|
||||
|
||||
if (sess->act_set_attachments == NULL) {
|
||||
return oxr_error(&log, XR_ERROR_ACTIONSET_NOT_ATTACHED,
|
||||
"ActionSet(s) have not been attached to this session");
|
||||
}
|
||||
OXR_SESSION_CHECK_ATTACHED_AND_RET(sess, &log);
|
||||
|
||||
if (getInfo->sourcePath == XR_NULL_PATH) {
|
||||
return oxr_error(&log, XR_ERROR_PATH_INVALID,
|
||||
@@ -487,7 +487,7 @@ oxr_xrGetInputSourceLocalizedName(XrSession session,
|
||||
XrResult ret = oxr_action_get_input_source_localized_name( //
|
||||
&log, //
|
||||
&inst->path_store, //
|
||||
sess, //
|
||||
&sess->action_context, //
|
||||
getInfo, //
|
||||
bufferCapacityInput, //
|
||||
bufferCountOutput, //
|
||||
@@ -805,11 +805,7 @@ oxr_xrEnumerateBoundSourcesForAction(XrSession session,
|
||||
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, enumerateInfo, XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO);
|
||||
OXR_VERIFY_ACTION_NOT_NULL(&log, enumerateInfo->action, act);
|
||||
|
||||
if (sess->act_set_attachments == NULL) {
|
||||
return oxr_error(&log, XR_ERROR_ACTIONSET_NOT_ATTACHED,
|
||||
"(session) xrAttachSessionActionSets has not "
|
||||
"been called on this session.");
|
||||
}
|
||||
OXR_SESSION_CHECK_ATTACHED_AND_RET(sess, &log);
|
||||
|
||||
return oxr_action_enumerate_bound_sources(&log, sess, act->act_key, sourceCapacityInput, sourceCountOutput,
|
||||
sources);
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
#include "oxr_subaction.h"
|
||||
#include "oxr_generated_bindings.h"
|
||||
#include "oxr_dpad_state.h"
|
||||
#include "oxr_session_action_context.h"
|
||||
#include "oxr_interaction_profile_array.h"
|
||||
|
||||
#include "../oxr_objects.h"
|
||||
#include "../oxr_logger.h"
|
||||
#include "../oxr_two_call.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -354,11 +354,12 @@ get_subaction_path_str(enum oxr_subaction_path subaction_path)
|
||||
}
|
||||
|
||||
static XrPath
|
||||
get_interaction_bound_to_sub_path(struct oxr_session *sess, enum oxr_subaction_path subaction_path)
|
||||
get_interaction_bound_to_sub_path(const struct oxr_session_action_context *action_context,
|
||||
enum oxr_subaction_path subaction_path)
|
||||
{
|
||||
switch (subaction_path) {
|
||||
#define OXR_PATH_MEMBER(lower, CAP, _) \
|
||||
case OXR_SUB_ACTION_PATH_##CAP: return sess->lower;
|
||||
case OXR_SUB_ACTION_PATH_##CAP: return action_context->lower;
|
||||
|
||||
OXR_FOR_EACH_VALID_SUBACTION_PATH_DETAILED(OXR_PATH_MEMBER)
|
||||
#undef OXR_PATH_MEMBER
|
||||
@@ -610,18 +611,15 @@ out:
|
||||
XrResult
|
||||
oxr_action_get_current_interaction_profile(struct oxr_logger *log,
|
||||
const struct oxr_instance_path_cache *cache,
|
||||
struct oxr_session *sess,
|
||||
const struct oxr_session_action_context *action_context,
|
||||
XrPath topLevelUserPath,
|
||||
XrInteractionProfileState *interactionProfile)
|
||||
{
|
||||
if (sess->act_set_attachments == NULL) {
|
||||
return oxr_error(log, XR_ERROR_ACTIONSET_NOT_ATTACHED,
|
||||
"xrAttachSessionActionSets has not been "
|
||||
"called on this session.");
|
||||
}
|
||||
// Action sets attachment is checked in the API function.
|
||||
|
||||
#define IDENTIFY_TOP_LEVEL_PATH(X) \
|
||||
if (topLevelUserPath == cache->X) { \
|
||||
interactionProfile->interactionProfile = sess->X; \
|
||||
interactionProfile->interactionProfile = action_context->X; \
|
||||
} else
|
||||
|
||||
OXR_FOR_EACH_VALID_SUBACTION_PATH(IDENTIFY_TOP_LEVEL_PATH)
|
||||
@@ -636,7 +634,7 @@ oxr_action_get_current_interaction_profile(struct oxr_logger *log,
|
||||
XrResult
|
||||
oxr_action_get_input_source_localized_name(struct oxr_logger *log,
|
||||
const struct oxr_path_store *store,
|
||||
struct oxr_session *sess,
|
||||
const struct oxr_session_action_context *action_context,
|
||||
const XrInputSourceLocalizedNameGetInfo *getInfo,
|
||||
uint32_t bufferCapacityInput,
|
||||
uint32_t *bufferCountOutput,
|
||||
@@ -653,7 +651,7 @@ oxr_action_get_input_source_localized_name(struct oxr_logger *log,
|
||||
}
|
||||
|
||||
// Get the interaction profile bound to this subaction_path.
|
||||
XrPath path = get_interaction_bound_to_sub_path(sess, subaction_path);
|
||||
XrPath path = get_interaction_bound_to_sub_path(action_context, subaction_path);
|
||||
if (path == XR_NULL_PATH) {
|
||||
return oxr_error(log, XR_ERROR_VALIDATION_FAILURE,
|
||||
"(getInfo->sourcePath) no interaction profile "
|
||||
@@ -663,7 +661,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.
|
||||
oxr_interaction_profile_array_find_by_path(&sess->profiles_on_attachment, path, &oip);
|
||||
oxr_interaction_profile_array_find_by_path(&action_context->profiles_on_attachment, path, &oip);
|
||||
if (oip == NULL) {
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "no interaction profile found");
|
||||
}
|
||||
|
||||
@@ -90,11 +90,12 @@ oxr_action_suggest_interaction_profile_bindings(struct oxr_logger *log,
|
||||
|
||||
/*!
|
||||
* Get the currently active interaction profile for a top-level user path
|
||||
* on the session (e.g. /user/hand/left). Requires action sets to be attached.
|
||||
* on the session action context (e.g. /user/hand/left). Requires action sets to
|
||||
* be attached.
|
||||
*
|
||||
* @param log Logger
|
||||
* @param cache Instance path cache
|
||||
* @param sess Session
|
||||
* @param action_context Action context
|
||||
* @param topLevelUserPath Top-level user path (e.g. left hand)
|
||||
* @param interactionProfile Output interaction profile state
|
||||
* @return XR_SUCCESS on success
|
||||
@@ -103,7 +104,7 @@ oxr_action_suggest_interaction_profile_bindings(struct oxr_logger *log,
|
||||
XrResult
|
||||
oxr_action_get_current_interaction_profile(struct oxr_logger *log,
|
||||
const struct oxr_instance_path_cache *cache,
|
||||
struct oxr_session *sess,
|
||||
const struct oxr_session_action_context *action_context,
|
||||
XrPath topLevelUserPath,
|
||||
XrInteractionProfileState *interactionProfile);
|
||||
|
||||
@@ -112,7 +113,7 @@ oxr_action_get_current_interaction_profile(struct oxr_logger *log,
|
||||
*
|
||||
* @param log Logger
|
||||
* @param path_store Needed to look up path strings.
|
||||
* @param sess Session.
|
||||
* @param action_context Action context
|
||||
* @param getInfo Input source localized name get info
|
||||
* @param bufferCapacityInput Buffer capacity
|
||||
* @param bufferCountOutput Buffer count output
|
||||
@@ -123,7 +124,7 @@ oxr_action_get_current_interaction_profile(struct oxr_logger *log,
|
||||
XrResult
|
||||
oxr_action_get_input_source_localized_name(struct oxr_logger *log,
|
||||
const struct oxr_path_store *store,
|
||||
struct oxr_session *sess,
|
||||
const struct oxr_session_action_context *action_context,
|
||||
const XrInputSourceLocalizedNameGetInfo *getInfo,
|
||||
uint32_t bufferCapacityInput,
|
||||
uint32_t *bufferCountOutput,
|
||||
|
||||
@@ -93,6 +93,26 @@ print_profiles(struct oxr_logger *log,
|
||||
oxr_log_slog(log, &slog);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Given an Action Set handle, return the @ref oxr_action_set and the
|
||||
* associated @ref oxr_action_set_attachment in the given Session.
|
||||
*/
|
||||
static void
|
||||
get_action_set_attachment(struct oxr_session_action_context *sess_context,
|
||||
XrActionSet actionSet,
|
||||
struct oxr_action_set_attachment **out_act_set_attached,
|
||||
struct oxr_action_set **out_act_set)
|
||||
{
|
||||
struct oxr_action_set *act_set = XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_action_set *, actionSet);
|
||||
|
||||
// Make sure all are set.
|
||||
*out_act_set = act_set;
|
||||
*out_act_set_attached = NULL;
|
||||
|
||||
// Safe to call even if nothing has been attached.
|
||||
oxr_session_action_context_find_set(sess_context, act_set->act_set_key, out_act_set_attached);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -100,12 +120,6 @@ print_profiles(struct oxr_logger *log,
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
oxr_session_get_action_set_attachment(struct oxr_session *sess,
|
||||
XrActionSet actionSet,
|
||||
struct oxr_action_set_attachment **act_set_attached,
|
||||
struct oxr_action_set **act_set);
|
||||
|
||||
static void
|
||||
oxr_action_cache_update(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
@@ -218,7 +232,7 @@ static void
|
||||
oxr_action_attachment_teardown(struct oxr_action_attachment *act_attached)
|
||||
{
|
||||
struct oxr_session *sess = act_attached->sess;
|
||||
u_hashmap_int_erase(sess->act_attachments_by_key, act_attached->act_key);
|
||||
u_hashmap_int_erase(sess->action_context.act_attachments_by_key, act_attached->act_key);
|
||||
|
||||
#define CACHE_TEARDOWN(X) oxr_action_cache_teardown(&(act_attached->X));
|
||||
OXR_FOR_EACH_SUBACTION_PATH(CACHE_TEARDOWN)
|
||||
@@ -242,7 +256,7 @@ oxr_action_attachment_init(struct oxr_logger *log,
|
||||
struct oxr_session *sess = act_set_attached->sess;
|
||||
act_attached->sess = sess;
|
||||
act_attached->act_set_attached = act_set_attached;
|
||||
u_hashmap_int_insert(sess->act_attachments_by_key, act->act_key, act_attached);
|
||||
u_hashmap_int_insert(sess->action_context.act_attachments_by_key, act->act_key, act_attached);
|
||||
|
||||
// Reference this action's refcounted data
|
||||
act_attached->act_ref = act->data;
|
||||
@@ -275,7 +289,7 @@ oxr_action_set_attachment_init(struct oxr_logger *log,
|
||||
act_set_attached->act_set_ref = act_set->data;
|
||||
oxr_refcounted_ref(&act_set_attached->act_set_ref->base);
|
||||
|
||||
u_hashmap_int_insert(sess->act_sets_attachments_by_key, act_set->act_set_key, act_set_attached);
|
||||
u_hashmap_int_insert(sess->action_context.act_sets_attachments_by_key, act_set->act_set_key, act_set_attached);
|
||||
|
||||
// Copy this for efficiency.
|
||||
act_set_attached->act_set_key = act_set->act_set_key;
|
||||
@@ -294,7 +308,7 @@ oxr_action_set_attachment_teardown(struct oxr_action_set_attachment *act_set_att
|
||||
act_set_attached->action_attachment_count = 0;
|
||||
|
||||
struct oxr_session *sess = act_set_attached->sess;
|
||||
u_hashmap_int_erase(sess->act_sets_attachments_by_key, act_set_attached->act_set_key);
|
||||
u_hashmap_int_erase(sess->action_context.act_sets_attachments_by_key, act_set_attached->act_set_key);
|
||||
|
||||
// Unref this action set's refcounted data
|
||||
oxr_refcounted_unref(&act_set_attached->act_set_ref->base);
|
||||
@@ -1088,7 +1102,7 @@ oxr_input_supressed(struct oxr_session *sess,
|
||||
|
||||
struct oxr_action_set *other_act_set = NULL;
|
||||
struct oxr_action_set_attachment *other_act_set_attached = NULL;
|
||||
oxr_session_get_action_set_attachment(sess, set, &other_act_set_attached, &other_act_set);
|
||||
get_action_set_attachment(&sess->action_context, set, &other_act_set_attached, &other_act_set);
|
||||
|
||||
if (other_act_set_attached == NULL) {
|
||||
continue;
|
||||
@@ -1814,34 +1828,6 @@ oxr_action_bind_io(struct oxr_logger *log,
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Given an Action Set handle, return the @ref oxr_action_set and the
|
||||
* associated
|
||||
* @ref oxr_action_set_attachment in the given Session.
|
||||
*
|
||||
* @private @memberof oxr_session
|
||||
*/
|
||||
static void
|
||||
oxr_session_get_action_set_attachment(struct oxr_session *sess,
|
||||
XrActionSet actionSet,
|
||||
struct oxr_action_set_attachment **act_set_attached,
|
||||
struct oxr_action_set **act_set)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
*act_set = XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_action_set *, actionSet);
|
||||
*act_set_attached = NULL;
|
||||
|
||||
// In case no action_sets have been attached.
|
||||
if (sess->act_sets_attachments_by_key == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = u_hashmap_int_find(sess->act_sets_attachments_by_key, (*act_set)->act_set_key, &ptr);
|
||||
if (ret == 0) {
|
||||
*act_set_attached = (struct oxr_action_set_attachment *)ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
oxr_session_get_action_attachment(struct oxr_session *sess,
|
||||
uint32_t act_key,
|
||||
@@ -1849,7 +1835,7 @@ oxr_session_get_action_attachment(struct oxr_session *sess,
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
int ret = u_hashmap_int_find(sess->act_attachments_by_key, act_key, &ptr);
|
||||
int ret = u_hashmap_int_find(sess->action_context.act_attachments_by_key, act_key, &ptr);
|
||||
if (ret == 0) {
|
||||
*out_act_attached = (struct oxr_action_attachment *)ptr;
|
||||
}
|
||||
@@ -1875,22 +1861,23 @@ oxr_session_attach_action_sets(struct oxr_logger *log,
|
||||
struct oxr_instance *inst = sess->sys->inst;
|
||||
|
||||
const struct oxr_instance_action_context *inst_context = inst->action_context;
|
||||
struct oxr_session_action_context *sess_context = &sess->action_context;
|
||||
|
||||
oxr_interaction_profile_array_clone(&inst_context->suggested_profiles, &sess->profiles_on_attachment);
|
||||
oxr_interaction_profile_array_clone(&inst_context->suggested_profiles, &sess_context->profiles_on_attachment);
|
||||
|
||||
// Allocate room for list. No need to check if anything has been
|
||||
// attached the API function does that.
|
||||
sess->action_set_attachment_count = bindInfo->countActionSets;
|
||||
sess->act_set_attachments =
|
||||
U_TYPED_ARRAY_CALLOC(struct oxr_action_set_attachment, sess->action_set_attachment_count);
|
||||
sess->action_context.action_set_attachment_count = bindInfo->countActionSets;
|
||||
sess->action_context.act_set_attachments =
|
||||
U_TYPED_ARRAY_CALLOC(struct oxr_action_set_attachment, sess->action_context.action_set_attachment_count);
|
||||
|
||||
// Set up the per-session data for these action sets.
|
||||
for (uint32_t i = 0; i < sess->action_set_attachment_count; i++) {
|
||||
for (uint32_t i = 0; i < sess->action_context.action_set_attachment_count; i++) {
|
||||
struct oxr_action_set *act_set =
|
||||
XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_action_set *, bindInfo->actionSets[i]);
|
||||
struct oxr_action_set_ref *act_set_ref = act_set->data;
|
||||
act_set_ref->ever_attached = true;
|
||||
struct oxr_action_set_attachment *act_set_attached = &sess->act_set_attachments[i];
|
||||
struct oxr_action_set_attachment *act_set_attached = &sess->action_context.act_set_attachments[i];
|
||||
oxr_action_set_attachment_init(log, sess, act_set, act_set_attached);
|
||||
|
||||
// Allocate the action attachments for this set.
|
||||
@@ -1924,13 +1911,14 @@ oxr_session_attach_action_sets(struct oxr_logger *log,
|
||||
static XrResult
|
||||
session_update_action_bindings(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
struct oxr_session *sess,
|
||||
const struct oxr_roles *roles)
|
||||
struct oxr_session_action_context *action_context,
|
||||
const struct oxr_roles *roles,
|
||||
bool *out_interaction_profile_changed)
|
||||
{
|
||||
// Convenience.
|
||||
const struct oxr_path_store *store = &inst->path_store;
|
||||
const struct oxr_instance_path_cache *cache = &inst->path_cache;
|
||||
const struct oxr_interaction_profile_array *array = &sess->profiles_on_attachment;
|
||||
const struct oxr_interaction_profile_array *array = &action_context->profiles_on_attachment;
|
||||
|
||||
struct oxr_profiles_per_subaction profiles = {0};
|
||||
find_profiles_from_roles(cache, array, roles, &profiles);
|
||||
@@ -1940,14 +1928,16 @@ session_update_action_bindings(struct oxr_logger *log,
|
||||
print_profiles(log, store, &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];
|
||||
for (size_t i = 0; i < action_context->action_set_attachment_count; i++) {
|
||||
struct oxr_action_set_attachment *act_set_attached = &action_context->act_set_attachments[i];
|
||||
for (size_t k = 0; k < act_set_attached->action_attachment_count; k++) {
|
||||
struct oxr_action_attachment *act_attached = &act_set_attached->act_attachments[k];
|
||||
oxr_action_attachment_bind(log, inst, act_attached, roles, &profiles);
|
||||
}
|
||||
}
|
||||
|
||||
bool interaction_profile_changed = false;
|
||||
|
||||
/*
|
||||
* This code will only send events (and update the bindings) if there
|
||||
* is a profile mapped to the subaction path. Meaning it won't update
|
||||
@@ -1960,15 +1950,17 @@ session_update_action_bindings(struct oxr_logger *log,
|
||||
if (path == XR_NULL_PATH) { \
|
||||
break; /* Only update on "active" interaction profiles per sub-action path. */ \
|
||||
} \
|
||||
if (sess->X != path) { \
|
||||
sess->X = path; \
|
||||
oxr_event_push_XrEventDataInteractionProfileChanged(log, sess); \
|
||||
if (action_context->X != path) { \
|
||||
action_context->X = path; \
|
||||
interaction_profile_changed = true; \
|
||||
} \
|
||||
} while (false);
|
||||
OXR_FOR_EACH_VALID_SUBACTION_PATH(POPULATE_PROFILE)
|
||||
#undef POPULATE_PROFILE
|
||||
|
||||
return oxr_session_success_result(sess);
|
||||
*out_interaction_profile_changed = interaction_profile_changed;
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
XrResult
|
||||
@@ -1978,6 +1970,9 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||
const XrActiveActionSet *actionSets,
|
||||
const XrActiveActionSetPrioritiesEXT *activePriorities)
|
||||
{
|
||||
struct oxr_session_action_context *sess_context = &sess->action_context;
|
||||
struct oxr_instance *inst = sess->sys->inst;
|
||||
|
||||
struct oxr_action_set *act_set = NULL;
|
||||
struct oxr_action_set_attachment *act_set_attached = NULL;
|
||||
|
||||
@@ -1988,7 +1983,7 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||
|
||||
// Check that all action sets has been attached.
|
||||
for (uint32_t i = 0; i < countActionSets; i++) {
|
||||
oxr_session_get_action_set_attachment(sess, actionSets[i].actionSet, &act_set_attached, &act_set);
|
||||
get_action_set_attachment(sess_context, actionSets[i].actionSet, &act_set_attached, &act_set);
|
||||
if (act_set_attached == NULL) {
|
||||
return oxr_error(log, XR_ERROR_ACTIONSET_NOT_ATTACHED,
|
||||
"(actionSets[%i].actionSet) action set '%s' has "
|
||||
@@ -2019,12 +2014,23 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||
|
||||
// Should we redo the bindings?
|
||||
{
|
||||
os_mutex_lock(&sess->sync_actions_mutex);
|
||||
if (sess->dynamic_roles_generation_id < roles.roles.generation_id) {
|
||||
sess->dynamic_roles_generation_id = roles.roles.generation_id;
|
||||
session_update_action_bindings(log, sess->sys->inst, sess, &roles);
|
||||
bool interaction_profile_changed = false;
|
||||
|
||||
os_mutex_lock(&sess_context->sync_actions_mutex);
|
||||
if (sess_context->dynamic_roles_generation_id < roles.roles.generation_id) {
|
||||
sess_context->dynamic_roles_generation_id = roles.roles.generation_id;
|
||||
session_update_action_bindings( //
|
||||
log, //
|
||||
inst, //
|
||||
sess_context, //
|
||||
&roles, //
|
||||
&interaction_profile_changed); //
|
||||
}
|
||||
os_mutex_unlock(&sess_context->sync_actions_mutex);
|
||||
|
||||
if (interaction_profile_changed) {
|
||||
oxr_event_push_XrEventDataInteractionProfileChanged(log, sess);
|
||||
}
|
||||
os_mutex_unlock(&sess->sync_actions_mutex);
|
||||
}
|
||||
|
||||
if (countActionSets == 0) {
|
||||
@@ -2044,8 +2050,8 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||
}
|
||||
|
||||
// Reset all action set attachments.
|
||||
for (size_t i = 0; i < sess->action_set_attachment_count; ++i) {
|
||||
act_set_attached = &sess->act_set_attachments[i];
|
||||
for (size_t i = 0; i < sess_context->action_set_attachment_count; ++i) {
|
||||
act_set_attached = &sess_context->act_set_attachments[i];
|
||||
U_ZERO(&act_set_attached->requested_subaction_paths);
|
||||
}
|
||||
|
||||
@@ -2054,7 +2060,7 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||
//! @todo can be listed more than once with different paths!
|
||||
for (uint32_t i = 0; i < countActionSets; i++) {
|
||||
struct oxr_subaction_paths subaction_paths;
|
||||
oxr_session_get_action_set_attachment(sess, actionSets[i].actionSet, &act_set_attached, &act_set);
|
||||
get_action_set_attachment(sess_context, actionSets[i].actionSet, &act_set_attached, &act_set);
|
||||
assert(act_set_attached != NULL);
|
||||
|
||||
if (!oxr_classify_subaction_paths(log, sess->sys->inst, 1, &actionSets[i].subactionPath,
|
||||
@@ -2090,11 +2096,10 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||
}
|
||||
|
||||
// Now, update all action attachments
|
||||
for (size_t i = 0; i < sess->action_set_attachment_count; ++i) {
|
||||
act_set_attached = &sess->act_set_attachments[i];
|
||||
for (size_t i = 0; i < sess_context->action_set_attachment_count; ++i) {
|
||||
act_set_attached = &sess_context->act_set_attachments[i];
|
||||
struct oxr_subaction_paths subaction_paths = act_set_attached->requested_subaction_paths;
|
||||
|
||||
|
||||
for (uint32_t k = 0; k < act_set_attached->action_attachment_count; k++) {
|
||||
struct oxr_action_attachment *act_attached = &act_set_attached->act_attachments[k];
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright 2018-2024, Collabora, Ltd.
|
||||
// Copyright 2023-2026, NVIDIA CORPORATION.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Holds per session action context.
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup oxr_main
|
||||
*/
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_hashmap.h"
|
||||
|
||||
#include "oxr_session_action_context.h"
|
||||
#include "../oxr_logger.h"
|
||||
#include "../oxr_objects.h"
|
||||
#include "oxr_input.h"
|
||||
|
||||
|
||||
XrResult
|
||||
oxr_session_action_context_init(struct oxr_session_action_context *action_context)
|
||||
{
|
||||
// Initialize dynamic roles generation_id and mutex
|
||||
action_context->dynamic_roles_generation_id = 0;
|
||||
os_mutex_init(&action_context->sync_actions_mutex);
|
||||
|
||||
// Action system hashmaps.
|
||||
int h_ret = u_hashmap_int_create(&action_context->act_sets_attachments_by_key);
|
||||
if (h_ret != 0) {
|
||||
return XR_ERROR_RUNTIME_FAILURE;
|
||||
}
|
||||
|
||||
// @todo Remove or check results.
|
||||
u_hashmap_int_create(&action_context->act_attachments_by_key);
|
||||
|
||||
// Initialize action set attachments
|
||||
action_context->act_set_attachments = NULL;
|
||||
action_context->action_set_attachment_count = 0;
|
||||
|
||||
// Initialize subaction paths
|
||||
#define INIT_PATH(X) action_context->X = XR_NULL_PATH;
|
||||
OXR_FOR_EACH_VALID_SUBACTION_PATH(INIT_PATH)
|
||||
#undef INIT_PATH
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
oxr_session_action_context_fini(struct oxr_session_action_context *action_context)
|
||||
{
|
||||
oxr_interaction_profile_array_clear(&action_context->profiles_on_attachment);
|
||||
|
||||
// Teardown action set attachments
|
||||
for (size_t i = 0; i < action_context->action_set_attachment_count; ++i) {
|
||||
oxr_action_set_attachment_teardown(&action_context->act_set_attachments[i]);
|
||||
}
|
||||
free(action_context->act_set_attachments);
|
||||
action_context->act_set_attachments = NULL;
|
||||
action_context->action_set_attachment_count = 0;
|
||||
|
||||
// If we tore everything down correctly, these are empty now.
|
||||
assert(action_context->act_sets_attachments_by_key == NULL ||
|
||||
u_hashmap_int_empty(action_context->act_sets_attachments_by_key));
|
||||
assert(action_context->act_attachments_by_key == NULL ||
|
||||
u_hashmap_int_empty(action_context->act_attachments_by_key));
|
||||
|
||||
u_hashmap_int_destroy(&action_context->act_sets_attachments_by_key);
|
||||
u_hashmap_int_destroy(&action_context->act_attachments_by_key);
|
||||
|
||||
// Destroy mutex
|
||||
os_mutex_destroy(&action_context->sync_actions_mutex);
|
||||
}
|
||||
|
||||
bool
|
||||
oxr_session_action_context_has_attached_act_sets(const struct oxr_session_action_context *action_context)
|
||||
{
|
||||
return action_context->act_set_attachments != NULL;
|
||||
}
|
||||
|
||||
XRT_NONNULL_ALL bool
|
||||
oxr_session_action_context_find_set(struct oxr_session_action_context *action_context,
|
||||
uint32_t act_set_key,
|
||||
struct oxr_action_set_attachment **out_act_set_attached)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
// In case no action_sets have been attached.
|
||||
if (!oxr_session_action_context_has_attached_act_sets(action_context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret = u_hashmap_int_find(action_context->act_sets_attachments_by_key, act_set_key, &ptr);
|
||||
if (ret == 0) {
|
||||
*out_act_set_attached = (struct oxr_action_set_attachment *)ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright 2018-2024, Collabora, Ltd.
|
||||
// Copyright 2023-2026, NVIDIA CORPORATION.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Holds per session action context.
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup oxr_main
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "os/os_threading.h"
|
||||
|
||||
#include "oxr_forward_declarations.h"
|
||||
#include "oxr_extension_support.h"
|
||||
#include "oxr_subaction.h"
|
||||
#include "oxr_interaction_profile_array.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Helper macros
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Helper macro to check if action sets are attached to a session.
|
||||
*
|
||||
* Returns XR_ERROR_ACTIONSET_NOT_ATTACHED if action sets have not been attached.
|
||||
*
|
||||
* @param SESS Session pointer
|
||||
* @param LOG Logger pointer
|
||||
* @ingroup oxr_main
|
||||
*/
|
||||
#define OXR_SESSION_CHECK_ATTACHED_AND_RET(SESS, LOG) \
|
||||
do { \
|
||||
if (!oxr_session_action_context_has_attached_act_sets(&(SESS)->action_context)) { \
|
||||
return oxr_error(LOG, XR_ERROR_ACTIONSET_NOT_ATTACHED, \
|
||||
"ActionSet(s) have not been attached to this session"); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Structs
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* This holds all of the action state that belongs on the session level.
|
||||
*
|
||||
* Future extensions might enable multiple action contexts per session.
|
||||
*/
|
||||
struct oxr_session_action_context
|
||||
{
|
||||
/*
|
||||
* Action Set fields
|
||||
*/
|
||||
|
||||
/*!
|
||||
* A map of action set key to action set attachments.
|
||||
*
|
||||
* If non-null, this means action sets have been attached to this
|
||||
* session, since this map points to elements of
|
||||
* oxr_session_action_context::act_set_attachments
|
||||
*/
|
||||
struct u_hashmap_int *act_sets_attachments_by_key;
|
||||
|
||||
/*!
|
||||
* An array of action set attachments that this session owns.
|
||||
*
|
||||
* If non-null, this means action sets have been attached to this
|
||||
* session.
|
||||
*/
|
||||
struct oxr_action_set_attachment *act_set_attachments;
|
||||
|
||||
/*!
|
||||
* Length of @ref oxr_session_action_context::act_set_attachments.
|
||||
*/
|
||||
size_t action_set_attachment_count;
|
||||
|
||||
|
||||
/*
|
||||
* Action fields
|
||||
*/
|
||||
|
||||
/*!
|
||||
* A map of action key to action attachment.
|
||||
*
|
||||
* The action attachments are actually owned by the action set
|
||||
* attachments, but we own the action set attachments, so this is OK.
|
||||
*
|
||||
* If non-null, this means an action context (default or otherwise)
|
||||
* action sets have been attached to the owning session, since this map
|
||||
* points to @p oxr_action_attachment members of
|
||||
* @ref oxr_session_action_context::act_set_attachments elements.
|
||||
*/
|
||||
struct u_hashmap_int *act_attachments_by_key;
|
||||
|
||||
|
||||
/*
|
||||
* Interaction Profiles fields
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Clone of all suggested binding profiles at the point of action set/session attachment.
|
||||
* @ref oxr_session_attach_action_sets
|
||||
*/
|
||||
struct oxr_interaction_profile_array profiles_on_attachment;
|
||||
|
||||
//! Cache of the last known system roles generation_id
|
||||
uint64_t dynamic_roles_generation_id;
|
||||
|
||||
//! Protects access to dynamic_roles_generation_id during sync actions
|
||||
struct os_mutex sync_actions_mutex;
|
||||
|
||||
/*!
|
||||
* Currently bound interaction profile.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define OXR_PATH_MEMBER(X) XrPath X;
|
||||
|
||||
OXR_FOR_EACH_VALID_SUBACTION_PATH(OXR_PATH_MEMBER)
|
||||
#undef OXR_PATH_MEMBER
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Initialize the action context for a session.
|
||||
*
|
||||
* @public @memberof oxr_session_action_context
|
||||
*/
|
||||
XRT_NONNULL_ALL XRT_CHECK_RESULT XrResult
|
||||
oxr_session_action_context_init(struct oxr_session_action_context *action_context);
|
||||
|
||||
/*!
|
||||
* Finalize and cleanup the action context for a session.
|
||||
*
|
||||
* @public @memberof oxr_session_action_context
|
||||
*/
|
||||
XRT_NONNULL_ALL void
|
||||
oxr_session_action_context_fini(struct oxr_session_action_context *action_context);
|
||||
|
||||
/*!
|
||||
* Check if action sets have been attached to the action context.
|
||||
*
|
||||
* @return true if action sets are attached, false otherwise
|
||||
* @public @memberof oxr_session_action_context
|
||||
*/
|
||||
XRT_NONNULL_ALL bool
|
||||
oxr_session_action_context_has_attached_act_sets(const struct oxr_session_action_context *action_context);
|
||||
|
||||
/*!
|
||||
* Helper to find action set attachment.
|
||||
*
|
||||
* @return true if the action set was found, false otherwise
|
||||
* @public @memberof oxr_session_action_context
|
||||
*/
|
||||
XRT_NONNULL_ALL bool
|
||||
oxr_session_action_context_find_set(struct oxr_session_action_context *action_context,
|
||||
uint32_t act_set_key,
|
||||
struct oxr_action_set_attachment **out_act_set_attached);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -55,6 +55,7 @@ struct oxr_action_attachment;
|
||||
struct oxr_action_set_attachment;
|
||||
struct oxr_action_input;
|
||||
struct oxr_action_output;
|
||||
struct oxr_session_action_context;
|
||||
struct oxr_dpad_state;
|
||||
struct oxr_binding;
|
||||
struct oxr_interaction_profile;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "actions/oxr_subaction.h"
|
||||
#include "actions/oxr_dpad_state.h"
|
||||
#include "actions/oxr_session_action_context.h"
|
||||
#include "actions/oxr_interaction_profile_array.h"
|
||||
#include "actions/oxr_instance_path_cache.h"
|
||||
#include "actions/oxr_instance_action_context.h"
|
||||
@@ -1410,63 +1411,9 @@ struct oxr_session
|
||||
struct os_precise_sleeper sleeper;
|
||||
|
||||
/*!
|
||||
* An array of action set attachments that this session owns.
|
||||
*
|
||||
* If non-null, this means action sets have been attached to this
|
||||
* session.
|
||||
*/
|
||||
struct oxr_action_set_attachment *act_set_attachments;
|
||||
|
||||
/*!
|
||||
* Length of @ref oxr_session::act_set_attachments.
|
||||
*/
|
||||
size_t action_set_attachment_count;
|
||||
|
||||
/*!
|
||||
* A map of action set key to action set attachments.
|
||||
*
|
||||
* If non-null, this means action sets have been attached to this
|
||||
* session, since this map points to elements of
|
||||
* oxr_session::act_set_attachments
|
||||
*/
|
||||
struct u_hashmap_int *act_sets_attachments_by_key;
|
||||
|
||||
/*!
|
||||
* A map of action key to action attachment.
|
||||
*
|
||||
* The action attachments are actually owned by the action set
|
||||
* attachments, but we own the action set attachments, so this is OK.
|
||||
*
|
||||
* If non-null, this means action sets have been attached to this
|
||||
* session, since this map points to @p oxr_action_attachment members of
|
||||
* @ref oxr_session::act_set_attachments elements.
|
||||
*/
|
||||
struct u_hashmap_int *act_attachments_by_key;
|
||||
|
||||
/*!
|
||||
* Clone of all suggested binding profiles at the point of action set/session attachment.
|
||||
* @ref oxr_session_attach_action_sets
|
||||
*/
|
||||
struct oxr_interaction_profile_array profiles_on_attachment;
|
||||
|
||||
//! Cache of the last known system roles generation_id
|
||||
uint64_t dynamic_roles_generation_id;
|
||||
|
||||
//! Protects access to dynamic_roles_generation_id during sync actions
|
||||
struct os_mutex sync_actions_mutex;
|
||||
|
||||
/*!
|
||||
* Currently bound interaction profile.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define OXR_PATH_MEMBER(X) XrPath X;
|
||||
|
||||
OXR_FOR_EACH_VALID_SUBACTION_PATH(OXR_PATH_MEMBER)
|
||||
#undef OXR_PATH_MEMBER
|
||||
/*!
|
||||
* @}
|
||||
* Holds all the action state that belongs on the session level.
|
||||
*/
|
||||
struct oxr_session_action_context action_context;
|
||||
|
||||
/*!
|
||||
* IPD, to be expanded to a proper 3D relation.
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "oxr_xret.h"
|
||||
#include "oxr_roles.h"
|
||||
#include "actions/oxr_input.h"
|
||||
#include "actions/oxr_session_action_context.h"
|
||||
#include "actions/oxr_binding.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -1062,21 +1063,7 @@ oxr_session_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
||||
|
||||
XrResult ret = oxr_event_remove_session_events(log, sess);
|
||||
|
||||
oxr_interaction_profile_array_clear(&sess->profiles_on_attachment);
|
||||
|
||||
for (size_t i = 0; i < sess->action_set_attachment_count; ++i) {
|
||||
oxr_action_set_attachment_teardown(&sess->act_set_attachments[i]);
|
||||
}
|
||||
free(sess->act_set_attachments);
|
||||
sess->act_set_attachments = NULL;
|
||||
sess->action_set_attachment_count = 0;
|
||||
|
||||
// If we tore everything down correctly, these are empty now.
|
||||
assert(sess->act_sets_attachments_by_key == NULL || u_hashmap_int_empty(sess->act_sets_attachments_by_key));
|
||||
assert(sess->act_attachments_by_key == NULL || u_hashmap_int_empty(sess->act_attachments_by_key));
|
||||
|
||||
u_hashmap_int_destroy(&sess->act_sets_attachments_by_key);
|
||||
u_hashmap_int_destroy(&sess->act_attachments_by_key);
|
||||
oxr_session_action_context_fini(&sess->action_context);
|
||||
|
||||
xrt_comp_destroy(&sess->compositor);
|
||||
xrt_comp_native_destroy(&sess->xcn);
|
||||
@@ -1085,7 +1072,6 @@ oxr_session_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
||||
os_precise_sleeper_deinit(&sess->sleeper);
|
||||
oxr_frame_sync_fini(&sess->frame_sync);
|
||||
os_mutex_destroy(&sess->active_wait_frames_lock);
|
||||
os_mutex_destroy(&sess->sync_actions_mutex);
|
||||
|
||||
free(sess);
|
||||
|
||||
@@ -1099,8 +1085,15 @@ oxr_session_allocate_and_init(struct oxr_logger *log,
|
||||
struct oxr_session **out_session)
|
||||
{
|
||||
struct oxr_session *sess = NULL;
|
||||
XrResult ret;
|
||||
OXR_ALLOCATE_HANDLE_OR_RETURN(log, sess, OXR_XR_DEBUG_SESSION, oxr_session_destroy, &sys->inst->handle);
|
||||
|
||||
// Needs to happen early due to mutex.
|
||||
ret = oxr_session_action_context_init(&sess->action_context);
|
||||
if (ret != XR_SUCCESS) {
|
||||
return oxr_error(log, ret, "Failed to initialize action context");
|
||||
}
|
||||
|
||||
// What graphics API type was this created with.
|
||||
sess->gfx_ext = gfx_ext;
|
||||
|
||||
@@ -1116,19 +1109,11 @@ oxr_session_allocate_and_init(struct oxr_logger *log,
|
||||
sess->active_wait_frames = 0;
|
||||
os_mutex_init(&sess->active_wait_frames_lock);
|
||||
|
||||
// Initialize dynamic roles generation_id and mutex
|
||||
sess->dynamic_roles_generation_id = 0;
|
||||
os_mutex_init(&sess->sync_actions_mutex);
|
||||
|
||||
// Debug and user options.
|
||||
sess->ipd_meters = debug_get_num_option_ipd() / 1000.0f;
|
||||
sess->frame_timing_spew = debug_get_bool_option_frame_timing_spew();
|
||||
sess->frame_timing_wait_sleep_ms = debug_get_num_option_wait_frame_sleep();
|
||||
|
||||
// Action system hashmaps.
|
||||
u_hashmap_int_create(&sess->act_sets_attachments_by_key);
|
||||
u_hashmap_int_create(&sess->act_attachments_by_key);
|
||||
|
||||
// This is set to something valid in begin session, used in xrEndFrame.
|
||||
sess->current_view_config_type = XR_VIEW_CONFIGURATION_TYPE_MAX_ENUM;
|
||||
|
||||
|
||||
Reference in new issue
Block a user