mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-05 13:28:16 +00:00
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:
parent
a35d7bd255
commit
7cf457d894
|
@ -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];
|
||||
|
||||
''')
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue