st/oxr,a/bindings: Move more verification logic to generated bindings

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2194>
This commit is contained in:
Christoph Haag 2024-03-01 14:31:29 +01:00 committed by Marge Bot
parent a35d7bd255
commit 7cf457d894
5 changed files with 182 additions and 294 deletions

View file

@ -285,6 +285,17 @@ class Profile:
self.extended_by = json_profile.get("extended_by")
if self.extended_by is None:
self.extended_by = []
ov = json_profile.get("openxr_version")
if ov is None:
self.openxr_version_promoted = { "major" : "0", "minor" : "0" }
else:
promoted = ov.get("promoted")
if promoted is None:
self.openxr_version_promoted = { "major" : "0", "minor" : "0" }
else:
self.openxr_version_promoted = { "major" : promoted.get("major"), "minor" : promoted.get("minor") }
self.is_virtual = profile_name.startswith("/virtual_profiles/")
self.identifiers = Identifier.parse_identifiers(json_profile)
@ -416,21 +427,6 @@ class Bindings:
return True
return False
def make_oxr_verify_extension_status_struct_str(self):
struct_str: str = f"struct {oxr_verify_extension_status_struct_name}{{\n"
ext_set = set()
for profile in itertools.chain(self.virtual_profiles, self.profiles):
ext_name = profile.extension_name
if ext_name is None or len(ext_name) == 0:
continue
if ext_name in ext_set:
continue
ext_set.add(ext_name)
struct_str += f"\tbool {ext_name};\n"
struct_str += "};\n"
return struct_str
header = '''// Copyright 2020-2022, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
@ -445,7 +441,7 @@ header = '''// Copyright 2020-2022, Collabora, Ltd.
func_start = '''
bool
{name}(const struct {ext_status_struct_name}* exts, const char *str, size_t length)
{name}(const struct oxr_extension_status *exts, const char *str, size_t length)
{{
'''
@ -464,13 +460,16 @@ if_strcmp = '''{exttab}if (strcmp(str, "{check}") == 0) {{
{exttab}\t\t}} else '''
def write_verify_func_switch(f, dict_of_lists, profile_name, ext_name):
def write_verify_func_switch(f, dict_of_lists, profile, profile_name, ext_name):
"""Generate function to check if a string is in a set of strings.
Input is a file to write the code into, a dict where keys are length and
the values are lists of strings of that length. And a suffix if any."""
if len(dict_of_lists) == 0:
return
if profile.extension_name is not None:
f.write(f'#ifdef OXR_HAVE_{profile.extension_name}\n')
f.write(f"\t// generated from: {profile_name}\n")
is_ext = ext_name is not None and len(ext_name) > 0
ext_tab = ""
@ -489,12 +488,14 @@ def write_verify_func_switch(f, dict_of_lists, profile_name, ext_name):
if is_ext:
f.write("\t}\n")
if profile.extension_name is not None:
f.write(f'#endif // OXR_HAVE_{profile.extension_name}\n')
def write_verify_func_body(f, profile, dict_name):
if profile is None or dict_name is None or len(dict_name) == 0:
return
write_verify_func_switch(f, getattr(
profile, dict_name), profile.name, profile.extension_name)
profile, dict_name), profile, profile.name, profile.extension_name)
if profile.parent_profiles is None:
return
for pp in profile.parent_profiles:
@ -513,24 +514,49 @@ def generate_verify_functions(f, profile):
write_verify_func(f, profile, "dpad_paths_by_length", "_dpad_path")
write_verify_func(f, profile, "dpad_emulators_by_length", "_dpad_emulator")
f.write(f'''
void
oxr_verify_{profile.validation_func_name}_ext(const struct oxr_extension_status *extensions, bool *out_supported, bool *out_enabled)
{{''')
if profile.extension_name is not None:
f.write(f'''
#ifdef OXR_HAVE_{profile.extension_name}
\t*out_supported = true;
\t*out_enabled = extensions->{profile.extension_name};
#else
\t*out_supported = false;
\t*out_enabled = false;
#endif // OXR_HAVE_{profile.extension_name}
''')
def generate_bindings_c(file, p):
else:
f.write(f'''
\t*out_supported = true;
\t*out_enabled = true;
''')
f.write(f'''}}
''')
def generate_bindings_c(file, b):
"""Generate the file to verify subpaths on a interaction profile."""
f = open(file, "w")
f.write(header.format(brief='Generated bindings data', group='oxr_main'))
f.write('''
#include "b_generated_bindings.h"
#include <string.h>
#include <oxr_objects.h>
// clang-format off
''')
for profile in p.profiles:
for profile in b.profiles:
generate_verify_functions(f, profile)
f.write(
f'\n\nstruct profile_template profile_templates[{len(p.profiles)}] = {{ // array of profile_template\n')
for profile in p.profiles:
f'\n\nstruct profile_template profile_templates[{len(b.profiles)}] = {{ // array of profile_template\n')
for profile in b.profiles:
hw_name = str(profile.name.split("/")[-1])
vendor_name = str(profile.name.split("/")[-2])
fname = vendor_name + "_" + hw_name + "_profile.json"
@ -594,7 +620,6 @@ def generate_bindings_c(file, p):
f.write(f'\t\t\t\t.output = {monado_binding},\n')
else:
f.write(f'\t\t\t\t.output = 0,\n')
f.write(f'\t\t\t}}, // /binding_template {idx}\n')
f.write('\t\t}, // /array of binding_template\n')
@ -630,13 +655,24 @@ def generate_bindings_c(file, p):
f.write('\t\t\t},\n')
f.write('\t\t}, // /array of dpad_emulation\n')
f.write(f'\t\t.openxr_version.promoted.major = {profile.openxr_version_promoted["major"]},\n')
f.write(f'\t\t.openxr_version.promoted.minor = {profile.openxr_version_promoted["minor"]},\n')
fn_prefixes = ["subpath", "dpad_path", "dpad_emulator"]
for prefix in fn_prefixes:
f.write(f'\t\t.{prefix}_fn = oxr_verify_{profile.validation_func_name}_{prefix},\n')
f.write(f'\t\t.ext_verify_fn = oxr_verify_{profile.validation_func_name}_ext,\n')
if profile.extension_name is None:
f.write(f'\t\t.extension_name = NULL,\n')
else:
f.write(f'\t\t.extension_name = "{profile.extension_name}",\n')
f.write('\t}, // /profile_template\n')
f.write('}; // /array of profile_template\n\n')
inputs = set()
outputs = set()
for profile in p.profiles:
for profile in b.profiles:
component: Component
for idx, component in enumerate(profile.components):
@ -693,34 +729,71 @@ def generate_bindings_c(file, p):
f.write(f'\treturn XRT_OUTPUT_NAME_SIMPLE_VIBRATION;\n')
f.write('}\n')
f.write(f'''
// Array of pointers to XrPath variables contained in each profile template
static XrPath *path_cache[{len(b.profiles)}] =
{{
''')
for profile_index, _ in enumerate(b.profiles):
f.write(f'\t&profile_templates[{profile_index}].path_cache,\n')
profile_index += 1
f.write(f'''}};
// Array of pointers to the location of the path cache name in each profile template.
// The name string itself is not a compile time constant.
static const char **path_cache_names[{len(b.profiles)}] =
{{
''')
for profile_index, _ in enumerate(b.profiles):
f.write(f'\t&profile_templates[{profile_index}].path,\n')
profile_index += 1
f.write(f'''}};
static uint64_t path_cache_count = {len(b.profiles)};
void oxr_get_interaction_profile_path_cache(XrPath **out_path_cache[{len(b.profiles)}], const char ***out_path_cache_names[''' + str(len(b.profiles)) + '''], uint64_t *out_path_cache_count)
{
*out_path_cache = path_cache;
*out_path_cache_names = path_cache_names;
*out_path_cache_count = path_cache_count;
}
''')
f.write("\n// clang-format on\n")
f.close()
def generate_bindings_h(file, p):
def generate_bindings_h(file, b):
"""Generate header for the verify subpaths functions."""
f = open(file, "w")
f.write(header.format(brief='Generated bindings data header',
group='oxr_api'))
f.write('''
f.write(f'''
#pragma once
#include <stddef.h>
#include "xrt/xrt_defines.h"
typedef uint64_t XrPath; // OpenXR typedef
struct oxr_extension_status;
/**
* @p out_path_cache Pointer to Array of XrPath pointers.
* @p out_path_cache_names Pointer to Array of string (char*) locations.
* @p out_path_cache_count Number of entries in the out_path_cache[_names] arrays.
*/
void oxr_get_interaction_profile_path_cache(XrPath **out_path_cache[{len(b.profiles)}], const char ***out_path_cache_names[''' + str(len(b.profiles)) + '''], uint64_t *out_path_cache_count);
// clang-format off
''')
oxr_verify_struct_str = p.make_oxr_verify_extension_status_struct_str()
f.write(oxr_verify_struct_str)
fn_prefixes = ["_subpath", "_dpad_path", "_dpad_emulator"]
for profile in p.profiles:
for profile in b.profiles:
for fn_suffix in fn_prefixes:
f.write(
f"\nbool\noxr_verify_{profile.validation_func_name}{fn_suffix}(const struct {oxr_verify_extension_status_struct_name}* extensions, const char *str, size_t length);\n")
f"\nbool\noxr_verify_{profile.validation_func_name}{fn_suffix}(const struct oxr_extension_status *extensions, const char *str, size_t length);\n")
f.write(f'''\nvoid\noxr_verify_{profile.validation_func_name}_ext(const struct oxr_extension_status *extensions, bool *out_supported, bool *out_enabled);\n''')
f.write(f'''
#define PATHS_PER_BINDING_TEMPLATE 16
@ -753,6 +826,9 @@ struct binding_template
\tenum xrt_output_name output;
}};
typedef bool (*path_verify_fn_t)(const struct oxr_extension_status *extensions, const char *, size_t);
typedef void (*ext_verify_fn_t)(const struct oxr_extension_status *extensions, bool *out_supported, bool *out_enabled);
struct profile_template
{{
\tenum xrt_device_name name;
@ -764,9 +840,23 @@ struct profile_template
\tsize_t binding_count;
\tstruct dpad_emulation *dpads;
\tsize_t dpad_count;
\tstruct {{
\t\tstruct {{
\t\t\tuint32_t major;
\t\t\tuint32_t minor;
\t\t}} promoted;
\t}} openxr_version;
\t// Only valid after path cache entries are initialized via oxr_get_interaction_profile_path_cache.
\tXrPath path_cache;
\tpath_verify_fn_t subpath_fn;
\tpath_verify_fn_t dpad_path_fn;
\tpath_verify_fn_t dpad_emulator_fn;
\text_verify_fn_t ext_verify_fn;
\tconst char *extension_name;
}};
#define NUM_PROFILE_TEMPLATES {len(p.profiles)}
#define NUM_PROFILE_TEMPLATES {len(b.profiles)}
extern struct profile_template profile_templates[NUM_PROFILE_TEMPLATES];
''')

View file

@ -27,9 +27,6 @@
#include "bindings/b_generated_bindings.h"
typedef bool (*path_verify_fn_t)(const struct oxr_verify_extension_status *, const char *, size_t);
/*
*
* Dpad functions.
@ -37,13 +34,12 @@ typedef bool (*path_verify_fn_t)(const struct oxr_verify_extension_status *, con
*/
#ifdef XR_EXT_dpad_binding
XrResult
static XrResult
process_dpad(struct oxr_logger *log,
struct oxr_instance *inst,
struct oxr_dpad_state *state,
const XrInteractionProfileDpadBindingEXT *dpad,
path_verify_fn_t dpad_emulator_fn,
const struct oxr_verify_extension_status *verify_ext_status,
const char *prefix,
const char *ip_str)
{
@ -57,7 +53,7 @@ process_dpad(struct oxr_logger *log,
dpad->binding);
}
if (!dpad_emulator_fn(verify_ext_status, str, length)) {
if (!dpad_emulator_fn(&inst->extensions, str, length)) {
return oxr_error(log, XR_ERROR_PATH_UNSUPPORTED,
"(%s->binding == \"%s\") is not a valid dpad binding path for profile \"%s\"", prefix,
str, ip_str);
@ -228,186 +224,46 @@ oxr_xrSuggestInteractionProfileBindings(XrInstance instance,
path_verify_fn_t subpath_fn = NULL;
path_verify_fn_t dpad_path_fn = NULL;
path_verify_fn_t dpad_emulator_fn = NULL;
ext_verify_fn_t ext_verify_fn = NULL;
bool has_dpad = inst->extensions.EXT_dpad_binding;
#define EXT_NOT_SUPPORTED(EXT) \
do { \
return oxr_error(&log, XR_ERROR_PATH_UNSUPPORTED, \
"(suggestedBindings->interactionProfile == \"%s\") used but XR_" #EXT \
" not supported by runtime", \
ip_str); \
} while (false)
struct profile_template *interaction_profile_template = NULL;
for (uint32_t i = 0; i < ARRAY_SIZE(profile_templates); i++) {
if (ip == profile_templates[i].path_cache) {
subpath_fn = profile_templates[i].subpath_fn;
dpad_path_fn = profile_templates[i].dpad_path_fn;
dpad_emulator_fn = profile_templates[i].dpad_emulator_fn;
ext_verify_fn = profile_templates[i].ext_verify_fn;
interaction_profile_template = &profile_templates[i];
break;
}
}
#define EXT_CHK_ENABLED(EXT) \
do { \
if (!inst->extensions.EXT) { \
return oxr_error(&log, XR_ERROR_PATH_UNSUPPORTED, \
"(suggestedBindings->interactionProfile == \"%s\") used but XR_" #EXT \
" not enabled", \
ip_str); \
} \
} while (false)
if (ip == inst->path_cache.khr_simple_controller) {
subpath_fn = oxr_verify_khr_simple_controller_subpath;
dpad_path_fn = oxr_verify_khr_simple_controller_dpad_path;
dpad_emulator_fn = oxr_verify_khr_simple_controller_dpad_emulator;
} else if (ip == inst->path_cache.google_daydream_controller) {
subpath_fn = oxr_verify_google_daydream_controller_subpath;
dpad_path_fn = oxr_verify_google_daydream_controller_dpad_path;
dpad_emulator_fn = oxr_verify_google_daydream_controller_dpad_emulator;
} else if (ip == inst->path_cache.htc_vive_controller) {
subpath_fn = oxr_verify_htc_vive_controller_subpath;
dpad_path_fn = oxr_verify_htc_vive_controller_dpad_path;
dpad_emulator_fn = oxr_verify_htc_vive_controller_dpad_emulator;
} else if (ip == inst->path_cache.htc_vive_pro) {
subpath_fn = oxr_verify_htc_vive_pro_subpath;
dpad_path_fn = oxr_verify_htc_vive_pro_dpad_path;
dpad_emulator_fn = oxr_verify_htc_vive_pro_dpad_emulator;
} else if (ip == inst->path_cache.microsoft_motion_controller) {
subpath_fn = oxr_verify_microsoft_motion_controller_subpath;
dpad_path_fn = oxr_verify_microsoft_motion_controller_dpad_path;
dpad_emulator_fn = oxr_verify_microsoft_motion_controller_dpad_emulator;
} else if (ip == inst->path_cache.microsoft_xbox_controller) {
subpath_fn = oxr_verify_microsoft_xbox_controller_subpath;
dpad_path_fn = oxr_verify_microsoft_xbox_controller_dpad_path;
dpad_emulator_fn = oxr_verify_microsoft_xbox_controller_dpad_emulator;
} else if (ip == inst->path_cache.oculus_go_controller) {
subpath_fn = oxr_verify_oculus_go_controller_subpath;
dpad_path_fn = oxr_verify_oculus_go_controller_dpad_path;
dpad_emulator_fn = oxr_verify_oculus_go_controller_dpad_emulator;
} else if (ip == inst->path_cache.oculus_touch_controller) {
subpath_fn = oxr_verify_oculus_touch_controller_subpath;
dpad_path_fn = oxr_verify_oculus_touch_controller_dpad_path;
dpad_emulator_fn = oxr_verify_oculus_touch_controller_dpad_emulator;
} else if (ip == inst->path_cache.valve_index_controller) {
subpath_fn = oxr_verify_valve_index_controller_subpath;
dpad_path_fn = oxr_verify_valve_index_controller_dpad_path;
dpad_emulator_fn = oxr_verify_valve_index_controller_dpad_emulator;
} else if (ip == inst->path_cache.hp_mixed_reality_controller) {
#ifdef OXR_HAVE_EXT_hp_mixed_reality_controller
EXT_CHK_ENABLED(EXT_hp_mixed_reality_controller);
#else
EXT_NOT_SUPPORTED(EXT_hp_mixed_reality_controller);
#endif
subpath_fn = oxr_verify_hp_mixed_reality_controller_subpath;
dpad_path_fn = oxr_verify_hp_mixed_reality_controller_dpad_path;
dpad_emulator_fn = oxr_verify_hp_mixed_reality_controller_dpad_emulator;
} else if (ip == inst->path_cache.samsung_odyssey_controller) {
#ifdef OXR_HAVE_EXT_samsung_odyssey_controller
EXT_CHK_ENABLED(EXT_samsung_odyssey_controller);
#else
EXT_NOT_SUPPORTED(EXT_samsung_odyssey_controller);
#endif
subpath_fn = oxr_verify_samsung_odyssey_controller_subpath;
dpad_path_fn = oxr_verify_samsung_odyssey_controller_dpad_path;
dpad_emulator_fn = oxr_verify_samsung_odyssey_controller_dpad_emulator;
} else if (ip == inst->path_cache.ml_ml2_controller) {
#ifdef OXR_HAVE_ML_ml2_controller_interaction
EXT_CHK_ENABLED(ML_ml2_controller_interaction);
#else
EXT_NOT_SUPPORTED(EL_ml2_controller_interaction);
#endif
subpath_fn = oxr_verify_ml_ml2_controller_subpath;
dpad_path_fn = oxr_verify_ml_ml2_controller_dpad_path;
dpad_emulator_fn = oxr_verify_ml_ml2_controller_dpad_emulator;
} else if (ip == inst->path_cache.mndx_ball_on_a_stick_controller) {
#ifdef OXR_HAVE_MNDX_ball_on_a_stick_controller
EXT_CHK_ENABLED(MNDX_ball_on_a_stick_controller);
#else
EXT_NOT_SUPPORTED(MNDX_ball_on_a_stick_controller);
#endif
subpath_fn = oxr_verify_mndx_ball_on_a_stick_controller_subpath;
dpad_path_fn = oxr_verify_mndx_ball_on_a_stick_controller_dpad_path;
dpad_emulator_fn = oxr_verify_mndx_ball_on_a_stick_controller_dpad_emulator;
} else if (ip == inst->path_cache.msft_hand_interaction) {
#ifdef OXR_HAVE_MSFT_hand_interaction
EXT_CHK_ENABLED(MSFT_hand_interaction);
#else
EXT_NOT_SUPPORTED(MSFT_hand_interaction);
#endif
subpath_fn = oxr_verify_microsoft_hand_interaction_subpath;
dpad_path_fn = oxr_verify_microsoft_hand_interaction_dpad_path;
dpad_emulator_fn = oxr_verify_microsoft_hand_interaction_dpad_emulator;
} else if (ip == inst->path_cache.ext_eye_gaze_interaction) {
#ifdef OXR_HAVE_EXT_eye_gaze_interaction
EXT_CHK_ENABLED(EXT_eye_gaze_interaction);
#else
EXT_NOT_SUPPORTED(EXT_eye_gaze_interaction);
#endif
subpath_fn = oxr_verify_ext_eye_gaze_interaction_subpath;
dpad_path_fn = oxr_verify_ext_eye_gaze_interaction_dpad_path;
dpad_emulator_fn = oxr_verify_ext_eye_gaze_interaction_dpad_emulator;
} else if (ip == inst->path_cache.ext_hand_interaction) {
#ifdef OXR_HAVE_EXT_hand_interaction
EXT_CHK_ENABLED(EXT_hand_interaction);
#else
EXT_NOT_SUPPORTED(EXT_hand_interaction);
#endif
subpath_fn = oxr_verify_ext_hand_interaction_ext_subpath;
dpad_path_fn = oxr_verify_ext_hand_interaction_ext_dpad_path;
dpad_emulator_fn = oxr_verify_ext_hand_interaction_ext_dpad_emulator;
} else if (ip == inst->path_cache.oppo_mr_controller) {
#ifdef OXR_HAVE_OPPO_controller_interaction
EXT_CHK_ENABLED(OPPO_controller_interaction);
#else
EXT_NOT_SUPPORTED(OPPO_controller_interaction);
#endif
subpath_fn = oxr_verify_oppo_mr_controller_oppo_subpath;
dpad_path_fn = oxr_verify_oppo_mr_controller_oppo_dpad_path;
dpad_emulator_fn = oxr_verify_oppo_mr_controller_oppo_dpad_emulator;
} else {
if (interaction_profile_template == NULL) {
return oxr_error(&log, XR_ERROR_PATH_UNSUPPORTED,
"(suggestedBindings->interactionProfile == \"%s\") is not "
"a supported interaction profile",
ip_str);
}
bool ext_supported;
bool ext_enabled;
ext_verify_fn(&inst->extensions, &ext_supported, &ext_enabled);
if (!ext_supported) {
return oxr_error(
&log, XR_ERROR_PATH_UNSUPPORTED,
"(suggestedBindings->interactionProfile == \"%s\") used but XR_%s not supported by runtime", ip_str,
interaction_profile_template->extension_name);
}
if (!ext_enabled) {
return oxr_error(&log, XR_ERROR_PATH_UNSUPPORTED,
"(suggestedBindings->interactionProfile == \"%s\") used but XR_%s not enabled", ip_str,
interaction_profile_template->extension_name);
}
// Needed in various paths here.
const char *str = NULL;
size_t length;
const struct oxr_verify_extension_status verify_ext_status = {
#ifdef OXR_HAVE_EXT_palm_pose
.EXT_palm_pose = inst->extensions.EXT_palm_pose,
#endif
#ifdef OXR_HAVE_EXT_hand_interaction
.EXT_hand_interaction = inst->extensions.EXT_hand_interaction,
#endif
#ifdef OXR_HAVE_EXT_hp_mixed_reality_controller
.EXT_hp_mixed_reality_controller = inst->extensions.EXT_hp_mixed_reality_controller,
#endif
#ifdef OXR_HAVE_EXT_samsung_odyssey_controller
.EXT_samsung_odyssey_controller = inst->extensions.EXT_samsung_odyssey_controller,
#endif
#ifdef OXR_HAVE_ML_ml2_controller_interaction
.ML_ml2_controller_interaction = inst->extensions.ML_ml2_controller_interaction,
#endif
#ifdef OXR_HAVE_MSFT_hand_interaction
.MSFT_hand_interaction = inst->extensions.MSFT_hand_interaction,
#endif
#ifdef OXR_HAVE_MNDX_ball_on_a_stick_controller
.MNDX_ball_on_a_stick_controller = inst->extensions.MNDX_ball_on_a_stick_controller,
#endif
#ifdef OXR_HAVE_MNDX_hydra
.MNDX_hydra = inst->extensions.MNDX_hydra,
#endif
#ifdef OXR_HAVE_MNDX_system_buttons
.MNDX_system_buttons = inst->extensions.MNDX_system_buttons,
#endif
#ifdef OXR_HAVE_EXT_eye_gaze_interaction
.EXT_eye_gaze_interaction = inst->extensions.EXT_eye_gaze_interaction,
#endif
#ifdef OXR_HAVE_HTCX_vive_tracker_interaction
.HTCX_vive_tracker_interaction = inst->extensions.HTCX_vive_tracker_interaction,
#endif
};
for (size_t i = 0; i < suggestedBindings->countSuggestedBindings; i++) {
const XrActionSuggestedBinding *s = &suggestedBindings->suggestedBindings[i];
@ -430,12 +286,12 @@ oxr_xrSuggestInteractionProfileBindings(XrInstance instance,
i, s->binding);
}
if (subpath_fn(&verify_ext_status, str, length)) {
if (subpath_fn(&inst->extensions, str, length)) {
continue;
}
#ifdef XR_EXT_dpad_binding
if (dpad_path_fn(&verify_ext_status, str, length)) {
if (dpad_path_fn(&inst->extensions, str, length)) {
if (!has_dpad) {
return oxr_error(
&log, XR_ERROR_PATH_UNSUPPORTED,
@ -482,8 +338,7 @@ oxr_xrSuggestInteractionProfileBindings(XrInstance instance,
"XrInteractionProfileDpadBindingEXT>",
i);
ret = process_dpad(&log, inst, &dpad_state, dpad, dpad_emulator_fn, &verify_ext_status, temp,
ip_str);
ret = process_dpad(&log, inst, &dpad_state, dpad, dpad_emulator_fn, temp, ip_str);
if (ret != XR_SUCCESS) {
// Teardown the state.
oxr_dpad_state_deinit(&dpad_state);

View file

@ -72,19 +72,22 @@ interaction_profile_find_in_instance(struct oxr_logger *log,
XrPath path,
struct oxr_interaction_profile **out_p)
{
return interaction_profile_find_in_array( //
log, //
inst->profile_count, //
inst->profiles, //
path, //
out_p); //
if (interaction_profile_find_in_array( //
log, //
inst->profile_count, //
inst->profiles, //
path, //
out_p)) {
return true;
}
return false;
}
static inline bool
internaction_profile_find_in_session(struct oxr_logger *log,
struct oxr_session *sess,
XrPath path,
struct oxr_interaction_profile **out_p)
interaction_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, //
@ -348,45 +351,16 @@ oxr_get_profile_for_device_name(struct oxr_logger *log,
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) 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;
case XRT_DEVICE_SIMPLE_CONTROLLER: FIND_PROFILE(khr_simple_controller); return;
case XRT_DEVICE_INDEX_CONTROLLER: FIND_PROFILE(valve_index_controller); return;
case XRT_DEVICE_VIVE_WAND: FIND_PROFILE(htc_vive_controller); return;
case XRT_DEVICE_TOUCH_CONTROLLER: FIND_PROFILE(oculus_touch_controller); return;
case XRT_DEVICE_WMR_CONTROLLER: FIND_PROFILE(microsoft_motion_controller); return;
case XRT_DEVICE_GO_CONTROLLER: FIND_PROFILE(oculus_go_controller); return;
case XRT_DEVICE_VIVE_PRO: FIND_PROFILE(htc_vive_pro); return;
case XRT_DEVICE_XBOX_CONTROLLER: FIND_PROFILE(microsoft_xbox_controller); return;
case XRT_DEVICE_HP_REVERB_G2_CONTROLLER: FIND_PROFILE(hp_mixed_reality_controller); return;
case XRT_DEVICE_SAMSUNG_ODYSSEY_CONTROLLER: FIND_PROFILE(samsung_odyssey_controller); return;
case XRT_DEVICE_ML2_CONTROLLER: FIND_PROFILE(ml_ml2_controller); return;
case XRT_DEVICE_HAND_INTERACTION: FIND_PROFILE(msft_hand_interaction); return;
case XRT_DEVICE_EYE_GAZE_INTERACTION: FIND_PROFILE(ext_eye_gaze_interaction); return;
case XRT_DEVICE_OPPO_MR_CONTROLLER: FIND_PROFILE(oppo_mr_controller); return;
case XRT_DEVICE_EXT_HAND_INTERACTION: FIND_PROFILE(ext_hand_interaction); return;
// no interaction
default:
case XRT_DEVICE_HYDRA:
case XRT_DEVICE_DAYDREAM:
case XRT_DEVICE_GENERIC_HMD:
case XRT_DEVICE_REALSENSE:
case XRT_DEVICE_HAND_TRACKER:
case XRT_DEVICE_VIVE_TRACKER_GEN1:
case XRT_DEVICE_VIVE_TRACKER_GEN2:
case XRT_DEVICE_VIVE_TRACKER_GEN3:
case XRT_DEVICE_VIVE_TRACKER_TUNDRA: return;
for (uint32_t i = 0; i < ARRAY_SIZE(profile_templates); i++) {
if (name == profile_templates[i].name) {
interaction_profile_find_in_session(log, sess, profile_templates[i].path_cache, out_p);
return;
}
}
#undef FIND_PROFILE
}
@ -695,7 +669,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.
internaction_profile_find_in_session(log, sess, path, &oip);
interaction_profile_find_in_session(log, sess, path, &oip);
if (oip == NULL) {
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "no interaction profile found");
}

View file

@ -8,6 +8,7 @@
* @ingroup oxr_main
*/
#include "bindings/b_generated_bindings.h"
#include "xrt/xrt_config_os.h"
#include "xrt/xrt_config_build.h"
#include "xrt/xrt_instance.h"
@ -253,27 +254,14 @@ oxr_instance_create(struct oxr_logger *log,
OXR_FOR_EACH_SUBACTION_PATH_DETAILED(CACHE_SUBACTION_PATHS)
#undef CACHE_SUBACTION_PATHS
// clang-format off
cache_path(log, inst, "/interaction_profiles/khr/simple_controller", &inst->path_cache.khr_simple_controller);
cache_path(log, inst, "/interaction_profiles/google/daydream_controller", &inst->path_cache.google_daydream_controller);
cache_path(log, inst, "/interaction_profiles/htc/vive_controller", &inst->path_cache.htc_vive_controller);
cache_path(log, inst, "/interaction_profiles/htc/vive_pro", &inst->path_cache.htc_vive_pro);
cache_path(log, inst, "/interaction_profiles/microsoft/motion_controller", &inst->path_cache.microsoft_motion_controller);
cache_path(log, inst, "/interaction_profiles/microsoft/xbox_controller", &inst->path_cache.microsoft_xbox_controller);
cache_path(log, inst, "/interaction_profiles/oculus/go_controller", &inst->path_cache.oculus_go_controller);
cache_path(log, inst, "/interaction_profiles/oculus/touch_controller", &inst->path_cache.oculus_touch_controller);
cache_path(log, inst, "/interaction_profiles/valve/index_controller", &inst->path_cache.valve_index_controller);
cache_path(log, inst, "/interaction_profiles/hp/mixed_reality_controller", &inst->path_cache.hp_mixed_reality_controller);
cache_path(log, inst, "/interaction_profiles/samsung/odyssey_controller", &inst->path_cache.samsung_odyssey_controller);
cache_path(log, inst, "/interaction_profiles/ml/ml2_controller", &inst->path_cache.ml_ml2_controller);
cache_path(log, inst, "/interaction_profiles/mndx/ball_on_a_stick_controller", &inst->path_cache.mndx_ball_on_a_stick_controller);
cache_path(log, inst, "/interaction_profiles/microsoft/hand_interaction", &inst->path_cache.msft_hand_interaction);
cache_path(log, inst, "/interaction_profiles/ext/eye_gaze_interaction", &inst->path_cache.ext_eye_gaze_interaction);
cache_path(log, inst, "/interaction_profiles/ext/hand_interaction_ext", &inst->path_cache.ext_hand_interaction);
cache_path(log, inst, "/interaction_profiles/oppo/mr_controller_oppo", &inst->path_cache.oppo_mr_controller);
// clang-format on
XrPath **path_cache;
const char ***path_cache_names;
uint64_t path_cache_count;
oxr_get_interaction_profile_path_cache(&path_cache, &path_cache_names, &path_cache_count);
for (uint32_t i = 0; i < path_cache_count; i++) {
cache_path(log, inst, *path_cache_names[i], path_cache[i]);
}
// fill in our application info - @todo - replicate all createInfo
// fields?

View file

@ -1653,25 +1653,6 @@ struct oxr_instance
OXR_FOR_EACH_SUBACTION_PATH(SUBACTION_PATH_MEMBER)
#undef SUBACTION_PATH_MEMBER
XrPath khr_simple_controller;
XrPath google_daydream_controller;
XrPath htc_vive_controller;
XrPath htc_vive_pro;
XrPath microsoft_motion_controller;
XrPath microsoft_xbox_controller;
XrPath oculus_go_controller;
XrPath oculus_touch_controller;
XrPath valve_index_controller;
XrPath hp_mixed_reality_controller;
XrPath samsung_odyssey_controller;
XrPath ml_ml2_controller;
XrPath mndx_ball_on_a_stick_controller;
XrPath msft_hand_interaction;
XrPath ext_eye_gaze_interaction;
XrPath ext_hand_interaction;
XrPath oppo_mr_controller;
} path_cache;
struct