The open source OpenXR runtime

Compare changes

Choose any two refs to compare.

Changed files
+3359 -1890
.gitlab-ci
cmake
doc
changes
auxiliary
ipc
misc_features
misc_fixes
state_trackers
xrt
scripts
src
xrt
auxiliary
compositor
drivers
include
ipc
state_trackers
targets
sdl_test
tracking
tests
+1 -2
.gitlab-ci/templates/.gitlab-ci.yml.jinja
··· 142 142 - .gitlab-ci/ci-cmake-build.sh {{- make_cmake_args(job.cmake_defines) }} 143 143 {%- if job.pahole %} 144 144 145 - - src/xrt/ipc/shared/proto.py src/xrt/ipc/shared/proto.json structs.txt 146 145 - mkdir -p "{{ job.name}}" 147 - - pahole --sizes --class_name file://structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "{{ job.name}}/ipc-sizes.txt"{% endif %} 146 + - pahole --sizes --class_name file://build/ipc-structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "{{ job.name}}/ipc-sizes.txt"{% endif %} 148 147 149 148 {#- gradle builds -#} 150 149 {%- elif "android" in job.name %}
+3 -3
.gitlab-ci/templates/include.win_containers.yml
··· 1 1 # {#- included by .gitlab-ci.yml.jinja #} 2 2 # {#- SPDX-License-Identifier: CC0-1.0 #} 3 - # {#- SPDX-FileCopyrightText: 2018-2022 Collabora, Ltd. and the Monado contributors #} 3 + # {#- SPDX-FileCopyrightText: 2018-2025 Collabora, Ltd. and the Monado contributors #} 4 4 5 5 ### 6 6 # Windows container-related jobs (prep and usage) ··· 9 9 inherit: 10 10 default: false 11 11 variables: 12 - MONADO_WIN_BASE_TAG: "20250418.0" 13 - MONADO_WIN_MAIN_TAG: "20250418.0" 12 + MONADO_WIN_BASE_TAG: "20251127.3" 13 + MONADO_WIN_MAIN_TAG: "20251127.3" 14 14 MONADO_BASE_IMAGE_PATH: "win2022/vs2022_base" 15 15 MONADO_MAIN_IMAGE_PATH: "win2022/vs2022" 16 16
+3 -3
.gitlab-ci/windows/monado_deps_build.ps1
··· 1 1 # Copyright 2019-2022, Mesa contributors 2 - # Copyright 2022, Collabora, Ltd. 2 + # Copyright 2022-2025, Collabora, Ltd. 3 3 # SPDX-License-Identifier: MIT 4 4 # Based on https://gitlab.freedesktop.org/mesa/mesa/-/blob/8396df5ad90aeb6ab2267811aba2187954562f81/.gitlab-ci/windows/mesa_deps_build.ps1 5 5 6 - $VulkanRTVersion = "1.3.283.0" 6 + $VulkanRTVersion = "1.4.328.1" 7 7 8 8 # Download new TLS certs from Windows Update 9 9 Get-Date ··· 28 28 Get-Date 29 29 Write-Host "Installing Vulkan runtime components" 30 30 $VulkanInstaller = "C:\VulkanRTInstaller.exe" 31 - Invoke-WebRequest -Uri "https://sdk.lunarg.com/sdk/download/$VulkanRTVersion/windows/VulkanRT-$VulkanRTVersion-Installer.exe" -OutFile "$VulkanInstaller" 31 + Invoke-WebRequest -Uri "https://sdk.lunarg.com/sdk/download/$VulkanRTVersion/windows/VulkanRT-X64-$VulkanRTVersion-Installer.exe" -OutFile "$VulkanInstaller" 32 32 Start-Process -NoNewWindow -Wait "$VulkanInstaller" -ArgumentList "/S" 33 33 if (!$?) { 34 34 Write-Host "Failed to install Vulkan runtime components"
+2 -2
.gitlab-ci/windows/monado_deps_vs2022.ps1
··· 1 1 # Copyright 2019-2022, Mesa contributors 2 - # Copyright 2022, Collabora, Ltd. 2 + # Copyright 2022-2025, Collabora, Ltd. 3 3 # SPDX-License-Identifier: MIT 4 4 # Based on https://gitlab.freedesktop.org/mesa/mesa/-/blob/8396df5ad90aeb6ab2267811aba2187954562f81/.gitlab-ci/windows/mesa_deps_vs2019.ps1 5 5 ··· 29 29 "--add" 30 30 "Microsoft.VisualStudio.Component.Windows10SDK" 31 31 "--add" 32 - "Microsoft.VisualStudio.Component.Windows11SDK.22000" 32 + "Microsoft.VisualStudio.Component.Windows11SDK.26100" 33 33 "--add" 34 34 "Component.Microsoft.Windows.CppWinRT" 35 35 "--add"
+4 -6
.gitlab-ci.yml
··· 56 56 inherit: 57 57 default: false 58 58 variables: 59 - MONADO_WIN_BASE_TAG: "20250418.0" 60 - MONADO_WIN_MAIN_TAG: "20250418.0" 59 + MONADO_WIN_BASE_TAG: "20251127.3" 60 + MONADO_WIN_MAIN_TAG: "20251127.3" 61 61 MONADO_BASE_IMAGE_PATH: "win2022/vs2022_base" 62 62 MONADO_MAIN_IMAGE_PATH: "win2022/vs2022" 63 63 ··· 369 369 370 370 - .gitlab-ci/prebuild.sh 371 371 - .gitlab-ci/ci-cmake-build.sh -DCMAKE_BUILD_TYPE=Debug -DXRT_HAVE_OPENCV=OFF 372 - - src/xrt/ipc/shared/proto.py src/xrt/ipc/shared/proto.json structs.txt 373 372 - mkdir -p "debian:cmake-no-opencv" 374 - - pahole --sizes --class_name file://structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "debian:cmake-no-opencv/ipc-sizes.txt" 373 + - pahole --sizes --class_name file://build/ipc-structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "debian:cmake-no-opencv/ipc-sizes.txt" 375 374 - cd build && ctest --output-on-failure 376 375 artifacts: 377 376 paths: ··· 408 407 409 408 - .gitlab-ci/prebuild.sh 410 409 - .gitlab-ci/ci-cmake-build.sh -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=.gitlab-ci/i386.cmake -DXRT_HAVE_OPENCV=OFF 411 - - src/xrt/ipc/shared/proto.py src/xrt/ipc/shared/proto.json structs.txt 412 410 - mkdir -p "debian:cmake:32bit" 413 - - pahole --sizes --class_name file://structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "debian:cmake:32bit/ipc-sizes.txt" 411 + - pahole --sizes --class_name file://build/ipc-structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "debian:cmake:32bit/ipc-sizes.txt" 414 412 - cd build && ctest --output-on-failure 415 413 artifacts: 416 414 paths:
+2
CMakeLists.txt
··· 58 58 include(OptionWithDeps) 59 59 include(SPIR-V) 60 60 include(GNUInstallDirs) 61 + include(MergeJSON) 61 62 if(NOT GIT_DESC) 62 63 include(GetGitRevisionDescription) 63 64 git_describe(GIT_DESC "--always") ··· 367 368 option(XRT_FEATURE_OPENXR_ACTIVE_ACTION_SET_PRIORITY "Enable XR_EXT_active_action_set_priority" ON) 368 369 option(XRT_FEATURE_OPENXR_BODY_TRACKING_FB "Enable XR_FB_body_tracking" OFF) 369 370 option(XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE "Enable XR_FB_display_refresh_rate" ON) 371 + option(XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID "Enable XR_ANDROID_face_tracking" OFF) 370 372 option(XRT_FEATURE_OPENXR_FACE_TRACKING2_FB "Enable XR_FB_face_tracking2" OFF) 371 373 option(XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC "Enable XR_HTC_facial_tracking" OFF) 372 374 option(XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL "Enable XR_MNDX_force_feedback_curl" ON)
+77
cmake/MergeJSON.cmake
··· 1 + # Copyright 2025, NVIDIA CORPORATION. 2 + # SPDX-License-Identifier: BSL-1.0 3 + 4 + # JSON merge function: merges multiple JSON files into one output file 5 + # 6 + # To use this function in your CMakeLists.txt: 7 + # include(${CMAKE_SOURCE_DIR}/scripts/CMakeLists.txt) 8 + # 9 + # Usage: 10 + # merge_json_files( 11 + # OUTPUT <output_file> 12 + # SOURCES <json_file1> <json_file2> ... 13 + # [ALLOW_OVERWRITE] 14 + # [IGNORE_SCHEMA] 15 + # ) 16 + # 17 + # Arguments: 18 + # OUTPUT - Output file path (required) 19 + # SOURCES - List of JSON files to merge (required) 20 + # ALLOW_OVERWRITE - Optional flag to allow duplicate keys 21 + # IGNORE_SCHEMA - Optional flag to ignore "$schema" field in output 22 + # 23 + # The function automatically: 24 + # - Sorts input files alphabetically for consistent results 25 + # - Tracks dependencies so output is regenerated when inputs change 26 + # - Errors on duplicate keys unless ALLOW_OVERWRITE is specified 27 + # 28 + # Example: 29 + # merge_json_files( 30 + # OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/merged.json" 31 + # SOURCES file1.json file2.json file3.json 32 + # IGNORE_SCHEMA 33 + # ) 34 + 35 + function(merge_json_files) 36 + set(options ALLOW_OVERWRITE IGNORE_SCHEMA) 37 + set(oneValueArgs OUTPUT) 38 + set(multiValueArgs SOURCES) 39 + 40 + cmake_parse_arguments( 41 + MERGE_JSON "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} 42 + ) 43 + 44 + if(NOT MERGE_JSON_OUTPUT) 45 + message(FATAL_ERROR "merge_json_files: OUTPUT argument is required") 46 + endif() 47 + 48 + if(NOT MERGE_JSON_SOURCES) 49 + message(FATAL_ERROR "merge_json_files: SOURCES argument is required") 50 + endif() 51 + 52 + # Build command arguments 53 + set(MERGE_COMMAND ${PYTHON_EXECUTABLE} 54 + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/merge_json.py -o 55 + "${MERGE_JSON_OUTPUT}" 56 + ) 57 + 58 + if(MERGE_JSON_ALLOW_OVERWRITE) 59 + list(APPEND MERGE_COMMAND --allow-overwrite) 60 + endif() 61 + 62 + if(MERGE_JSON_IGNORE_SCHEMA) 63 + list(APPEND MERGE_COMMAND --ignore-schema) 64 + endif() 65 + 66 + list(APPEND MERGE_COMMAND ${MERGE_JSON_SOURCES}) 67 + 68 + # Create custom command with proper dependencies 69 + add_custom_command( 70 + OUTPUT "${MERGE_JSON_OUTPUT}" 71 + COMMAND ${MERGE_COMMAND} 72 + VERBATIM 73 + DEPENDS ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/merge_json.py 74 + ${MERGE_JSON_SOURCES} 75 + COMMENT "Merging JSON files into ${MERGE_JSON_OUTPUT}" 76 + ) 77 + endfunction()
+139
cmake/merge_json.py
··· 1 + #!/usr/bin/env python3 2 + # Copyright 2025, NVIDIA CORPORATION. 3 + # SPDX-License-Identifier: BSL-1.0 4 + """ 5 + Helper script to merge multiple JSON files into one. 6 + 7 + This script merges the root JSON objects from multiple input files 8 + while preserving field ordering. Files are processed in sorted order 9 + to ensure consistent results. Fields are merged in the order they 10 + appear across the input files. 11 + """ 12 + 13 + import argparse 14 + import json 15 + import sys 16 + from pathlib import Path 17 + 18 + 19 + def merge_json_files(json_files, output_file, allow_overwrite=False, 20 + ignore_schema=False): 21 + """ 22 + Merge multiple JSON files into a single output file. 23 + 24 + Args: 25 + json_files: List of paths to JSON files to merge 26 + output_file: Path to the output file 27 + allow_overwrite: If True, allow later files to overwrite keys 28 + from earlier files 29 + ignore_schema: If True, ignore the "$schema" field in input files 30 + """ 31 + merged = {} 32 + 33 + # Sort files to ensure consistent ordering 34 + sorted_files = sorted(json_files) 35 + 36 + for json_file in sorted_files: 37 + try: 38 + with open(json_file, 'r', encoding='utf-8') as f: 39 + data = json.load(f) 40 + 41 + if not isinstance(data, dict): 42 + print(f"Error: {json_file} does not contain a JSON " 43 + f"object at root level", 44 + file=sys.stderr) 45 + sys.exit(1) 46 + 47 + # Merge while preserving order - check for duplicates 48 + for key, value in data.items(): 49 + if key == "$schema" and ignore_schema: 50 + continue 51 + if key in merged: 52 + if allow_overwrite: 53 + print(f"Warning: Key '{key}' from {json_file} " 54 + f"overwrites previous definition", 55 + file=sys.stderr) 56 + else: 57 + print(f"Error: Duplicate key '{key}' found in " 58 + f"{json_file}. Use --allow-overwrite to " 59 + f"permit overwriting.", 60 + file=sys.stderr) 61 + sys.exit(1) 62 + merged[key] = value 63 + 64 + except FileNotFoundError: 65 + print(f"Error: File not found: {json_file}", file=sys.stderr) 66 + sys.exit(1) 67 + except json.JSONDecodeError as e: 68 + print(f"Error: Failed to parse JSON from {json_file}: {e}", 69 + file=sys.stderr) 70 + sys.exit(1) 71 + except Exception as e: 72 + print(f"Error: Failed to read {json_file}: {e}", 73 + file=sys.stderr) 74 + sys.exit(1) 75 + 76 + 77 + # Write merged JSON to output file 78 + try: 79 + with open(output_file, 'w', encoding='utf-8') as f: 80 + json.dump(merged, f, indent='\t', ensure_ascii=False) 81 + f.write('\n') # Add trailing newline 82 + 83 + # Printing, left in if we want it in the future. 84 + if False: 85 + print(f"Successfully merged {len(json_files)} file(s) into " 86 + f"{output_file}") 87 + except Exception as e: 88 + print(f"Error: Failed to write to {output_file}: {e}", 89 + file=sys.stderr) 90 + sys.exit(1) 91 + 92 + 93 + def main(): 94 + parser = argparse.ArgumentParser( 95 + description='Merge multiple JSON files into one, preserving ' 96 + 'field ordering.', 97 + formatter_class=argparse.RawDescriptionHelpFormatter, 98 + epilog=""" 99 + Examples: 100 + %(prog)s -o merged.json file1.json file2.json file3.json 101 + %(prog)s -o output.json base.json overrides.json 102 + %(prog)s -o output.json --allow-overwrite base.json overrides.json 103 + %(prog)s -o output.json --ignore-schema schema.json data.json 104 + """ 105 + ) 106 + 107 + parser.add_argument('-o', '--output', 108 + required=True, 109 + metavar='OUTPUT', 110 + help='Output file path for the merged JSON') 111 + 112 + parser.add_argument('--allow-overwrite', 113 + action='store_true', 114 + help='Allow later files to overwrite duplicate ' 115 + 'keys from earlier files') 116 + 117 + parser.add_argument('--ignore-schema', 118 + action='store_true', 119 + help='Ignore the "$schema" field in input files') 120 + 121 + parser.add_argument('json_files', 122 + nargs='+', 123 + metavar='JSON_FILE', 124 + help='JSON files (will be sorted alphabetically)') 125 + 126 + args = parser.parse_args() 127 + 128 + # Validate that we have at least one input file 129 + if not args.json_files: 130 + print("Error: At least one JSON file must be provided", 131 + file=sys.stderr) 132 + sys.exit(1) 133 + 134 + merge_json_files(args.json_files, args.output, args.allow_overwrite, 135 + args.ignore_schema) 136 + 137 + 138 + if __name__ == '__main__': 139 + main()
+1
doc/changes/auxiliary/mr.2613.md
··· 1 + a/math: Make relation history motion estimation API take in a single mutable relation
+1
doc/changes/ipc/mr.2644.md
··· 1 + Bump IPC_MAX_CLIENTS from 8 to 32.
+2
doc/changes/misc_features/mr.2605.md
··· 1 + ### Added 2 + - oxr: Implements XR_ANDROID_face_tracking extension.
+1
doc/changes/misc_fixes/mr.2579.md
··· 1 + Fixes tests_aux_d3d_d3d11 failing in DuplicateHandle before importing
+1
doc/changes/state_trackers/mr.2647.md
··· 1 + st/oxr: Report proper timestamps in XrEventDataSessionStateChanged instead of 0.
+3
doc/changes/xrt/mr.2633.md
··· 1 + Enable the use of [X_macro](https://en.wikipedia.org/wiki/X_macro) pattern with 2 + more the enums in the `xrt_defines.h` header. Code has been changed to use these 3 + as well reducing the amount of generated code needed.
+1
scripts/generate_oxr_ext_support.py
··· 76 76 ['XR_EXT_samsung_odyssey_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'], 77 77 ['XR_EXT_user_presence', 'XRT_FEATURE_OPENXR_USER_PRESENCE'], 78 78 # Vendor extensions, sorted alphabetically. 79 + ['XR_ANDROID_face_tracking', 'XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID'], 79 80 ['XR_BD_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE'], 80 81 ['XR_FB_body_tracking', 'XRT_FEATURE_OPENXR_BODY_TRACKING_FB'], 81 82 ['XR_FB_composition_layer_alpha_blend', 'XRT_FEATURE_OPENXR_LAYER_FB_ALPHA_BLEND'],
+1
scripts/mapping.imp
··· 40 40 { symbol: ["XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META", "public", "\"xrt/xrt_config_build.h\"", "public"] }, 41 41 { symbol: ["XRT_FEATURE_OPENXR_DEBUG_UTILS", "public", "\"xrt/xrt_config_build.h\"", "public"] }, 42 42 { symbol: ["XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE", "public", "\"xrt/xrt_config_build.h\"", "public"] }, 43 + { symbol: ["XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID", "public", "\"xrt/xrt_config_build.h\"", "public"] }, 43 44 { symbol: ["XRT_FEATURE_OPENXR_FACE_TRACKING2_FB", "public", "\"xrt/xrt_config_build.h\"", "public"] }, 44 45 { symbol: ["XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC", "public", "\"xrt/xrt_config_build.h\"", "public"] }, 45 46 { symbol: ["XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL", "public", "\"xrt/xrt_config_build.h\"", "public"] },
-17
src/xrt/auxiliary/bindings/b_generated_bindings_helpers.c.template
··· 14 14 15 15 // clang-format off 16 16 17 - const char * 18 - xrt_input_name_string(enum xrt_input_name input) { 19 - switch(input) 20 - { 21 - $xrt_input_name_string_switch 22 - } 23 - } 24 - 25 17 enum xrt_input_name 26 18 xrt_input_name_enum(const char *input) 27 19 { 28 20 $xrt_input_name_enum_content 29 - } 30 - 31 - const char * 32 - xrt_output_name_string(enum xrt_output_name output) 33 - { 34 - switch(output) 35 - { 36 - $xrt_output_name_string_switch 37 - } 38 21 } 39 22 40 23 enum xrt_output_name
-6
src/xrt/auxiliary/bindings/b_generated_bindings_helpers.h
··· 17 17 extern "C" { 18 18 #endif 19 19 20 - const char * 21 - xrt_input_name_string(enum xrt_input_name input); 22 - 23 20 enum xrt_input_name 24 21 xrt_input_name_enum(const char *input); 25 - 26 - const char * 27 - xrt_output_name_string(enum xrt_output_name output); 28 22 29 23 enum xrt_output_name 30 24 xrt_output_name_enum(const char *output);
-12
src/xrt/auxiliary/bindings/bindings.py
··· 588 588 inputs.add("XRT_INPUT_HT_CONFORMING_RIGHT") 589 589 inputs.add("XRT_INPUT_GENERIC_TRACKER_POSE") 590 590 591 - xrt_input_name_string_switch = '\n'.join( 592 - [(f'\tcase {input}: return "{input}";') for input in sorted(inputs)] 593 - ) 594 - xrt_input_name_string_switch += (f'\n\tdefault: return "UNKNOWN";') 595 - 596 591 xrt_input_name_enum_content = '\n'.join( 597 592 [f'\tif(strcmp("{input}", input) == 0) return {input};' for input in sorted(inputs)] 598 593 ) 599 594 xrt_input_name_enum_content += f'\n\treturn XRT_INPUT_GENERIC_TRACKER_POSE;' 600 595 601 - xrt_output_name_string_switch = '\n'.join( 602 - [(f'\tcase {output}: return "{output}";') for output in sorted(outputs)] 603 - ) 604 - xrt_output_name_string_switch+= f'\n\tdefault: return "UNKNOWN";' 605 - 606 596 xrt_output_name_enum_content = '\n'.join( 607 597 [f'\tif(strcmp("{output}", output) == 0) return {output};' for output in sorted(outputs)] 608 598 ) ··· 614 604 615 605 with open(file, "w") as f: 616 606 filled = src.substitute( 617 - xrt_input_name_string_switch=xrt_input_name_string_switch, 618 607 xrt_input_name_enum_content=xrt_input_name_enum_content, 619 - xrt_output_name_string_switch=xrt_output_name_string_switch, 620 608 xrt_output_name_enum_content=xrt_output_name_enum_content 621 609 ) 622 610 f.write(filled)
+21
src/xrt/auxiliary/math/m_api.h
··· 18 18 19 19 #include "xrt/xrt_defines.h" 20 20 21 + #include "math/m_mathinclude.h" 22 + 21 23 #ifdef __cplusplus 22 24 extern "C" { 23 25 #endif ··· 74 76 * @ingroup aux_math 75 77 */ 76 78 #define CLAMP(X, A, B) (MIN(MAX((X), (A)), (B))) 79 + 80 + /*! 81 + * Degrees to radians conversion. 82 + * 83 + * @ingroup aux_math 84 + */ 85 + // clang-format off 86 + // @todo: Remove the clang-format off/on when we move to a newer clang-format in CI. 87 + #define DEG_TO_RAD(DEG) ((DEG) * M_PI / 180.) 88 + // clang-format on 89 + 90 + /*! 91 + * Radians to degrees conversion. 92 + * 93 + * @ingroup aux_math 94 + */ 95 + // clang-format off 96 + #define RAD_TO_DEG(RAD) ((RAD) * 180.0 / M_PI) 97 + // clang-format on 77 98 78 99 79 100 /*
+37 -33
src/xrt/auxiliary/math/m_relation_history.cpp
··· 183 183 } 184 184 } 185 185 186 - bool 187 - m_relation_history_estimate_motion(struct m_relation_history *rh, 188 - const struct xrt_space_relation *in_relation, 189 - int64_t timestamp, 190 - struct xrt_space_relation *out_relation) 186 + static void 187 + m_relation_history_estimate_motion(struct xrt_space_relation const &old_relation, 188 + struct xrt_space_relation const &new_relation, 189 + float dt, 190 + struct xrt_vec3 &out_linear_velocity, 191 + struct xrt_vec3 &out_angular_velocity, 192 + enum xrt_space_relation_flags &out_flags) 191 193 { 194 + assert(dt != 0.0f); 192 195 193 - int64_t last_time_ns; 194 - struct xrt_space_relation last_relation; 195 - if (!m_relation_history_get_latest(rh, &last_time_ns, &last_relation)) { 196 - return false; 197 - }; 196 + enum xrt_space_relation_flags shared_flags = 197 + (enum xrt_space_relation_flags)(old_relation.relation_flags & new_relation.relation_flags); 198 198 199 - float dt = (float)time_ns_to_s(timestamp - last_time_ns); 199 + // If both relations have position data, estimate linear velocity 200 + if (shared_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) { 201 + out_flags = (enum xrt_space_relation_flags)(out_flags | XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT); 200 202 201 - // Used to find out what values are valid in both the old relation and the new relation 202 - enum xrt_space_relation_flags tmp_flags = 203 - (enum xrt_space_relation_flags)(last_relation.relation_flags & in_relation->relation_flags); 204 - 205 - // Brevity 206 - enum xrt_space_relation_flags &outf = out_relation->relation_flags; 207 - 208 - 209 - if (tmp_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) { 210 - outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_POSITION_VALID_BIT); 211 - outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_POSITION_TRACKED_BIT); 203 + out_linear_velocity = (new_relation.pose.position - old_relation.pose.position) / dt; 204 + } 212 205 213 - outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT); 206 + // If both relations have orientation data, estimate angular velocity 207 + if (shared_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) { 208 + out_flags = (enum xrt_space_relation_flags)(out_flags | XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT); 214 209 215 - out_relation->linear_velocity = (in_relation->pose.position - last_relation.pose.position) / dt; 210 + math_quat_finite_difference(&old_relation.pose.orientation, &new_relation.pose.orientation, dt, 211 + &out_angular_velocity); 216 212 } 213 + } 214 + 215 + bool 216 + m_relation_history_push_with_motion_estimation(struct m_relation_history *rh, 217 + struct xrt_space_relation const *in_relation, 218 + int64_t timestamp) 219 + { 220 + assert((in_relation->relation_flags & XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT) == 0); 221 + assert((in_relation->relation_flags & XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT) == 0); 217 222 218 - if (tmp_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) { 219 - outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_ORIENTATION_VALID_BIT); 220 - outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); 223 + struct xrt_space_relation final_relation = *in_relation; 221 224 222 - outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT); 225 + int64_t last_time_ns; 226 + struct xrt_space_relation last_relation; 227 + if (m_relation_history_get_latest(rh, &last_time_ns, &last_relation) && timestamp > last_time_ns) { 228 + float dt = (float)time_ns_to_s(timestamp - last_time_ns); 223 229 224 - math_quat_finite_difference(&last_relation.pose.orientation, &in_relation->pose.orientation, dt, 225 - &out_relation->angular_velocity); 230 + m_relation_history_estimate_motion(last_relation, *in_relation, dt, final_relation.linear_velocity, 231 + final_relation.angular_velocity, final_relation.relation_flags); 226 232 } 227 233 228 - out_relation->pose = in_relation->pose; 229 - 230 - return true; 234 + return m_relation_history_push(rh, &final_relation, timestamp); 231 235 } 232 236 233 237 bool
+15 -17
src/xrt/auxiliary/math/m_relation_history.h
··· 63 63 m_relation_history_push(struct m_relation_history *rh, struct xrt_space_relation const *in_relation, int64_t timestamp); 64 64 65 65 /*! 66 - * Interpolates or extrapolates to the desired timestamp. 66 + * Pushes a new pose to the history, estimating linear and angular velocity based on the previous entry. 67 67 * 68 - * Read-only operation - doesn't remove anything from the buffer or anything like that - you can call this as often as 69 - * you want. 68 + * If the history is full, it will also pop a pose out of the other side of the buffer. 69 + * 70 + * @return false if the timestamp is earlier than the most recent timestamp already recorded 70 71 * 71 72 * @public @memberof m_relation_history 72 73 */ 73 - enum m_relation_history_result 74 - m_relation_history_get(const struct m_relation_history *rh, 75 - int64_t at_timestamp_ns, 76 - struct xrt_space_relation *out_relation); 74 + bool 75 + m_relation_history_push_with_motion_estimation(struct m_relation_history *rh, 76 + struct xrt_space_relation const *in_relation, 77 + int64_t timestamp); 77 78 78 79 /*! 79 - * Estimates the movement (velocity and angular velocity) of a new relation based on 80 - * the latest relation found in the buffer (as returned by m_relation_history_get_latest). 80 + * Interpolates or extrapolates to the desired timestamp. 81 81 * 82 - * Read-only on m_relation_history and in_relation. 83 - * Copies in_relation->pose to out_relation->pose, and writes new flags and linear/angular velocities to 84 - * out_relation->pose. OK to alias in_relation and out_relation. 82 + * Read-only operation - doesn't remove anything from the buffer or anything like that - you can call this as often 83 + * as you want. 85 84 * 86 85 * @public @memberof m_relation_history 87 86 */ 88 - bool 89 - m_relation_history_estimate_motion(struct m_relation_history *rh, 90 - const struct xrt_space_relation *in_relation, 91 - int64_t timestamp, 92 - struct xrt_space_relation *out_relation); 87 + enum m_relation_history_result 88 + m_relation_history_get(const struct m_relation_history *rh, 89 + int64_t at_timestamp_ns, 90 + struct xrt_space_relation *out_relation); 93 91 94 92 /*! 95 93 * Get the latest report in the buffer, if any.
+2
src/xrt/auxiliary/util/CMakeLists.txt
··· 29 29 u_deque.h 30 30 u_device.c 31 31 u_device.h 32 + u_device_ni.c 33 + u_device_ni.h 32 34 u_distortion.c 33 35 u_distortion.h 34 36 u_distortion_mesh.c
+2 -1
src/xrt/auxiliary/util/u_config_json.c
··· 14 14 #include "util/u_file.h" 15 15 #include "util/u_json.h" 16 16 #include "util/u_debug.h" 17 + #include "util/u_pretty_print.h" 17 18 18 19 #include "u_config_json.h" 19 20 ··· 504 505 505 506 cJSON_AddItemToObject(entry, "offset", make_pose(&overrides[i].offset)); 506 507 507 - const char *input_name_string = xrt_input_name_string(overrides[i].input_name); 508 + const char *input_name_string = u_str_xrt_input_name(overrides[i].input_name); 508 509 cJSON_AddStringToObject(entry, "xrt_input_name", input_name_string); 509 510 510 511 cJSON_AddItemToArray(o, entry);
+50 -189
src/xrt/auxiliary/util/u_device.c
··· 11 11 */ 12 12 13 13 #include "util/u_device.h" 14 + #include "util/u_device_ni.h" 14 15 #include "util/u_logging.h" 15 16 #include "util/u_misc.h" 16 17 #include "util/u_visibility_mask.h" ··· 511 512 512 513 /* 513 514 * 514 - * Not implemented function helpers. 515 + * Helper function to fill in defaults. 515 516 * 516 517 */ 517 518 518 - #define E(FN) U_LOG_E("Function " #FN " is not implemented for '%s'", xdev->str) 519 - 520 - xrt_result_t 521 - u_device_ni_get_hand_tracking(struct xrt_device *xdev, 522 - enum xrt_input_name name, 523 - int64_t desired_timestamp_ns, 524 - struct xrt_hand_joint_set *out_value, 525 - int64_t *out_timestamp_ns) 526 - { 527 - E(get_hand_tracking); 528 - return XRT_ERROR_NOT_IMPLEMENTED; 529 - } 530 - 531 - xrt_result_t 532 - u_device_ni_get_face_tracking(struct xrt_device *xdev, 533 - enum xrt_input_name facial_expression_type, 534 - int64_t at_timestamp_ns, 535 - struct xrt_facial_expression_set *out_value) 536 - { 537 - E(get_face_tracking); 538 - return XRT_ERROR_NOT_IMPLEMENTED; 539 - } 540 - 541 - xrt_result_t 542 - u_device_ni_get_body_skeleton(struct xrt_device *xdev, 543 - enum xrt_input_name body_tracking_type, 544 - struct xrt_body_skeleton *out_value) 545 - { 546 - E(get_body_skeleton); 547 - return XRT_ERROR_NOT_IMPLEMENTED; 548 - } 549 - 550 - xrt_result_t 551 - u_device_ni_get_body_joints(struct xrt_device *xdev, 552 - enum xrt_input_name body_tracking_type, 553 - int64_t desired_timestamp_ns, 554 - struct xrt_body_joint_set *out_value) 555 - { 556 - E(get_body_joints); 557 - return XRT_ERROR_NOT_IMPLEMENTED; 558 - } 559 - 560 - xrt_result_t 561 - u_device_ni_reset_body_tracking_calibration_meta(struct xrt_device *xdev) 562 - { 563 - E(reset_body_tracking_calibration_meta); 564 - return XRT_ERROR_NOT_IMPLEMENTED; 565 - } 566 - 567 - xrt_result_t 568 - u_device_ni_set_body_tracking_calibration_override_meta(struct xrt_device *xdev, float new_body_height) 569 - { 570 - E(set_body_tracking_calibration_override_meta); 571 - return XRT_ERROR_NOT_IMPLEMENTED; 572 - } 573 - 574 - xrt_result_t 575 - u_device_ni_set_output(struct xrt_device *xdev, enum xrt_output_name name, const struct xrt_output_value *value) 576 - { 577 - E(set_output); 578 - return XRT_ERROR_NOT_IMPLEMENTED; 579 - } 580 - 581 - xrt_result_t 582 - u_device_ni_get_output_limits(struct xrt_device *xdev, struct xrt_output_limits *limits) 583 - { 584 - E(get_output_limits); 585 - return XRT_ERROR_NOT_IMPLEMENTED; 586 - } 587 - 588 - xrt_result_t 589 - u_device_ni_get_presence(struct xrt_device *xdev, bool *presence) 590 - { 591 - E(get_presence); 592 - return XRT_ERROR_NOT_IMPLEMENTED; 593 - } 594 - 595 - xrt_result_t 596 - u_device_ni_begin_plane_detection_ext(struct xrt_device *xdev, 597 - const struct xrt_plane_detector_begin_info_ext *begin_info, 598 - uint64_t plane_detection_id, 599 - uint64_t *out_plane_detection_id) 600 - { 601 - E(begin_plane_detection_ext); 602 - return XRT_ERROR_NOT_IMPLEMENTED; 603 - } 604 - 605 - xrt_result_t 606 - u_device_ni_destroy_plane_detection_ext(struct xrt_device *xdev, uint64_t plane_detection_id) 607 - { 608 - E(destroy_plane_detection_ext); 609 - return XRT_ERROR_NOT_IMPLEMENTED; 610 - } 611 - 612 - xrt_result_t 613 - u_device_ni_get_plane_detection_state_ext(struct xrt_device *xdev, 614 - uint64_t plane_detection_id, 615 - enum xrt_plane_detector_state_ext *out_state) 616 - { 617 - E(get_plane_detection_state_ext); 618 - return XRT_ERROR_NOT_IMPLEMENTED; 619 - } 620 - 621 - xrt_result_t 622 - u_device_ni_get_plane_detections_ext(struct xrt_device *xdev, 623 - uint64_t plane_detection_id, 624 - struct xrt_plane_detections_ext *out_detections) 625 - { 626 - E(get_plane_detections_ext); 627 - return XRT_ERROR_NOT_IMPLEMENTED; 628 - } 629 - 630 - xrt_result_t 631 - u_device_ni_get_view_poses(struct xrt_device *xdev, 632 - const struct xrt_vec3 *default_eye_relation, 633 - int64_t at_timestamp_ns, 634 - enum xrt_view_type view_type, 635 - uint32_t view_count, 636 - struct xrt_space_relation *out_head_relation, 637 - struct xrt_fov *out_fovs, 638 - struct xrt_pose *out_poses) 519 + void 520 + u_device_populate_function_pointers(struct xrt_device *xdev, 521 + u_device_get_tracked_pose_function_t get_tracked_pose_fn, 522 + u_device_destroy_function_t destroy_fn) 639 523 { 640 - E(get_view_poses); 641 - return XRT_ERROR_NOT_IMPLEMENTED; 642 - } 524 + if (get_tracked_pose_fn == NULL) { 525 + U_LOG_E("Got get_tracked_pose_fn == NULL!"); 526 + assert(get_tracked_pose_fn != NULL); 527 + } 643 528 644 - xrt_result_t 645 - u_device_ni_compute_distortion( 646 - struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *out_result) 647 - { 648 - E(compute_distortion); 649 - return XRT_ERROR_NOT_IMPLEMENTED; 650 - } 529 + if (destroy_fn == NULL) { 530 + U_LOG_E("Got destroy_fn == NULL!"); 531 + assert(destroy_fn != NULL); 532 + } 651 533 652 - xrt_result_t 653 - u_device_ni_get_visibility_mask(struct xrt_device *xdev, 654 - enum xrt_visibility_mask_type type, 655 - uint32_t view_index, 656 - struct xrt_visibility_mask **out_mask) 657 - { 658 - E(get_visibility_mask); 659 - return XRT_ERROR_NOT_IMPLEMENTED; 660 - } 534 + /* 535 + * This must be implemented by the xrt_device, but not necessarily by 536 + * the driver so use noop version. 537 + */ 538 + xdev->update_inputs = u_device_noop_update_inputs; 661 539 662 - xrt_result_t 663 - u_device_ni_ref_space_usage(struct xrt_device *xdev, 664 - enum xrt_reference_space_type type, 665 - enum xrt_input_name name, 666 - bool used) 667 - { 668 - E(ref_space_usage); 669 - return XRT_ERROR_NOT_IMPLEMENTED; 670 - } 540 + // This must be implemented by the driver. 541 + xdev->get_tracked_pose = get_tracked_pose_fn; 671 542 672 - bool 673 - u_device_ni_is_form_factor_available(struct xrt_device *xdev, enum xrt_form_factor form_factor) 674 - { 675 - E(is_form_factor_available); 676 - return false; 677 - } 543 + /* 544 + * These are not required to be implemented by the xrt_device, so use 545 + * not implemented versions, and let the driver override if needed. 546 + */ 547 + xdev->get_hand_tracking = u_device_ni_get_hand_tracking; 548 + xdev->get_face_tracking = u_device_ni_get_face_tracking; 549 + xdev->get_body_skeleton = u_device_ni_get_body_skeleton; 550 + xdev->get_body_joints = u_device_ni_get_body_joints; 551 + xdev->reset_body_tracking_calibration_meta = u_device_ni_reset_body_tracking_calibration_meta; 552 + xdev->set_body_tracking_calibration_override_meta = u_device_ni_set_body_tracking_calibration_override_meta; 553 + xdev->set_output = u_device_ni_set_output; 554 + xdev->get_output_limits = u_device_ni_get_output_limits; 555 + xdev->get_presence = u_device_ni_get_presence; 556 + xdev->begin_plane_detection_ext = u_device_ni_begin_plane_detection_ext; 557 + xdev->destroy_plane_detection_ext = u_device_ni_destroy_plane_detection_ext; 558 + xdev->get_plane_detection_state_ext = u_device_ni_get_plane_detection_state_ext; 559 + xdev->get_plane_detections_ext = u_device_ni_get_plane_detections_ext; 560 + xdev->get_view_poses = u_device_ni_get_view_poses; 561 + xdev->compute_distortion = u_device_ni_compute_distortion; 562 + xdev->get_visibility_mask = u_device_ni_get_visibility_mask; 563 + xdev->ref_space_usage = u_device_ni_ref_space_usage; 564 + xdev->is_form_factor_available = u_device_ni_is_form_factor_available; 565 + xdev->get_battery_status = u_device_ni_get_battery_status; 566 + xdev->get_brightness = u_device_ni_get_brightness; 567 + xdev->set_brightness = u_device_ni_set_brightness; 568 + xdev->begin_feature = u_device_ni_begin_feature; 569 + xdev->end_feature = u_device_ni_end_feature; 678 570 679 - xrt_result_t 680 - u_device_ni_get_battery_status(struct xrt_device *xdev, bool *out_present, bool *out_charging, float *out_charge) 681 - { 682 - E(get_battery_status); 683 - return XRT_ERROR_NOT_IMPLEMENTED; 684 - } 685 - 686 - xrt_result_t 687 - u_device_ni_get_brightness(struct xrt_device *xdev, float *out_brightness) 688 - { 689 - E(get_brightness); 690 - return XRT_ERROR_NOT_IMPLEMENTED; 691 - } 692 - 693 - xrt_result_t 694 - u_device_ni_set_brightness(struct xrt_device *xdev, float brightness, bool relative) 695 - { 696 - E(set_brightness); 697 - return XRT_ERROR_NOT_IMPLEMENTED; 698 - } 699 - 700 - xrt_result_t 701 - u_device_ni_begin_feature(struct xrt_device *xdev, enum xrt_device_feature_type type) 702 - { 703 - E(begin_feature); 704 - return XRT_ERROR_NOT_IMPLEMENTED; 705 - } 706 - 707 - xrt_result_t 708 - u_device_ni_end_feature(struct xrt_device *xdev, enum xrt_device_feature_type type) 709 - { 710 - E(end_feature); 711 - return XRT_ERROR_NOT_IMPLEMENTED; 571 + // This must be implemented by the driver. 572 + xdev->destroy = destroy_fn; 712 573 }
+21 -203
src/xrt/auxiliary/util/u_device.h
··· 206 206 207 207 /* 208 208 * 209 - * Not implemented function helpers. 210 - * 211 - */ 212 - 213 - /*! 214 - * Not implemented function for @ref xrt_device::get_hand_tracking. 215 - * 216 - * @ingroup aux_util 217 - */ 218 - xrt_result_t 219 - u_device_ni_get_hand_tracking(struct xrt_device *xdev, 220 - enum xrt_input_name name, 221 - int64_t desired_timestamp_ns, 222 - struct xrt_hand_joint_set *out_value, 223 - int64_t *out_timestamp_ns); 224 - 225 - /*! 226 - * Not implemented function for @ref xrt_device::get_face_tracking. 227 - * 228 - * @ingroup aux_util 229 - */ 230 - xrt_result_t 231 - u_device_ni_get_face_tracking(struct xrt_device *xdev, 232 - enum xrt_input_name facial_expression_type, 233 - int64_t at_timestamp_ns, 234 - struct xrt_facial_expression_set *out_value); 235 - 236 - /*! 237 - * Not implemented function for @ref xrt_device::get_body_skeleton. 238 - * 239 - * @ingroup aux_util 240 - */ 241 - xrt_result_t 242 - u_device_ni_get_body_skeleton(struct xrt_device *xdev, 243 - enum xrt_input_name body_tracking_type, 244 - struct xrt_body_skeleton *out_value); 245 - 246 - /*! 247 - * Not implemented function for @ref xrt_device::get_body_joints. 248 - * 249 - * @ingroup aux_util 250 - */ 251 - xrt_result_t 252 - u_device_ni_get_body_joints(struct xrt_device *xdev, 253 - enum xrt_input_name body_tracking_type, 254 - int64_t desired_timestamp_ns, 255 - struct xrt_body_joint_set *out_value); 256 - 257 - /*! 258 - * Not implemented function for @ref xrt_device::reset_body_tracking_calibration_meta. 259 - * 260 - * @ingroup aux_util 261 - */ 262 - xrt_result_t 263 - u_device_ni_reset_body_tracking_calibration_meta(struct xrt_device *xdev); 264 - 265 - /*! 266 - * Not implemented function for @ref xrt_device::set_body_tracking_calibration_override_meta. 267 - * 268 - * @ingroup aux_util 269 - */ 270 - xrt_result_t 271 - u_device_ni_set_body_tracking_calibration_override_meta(struct xrt_device *xdev, float new_body_height); 272 - 273 - /*! 274 - * Not implemented function for @ref xrt_device::set_output. 275 - * 276 - * @ingroup aux_util 277 - */ 278 - xrt_result_t 279 - u_device_ni_set_output(struct xrt_device *xdev, enum xrt_output_name name, const struct xrt_output_value *value); 280 - 281 - /*! 282 - * Not implemented function for @ref xrt_device::get_output_limits. 283 - * 284 - * @ingroup aux_util 285 - */ 286 - xrt_result_t 287 - u_device_ni_get_output_limits(struct xrt_device *xdev, struct xrt_output_limits *limits); 288 - 289 - /*! 290 - * Not implemented function for @ref xrt_device::get_presence. 291 - * 292 - * @ingroup aux_util 293 - */ 294 - xrt_result_t 295 - u_device_ni_get_presence(struct xrt_device *xdev, bool *presence); 296 - 297 - /*! 298 - * Not implemented function for @ref xrt_device::begin_plane_detection_ext. 299 - * 300 - * @ingroup aux_util 301 - */ 302 - xrt_result_t 303 - u_device_ni_begin_plane_detection_ext(struct xrt_device *xdev, 304 - const struct xrt_plane_detector_begin_info_ext *begin_info, 305 - uint64_t plane_detection_id, 306 - uint64_t *out_plane_detection_id); 307 - 308 - /*! 309 - * Not implemented function for @ref xrt_device::destroy_plane_detection_ext. 310 - * 311 - * @ingroup aux_util 312 - */ 313 - xrt_result_t 314 - u_device_ni_destroy_plane_detection_ext(struct xrt_device *xdev, uint64_t plane_detection_id); 315 - 316 - /*! 317 - * Not implemented function for @ref xrt_device::get_plane_detection_state_ext. 318 - * 319 - * @ingroup aux_util 320 - */ 321 - xrt_result_t 322 - u_device_ni_get_plane_detection_state_ext(struct xrt_device *xdev, 323 - uint64_t plane_detection_id, 324 - enum xrt_plane_detector_state_ext *out_state); 325 - 326 - /*! 327 - * Not implemented function for @ref xrt_device::get_plane_detections_ext. 328 - * 329 - * @ingroup aux_util 330 - */ 331 - xrt_result_t 332 - u_device_ni_get_plane_detections_ext(struct xrt_device *xdev, 333 - uint64_t plane_detection_id, 334 - struct xrt_plane_detections_ext *out_detections); 335 - 336 - /*! 337 - * Not implemented function for @ref xrt_device::get_view_poses. 338 - * 339 - * @ingroup aux_util 340 - */ 341 - xrt_result_t 342 - u_device_ni_get_view_poses(struct xrt_device *xdev, 343 - const struct xrt_vec3 *default_eye_relation, 344 - int64_t at_timestamp_ns, 345 - enum xrt_view_type view_type, 346 - uint32_t view_count, 347 - struct xrt_space_relation *out_head_relation, 348 - struct xrt_fov *out_fovs, 349 - struct xrt_pose *out_poses); 350 - 351 - /*! 352 - * Not implemented function for @ref xrt_device::compute_distortion. 353 - * 354 - * @ingroup aux_util 355 - */ 356 - xrt_result_t 357 - u_device_ni_compute_distortion( 358 - struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *out_result); 359 - 360 - /*! 361 - * Not implemented function for @ref xrt_device::get_visibility_mask. 362 - * 363 - * @ingroup aux_util 364 - */ 365 - xrt_result_t 366 - u_device_ni_get_visibility_mask(struct xrt_device *xdev, 367 - enum xrt_visibility_mask_type type, 368 - uint32_t view_index, 369 - struct xrt_visibility_mask **out_mask); 370 - 371 - /*! 372 - * Not implemented function for @ref xrt_device::ref_space_usage. 373 - * 374 - * @ingroup aux_util 375 - */ 376 - xrt_result_t 377 - u_device_ni_ref_space_usage(struct xrt_device *xdev, 378 - enum xrt_reference_space_type type, 379 - enum xrt_input_name name, 380 - bool used); 381 - 382 - /*! 383 - * Not implemented function for @ref xrt_device::is_form_factor_available. 384 - * 385 - * @ingroup aux_util 386 - */ 387 - bool 388 - u_device_ni_is_form_factor_available(struct xrt_device *xdev, enum xrt_form_factor form_factor); 389 - 390 - /*! 391 - * Not implemented function for @ref xrt_device::get_battery_status. 209 + * Helper function to fill in defaults. 392 210 * 393 - * @ingroup aux_util 394 211 */ 395 - xrt_result_t 396 - u_device_ni_get_battery_status(struct xrt_device *xdev, bool *out_present, bool *out_charging, float *out_charge); 397 212 398 213 /*! 399 - * Not implemented function for @ref xrt_device::get_brightness. 214 + * Function pointer type for the device's get_tracked_pose function. 400 215 * 401 216 * @ingroup aux_util 402 217 */ 403 - xrt_result_t 404 - u_device_ni_get_brightness(struct xrt_device *xdev, float *out_brightness); 218 + typedef xrt_result_t (*u_device_get_tracked_pose_function_t)(struct xrt_device *xdev, 219 + const enum xrt_input_name name, 220 + const int64_t at_timestamp_ns, 221 + struct xrt_space_relation *const out_relation); 405 222 406 223 /*! 407 - * Not implemented function for @ref xrt_device::set_brightness. 224 + * Function pointer type for the device's destroy function. 408 225 * 409 226 * @ingroup aux_util 410 227 */ 411 - xrt_result_t 412 - u_device_ni_set_brightness(struct xrt_device *xdev, float brightness, bool relative); 228 + typedef void (*u_device_destroy_function_t)(struct xrt_device *xdev); 413 229 414 230 /*! 415 - * Not implemented function for @ref xrt_device::begin_feature. 231 + * Populate the device's function pointers with default implementations. 416 232 * 417 - * @ingroup aux_util 418 - */ 419 - xrt_result_t 420 - u_device_ni_begin_feature(struct xrt_device *xdev, enum xrt_device_feature_type type); 421 - 422 - /*! 423 - * Not implemented function for @ref xrt_device::end_feature. 233 + * This function fills in all device function pointers with either noop or 234 + * not-implemented versions, allowing drivers to override only the functions 235 + * they actually implement. The exceptions are get_tracked_pose and destroy, 236 + * which must be implemented by the driver and are passed in as function 237 + * pointers, these must not be NULL. 424 238 * 239 + * @param[in,out] xdev The device to populate with default function pointers. 240 + * @param[in] get_tracked_pose_fn The function pointer to the device's get_tracked_pose function. 241 + * @param[in] destroy_fn The function pointer to the device's destroy function. 425 242 * @ingroup aux_util 426 243 */ 427 - xrt_result_t 428 - u_device_ni_end_feature(struct xrt_device *xdev, enum xrt_device_feature_type type); 429 - 244 + void 245 + u_device_populate_function_pointers(struct xrt_device *xdev, 246 + u_device_get_tracked_pose_function_t get_tracked_pose_fn, 247 + u_device_destroy_function_t destroy_fn); 430 248 431 249 #ifdef __cplusplus 432 250 }
+217
src/xrt/auxiliary/util/u_device_ni.c
··· 1 + // Copyright 2019-2025, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Not implemented function helpers for device drivers. 6 + * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @author Rylie Pavlik <rylie.pavlik@collabora.com> 8 + * @author Moshi Turner <moshiturner@protonmail.com> 9 + * @author Simon Zeni <simon.zeni@collabora.com> 10 + * @ingroup aux_util 11 + */ 12 + 13 + #include "util/u_device_ni.h" 14 + #include "util/u_logging.h" 15 + 16 + 17 + /* 18 + * 19 + * Not implemented function helpers. 20 + * 21 + */ 22 + 23 + #define E(FN) U_LOG_E("Function " #FN " is not implemented for '%s'", xdev->str) 24 + 25 + xrt_result_t 26 + u_device_ni_get_hand_tracking(struct xrt_device *xdev, 27 + enum xrt_input_name name, 28 + int64_t desired_timestamp_ns, 29 + struct xrt_hand_joint_set *out_value, 30 + int64_t *out_timestamp_ns) 31 + { 32 + E(get_hand_tracking); 33 + return XRT_ERROR_NOT_IMPLEMENTED; 34 + } 35 + 36 + xrt_result_t 37 + u_device_ni_get_face_tracking(struct xrt_device *xdev, 38 + enum xrt_input_name facial_expression_type, 39 + int64_t at_timestamp_ns, 40 + struct xrt_facial_expression_set *out_value) 41 + { 42 + E(get_face_tracking); 43 + return XRT_ERROR_NOT_IMPLEMENTED; 44 + } 45 + 46 + xrt_result_t 47 + u_device_ni_get_body_skeleton(struct xrt_device *xdev, 48 + enum xrt_input_name body_tracking_type, 49 + struct xrt_body_skeleton *out_value) 50 + { 51 + E(get_body_skeleton); 52 + return XRT_ERROR_NOT_IMPLEMENTED; 53 + } 54 + 55 + xrt_result_t 56 + u_device_ni_get_body_joints(struct xrt_device *xdev, 57 + enum xrt_input_name body_tracking_type, 58 + int64_t desired_timestamp_ns, 59 + struct xrt_body_joint_set *out_value) 60 + { 61 + E(get_body_joints); 62 + return XRT_ERROR_NOT_IMPLEMENTED; 63 + } 64 + 65 + xrt_result_t 66 + u_device_ni_reset_body_tracking_calibration_meta(struct xrt_device *xdev) 67 + { 68 + E(reset_body_tracking_calibration_meta); 69 + return XRT_ERROR_NOT_IMPLEMENTED; 70 + } 71 + 72 + xrt_result_t 73 + u_device_ni_set_body_tracking_calibration_override_meta(struct xrt_device *xdev, float new_body_height) 74 + { 75 + E(set_body_tracking_calibration_override_meta); 76 + return XRT_ERROR_NOT_IMPLEMENTED; 77 + } 78 + 79 + xrt_result_t 80 + u_device_ni_set_output(struct xrt_device *xdev, enum xrt_output_name name, const struct xrt_output_value *value) 81 + { 82 + E(set_output); 83 + return XRT_ERROR_NOT_IMPLEMENTED; 84 + } 85 + 86 + xrt_result_t 87 + u_device_ni_get_output_limits(struct xrt_device *xdev, struct xrt_output_limits *limits) 88 + { 89 + E(get_output_limits); 90 + return XRT_ERROR_NOT_IMPLEMENTED; 91 + } 92 + 93 + xrt_result_t 94 + u_device_ni_get_presence(struct xrt_device *xdev, bool *presence) 95 + { 96 + E(get_presence); 97 + return XRT_ERROR_NOT_IMPLEMENTED; 98 + } 99 + 100 + xrt_result_t 101 + u_device_ni_begin_plane_detection_ext(struct xrt_device *xdev, 102 + const struct xrt_plane_detector_begin_info_ext *begin_info, 103 + uint64_t plane_detection_id, 104 + uint64_t *out_plane_detection_id) 105 + { 106 + E(begin_plane_detection_ext); 107 + return XRT_ERROR_NOT_IMPLEMENTED; 108 + } 109 + 110 + xrt_result_t 111 + u_device_ni_destroy_plane_detection_ext(struct xrt_device *xdev, uint64_t plane_detection_id) 112 + { 113 + E(destroy_plane_detection_ext); 114 + return XRT_ERROR_NOT_IMPLEMENTED; 115 + } 116 + 117 + xrt_result_t 118 + u_device_ni_get_plane_detection_state_ext(struct xrt_device *xdev, 119 + uint64_t plane_detection_id, 120 + enum xrt_plane_detector_state_ext *out_state) 121 + { 122 + E(get_plane_detection_state_ext); 123 + return XRT_ERROR_NOT_IMPLEMENTED; 124 + } 125 + 126 + xrt_result_t 127 + u_device_ni_get_plane_detections_ext(struct xrt_device *xdev, 128 + uint64_t plane_detection_id, 129 + struct xrt_plane_detections_ext *out_detections) 130 + { 131 + E(get_plane_detections_ext); 132 + return XRT_ERROR_NOT_IMPLEMENTED; 133 + } 134 + 135 + xrt_result_t 136 + u_device_ni_get_view_poses(struct xrt_device *xdev, 137 + const struct xrt_vec3 *default_eye_relation, 138 + int64_t at_timestamp_ns, 139 + enum xrt_view_type view_type, 140 + uint32_t view_count, 141 + struct xrt_space_relation *out_head_relation, 142 + struct xrt_fov *out_fovs, 143 + struct xrt_pose *out_poses) 144 + { 145 + E(get_view_poses); 146 + return XRT_ERROR_NOT_IMPLEMENTED; 147 + } 148 + 149 + xrt_result_t 150 + u_device_ni_compute_distortion( 151 + struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *out_result) 152 + { 153 + E(compute_distortion); 154 + return XRT_ERROR_NOT_IMPLEMENTED; 155 + } 156 + 157 + xrt_result_t 158 + u_device_ni_get_visibility_mask(struct xrt_device *xdev, 159 + enum xrt_visibility_mask_type type, 160 + uint32_t view_index, 161 + struct xrt_visibility_mask **out_mask) 162 + { 163 + E(get_visibility_mask); 164 + return XRT_ERROR_NOT_IMPLEMENTED; 165 + } 166 + 167 + xrt_result_t 168 + u_device_ni_ref_space_usage(struct xrt_device *xdev, 169 + enum xrt_reference_space_type type, 170 + enum xrt_input_name name, 171 + bool used) 172 + { 173 + E(ref_space_usage); 174 + return XRT_ERROR_NOT_IMPLEMENTED; 175 + } 176 + 177 + bool 178 + u_device_ni_is_form_factor_available(struct xrt_device *xdev, enum xrt_form_factor form_factor) 179 + { 180 + E(is_form_factor_available); 181 + return false; 182 + } 183 + 184 + xrt_result_t 185 + u_device_ni_get_battery_status(struct xrt_device *xdev, bool *out_present, bool *out_charging, float *out_charge) 186 + { 187 + E(get_battery_status); 188 + return XRT_ERROR_NOT_IMPLEMENTED; 189 + } 190 + 191 + xrt_result_t 192 + u_device_ni_get_brightness(struct xrt_device *xdev, float *out_brightness) 193 + { 194 + E(get_brightness); 195 + return XRT_ERROR_NOT_IMPLEMENTED; 196 + } 197 + 198 + xrt_result_t 199 + u_device_ni_set_brightness(struct xrt_device *xdev, float brightness, bool relative) 200 + { 201 + E(set_brightness); 202 + return XRT_ERROR_NOT_IMPLEMENTED; 203 + } 204 + 205 + xrt_result_t 206 + u_device_ni_begin_feature(struct xrt_device *xdev, enum xrt_device_feature_type type) 207 + { 208 + E(begin_feature); 209 + return XRT_ERROR_NOT_IMPLEMENTED; 210 + } 211 + 212 + xrt_result_t 213 + u_device_ni_end_feature(struct xrt_device *xdev, enum xrt_device_feature_type type) 214 + { 215 + E(end_feature); 216 + return XRT_ERROR_NOT_IMPLEMENTED; 217 + }
+249
src/xrt/auxiliary/util/u_device_ni.h
··· 1 + // Copyright 2019-2025, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Not implemented function helpers for device drivers. 6 + * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @author Rylie Pavlik <rylie.pavlik@collabora.com> 8 + * @author Moshi Turner <moshiturner@protonmail.com> 9 + * @author Simon Zeni <simon.zeni@collabora.com> 10 + * @ingroup aux_util 11 + */ 12 + 13 + #pragma once 14 + 15 + #include "xrt/xrt_compiler.h" 16 + #include "xrt/xrt_device.h" 17 + 18 + #ifdef __cplusplus 19 + extern "C" { 20 + #endif 21 + 22 + 23 + /* 24 + * 25 + * Not implemented function helpers. 26 + * 27 + */ 28 + 29 + /*! 30 + * Not implemented function for @ref xrt_device::get_hand_tracking. 31 + * 32 + * @ingroup aux_util 33 + */ 34 + xrt_result_t 35 + u_device_ni_get_hand_tracking(struct xrt_device *xdev, 36 + enum xrt_input_name name, 37 + int64_t desired_timestamp_ns, 38 + struct xrt_hand_joint_set *out_value, 39 + int64_t *out_timestamp_ns); 40 + 41 + /*! 42 + * Not implemented function for @ref xrt_device::get_face_tracking. 43 + * 44 + * @ingroup aux_util 45 + */ 46 + xrt_result_t 47 + u_device_ni_get_face_tracking(struct xrt_device *xdev, 48 + enum xrt_input_name facial_expression_type, 49 + int64_t at_timestamp_ns, 50 + struct xrt_facial_expression_set *out_value); 51 + 52 + /*! 53 + * Not implemented function for @ref xrt_device::get_body_skeleton. 54 + * 55 + * @ingroup aux_util 56 + */ 57 + xrt_result_t 58 + u_device_ni_get_body_skeleton(struct xrt_device *xdev, 59 + enum xrt_input_name body_tracking_type, 60 + struct xrt_body_skeleton *out_value); 61 + 62 + /*! 63 + * Not implemented function for @ref xrt_device::get_body_joints. 64 + * 65 + * @ingroup aux_util 66 + */ 67 + xrt_result_t 68 + u_device_ni_get_body_joints(struct xrt_device *xdev, 69 + enum xrt_input_name body_tracking_type, 70 + int64_t desired_timestamp_ns, 71 + struct xrt_body_joint_set *out_value); 72 + 73 + /*! 74 + * Not implemented function for @ref xrt_device::reset_body_tracking_calibration_meta. 75 + * 76 + * @ingroup aux_util 77 + */ 78 + xrt_result_t 79 + u_device_ni_reset_body_tracking_calibration_meta(struct xrt_device *xdev); 80 + 81 + /*! 82 + * Not implemented function for @ref xrt_device::set_body_tracking_calibration_override_meta. 83 + * 84 + * @ingroup aux_util 85 + */ 86 + xrt_result_t 87 + u_device_ni_set_body_tracking_calibration_override_meta(struct xrt_device *xdev, float new_body_height); 88 + 89 + /*! 90 + * Not implemented function for @ref xrt_device::set_output. 91 + * 92 + * @ingroup aux_util 93 + */ 94 + xrt_result_t 95 + u_device_ni_set_output(struct xrt_device *xdev, enum xrt_output_name name, const struct xrt_output_value *value); 96 + 97 + /*! 98 + * Not implemented function for @ref xrt_device::get_output_limits. 99 + * 100 + * @ingroup aux_util 101 + */ 102 + xrt_result_t 103 + u_device_ni_get_output_limits(struct xrt_device *xdev, struct xrt_output_limits *limits); 104 + 105 + /*! 106 + * Not implemented function for @ref xrt_device::get_presence. 107 + * 108 + * @ingroup aux_util 109 + */ 110 + xrt_result_t 111 + u_device_ni_get_presence(struct xrt_device *xdev, bool *presence); 112 + 113 + /*! 114 + * Not implemented function for @ref xrt_device::begin_plane_detection_ext. 115 + * 116 + * @ingroup aux_util 117 + */ 118 + xrt_result_t 119 + u_device_ni_begin_plane_detection_ext(struct xrt_device *xdev, 120 + const struct xrt_plane_detector_begin_info_ext *begin_info, 121 + uint64_t plane_detection_id, 122 + uint64_t *out_plane_detection_id); 123 + 124 + /*! 125 + * Not implemented function for @ref xrt_device::destroy_plane_detection_ext. 126 + * 127 + * @ingroup aux_util 128 + */ 129 + xrt_result_t 130 + u_device_ni_destroy_plane_detection_ext(struct xrt_device *xdev, uint64_t plane_detection_id); 131 + 132 + /*! 133 + * Not implemented function for @ref xrt_device::get_plane_detection_state_ext. 134 + * 135 + * @ingroup aux_util 136 + */ 137 + xrt_result_t 138 + u_device_ni_get_plane_detection_state_ext(struct xrt_device *xdev, 139 + uint64_t plane_detection_id, 140 + enum xrt_plane_detector_state_ext *out_state); 141 + 142 + /*! 143 + * Not implemented function for @ref xrt_device::get_plane_detections_ext. 144 + * 145 + * @ingroup aux_util 146 + */ 147 + xrt_result_t 148 + u_device_ni_get_plane_detections_ext(struct xrt_device *xdev, 149 + uint64_t plane_detection_id, 150 + struct xrt_plane_detections_ext *out_detections); 151 + 152 + /*! 153 + * Not implemented function for @ref xrt_device::get_view_poses. 154 + * 155 + * @ingroup aux_util 156 + */ 157 + xrt_result_t 158 + u_device_ni_get_view_poses(struct xrt_device *xdev, 159 + const struct xrt_vec3 *default_eye_relation, 160 + int64_t at_timestamp_ns, 161 + enum xrt_view_type view_type, 162 + uint32_t view_count, 163 + struct xrt_space_relation *out_head_relation, 164 + struct xrt_fov *out_fovs, 165 + struct xrt_pose *out_poses); 166 + 167 + /*! 168 + * Not implemented function for @ref xrt_device::compute_distortion. 169 + * 170 + * @ingroup aux_util 171 + */ 172 + xrt_result_t 173 + u_device_ni_compute_distortion( 174 + struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *out_result); 175 + 176 + /*! 177 + * Not implemented function for @ref xrt_device::get_visibility_mask. 178 + * 179 + * @ingroup aux_util 180 + */ 181 + xrt_result_t 182 + u_device_ni_get_visibility_mask(struct xrt_device *xdev, 183 + enum xrt_visibility_mask_type type, 184 + uint32_t view_index, 185 + struct xrt_visibility_mask **out_mask); 186 + 187 + /*! 188 + * Not implemented function for @ref xrt_device::ref_space_usage. 189 + * 190 + * @ingroup aux_util 191 + */ 192 + xrt_result_t 193 + u_device_ni_ref_space_usage(struct xrt_device *xdev, 194 + enum xrt_reference_space_type type, 195 + enum xrt_input_name name, 196 + bool used); 197 + 198 + /*! 199 + * Not implemented function for @ref xrt_device::is_form_factor_available. 200 + * 201 + * @ingroup aux_util 202 + */ 203 + bool 204 + u_device_ni_is_form_factor_available(struct xrt_device *xdev, enum xrt_form_factor form_factor); 205 + 206 + /*! 207 + * Not implemented function for @ref xrt_device::get_battery_status. 208 + * 209 + * @ingroup aux_util 210 + */ 211 + xrt_result_t 212 + u_device_ni_get_battery_status(struct xrt_device *xdev, bool *out_present, bool *out_charging, float *out_charge); 213 + 214 + /*! 215 + * Not implemented function for @ref xrt_device::get_brightness. 216 + * 217 + * @ingroup aux_util 218 + */ 219 + xrt_result_t 220 + u_device_ni_get_brightness(struct xrt_device *xdev, float *out_brightness); 221 + 222 + /*! 223 + * Not implemented function for @ref xrt_device::set_brightness. 224 + * 225 + * @ingroup aux_util 226 + */ 227 + xrt_result_t 228 + u_device_ni_set_brightness(struct xrt_device *xdev, float brightness, bool relative); 229 + 230 + /*! 231 + * Not implemented function for @ref xrt_device::begin_feature. 232 + * 233 + * @ingroup aux_util 234 + */ 235 + xrt_result_t 236 + u_device_ni_begin_feature(struct xrt_device *xdev, enum xrt_device_feature_type type); 237 + 238 + /*! 239 + * Not implemented function for @ref xrt_device::end_feature. 240 + * 241 + * @ingroup aux_util 242 + */ 243 + xrt_result_t 244 + u_device_ni_end_feature(struct xrt_device *xdev, enum xrt_device_feature_type type); 245 + 246 + 247 + #ifdef __cplusplus 248 + } 249 + #endif
-2
src/xrt/auxiliary/util/u_hand_simulation.c
··· 32 32 struct xrt_quat q[HAND_SIM_NUM_FINGERS][HAND_SIM_NUM_ORIENTATIONS_IN_FINGER]; 33 33 }; 34 34 35 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 36 - 37 35 // For debugging. 38 36 #if 0 39 37 #include <iostream>
-2
src/xrt/auxiliary/util/u_hand_tracking.c
··· 20 20 #include "util/u_time.h" 21 21 22 22 23 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 24 - 25 23 bool 26 24 u_hand_joint_is_metacarpal(enum xrt_hand_joint joint) 27 25 {
+86 -52
src/xrt/auxiliary/util/u_pretty_print.c
··· 1 1 // Copyright 2022-2024, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 39 40 case XRT_INPUT_TYPE_HAND_TRACKING: return "HAND_TRACKING"; 40 41 case XRT_INPUT_TYPE_FACE_TRACKING: return "FACE_TRACKING"; 41 42 case XRT_INPUT_TYPE_BODY_TRACKING: return "BODY_TRACKING"; 42 - default: return "<UNKNOWN>"; 43 43 } 44 + 45 + return "<UNKNOWN>"; 46 + } 47 + 48 + const char * 49 + get_xrt_output_type_short_str(enum xrt_output_type type) 50 + { 51 + switch (type) { 52 + case XRT_OUTPUT_TYPE_VIBRATION: return "XRT_OUTPUT_TYPE_VIBRATION"; 53 + case XRT_OUTPUT_TYPE_FORCE_FEEDBACK: return "XRT_OUTPUT_TYPE_FORCE_FEEDBACK"; 54 + } 55 + 56 + return "<UNKNOWN>"; 44 57 } 45 58 46 59 void ··· 70 83 71 84 /* 72 85 * 86 + * 'Exported' str functions. 87 + * 88 + */ 89 + 90 + const char * 91 + u_str_xrt_input_name_or_null(enum xrt_input_name name) 92 + { 93 + #define XRT_INPUT_LIST_TO_CASE(NAME, _) \ 94 + case NAME: return #NAME; 95 + 96 + // No default case so we get warnings of missing entries. 97 + switch (name) { 98 + XRT_INPUT_LIST(XRT_INPUT_LIST_TO_CASE) 99 + } 100 + 101 + #undef XRT_INPUT_LIST_TO_CASE 102 + 103 + return NULL; 104 + } 105 + 106 + const char * 107 + u_str_xrt_output_name_or_null(enum xrt_output_name name) 108 + { 109 + #define XRT_OUTPUT_LIST_TO_CASE(NAME, _) \ 110 + case NAME: return #NAME; 111 + 112 + // No default case so we get warnings of missing entries. 113 + switch (name) { 114 + XRT_OUTPUT_LIST(XRT_OUTPUT_LIST_TO_CASE) 115 + } 116 + 117 + #undef XRT_OUTPUT_LIST_TO_CASE 118 + 119 + return NULL; 120 + } 121 + 122 + const char * 123 + u_str_xrt_device_name_or_null(enum xrt_device_name name) 124 + { 125 + #define XRT_DEVICE_NAME_LIST_TO_CASE(NAME) \ 126 + case NAME: return #NAME; 127 + 128 + // No default case so we get warnings of missing entries. 129 + switch (name) { 130 + XRT_DEVICE_NAME_LIST(XRT_DEVICE_NAME_LIST_TO_CASE) 131 + } 132 + 133 + #undef XRT_DEVICE_NAME_LIST_TO_CASE 134 + 135 + return NULL; 136 + } 137 + 138 + 139 + /* 140 + * 73 141 * 'Exported' functions. 74 142 * 75 143 */ ··· 112 180 void 113 181 u_pp_xrt_input_name(struct u_pp_delegate dg, enum xrt_input_name name) 114 182 { 115 - #define XRT_INPUT_LIST_TO_CASE(NAME, _) \ 116 - case NAME: DG(#NAME); return; 117 - 118 - switch (name) { 119 - XRT_INPUT_LIST(XRT_INPUT_LIST_TO_CASE) 183 + const char *might_be_null = u_str_xrt_input_name_or_null(name); 184 + if (might_be_null != NULL) { 185 + DG(might_be_null); 186 + return; 120 187 } 121 188 122 - #undef XRT_INPUT_LIST_TO_CASE 123 - 124 189 /* 125 - * No default case so we get warnings of missing entries. 126 190 * Invalid values handled below. 127 191 */ 128 192 ··· 136 200 void 137 201 u_pp_xrt_output_name(struct u_pp_delegate dg, enum xrt_output_name name) 138 202 { 139 - #define XRT_OUTPUT_CASE(NAME) \ 140 - case NAME: DG(#NAME); return 203 + const char *might_be_null = u_str_xrt_output_name_or_null(name); 204 + if (might_be_null != NULL) { 205 + DG(might_be_null); 206 + return; 207 + } 141 208 142 - switch (name) { 143 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_SIMPLE_VIBRATION); 144 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_PSMV_RUMBLE_VIBRATION); 145 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_INDEX_HAPTIC); 146 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_VIVE_HAPTIC); 147 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_WMR_HAPTIC); 209 + /* 210 + * Invalid values handled below. 211 + */ 148 212 149 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_XBOX_HAPTIC_LEFT); 150 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_XBOX_HAPTIC_RIGHT); 151 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_XBOX_HAPTIC_LEFT_TRIGGER); 152 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_XBOX_HAPTIC_RIGHT_TRIGGER); 213 + uint32_t id = XRT_GET_OUTPUT_ID(name); 214 + enum xrt_output_type type = XRT_GET_OUTPUT_TYPE(name); 215 + const char *str = get_xrt_output_type_short_str(type); 153 216 154 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_TOUCH_HAPTIC); 155 - 156 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT); 157 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT); 158 - 159 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_G2_CONTROLLER_HAPTIC); 160 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_ODYSSEY_CONTROLLER_HAPTIC); 161 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_ML2_CONTROLLER_VIBRATION); 162 - 163 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_PSSENSE_VIBRATION); 164 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_PSSENSE_TRIGGER_FEEDBACK); 165 - 166 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_VIVE_TRACKER_HAPTIC); 167 - 168 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_OPPO_MR_HAPTIC); 169 - 170 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_PICO_NEO3_HAPTIC); 171 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_PICO4_HAPTIC); 172 - 173 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_VIVE_COSMOS_HAPTIC); 174 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_VIVE_FOCUS3_HAPTIC); 175 - 176 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC); 177 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC_TRIGGER); 178 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC_THUMB); 179 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_TOUCH_PLUS_HAPTIC); 180 - 181 - XRT_OUTPUT_CASE(XRT_OUTPUT_NAME_PSVR2_HAPTIC); 182 - } 183 - 184 - #undef XRT_OUTPUT_CASE 217 + u_pp(dg, "XRT_OUTPUT_0x%04x_%s", id, str); 185 218 } 186 219 187 220 void ··· 234 267 case XRT_OPERATION_CANCELLED: DG("XRT_OPERATION_CANCELLED"); return; 235 268 case XRT_ERROR_FUTURE_RESULT_NOT_READY: DG("XRT_ERROR_FUTURE_RESULT_NOT_READY"); return; 236 269 case XRT_ERROR_FUTURE_ALREADY_COMPLETE: DG("XRT_ERROR_FUTURE_ALREADY_COMPLETE"); return; 270 + case XRT_ERROR_DEVICE_NOT_ATTACHABLE: DG("XRT_ERROR_DEVICE_NOT_ATTACHABLE"); return; 237 271 } 238 272 // clang-format on 239 273
+43
src/xrt/auxiliary/util/u_pretty_print.h
··· 29 29 * they can easily be chained together to form a debug message printing out 30 30 * various information. Most of the final logging functions in Monado inserts a 31 31 * newline at the end of the message and we don't want two to be inserted. 32 + * 33 + * There are also helpers that goes from an enum to a string that that doesn't 34 + * use the delegate to do the printing, these returns string that are compiled 35 + * into the binary. They will return 'UNKNOWN' if they don't know the value. 36 + * But can be made to return NULL on unknown. 32 37 */ 38 + 39 + /*! 40 + * Returns a string of the input name, or NULL if invalid. 41 + * 42 + * @ingroup aux_pretty 43 + */ 44 + const char * 45 + u_str_xrt_input_name_or_null(enum xrt_input_name name); 46 + 47 + /*! 48 + * Returns a string of the output name, or NULL if invalid. 49 + * 50 + * @ingroup aux_pretty 51 + */ 52 + const char * 53 + u_str_xrt_output_name_or_null(enum xrt_output_name name); 54 + 55 + /*! 56 + * Returns a string of the device name, or NULL if invalid. 57 + * 58 + * @ingroup aux_pretty 59 + */ 60 + const char * 61 + u_str_xrt_device_name_or_null(enum xrt_device_name name); 62 + 63 + #define U_STR_NO_NULL(NAME, TYPE) \ 64 + static inline const char *NAME(TYPE enumerate) \ 65 + { \ 66 + const char *str = NAME##_or_null(enumerate); \ 67 + return str != NULL ? str : "UNKNOWN"; \ 68 + } 69 + 70 + U_STR_NO_NULL(u_str_xrt_input_name, enum xrt_input_name) 71 + U_STR_NO_NULL(u_str_xrt_output_name, enum xrt_output_name) 72 + U_STR_NO_NULL(u_str_xrt_device_name, enum xrt_device_name) 73 + 74 + #undef U_STR_NO_NULL 75 + 33 76 34 77 /*! 35 78 * Function prototype for receiving pretty printed strings.
+132 -18
src/xrt/auxiliary/util/u_space_overseer.c
··· 1 1 // Copyright 2023, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 42 43 U_SPACE_TYPE_POSE, 43 44 U_SPACE_TYPE_OFFSET, 44 45 U_SPACE_TYPE_ROOT, 46 + 47 + /*! 48 + * Space designed to be attachable to others, most importantly it is 49 + * re-attachable, and in order to move all of the spaces that has this 50 + * space as it's parent/next we need a node that can be updated. 51 + */ 52 + U_SPACE_TYPE_ATTACHABLE, 45 53 }; 46 54 47 55 /*! ··· 330 338 m_relation_chain_push_relation(xrc, &xsr); 331 339 } break; 332 340 case U_SPACE_TYPE_OFFSET: m_relation_chain_push_pose_if_not_identity(xrc, &space->offset.pose); break; 333 - case U_SPACE_TYPE_ROOT: return; // Stops the traversing. 341 + case U_SPACE_TYPE_ROOT: return; // Stops the traversing. 342 + case U_SPACE_TYPE_ATTACHABLE: break; // No-op 334 343 } 335 344 336 345 // Please tail-call optimise this miss compiler. ··· 352 361 case U_SPACE_TYPE_NULL: break; 353 362 case U_SPACE_TYPE_POSE: break; 354 363 case U_SPACE_TYPE_OFFSET: break; 355 - case U_SPACE_TYPE_ROOT: return; // Stops the traversing. 364 + case U_SPACE_TYPE_ROOT: return; // Stops the traversing. 365 + case U_SPACE_TYPE_ATTACHABLE: break; // No-op 356 366 } 357 367 358 368 // Can't tail-call optimise this one :( ··· 371 381 } break; 372 382 case U_SPACE_TYPE_OFFSET: m_relation_chain_push_inverted_pose_if_not_identity(xrc, &space->offset.pose); break; 373 383 case U_SPACE_TYPE_ROOT: assert(false); // Should not get here. 384 + case U_SPACE_TYPE_ATTACHABLE: break; // No-op 374 385 } 375 386 } 376 387 ··· 469 480 470 481 // Created with one reference. 471 482 uso->base.semantic.root = &us->base; 483 + } 484 + 485 + 486 + /* 487 + * 488 + * Device helpers. 489 + * 490 + */ 491 + 492 + /*! 493 + * Helper function to add a device to the space overseer. This function 494 + * handles creating or finding a space for the device's tracking origin 495 + * and linking the device to that space. 496 + */ 497 + static xrt_result_t 498 + add_device_helper(struct u_space_overseer *uso, struct xrt_device *xdev) 499 + { 500 + struct xrt_tracking_origin *torig = xdev->tracking_origin; 501 + assert(torig != NULL); 502 + 503 + struct xrt_space *root = uso->base.semantic.root; 504 + uint64_t key = (uint64_t)(intptr_t)torig; 505 + struct xrt_space *xs = NULL; 506 + 507 + // Need to take the write lock. 508 + pthread_rwlock_wrlock(&uso->lock); 509 + 510 + // Does this tracking origin already have space. 511 + void *ptr = NULL; 512 + u_hashmap_int_find(uso->xto_map, key, &ptr); 513 + 514 + if (ptr != NULL) { 515 + xs = (struct xrt_space *)ptr; 516 + } else if (torig->type == XRT_TRACKING_TYPE_ATTACHABLE) { 517 + /* 518 + * If we ever make u_space_overseer sub-classable make sure 519 + * this calls the right function, can't call interface function 520 + * as the lock is held here. 521 + */ 522 + xs = (struct xrt_space *)create_space(U_SPACE_TYPE_ATTACHABLE, u_space(root)); 523 + u_hashmap_int_insert(uso->xto_map, key, xs); 524 + } else { 525 + /* 526 + * If we ever make u_space_overseer sub-classable make sure 527 + * this calls the right function, can't call interface function 528 + * as the lock is held here. 529 + */ 530 + xs = (struct xrt_space *)create_space(U_SPACE_TYPE_OFFSET, u_space(root)); 531 + 532 + update_offset_write_locked(u_space(xs), &torig->initial_offset); 533 + 534 + u_hashmap_int_insert(uso->xto_map, key, xs); 535 + } 536 + 537 + pthread_rwlock_unlock(&uso->lock); 538 + 539 + u_space_overseer_link_space_to_device(uso, xs, xdev); 540 + 541 + return XRT_SUCCESS; 472 542 } 473 543 474 544 ··· 1033 1103 return xret; 1034 1104 } 1035 1105 1106 + static xrt_result_t 1107 + add_device(struct xrt_space_overseer *xso, struct xrt_device *xdev) 1108 + { 1109 + struct u_space_overseer *uso = u_space_overseer(xso); 1110 + 1111 + return add_device_helper(uso, xdev); 1112 + } 1113 + 1114 + static xrt_result_t 1115 + attach_device(struct xrt_space_overseer *xso, struct xrt_device *xdev, struct xrt_space *space) 1116 + { 1117 + struct u_space_overseer *uso = u_space_overseer(xso); 1118 + 1119 + // Check that the device has the correct tracking origin type. 1120 + if (xdev->tracking_origin == NULL || xdev->tracking_origin->type != XRT_TRACKING_TYPE_ATTACHABLE) { 1121 + U_LOG_E("Device '%s' does not have XRT_TRACKING_TYPE_ATTACHABLE tracking origin type", xdev->str); 1122 + return XRT_ERROR_DEVICE_NOT_ATTACHABLE; 1123 + } 1124 + 1125 + // If no space is provided, use the root space. 1126 + struct xrt_space *target_space = space; 1127 + if (target_space == NULL) { 1128 + target_space = uso->base.semantic.root; 1129 + } 1130 + 1131 + xrt_result_t xret = XRT_SUCCESS; 1132 + pthread_rwlock_wrlock(&uso->lock); 1133 + 1134 + 1135 + void *ptr = NULL; 1136 + uint64_t key = (uint64_t)(intptr_t)xdev->tracking_origin; 1137 + u_hashmap_int_find(uso->xto_map, key, &ptr); 1138 + if (ptr == NULL) { 1139 + U_LOG_E("Device doesn't have space associated with it!"); 1140 + xret = XRT_ERROR_DEVICE_NOT_ATTACHABLE; 1141 + goto err_unlock; 1142 + } 1143 + 1144 + struct u_space *us = (struct u_space *)ptr; 1145 + if (us->type != U_SPACE_TYPE_ATTACHABLE) { 1146 + U_LOG_E("Device doesn't have a attachable space!"); 1147 + xret = XRT_ERROR_DEVICE_NOT_ATTACHABLE; 1148 + goto err_unlock; 1149 + } 1150 + 1151 + // Update the link. 1152 + u_space_reference(&us->next, u_space(target_space)); 1153 + 1154 + err_unlock: 1155 + pthread_rwlock_unlock(&uso->lock); 1156 + 1157 + return xret; 1158 + } 1159 + 1036 1160 static void 1037 1161 destroy(struct xrt_space_overseer *xso) 1038 1162 { ··· 1089 1213 uso->base.set_tracking_origin_offset = set_tracking_origin_offset; 1090 1214 uso->base.get_reference_space_offset = get_reference_space_offset; 1091 1215 uso->base.set_reference_space_offset = set_reference_space_offset; 1216 + uso->base.add_device = add_device; 1217 + uso->base.attach_device = attach_device; 1092 1218 uso->base.destroy = destroy; 1093 1219 uso->broadcast = broadcast; 1094 1220 ··· 1117 1243 bool root_is_unbounded, 1118 1244 bool per_app_local_spaces) 1119 1245 { 1120 - struct xrt_space *root = uso->base.semantic.root; // Convenience 1121 1246 uso->per_app_local_spaces = per_app_local_spaces; 1122 1247 1248 + // Add all devices to the space overseer. 1123 1249 for (uint32_t i = 0; i < xdev_count; i++) { 1124 - struct xrt_device *xdev = xdevs[i]; 1125 - struct xrt_tracking_origin *torig = xdev->tracking_origin; 1126 - uint64_t key = (uint64_t)(intptr_t)torig; 1127 - struct xrt_space *xs = NULL; 1128 - 1129 - void *ptr = NULL; 1130 - u_hashmap_int_find(uso->xto_map, key, &ptr); 1131 - 1132 - if (ptr != NULL) { 1133 - xs = (struct xrt_space *)ptr; 1134 - } else { 1135 - u_space_overseer_create_offset_space(uso, root, &torig->initial_offset, &xs); 1136 - u_hashmap_int_insert(uso->xto_map, key, xs); 1250 + xrt_result_t xret = add_device_helper(uso, xdevs[i]); 1251 + if (xret != XRT_SUCCESS) { 1252 + U_LOG_E("Failed to add device '%s' to space overseer!", xdevs[i]->str); 1137 1253 } 1138 - 1139 - u_space_overseer_link_space_to_device(uso, xs, xdev); 1140 1254 } 1141 1255 1142 1256 // If these are set something is probably wrong, but just in case unset them.
-2
src/xrt/auxiliary/vive/vive_poses.c
··· 12 12 #include "math/m_mathinclude.h" 13 13 #include "math/m_api.h" 14 14 15 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 16 - 17 15 static void 18 16 vive_poses_apply_right_transform(struct xrt_vec3 *out_transform_position, struct xrt_vec3 *out_transform_rotation) 19 17 {
+8 -2
src/xrt/auxiliary/vk/vk_bundle_init.c
··· 241 241 242 242 vk->features.timestamp_compute_and_graphics = pdp.limits.timestampComputeAndGraphics; 243 243 vk->features.timestamp_period = pdp.limits.timestampPeriod; 244 - vk->features.max_per_stage_descriptor_sampled_images = pdp.limits.maxPerStageDescriptorSampledImages; 245 - vk->features.max_per_stage_descriptor_storage_images = pdp.limits.maxPerStageDescriptorStorageImages; 244 + 245 + vk->limits.max_sampler_allocation_count = pdp.limits.maxSamplerAllocationCount; 246 + vk->limits.max_bound_descriptor_sets = pdp.limits.maxBoundDescriptorSets; 247 + vk->limits.max_descriptor_set_samplers = pdp.limits.maxDescriptorSetSamplers; 248 + vk->limits.max_descriptor_set_sampled_images = pdp.limits.maxDescriptorSetSampledImages; 249 + vk->limits.max_per_stage_descriptor_samplers = pdp.limits.maxPerStageDescriptorSamplers; 250 + vk->limits.max_per_stage_descriptor_sampled_images = pdp.limits.maxPerStageDescriptorSampledImages; 251 + vk->limits.max_per_stage_descriptor_storage_images = pdp.limits.maxPerStageDescriptorStorageImages; 246 252 247 253 248 254 /*
+24 -6
src/xrt/auxiliary/vk/vk_helpers.h
··· 200 200 //! Were timeline semaphore requested, available, and enabled? 201 201 bool timeline_semaphore; 202 202 203 - //! Per stage limit on sampled images (includes combined). 204 - uint32_t max_per_stage_descriptor_sampled_images; 205 - 206 - //! Per stage limit on storage images. 207 - uint32_t max_per_stage_descriptor_storage_images; 208 - 209 203 //! Was synchronization2 requested, available, and enabled? 210 204 bool synchronization_2; 211 205 ··· 215 209 //! Was KHR_video_maintenance1 requested, available, and enabled? 216 210 bool video_maintenance_1; 217 211 } features; 212 + 213 + struct 214 + { 215 + //! Maximum number of sampler objects, as created by vkCreateSampler, which can simultaneously exist on 216 + uint32_t max_sampler_allocation_count; 217 + 218 + //! Maximum number of descriptor sets that can be simultaneously used by a pipeline. 219 + uint32_t max_bound_descriptor_sets; 220 + 221 + //! Maximum number of samplers that can be included in a pipeline layout. 222 + uint32_t max_descriptor_set_samplers; 223 + 224 + //! Maximum number of sampled images that can be included in a pipeline layout. 225 + uint32_t max_descriptor_set_sampled_images; 226 + 227 + //! Maximum number of samplers that can be accessible to a single shader stage in a pipeline layout. 228 + uint32_t max_per_stage_descriptor_samplers; 229 + 230 + //! Per stage limit on sampled images (includes combined). 231 + uint32_t max_per_stage_descriptor_sampled_images; 232 + 233 + //! Per stage limit on storage images. 234 + uint32_t max_per_stage_descriptor_storage_images; 235 + } limits; 218 236 219 237 //! Is the GPU a tegra device. 220 238 bool is_tegra;
+5 -2
src/xrt/compositor/main/comp_compositor.c
··· 1132 1132 struct xrt_system_compositor_info sys_info_storage = {0}; 1133 1133 struct xrt_system_compositor_info *sys_info = &sys_info_storage; 1134 1134 1135 - // Required by OpenXR spec. 1136 - sys_info->max_layers = XRT_MAX_LAYERS; 1135 + // Required by OpenXR spec (minimum 16). 1136 + sys_info->max_layers = render_max_layers_capable( // 1137 + get_vk(c), // 1138 + c->settings.use_compute, // 1139 + XRT_MAX_LAYERS); // 1137 1140 sys_info->compositor_vk_deviceUUID = c->settings.selected_gpu_deviceUUID; 1138 1141 sys_info->client_vk_deviceUUID = c->settings.client_gpu_deviceUUID; 1139 1142 sys_info->client_d3d_deviceLUID = c->settings.client_gpu_deviceLUID;
+4 -1
src/xrt/compositor/multi/comp_multi_system.c
··· 423 423 .fb_face_tracking2_enabled = false, 424 424 .meta_body_tracking_full_body_enabled = false, 425 425 .meta_body_tracking_calibration_enabled = false, 426 + .android_face_tracking_enabled = false, 426 427 }; 427 428 428 429 switch (msc->sessions.state) { ··· 591 592 */ 592 593 593 594 static xrt_result_t 594 - system_compositor_set_state(struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused) 595 + system_compositor_set_state( 596 + struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused, int64_t timestamp_ns) 595 597 { 596 598 struct multi_system_compositor *msc = multi_system_compositor(xsc); 597 599 struct multi_compositor *mc = multi_compositor(xc); ··· 606 608 xse.type = XRT_SESSION_EVENT_STATE_CHANGE; 607 609 xse.state.visible = visible; 608 610 xse.state.focused = focused; 611 + xse.state.timestamp_ns = timestamp_ns; 609 612 610 613 return multi_compositor_push_event(mc, &xse); 611 614 }
+7 -1
src/xrt/compositor/null/null_compositor.c
··· 268 268 { 269 269 struct xrt_system_compositor_info *sys_info = &c->sys_info; 270 270 271 - // Required by OpenXR spec. 271 + /* 272 + * Required by OpenXR spec (minimum 16). 273 + * 274 + * NOTE: When using Vulkan compositor components (c/render, c/util), 275 + * call render_max_layers_capable() to clamp this value based on 276 + * actual device limits. 277 + */ 272 278 sys_info->max_layers = XRT_MAX_LAYERS; 273 279 274 280 uint32_t view_count = xdev->hmd->view_count;
+25 -2
src/xrt/compositor/render/render_interface.h
··· 59 59 #define RENDER_MAX_LAYERS (XRT_MAX_LAYERS) 60 60 61 61 /*! 62 + * The maximum number samplers per view that can be used by the compute shader 63 + * for layer composition (layer.comp) 64 + */ 65 + #define RENDER_CS_MAX_SAMPLERS_PER_VIEW 2 66 + 67 + /*! 62 68 * Max number of images that can be given at a single time to the layer 63 69 * squasher in a single dispatch. 64 70 */ 65 - #define RENDER_MAX_IMAGES_SIZE (RENDER_MAX_LAYERS * XRT_MAX_VIEWS) 66 - #define RENDER_MAX_IMAGES_COUNT(RENDER_RESOURCES) (RENDER_MAX_LAYERS * RENDER_RESOURCES->view_count) 71 + #define RENDER_MAX_IMAGES_SIZE (RENDER_MAX_LAYERS * RENDER_CS_MAX_SAMPLERS_PER_VIEW) 67 72 68 73 /*! 69 74 * Maximum number of times that the layer squasher shader can run per ··· 88 93 //! The binding that the shared layer fragment shader has its source on. 89 94 #define RENDER_BINDING_LAYER_SHARED_SRC 1 90 95 96 + /*! 97 + * The maximum number samplers per view that can be used by the compute shader 98 + * for layer composition (layer.comp) 99 + */ 100 + #define RENDER_CS_MAX_SAMPLERS_PER_VIEW 2 91 101 92 102 /* 93 103 * 94 104 * Util functions. 95 105 * 96 106 */ 107 + 108 + /*! 109 + * Determines the maximum number of compositor layers supported based on Vulkan 110 + * device limits and the composition path being used. 111 + * 112 + * @param vk Vulkan bundle containing device properties 113 + * @param use_compute True if using compute pipeline path, false for graphics 114 + * @param desired_max_layers Maximum layers requested by the compositor 115 + * @return Actual maximum layers supported, clamped by device limits (minimum 16) 116 + * 117 + */ 118 + uint32_t 119 + render_max_layers_capable(const struct vk_bundle *vk, bool use_compute, uint32_t desired_max_layers); 97 120 98 121 /*! 99 122 * Create a simplified projection matrix for timewarp.
+1 -1
src/xrt/compositor/render/render_resources.c
··· 543 543 r->compute.ubo_binding = 3; 544 544 545 545 r->compute.layer.image_array_size = 546 - MIN(vk->features.max_per_stage_descriptor_sampled_images, RENDER_MAX_IMAGES_COUNT(r)); 546 + MIN(vk->limits.max_per_stage_descriptor_sampled_images, RENDER_MAX_IMAGES_SIZE); 547 547 548 548 549 549 /*
+49
src/xrt/compositor/render/render_util.c
··· 87 87 * 88 88 */ 89 89 90 + uint32_t 91 + render_max_layers_capable(const struct vk_bundle *vk, bool use_compute, uint32_t desired_max_layers) 92 + { 93 + /*! 94 + * Graphics pipeline: 95 + * 96 + * This path has no relevant Vulkan device limits that would 97 + * constrain the maximum number of layers (each layer uses a single descriptor 98 + * set bound individually per draw). 99 + */ 100 + if (!use_compute) { 101 + // The min required by OpenXR spec is 16. 102 + return MAX(desired_max_layers, 16); 103 + } 104 + 105 + /*! 106 + * Compute pipeline: 107 + * 108 + * Clamp max layers based on compute pipeline descriptor limits. 109 + * 110 + * The compute path uses an array of combined image samplers, with 111 + * @ref samplers_per_layer samplers needed per layer. We check both the 112 + * per-stage sampler and sampled image limits, then calculate the 113 + * maximum number of complete layers that fit within those limits. 114 + */ 115 + uint32_t desired_image_sampler_count = desired_max_layers * RENDER_CS_MAX_SAMPLERS_PER_VIEW; 116 + 117 + const uint32_t max_sizes[] = { 118 + vk->limits.max_per_stage_descriptor_samplers, 119 + vk->limits.max_per_stage_descriptor_sampled_images, 120 + }; 121 + for (uint32_t i = 0; i < ARRAY_SIZE(max_sizes); ++i) { 122 + desired_image_sampler_count = MIN(desired_image_sampler_count, max_sizes[i]); 123 + } 124 + 125 + const uint32_t calculated_max_layers = desired_image_sampler_count / RENDER_CS_MAX_SAMPLERS_PER_VIEW; 126 + 127 + if (calculated_max_layers < 16) { 128 + VK_WARN(vk, 129 + "Device supports only %u compositor layers due to Vulkan limits. " 130 + "which is below Vulkan minimum of 16. " 131 + "This may indicate a driver bug. Attempting 16 anyway.", 132 + calculated_max_layers); 133 + } 134 + 135 + // The min required by OpenXR spec is 16. 136 + return MAX(calculated_max_layers, 16); 137 + } 138 + 90 139 void 91 140 render_calc_time_warp_matrix(const struct xrt_pose *src_pose, 92 141 const struct xrt_fov *src_fov,
+1 -6
src/xrt/drivers/android/android_sensors.c
··· 133 133 args->tray_to_lens_distance_meters = params.tray_to_lens_distance; 134 134 } 135 135 136 - #define DEG_TO_RAD(x) (float)(x * M_PI / 180.0) 137 136 args->fov = (struct xrt_fov){.angle_left = -DEG_TO_RAD(angles[0]), 138 137 .angle_right = DEG_TO_RAD(angles[1]), 139 138 .angle_down = -DEG_TO_RAD(angles[2]), 140 139 .angle_up = DEG_TO_RAD(angles[3])}; 141 - #undef DEG_TO_RAD 142 140 143 141 ANDROID_INFO(d, "loaded calibration for device %s (%s)", model, vendor); 144 142 ··· 354 352 struct android_device *d = U_DEVICE_ALLOCATE(struct android_device, flags, 1, 0); 355 353 356 354 d->base.name = XRT_DEVICE_GENERIC_HMD; 357 - d->base.destroy = android_device_destroy; 358 - d->base.update_inputs = u_device_noop_update_inputs; 359 - d->base.set_output = u_device_ni_set_output; 360 - d->base.get_tracked_pose = android_device_get_tracked_pose; 355 + u_device_populate_function_pointers(&d->base, android_device_get_tracked_pose, android_device_destroy); 361 356 d->base.get_view_poses = u_device_get_view_poses; 362 357 d->base.get_visibility_mask = u_device_get_visibility_mask; 363 358 d->base.compute_distortion = android_device_compute_distortion;
+2 -2
src/xrt/drivers/arduino/arduino_device.c
··· 405 405 406 406 m_imu_3dof_init(&ad->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_300MS); 407 407 408 - #define DEG_TO_RAD ((double)M_PI / 180.0) 408 + #define DEG_TO_RAD_MULTIPLIER ((double)M_PI / 180.0) 409 409 float accel_ticks_to_float = (4.0 * MATH_GRAVITY_M_S2) / INT16_MAX; 410 - float gyro_ticks_to_float = (2000.0 * DEG_TO_RAD) / INT16_MAX; 410 + float gyro_ticks_to_float = (2000.0 * DEG_TO_RAD_MULTIPLIER) / INT16_MAX; 411 411 412 412 m_imu_pre_filter_init(&ad->pre_filter, accel_ticks_to_float, gyro_ticks_to_float); 413 413 m_imu_pre_filter_set_switch_x_and_y(&ad->pre_filter);
+1 -5
src/xrt/drivers/euroc/euroc_device.c
··· 206 206 xd->inputs[0].name = XRT_INPUT_SIMPLE_GRIP_POSE; 207 207 } 208 208 209 - xd->update_inputs = u_device_noop_update_inputs; 210 - xd->get_tracked_pose = euroc_device_get_tracked_pose; 211 - xd->destroy = euroc_device_destroy; 209 + u_device_populate_function_pointers(xd, euroc_device_get_tracked_pose, euroc_device_destroy); 212 210 if (is_hmd) { 213 211 xd->get_view_poses = u_device_get_view_poses; 214 - } else { 215 - xd->get_view_poses = u_device_ni_get_view_poses; 216 212 } 217 213 218 214 u_var_add_root(ed, dev_name, false);
+1 -3
src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp
··· 513 513 cemud[i]->base.inputs[CEMU_INDEX_GRIP].name = XRT_INPUT_HAND_CTRL_EMU_GRIP_POSE; 514 514 cemud[i]->base.inputs[CEMU_INDEX_AIM].name = XRT_INPUT_HAND_CTRL_EMU_AIM_POSE; 515 515 516 + u_device_populate_function_pointers(&cemud[i]->base, cemu_device_get_tracked_pose, cemu_device_destroy); 516 517 cemud[i]->base.update_inputs = cemu_device_update_inputs; 517 - cemud[i]->base.get_tracked_pose = cemu_device_get_tracked_pose; 518 - cemud[i]->base.set_output = u_device_ni_set_output; 519 518 cemud[i]->base.get_hand_tracking = cemu_device_get_hand_tracking; 520 - cemud[i]->base.destroy = cemu_device_destroy; 521 519 522 520 cemud[i]->base.device_type = 523 521 i ? XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER : XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER;
+2 -6
src/xrt/drivers/hydra/hydra_driver.c
··· 345 345 (XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) | 346 346 (XRT_SPACE_RELATION_POSITION_TRACKED_BIT | XRT_SPACE_RELATION_POSITION_VALID_BIT); 347 347 348 - m_relation_history_estimate_motion(state->relation_history, &space_relation, now, &space_relation); 349 - 350 - m_relation_history_push(state->relation_history, &space_relation, now); 348 + m_relation_history_push_with_motion_estimation(state->relation_history, &space_relation, now); 351 349 352 350 state->buttons = hydra_read_uint8(&buf); 353 351 ··· 799 797 for (size_t i = 0; i < 2; ++i) { 800 798 struct hydra_device *hd = hs->devs[i]; 801 799 802 - hd->base.destroy = hydra_device_destroy; 800 + u_device_populate_function_pointers(&hd->base, hydra_device_get_tracked_pose, hydra_device_destroy); 803 801 hd->base.update_inputs = hydra_device_update_inputs; 804 - hd->base.get_tracked_pose = hydra_device_get_tracked_pose; 805 - hd->base.set_output = u_device_ni_set_output; 806 802 hd->base.name = XRT_DEVICE_HYDRA; 807 803 snprintf(hd->base.str, XRT_DEVICE_NAME_LEN, "%s %i", "Razer Hydra Controller", (int)(i + 1)); 808 804 snprintf(hd->base.serial, XRT_DEVICE_NAME_LEN, "%s%i", "RZRHDRC", (int)(i + 1));
+2 -5
src/xrt/drivers/ohmd/oh_device.c
··· 757 757 758 758 enum u_device_alloc_flags flags = U_DEVICE_ALLOC_HMD; 759 759 struct oh_device *ohd = U_DEVICE_ALLOCATE(struct oh_device, flags, 1, 0); 760 + u_device_populate_function_pointers(&ohd->base, oh_device_get_tracked_pose, oh_device_destroy); 760 761 ohd->base.update_inputs = oh_device_update_inputs; 761 - ohd->base.get_tracked_pose = oh_device_get_tracked_pose; 762 762 ohd->base.get_view_poses = u_device_get_view_poses; 763 - ohd->base.destroy = oh_device_destroy; 764 763 ohd->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE; 765 764 ohd->base.name = XRT_DEVICE_GENERIC_HMD; 766 765 ohd->ctx = ctx; ··· 1074 1073 1075 1074 enum u_device_alloc_flags flags = 0; 1076 1075 struct oh_device *ohd = U_DEVICE_ALLOCATE(struct oh_device, flags, input_count, output_count); 1076 + u_device_populate_function_pointers(&ohd->base, oh_device_get_tracked_pose, oh_device_destroy); 1077 1077 ohd->base.update_inputs = oh_device_update_inputs; 1078 1078 ohd->base.set_output = oh_device_set_output; 1079 - ohd->base.get_tracked_pose = oh_device_get_tracked_pose; 1080 - ohd->base.get_view_poses = u_device_ni_get_view_poses; 1081 - ohd->base.destroy = oh_device_destroy; 1082 1079 if (oculus_touch) { 1083 1080 ohd->ohmd_device_type = OPENHMD_OCULUS_RIFT_CONTROLLER; 1084 1081 ohd->base.name = XRT_DEVICE_TOUCH_CONTROLLER;
-2
src/xrt/drivers/pssense/pssense_driver.c
··· 43 43 44 44 DEBUG_GET_ONCE_LOG_OPTION(pssense_log, "PSSENSE_LOG", U_LOGGING_INFO) 45 45 46 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 47 - 48 46 static struct xrt_binding_input_pair simple_inputs_pssense[4] = { 49 47 {XRT_INPUT_SIMPLE_SELECT_CLICK, XRT_INPUT_PSSENSE_TRIGGER_VALUE}, 50 48 {XRT_INPUT_SIMPLE_MENU_CLICK, XRT_INPUT_PSSENSE_OPTIONS_CLICK},
+1 -4
src/xrt/drivers/realsense/rs_ddev.c
··· 448 448 449 449 U_LOG_D("Realsense opts are %i %i %i %i %i\n", rs->enable_mapping, rs->enable_pose_jumping, 450 450 rs->enable_relocalization, rs->enable_pose_prediction, rs->enable_pose_filtering); 451 - rs->base.update_inputs = u_device_noop_update_inputs; 452 - rs->base.get_tracked_pose = rs_ddev_get_tracked_pose; 453 - rs->base.get_view_poses = u_device_ni_get_view_poses; 454 - rs->base.destroy = rs_ddev_destroy; 451 + u_device_populate_function_pointers(&rs->base, rs_ddev_get_tracked_pose, rs_ddev_destroy); 455 452 rs->base.name = XRT_DEVICE_REALSENSE; 456 453 rs->base.tracking_origin->type = XRT_TRACKING_TYPE_EXTERNAL_SLAM; 457 454
+1 -4
src/xrt/drivers/remote/r_device.c
··· 193 193 struct r_device, flags, input_count, output_count); 194 194 195 195 // Setup the basics. 196 + u_device_populate_function_pointers(&rd->base, r_device_get_tracked_pose, r_device_destroy); 196 197 rd->base.update_inputs = r_device_update_inputs; 197 - rd->base.get_tracked_pose = r_device_get_tracked_pose; 198 198 rd->base.get_hand_tracking = r_device_get_hand_tracking; 199 - rd->base.get_view_poses = u_device_ni_get_view_poses; 200 - rd->base.set_output = u_device_ni_set_output; 201 - rd->base.destroy = r_device_destroy; 202 199 rd->base.tracking_origin = &r->origin; 203 200 rd->base.supported.orientation_tracking = true; 204 201 rd->base.supported.position_tracking = true;
+1 -5
src/xrt/drivers/remote/r_hmd.c
··· 124 124 struct r_hmd, flags, input_count, output_count); 125 125 126 126 // Setup the basics. 127 - rh->base.update_inputs = u_device_noop_update_inputs; 128 - rh->base.get_tracked_pose = r_hmd_get_tracked_pose; 129 - rh->base.get_hand_tracking = u_device_ni_get_hand_tracking; 127 + u_device_populate_function_pointers(&rh->base, r_hmd_get_tracked_pose, r_hmd_destroy); 130 128 rh->base.get_view_poses = r_hmd_get_view_poses; 131 - rh->base.set_output = u_device_ni_set_output; 132 - rh->base.destroy = r_hmd_destroy; 133 129 rh->base.tracking_origin = &r->origin; 134 130 rh->base.supported.orientation_tracking = true; 135 131 rh->base.supported.position_tracking = true;
-1
src/xrt/drivers/rift/rift_interface.h
··· 37 37 #define IMU_SAMPLE_RATE (1000) // 1000hz 38 38 #define NS_PER_SAMPLE (1000 * 1000) // 1ms (1,000,000 ns) per sample 39 39 40 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.0) 41 40 #define MICROMETERS_TO_METERS(microns) (float)microns / 1000000.0f 42 41 43 42 // value taken from LibOVR 0.4.4
+1 -5
src/xrt/drivers/rift_s/rift_s_controller.c
··· 40 40 /* Set to 1 to print controller states continuously */ 41 41 #define DUMP_CONTROLLER_STATE 0 42 42 43 - #define DEG_TO_RAD(D) ((D)*M_PI / 180.) 44 - 45 43 static struct xrt_binding_input_pair simple_inputs_rift_s[4] = { 46 44 {XRT_INPUT_SIMPLE_SELECT_CLICK, XRT_INPUT_TOUCH_TRIGGER_VALUE}, 47 45 {XRT_INPUT_SIMPLE_MENU_CLICK, XRT_INPUT_TOUCH_MENU_CLICK}, ··· 606 604 607 605 os_mutex_init(&ctrl->mutex); 608 606 607 + u_device_populate_function_pointers(&ctrl->base, rift_s_controller_get_tracked_pose, rift_s_controller_destroy); 609 608 ctrl->base.update_inputs = rift_s_controller_update_inputs; 610 - ctrl->base.set_output = u_device_ni_set_output; 611 - ctrl->base.get_tracked_pose = rift_s_controller_get_tracked_pose; 612 609 ctrl->base.get_view_poses = u_device_get_view_poses; 613 - ctrl->base.destroy = rift_s_controller_destroy; 614 610 ctrl->base.name = XRT_DEVICE_TOUCH_CONTROLLER; 615 611 ctrl->base.device_type = device_type; 616 612
-2
src/xrt/drivers/rift_s/rift_s_hmd.c
··· 40 40 41 41 #include "rift_s_hmd.h" 42 42 43 - #define DEG_TO_RAD(D) ((D)*M_PI / 180.) 44 - 45 43 46 44 static xrt_result_t 47 45 rift_s_get_tracked_pose(struct xrt_device *xdev,
-2
src/xrt/drivers/simula/svr_hmd.c
··· 97 97 return XRT_SUCCESS; 98 98 } 99 99 100 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 101 - 102 100 static xrt_result_t 103 101 svr_hmd_get_view_poses(struct xrt_device *xdev, 104 102 const struct xrt_vec3 *default_eye_relation,
+1 -5
src/xrt/drivers/simulated/simulated_controller.c
··· 347 347 348 348 // Allocate. 349 349 struct simulated_device *sd = U_DEVICE_ALLOCATE(struct simulated_device, flags, input_count, output_count); 350 + u_device_populate_function_pointers(&sd->base, simulated_device_get_tracked_pose, simulated_device_destroy); 350 351 sd->base.update_inputs = simulated_device_update_inputs; 351 - sd->base.get_tracked_pose = simulated_device_get_tracked_pose; 352 - sd->base.get_hand_tracking = u_device_ni_get_hand_tracking; 353 - sd->base.get_view_poses = u_device_ni_get_view_poses; 354 - sd->base.set_output = u_device_ni_set_output; 355 - sd->base.destroy = simulated_device_destroy; 356 352 sd->base.tracking_origin = origin; 357 353 sd->base.supported.orientation_tracking = true; 358 354 sd->base.supported.position_tracking = true;
+14 -22
src/xrt/drivers/steamvr_lh/device.cpp
··· 662 662 const auto it = std::ranges::lower_bound(joint_history, desired_timestamp_ns, {}, 663 663 [](const JointsWithTimestamp &joint) { return joint.timestamp; }); 664 664 665 - auto predict_joint_set = [out_value, out_timestamp_ns, 666 - desired_timestamp_ns](const JointsWithTimestamp &joints) { 667 - out_value->is_active = joints.joint_set.is_active; 668 - int64_t delta_ns = desired_timestamp_ns - joints.timestamp; 669 - double delta_s = time_ns_to_s(delta_ns); 670 - 671 - *out_timestamp_ns = desired_timestamp_ns; 672 - m_predict_relation(&joints.joint_set.hand_pose, delta_s, &out_value->hand_pose); 673 - for (int i = 0; i < XRT_HAND_JOINT_COUNT; i++) { 674 - auto &new_joint = joints.joint_set.values.hand_joint_set_default[i]; 675 - auto &interp_joint = out_value->values.hand_joint_set_default[i]; 676 - 677 - m_predict_relation(&new_joint.relation, delta_s, &interp_joint.relation); 678 - interp_joint.radius = new_joint.radius; 679 - } 680 - }; 681 - 682 665 if (it == joint_history.end()) { 683 666 // Timestamp is newer than anything in history 684 - predict_joint_set(joint_history.back()); 667 + *out_value = joint_history.back().joint_set; 668 + *out_timestamp_ns = it->timestamp; 685 669 } else if (desired_timestamp_ns == it->timestamp) { 686 670 *out_value = it->joint_set; 687 671 *out_timestamp_ns = it->timestamp; 688 672 } else if (it == joint_history.begin()) { 689 673 // Timestamp is older than anything in history 690 - predict_joint_set(joint_history.front()); 674 + *out_value = joint_history.front().joint_set; 675 + *out_timestamp_ns = it->timestamp; 691 676 } else { 692 677 // Interpolate 693 678 auto it_previous = it - 1; ··· 1061 1046 relation.linear_velocity = copy_vec3(newPose.vecVelocity); 1062 1047 relation.angular_velocity = copy_vec3(newPose.vecAngularVelocity); 1063 1048 1064 - math_quat_rotate_vec3(&relation.pose.orientation, &relation.angular_velocity, &relation.angular_velocity); 1049 + // local transform (head to driver offset) 1050 + const xrt_pose local = copy_pose(newPose.qDriverFromHeadRotation, newPose.vecDriverFromHeadTranslation); 1051 + 1052 + // IMU linear velocity contribution due to rotation around driver origin (tangential velocity) 1053 + xrt_vec3 tangential_velocity; 1054 + math_vec3_cross(&relation.angular_velocity, &local.position, &tangential_velocity); 1055 + math_quat_rotate_vec3(&relation.pose.orientation, &tangential_velocity, &tangential_velocity); 1056 + math_vec3_accum(&tangential_velocity, &relation.linear_velocity); 1065 1057 1066 - // apply over local transform 1067 - const xrt_pose local = copy_pose(newPose.qDriverFromHeadRotation, newPose.vecDriverFromHeadTranslation); 1058 + // apply local transform 1059 + math_quat_rotate_vec3(&relation.pose.orientation, &relation.angular_velocity, &relation.angular_velocity); 1068 1060 math_pose_transform(&relation.pose, &local, &relation.pose); 1069 1061 1070 1062 // apply world transform
+1 -4
src/xrt/drivers/twrap/twrap_slam.c
··· 159 159 160 160 161 161 162 - dx->base.update_inputs = u_device_noop_update_inputs; 163 - dx->base.get_tracked_pose = twrap_slam_get_tracked_pose; 164 - dx->base.get_view_poses = u_device_ni_get_view_poses; 165 - dx->base.destroy = twrap_slam_destroy; 162 + u_device_populate_function_pointers(&dx->base, twrap_slam_get_tracked_pose, twrap_slam_destroy); 166 163 dx->base.name = name; 167 164 dx->base.tracking_origin->type = XRT_TRACKING_TYPE_OTHER; 168 165 dx->base.inputs[0].name = XRT_INPUT_GENERIC_TRACKER_POSE;
+4 -2
src/xrt/drivers/wmr/wmr_controller_base.c
··· 526 526 wmr_controller_base_init(struct wmr_controller_base *wcb, 527 527 struct wmr_controller_connection *conn, 528 528 enum xrt_device_type controller_type, 529 - enum u_logging_level log_level) 529 + enum u_logging_level log_level, 530 + u_device_destroy_function_t destroy_fn) 530 531 { 531 532 DRV_TRACE_MARKER(); 532 533 ··· 544 545 snprintf(wcb->base.serial, XRT_DEVICE_NAME_LEN, "Right Controller"); 545 546 } 546 547 547 - wcb->base.get_tracked_pose = wmr_controller_base_get_tracked_pose; 548 + // Set all functions. 549 + u_device_populate_function_pointers(&wcb->base, wmr_controller_base_get_tracked_pose, destroy_fn); 548 550 549 551 wcb->base.name = XRT_DEVICE_WMR_CONTROLLER; 550 552 wcb->base.device_type = controller_type;
+3 -1
src/xrt/drivers/wmr/wmr_controller_base.h
··· 16 16 17 17 #include "os/os_threading.h" 18 18 #include "math/m_imu_3dof.h" 19 + #include "util/u_device.h" 19 20 #include "util/u_logging.h" 20 21 #include "xrt/xrt_device.h" 21 22 ··· 129 130 wmr_controller_base_init(struct wmr_controller_base *wcb, 130 131 struct wmr_controller_connection *conn, 131 132 enum xrt_device_type controller_type, 132 - enum u_logging_level log_level); 133 + enum u_logging_level log_level, 134 + u_device_destroy_function_t destroy_fn); 133 135 134 136 void 135 137 wmr_controller_base_deinit(struct wmr_controller_base *wcb);
+3 -5
src/xrt/drivers/wmr/wmr_controller_hp.c
··· 360 360 U_DEVICE_ALLOCATE(struct wmr_controller_hp, flags, WMR_CONTROLLER_INDEX_COUNT, 1); 361 361 struct wmr_controller_base *wcb = (struct wmr_controller_base *)(ctrl); 362 362 363 - if (!wmr_controller_base_init(wcb, conn, controller_type, log_level)) { 363 + if (!wmr_controller_base_init(wcb, conn, controller_type, log_level, wmr_controller_hp_destroy)) { 364 364 wmr_controller_hp_destroy(&wcb->base); 365 365 return NULL; 366 366 } 367 367 368 368 wcb->handle_input_packet = handle_input_packet; 369 369 370 + // Only set those we want to overwrite. 371 + wcb->base.update_inputs = wmr_controller_hp_update_inputs; 370 372 wcb->base.name = XRT_DEVICE_HP_REVERB_G2_CONTROLLER; 371 373 372 374 if (controller_type == XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER) { ··· 374 376 } else { 375 377 snprintf(wcb->base.str, ARRAY_SIZE(wcb->base.str), "HP Reverb G2 Right Controller"); 376 378 } 377 - 378 - wcb->base.destroy = wmr_controller_hp_destroy; 379 - wcb->base.update_inputs = wmr_controller_hp_update_inputs; 380 - wcb->base.set_output = u_device_ni_set_output; 381 379 382 380 SET_INPUT(wcb, MENU_CLICK, MENU_CLICK); 383 381 SET_INPUT(wcb, HOME_CLICK, HOME_CLICK);
+4 -4
src/xrt/drivers/wmr/wmr_controller_og.c
··· 413 413 struct wmr_controller_og *ctrl = U_DEVICE_ALLOCATE(struct wmr_controller_og, flags, 11, 1); 414 414 struct wmr_controller_base *wcb = (struct wmr_controller_base *)(ctrl); 415 415 416 - if (!wmr_controller_base_init(wcb, conn, controller_type, log_level)) { 416 + if (!wmr_controller_base_init(wcb, conn, controller_type, log_level, wmr_controller_og_destroy)) { 417 417 wmr_controller_og_destroy(&wcb->base); 418 418 return NULL; 419 419 } 420 420 421 421 wcb->handle_input_packet = handle_input_packet; 422 422 423 + // Only set those we want to overwrite. 424 + wcb->base.update_inputs = wmr_controller_og_update_inputs; 425 + 423 426 if (pid == ODYSSEY_CONTROLLER_PID) { 424 427 wcb->base.name = XRT_DEVICE_SAMSUNG_ODYSSEY_CONTROLLER; 425 428 } else { 426 429 wcb->base.name = XRT_DEVICE_WMR_CONTROLLER; 427 430 } 428 - wcb->base.destroy = wmr_controller_og_destroy; 429 - wcb->base.update_inputs = wmr_controller_og_update_inputs; 430 - wcb->base.set_output = u_device_ni_set_output; 431 431 432 432 if (pid == ODYSSEY_CONTROLLER_PID) { 433 433 SET_ODYSSEY_INPUT(wcb, MENU_CLICK);
+6 -3
src/xrt/include/xrt/xrt_compositor.h
··· 966 966 bool fb_face_tracking2_enabled; 967 967 bool meta_body_tracking_full_body_enabled; 968 968 bool meta_body_tracking_calibration_enabled; 969 + bool android_face_tracking_enabled; 969 970 }; 970 971 971 972 /*! ··· 2390 2391 xrt_result_t (*set_state)(struct xrt_system_compositor *xsc, 2391 2392 struct xrt_compositor *xc, 2392 2393 bool visible, 2393 - bool focused); 2394 + bool focused, 2395 + int64_t timestamp_ns); 2394 2396 2395 2397 /*! 2396 2398 * Set the rendering Z order for rendering, visible has higher priority ··· 2490 2492 * @public @memberof xrt_system_compositor 2491 2493 */ 2492 2494 static inline xrt_result_t 2493 - xrt_syscomp_set_state(struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused) 2495 + xrt_syscomp_set_state( 2496 + struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused, int64_t timestamp_ns) 2494 2497 { 2495 2498 if (xsc->xmcc == NULL) { 2496 2499 return XRT_ERROR_MULTI_SESSION_NOT_IMPLEMENTED; 2497 2500 } 2498 2501 2499 - return xsc->xmcc->set_state(xsc, xc, visible, focused); 2502 + return xsc->xmcc->set_state(xsc, xc, visible, focused, timestamp_ns); 2500 2503 } 2501 2504 2502 2505 /*!
+1
src/xrt/include/xrt/xrt_config_build.h.cmake_in
··· 37 37 #cmakedefine XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META 38 38 #cmakedefine XRT_FEATURE_OPENXR_DEBUG_UTILS 39 39 #cmakedefine XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE 40 + #cmakedefine XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID 40 41 #cmakedefine XRT_FEATURE_OPENXR_FACE_TRACKING2_FB 41 42 #cmakedefine XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC 42 43 #cmakedefine XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL
+277 -121
src/xrt/include/xrt/xrt_defines.h
··· 716 716 * 717 717 */ 718 718 719 + // clang-format off 720 + #define XRT_DEVICE_NAME_LIST(_) \ 721 + _(XRT_DEVICE_INVALID) \ 722 + \ 723 + _(XRT_DEVICE_GENERIC_HMD) \ 724 + \ 725 + /* Vive stuff. */ \ 726 + _(XRT_DEVICE_VIVE_PRO) \ 727 + _(XRT_DEVICE_VIVE_WAND) \ 728 + _(XRT_DEVICE_VIVE_TRACKER) /* Generic, only used for bindings. */ \ 729 + _(XRT_DEVICE_VIVE_TRACKER_GEN1) \ 730 + _(XRT_DEVICE_VIVE_TRACKER_GEN2) \ 731 + _(XRT_DEVICE_VIVE_TRACKER_GEN3) \ 732 + _(XRT_DEVICE_VIVE_TRACKER_TUNDRA) \ 733 + \ 734 + /* "Controllers" somewhat sorted as listed in spec. */\ 735 + _(XRT_DEVICE_SIMPLE_CONTROLLER) \ 736 + _(XRT_DEVICE_DAYDREAM) \ 737 + _(XRT_DEVICE_WMR_CONTROLLER) \ 738 + _(XRT_DEVICE_XBOX_CONTROLLER) \ 739 + _(XRT_DEVICE_GO_CONTROLLER) \ 740 + _(XRT_DEVICE_TOUCH_CONTROLLER) \ 741 + _(XRT_DEVICE_INDEX_CONTROLLER) \ 742 + \ 743 + _(XRT_DEVICE_HP_REVERB_G2_CONTROLLER) \ 744 + _(XRT_DEVICE_SAMSUNG_ODYSSEY_CONTROLLER) \ 745 + _(XRT_DEVICE_ML2_CONTROLLER) \ 746 + _(XRT_DEVICE_OPPO_MR_CONTROLLER) \ 747 + \ 748 + _(XRT_DEVICE_HAND_INTERACTION) \ 749 + \ 750 + _(XRT_DEVICE_EYE_GAZE_INTERACTION) \ 751 + \ 752 + _(XRT_DEVICE_PSMV) \ 753 + _(XRT_DEVICE_PSSENSE) \ 754 + _(XRT_DEVICE_HYDRA) \ 755 + _(XRT_DEVICE_RIFT_REMOTE) \ 756 + _(XRT_DEVICE_BLUBUR_S1) \ 757 + _(XRT_DEVICE_PSVR2) \ 758 + \ 759 + /* Other misc stuff. */\ 760 + _(XRT_DEVICE_HAND_TRACKER) \ 761 + _(XRT_DEVICE_REALSENSE) \ 762 + _(XRT_DEVICE_DEPTHAI) \ 763 + \ 764 + /*! XR_EXT_hand_interaction */\ 765 + _(XRT_DEVICE_EXT_HAND_INTERACTION) \ 766 + \ 767 + /*! XR_HTC_facial_tracking */\ 768 + _(XRT_DEVICE_HTC_FACE_TRACKING) \ 769 + \ 770 + /*! XR_FB_body_tracking */\ 771 + _(XRT_DEVICE_FB_BODY_TRACKING) \ 772 + \ 773 + /*! XR_FB_face_tracking2 */\ 774 + _(XRT_DEVICE_FB_FACE_TRACKING2) \ 775 + \ 776 + /* added in OpenXR 1.1 */\ 777 + _(XRT_DEVICE_PICO_NEO3_CONTROLLER) \ 778 + _(XRT_DEVICE_PICO4_CONTROLLER) \ 779 + _(XRT_DEVICE_PICO_G3_CONTROLLER) \ 780 + \ 781 + _(XRT_DEVICE_VIVE_COSMOS_CONTROLLER) \ 782 + _(XRT_DEVICE_VIVE_FOCUS3_CONTROLLER) \ 783 + \ 784 + _(XRT_DEVICE_TOUCH_PRO_CONTROLLER) \ 785 + _(XRT_DEVICE_TOUCH_PLUS_CONTROLLER) \ 786 + _(XRT_DEVICE_TOUCH_CONTROLLER_RIFT_CV1) \ 787 + _(XRT_DEVICE_TOUCH_CONTROLLER_QUEST_1_RIFT_S) \ 788 + _(XRT_DEVICE_TOUCH_CONTROLLER_QUEST_2) \ 789 + \ 790 + /* Hand based controller emulation. */\ 791 + _(XRT_DEVICE_HAND_CTRL_EMU) \ 792 + \ 793 + /* Please keep this comment and the trailing \ to reduce lines changed when adding entries. */ 794 + // clang-format on 795 + 719 796 /*! 720 797 * A enum that is used to name devices so that the 721 798 * state trackers can reason about the devices easier. 722 799 */ 723 800 enum xrt_device_name 724 801 { 725 - XRT_DEVICE_INVALID = 0, 802 + #define XRT_DEVICE_NAME_TO_ENUM(NAME) NAME, 726 803 727 - XRT_DEVICE_GENERIC_HMD = 1, 804 + XRT_DEVICE_NAME_LIST(XRT_DEVICE_NAME_TO_ENUM) 728 805 729 - // Vive stuff. 730 - XRT_DEVICE_VIVE_PRO, 731 - XRT_DEVICE_VIVE_WAND, 732 - XRT_DEVICE_VIVE_TRACKER, // Generic, only used for bindings. 733 - XRT_DEVICE_VIVE_TRACKER_GEN1, 734 - XRT_DEVICE_VIVE_TRACKER_GEN2, 735 - XRT_DEVICE_VIVE_TRACKER_GEN3, 736 - XRT_DEVICE_VIVE_TRACKER_TUNDRA, 737 - 738 - // "Controllers" somewhat sorted as listed in spec. 739 - XRT_DEVICE_SIMPLE_CONTROLLER, 740 - XRT_DEVICE_DAYDREAM, 741 - XRT_DEVICE_WMR_CONTROLLER, 742 - XRT_DEVICE_XBOX_CONTROLLER, 743 - XRT_DEVICE_GO_CONTROLLER, 744 - XRT_DEVICE_TOUCH_CONTROLLER, 745 - XRT_DEVICE_INDEX_CONTROLLER, 746 - 747 - XRT_DEVICE_HP_REVERB_G2_CONTROLLER, 748 - XRT_DEVICE_SAMSUNG_ODYSSEY_CONTROLLER, 749 - XRT_DEVICE_ML2_CONTROLLER, 750 - XRT_DEVICE_OPPO_MR_CONTROLLER, 751 - 752 - XRT_DEVICE_HAND_INTERACTION, 753 - 754 - XRT_DEVICE_EYE_GAZE_INTERACTION, 755 - 756 - XRT_DEVICE_PSMV, 757 - XRT_DEVICE_PSSENSE, 758 - XRT_DEVICE_HYDRA, 759 - XRT_DEVICE_RIFT_REMOTE, 760 - XRT_DEVICE_BLUBUR_S1, 761 - XRT_DEVICE_PSVR2, 762 - 763 - // Other misc stuff. 764 - XRT_DEVICE_HAND_TRACKER, 765 - XRT_DEVICE_REALSENSE, 766 - XRT_DEVICE_DEPTHAI, 767 - 768 - //! XR_EXT_hand_interaction 769 - XRT_DEVICE_EXT_HAND_INTERACTION, 770 - 771 - //! XR_HTC_facial_tracking 772 - XRT_DEVICE_HTC_FACE_TRACKING, 773 - 774 - //! XR_FB_body_tracking 775 - XRT_DEVICE_FB_BODY_TRACKING, 776 - 777 - //! XR_FB_face_tracking2 778 - XRT_DEVICE_FB_FACE_TRACKING2, 779 - 780 - // added in OpenXR 1.1 781 - XRT_DEVICE_PICO_NEO3_CONTROLLER, 782 - XRT_DEVICE_PICO4_CONTROLLER, 783 - XRT_DEVICE_PICO_G3_CONTROLLER, 784 - 785 - XRT_DEVICE_VIVE_COSMOS_CONTROLLER, 786 - XRT_DEVICE_VIVE_FOCUS3_CONTROLLER, 787 - 788 - XRT_DEVICE_TOUCH_PRO_CONTROLLER, 789 - XRT_DEVICE_TOUCH_PLUS_CONTROLLER, 790 - XRT_DEVICE_TOUCH_CONTROLLER_RIFT_CV1, 791 - XRT_DEVICE_TOUCH_CONTROLLER_QUEST_1_RIFT_S, 792 - XRT_DEVICE_TOUCH_CONTROLLER_QUEST_2, 793 - 794 - // Hand based controller emulation. 795 - XRT_DEVICE_HAND_CTRL_EMU, 806 + #undef XRT_DEVICE_NAME_TO_ENUM 796 807 }; 797 808 798 809 /*! ··· 1170 1181 _(XRT_INPUT_HTC_LIP_FACE_TRACKING , XRT_INPUT_NAME(0x0602, FACE_TRACKING)) \ 1171 1182 _(XRT_INPUT_FB_FACE_TRACKING2_AUDIO , XRT_INPUT_NAME(0x0603, FACE_TRACKING)) \ 1172 1183 _(XRT_INPUT_FB_FACE_TRACKING2_VISUAL , XRT_INPUT_NAME(0x0604, FACE_TRACKING)) \ 1184 + _(XRT_INPUT_ANDROID_FACE_TRACKING , XRT_INPUT_NAME(0x0605, FACE_TRACKING)) \ 1173 1185 \ 1174 1186 _(XRT_INPUT_GENERIC_BODY_TRACKING , XRT_INPUT_NAME(0x0700, BODY_TRACKING)) \ 1175 1187 _(XRT_INPUT_FB_BODY_TRACKING , XRT_INPUT_NAME(0x0701, BODY_TRACKING)) \ ··· 1481 1493 #define XRT_OUTPUT_TYPE_BITMASK 0xffu 1482 1494 1483 1495 /*! 1496 + * @brief Create an enum value for xrt_output_name that packs an ID and output 1497 + * type. 1498 + * 1499 + * @param id an integer 1500 + * @param type The suffix of an xrt_output_type value name: `XRT_OUTPUT_TYPE_` is 1501 + * prepended automatically. 1502 + * 1503 + * @see xrt_output_name 1504 + * @ingroup xrt_iface 1505 + */ 1506 + #define XRT_OUTPUT_NAME(id, type) ((UINT32_C(id) << XRT_OUTPUT_TYPE_BITWIDTH) | (uint32_t)XRT_OUTPUT_TYPE_##type) 1507 + 1508 + /*! 1509 + * @brief Extract the xrt_output_type from an xrt_output_name. 1510 + * 1511 + * @param name An xrt_output_name value 1512 + * 1513 + * @relates xrt_output_name 1514 + * @returns @ref xrt_output_type 1515 + * @ingroup xrt_iface 1516 + */ 1517 + #define XRT_GET_OUTPUT_TYPE(name) ((enum xrt_output_type)(name & XRT_OUTPUT_TYPE_BITMASK)) 1518 + 1519 + /*! 1520 + * @brief Extract the xrt_output_name id from an xrt_output_name. 1521 + * 1522 + * @param name An xrt_output_name value 1523 + * 1524 + * @relates xrt_output_name 1525 + * @returns The extracted id. 1526 + * @ingroup xrt_iface 1527 + */ 1528 + #define XRT_GET_OUTPUT_ID(name) ((uint32_t)(name >> XRT_OUTPUT_TYPE_BITWIDTH)) 1529 + 1530 + /*! 1484 1531 * Base type of this output. 1485 1532 * 1486 1533 * @ingroup xrt_iface ··· 1493 1540 // clang-format on 1494 1541 }; 1495 1542 1496 - #define XRT_OUTPUT_NAME(id, type) ((UINT32_C(id) << XRT_OUTPUT_TYPE_BITWIDTH) | (uint32_t)XRT_OUTPUT_TYPE_##type) 1543 + // clang-format off 1544 + #define XRT_OUTPUT_LIST(_) \ 1545 + _(XRT_OUTPUT_NAME_SIMPLE_VIBRATION , XRT_OUTPUT_NAME(0x0010, VIBRATION)) \ 1546 + _(XRT_OUTPUT_NAME_PSMV_RUMBLE_VIBRATION , XRT_OUTPUT_NAME(0x0020, VIBRATION)) \ 1547 + _(XRT_OUTPUT_NAME_INDEX_HAPTIC , XRT_OUTPUT_NAME(0x0030, VIBRATION)) \ 1548 + _(XRT_OUTPUT_NAME_VIVE_HAPTIC , XRT_OUTPUT_NAME(0x0040, VIBRATION)) \ 1549 + _(XRT_OUTPUT_NAME_WMR_HAPTIC , XRT_OUTPUT_NAME(0x0050, VIBRATION)) \ 1550 + \ 1551 + _(XRT_OUTPUT_NAME_XBOX_HAPTIC_LEFT , XRT_OUTPUT_NAME(0x0060, VIBRATION)) \ 1552 + _(XRT_OUTPUT_NAME_XBOX_HAPTIC_RIGHT , XRT_OUTPUT_NAME(0x0061, VIBRATION)) \ 1553 + _(XRT_OUTPUT_NAME_XBOX_HAPTIC_LEFT_TRIGGER , XRT_OUTPUT_NAME(0x0062, VIBRATION)) \ 1554 + _(XRT_OUTPUT_NAME_XBOX_HAPTIC_RIGHT_TRIGGER , XRT_OUTPUT_NAME(0x0063, VIBRATION)) \ 1555 + \ 1556 + _(XRT_OUTPUT_NAME_TOUCH_HAPTIC , XRT_OUTPUT_NAME(0x0070, VIBRATION)) \ 1557 + \ 1558 + _(XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT , XRT_OUTPUT_NAME(0x0080, FORCE_FEEDBACK)) \ 1559 + _(XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT , XRT_OUTPUT_NAME(0x0081, FORCE_FEEDBACK)) \ 1560 + \ 1561 + _(XRT_OUTPUT_NAME_G2_CONTROLLER_HAPTIC , XRT_OUTPUT_NAME(0x0090, VIBRATION)) \ 1562 + _(XRT_OUTPUT_NAME_ODYSSEY_CONTROLLER_HAPTIC , XRT_OUTPUT_NAME(0x00A0, VIBRATION)) \ 1563 + _(XRT_OUTPUT_NAME_ML2_CONTROLLER_VIBRATION , XRT_OUTPUT_NAME(0x00B0, VIBRATION)) \ 1564 + \ 1565 + _(XRT_OUTPUT_NAME_PSSENSE_VIBRATION , XRT_OUTPUT_NAME(0x00C0, VIBRATION)) \ 1566 + _(XRT_OUTPUT_NAME_PSSENSE_TRIGGER_FEEDBACK , XRT_OUTPUT_NAME(0x00C1, FORCE_FEEDBACK)) \ 1567 + \ 1568 + _(XRT_OUTPUT_NAME_VIVE_TRACKER_HAPTIC , XRT_OUTPUT_NAME(0x00D0, VIBRATION)) \ 1569 + \ 1570 + _(XRT_OUTPUT_NAME_OPPO_MR_HAPTIC , XRT_OUTPUT_NAME(0x00E0, VIBRATION)) \ 1571 + \ 1572 + _(XRT_OUTPUT_NAME_PICO_NEO3_HAPTIC , XRT_OUTPUT_NAME(0x00F0, VIBRATION)) \ 1573 + _(XRT_OUTPUT_NAME_PICO4_HAPTIC , XRT_OUTPUT_NAME(0x0100, VIBRATION)) \ 1574 + \ 1575 + _(XRT_OUTPUT_NAME_VIVE_COSMOS_HAPTIC , XRT_OUTPUT_NAME(0x0200, VIBRATION)) \ 1576 + _(XRT_OUTPUT_NAME_VIVE_FOCUS3_HAPTIC , XRT_OUTPUT_NAME(0x0300, VIBRATION)) \ 1577 + \ 1578 + _(XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC , XRT_OUTPUT_NAME(0x0400, VIBRATION)) \ 1579 + _(XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC_TRIGGER , XRT_OUTPUT_NAME(0x0500, VIBRATION)) \ 1580 + _(XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC_THUMB , XRT_OUTPUT_NAME(0x0600, VIBRATION)) \ 1581 + _(XRT_OUTPUT_NAME_TOUCH_PLUS_HAPTIC , XRT_OUTPUT_NAME(0x0700, VIBRATION)) \ 1582 + \ 1583 + _(XRT_OUTPUT_NAME_PSVR2_HAPTIC , XRT_OUTPUT_NAME(0x0800, VIBRATION)) \ 1584 + \ 1585 + /* Please keep this comment and the trailing \ to reduce lines changed when adding entries. */ 1586 + // clang-format on 1587 + 1588 + /*! 1589 + * Name of a output with a baked in type. 1590 + * 1591 + * @see xrt_output_type 1592 + * @ingroup xrt_iface 1593 + */ 1594 + enum xrt_output_name 1595 + { 1596 + #define XRT_OUTPUT_LIST_TO_NAME_VALUE(NAME, VALUE) NAME = VALUE, 1597 + 1598 + XRT_OUTPUT_LIST(XRT_OUTPUT_LIST_TO_NAME_VALUE) 1599 + 1600 + #undef XRT_OUTPUT_LIST_TO_NAME_VALUE 1601 + }; 1497 1602 1498 1603 enum xrt_face_expression2_fb 1499 1604 { ··· 1660 1765 #define XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC 14 1661 1766 #define XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC 37 1662 1767 1768 + enum xrt_face_confidence_regions_android 1769 + { 1770 + XRT_FACE_CONFIDENCE_REGIONS_LOWER_ANDROID = 0, 1771 + XRT_FACE_CONFIDENCE_REGIONS_LEFT_UPPER_ANDROID = 1, 1772 + XRT_FACE_CONFIDENCE_REGIONS_RIGHT_UPPER_ANDROID = 2, 1773 + }; 1774 + 1775 + enum xrt_face_parameter_indices_android 1776 + { 1777 + XRT_FACE_PARAMETER_INDICES_BROW_LOWERER_L_ANDROID = 0, 1778 + XRT_FACE_PARAMETER_INDICES_BROW_LOWERER_R_ANDROID = 1, 1779 + XRT_FACE_PARAMETER_INDICES_CHEEK_PUFF_L_ANDROID = 2, 1780 + XRT_FACE_PARAMETER_INDICES_CHEEK_PUFF_R_ANDROID = 3, 1781 + XRT_FACE_PARAMETER_INDICES_CHEEK_RAISER_L_ANDROID = 4, 1782 + XRT_FACE_PARAMETER_INDICES_CHEEK_RAISER_R_ANDROID = 5, 1783 + XRT_FACE_PARAMETER_INDICES_CHEEK_SUCK_L_ANDROID = 6, 1784 + XRT_FACE_PARAMETER_INDICES_CHEEK_SUCK_R_ANDROID = 7, 1785 + XRT_FACE_PARAMETER_INDICES_CHIN_RAISER_B_ANDROID = 8, 1786 + XRT_FACE_PARAMETER_INDICES_CHIN_RAISER_T_ANDROID = 9, 1787 + XRT_FACE_PARAMETER_INDICES_DIMPLER_L_ANDROID = 10, 1788 + XRT_FACE_PARAMETER_INDICES_DIMPLER_R_ANDROID = 11, 1789 + XRT_FACE_PARAMETER_INDICES_EYES_CLOSED_L_ANDROID = 12, 1790 + XRT_FACE_PARAMETER_INDICES_EYES_CLOSED_R_ANDROID = 13, 1791 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_DOWN_L_ANDROID = 14, 1792 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_DOWN_R_ANDROID = 15, 1793 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_LEFT_L_ANDROID = 16, 1794 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_LEFT_R_ANDROID = 17, 1795 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_RIGHT_L_ANDROID = 18, 1796 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_RIGHT_R_ANDROID = 19, 1797 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_UP_L_ANDROID = 20, 1798 + XRT_FACE_PARAMETER_INDICES_EYES_LOOK_UP_R_ANDROID = 21, 1799 + XRT_FACE_PARAMETER_INDICES_INNER_BROW_RAISER_L_ANDROID = 22, 1800 + XRT_FACE_PARAMETER_INDICES_INNER_BROW_RAISER_R_ANDROID = 23, 1801 + XRT_FACE_PARAMETER_INDICES_JAW_DROP_ANDROID = 24, 1802 + XRT_FACE_PARAMETER_INDICES_JAW_SIDEWAYS_LEFT_ANDROID = 25, 1803 + XRT_FACE_PARAMETER_INDICES_JAW_SIDEWAYS_RIGHT_ANDROID = 26, 1804 + XRT_FACE_PARAMETER_INDICES_JAW_THRUST_ANDROID = 27, 1805 + XRT_FACE_PARAMETER_INDICES_LID_TIGHTENER_L_ANDROID = 28, 1806 + XRT_FACE_PARAMETER_INDICES_LID_TIGHTENER_R_ANDROID = 29, 1807 + XRT_FACE_PARAMETER_INDICES_LIP_CORNER_DEPRESSOR_L_ANDROID = 30, 1808 + XRT_FACE_PARAMETER_INDICES_LIP_CORNER_DEPRESSOR_R_ANDROID = 31, 1809 + XRT_FACE_PARAMETER_INDICES_LIP_CORNER_PULLER_L_ANDROID = 32, 1810 + XRT_FACE_PARAMETER_INDICES_LIP_CORNER_PULLER_R_ANDROID = 33, 1811 + XRT_FACE_PARAMETER_INDICES_LIP_FUNNELER_LB_ANDROID = 34, 1812 + XRT_FACE_PARAMETER_INDICES_LIP_FUNNELER_LT_ANDROID = 35, 1813 + XRT_FACE_PARAMETER_INDICES_LIP_FUNNELER_RB_ANDROID = 36, 1814 + XRT_FACE_PARAMETER_INDICES_LIP_FUNNELER_RT_ANDROID = 37, 1815 + XRT_FACE_PARAMETER_INDICES_LIP_PRESSOR_L_ANDROID = 38, 1816 + XRT_FACE_PARAMETER_INDICES_LIP_PRESSOR_R_ANDROID = 39, 1817 + XRT_FACE_PARAMETER_INDICES_LIP_PUCKER_L_ANDROID = 40, 1818 + XRT_FACE_PARAMETER_INDICES_LIP_PUCKER_R_ANDROID = 41, 1819 + XRT_FACE_PARAMETER_INDICES_LIP_STRETCHER_L_ANDROID = 42, 1820 + XRT_FACE_PARAMETER_INDICES_LIP_STRETCHER_R_ANDROID = 43, 1821 + XRT_FACE_PARAMETER_INDICES_LIP_SUCK_LB_ANDROID = 44, 1822 + XRT_FACE_PARAMETER_INDICES_LIP_SUCK_LT_ANDROID = 45, 1823 + XRT_FACE_PARAMETER_INDICES_LIP_SUCK_RB_ANDROID = 46, 1824 + XRT_FACE_PARAMETER_INDICES_LIP_SUCK_RT_ANDROID = 47, 1825 + XRT_FACE_PARAMETER_INDICES_LIP_TIGHTENER_L_ANDROID = 48, 1826 + XRT_FACE_PARAMETER_INDICES_LIP_TIGHTENER_R_ANDROID = 49, 1827 + XRT_FACE_PARAMETER_INDICES_LIPS_TOWARD_ANDROID = 50, 1828 + XRT_FACE_PARAMETER_INDICES_LOWER_LIP_DEPRESSOR_L_ANDROID = 51, 1829 + XRT_FACE_PARAMETER_INDICES_LOWER_LIP_DEPRESSOR_R_ANDROID = 52, 1830 + XRT_FACE_PARAMETER_INDICES_MOUTH_LEFT_ANDROID = 53, 1831 + XRT_FACE_PARAMETER_INDICES_MOUTH_RIGHT_ANDROID = 54, 1832 + XRT_FACE_PARAMETER_INDICES_NOSE_WRINKLER_L_ANDROID = 55, 1833 + XRT_FACE_PARAMETER_INDICES_NOSE_WRINKLER_R_ANDROID = 56, 1834 + XRT_FACE_PARAMETER_INDICES_OUTER_BROW_RAISER_L_ANDROID = 57, 1835 + XRT_FACE_PARAMETER_INDICES_OUTER_BROW_RAISER_R_ANDROID = 58, 1836 + XRT_FACE_PARAMETER_INDICES_UPPER_LID_RAISER_L_ANDROID = 59, 1837 + XRT_FACE_PARAMETER_INDICES_UPPER_LID_RAISER_R_ANDROID = 60, 1838 + XRT_FACE_PARAMETER_INDICES_UPPER_LIP_RAISER_L_ANDROID = 61, 1839 + XRT_FACE_PARAMETER_INDICES_UPPER_LIP_RAISER_R_ANDROID = 62, 1840 + XRT_FACE_PARAMETER_INDICES_TONGUE_OUT_ANDROID = 63, 1841 + XRT_FACE_PARAMETER_INDICES_TONGUE_LEFT_ANDROID = 64, 1842 + XRT_FACE_PARAMETER_INDICES_TONGUE_RIGHT_ANDROID = 65, 1843 + XRT_FACE_PARAMETER_INDICES_TONGUE_UP_ANDROID = 66, 1844 + XRT_FACE_PARAMETER_INDICES_TONGUE_DOWN_ANDROID = 67, 1845 + }; 1846 + 1847 + enum xrt_face_tracking_state_android 1848 + { 1849 + XRT_FACE_TRACKING_STATE_PAUSED_ANDROID = 0, 1850 + XRT_FACE_TRACKING_STATE_STOPPED_ANDROID = 1, 1851 + XRT_FACE_TRACKING_STATE_TRACKING_ANDROID = 2, 1852 + }; 1853 + 1854 + #define XRT_FACE_PARAMETER_COUNT_ANDROID 68 1855 + 1856 + #define XRT_FACE_REGION_CONFIDENCE_COUNT_ANDROID 3 1857 + 1663 1858 struct xrt_facial_base_expression_set_htc 1664 1859 { 1665 1860 int64_t sample_time_ns; ··· 1692 1887 bool is_eye_following_blendshapes_valid; 1693 1888 }; 1694 1889 1890 + struct xrt_facial_expression_set_android 1891 + { 1892 + // ordered by xrt_face_parameter_indices_android 1893 + float parameters[XRT_FACE_PARAMETER_COUNT_ANDROID]; 1894 + float region_confidences[XRT_FACE_REGION_CONFIDENCE_COUNT_ANDROID]; 1895 + 1896 + uint64_t sample_time_ns; 1897 + 1898 + XRT_ALIGNAS(8) bool is_valid; 1899 + }; 1900 + 1695 1901 struct xrt_facial_expression_set 1696 1902 { 1697 1903 union { ··· 1699 1905 struct xrt_facial_eye_expression_set_htc eye_expression_set_htc; 1700 1906 struct xrt_facial_lip_expression_set_htc lip_expression_set_htc; 1701 1907 struct xrt_facial_expression_set2_fb face_expression_set2_fb; 1908 + struct xrt_facial_expression_set_android face_expression_set_android; 1702 1909 }; 1703 1910 }; 1704 1911 ··· 1966 2173 }; 1967 2174 // in driver global space, without tracking_origin offset 1968 2175 struct xrt_space_relation body_pose; 1969 - }; 1970 - 1971 - /*! 1972 - * Name of a output with a baked in type. 1973 - * 1974 - * @see xrt_output_type 1975 - * @ingroup xrt_iface 1976 - */ 1977 - enum xrt_output_name 1978 - { 1979 - // clang-format off 1980 - XRT_OUTPUT_NAME_SIMPLE_VIBRATION = XRT_OUTPUT_NAME(0x0010, VIBRATION), 1981 - XRT_OUTPUT_NAME_PSMV_RUMBLE_VIBRATION = XRT_OUTPUT_NAME(0x0020, VIBRATION), 1982 - XRT_OUTPUT_NAME_INDEX_HAPTIC = XRT_OUTPUT_NAME(0x0030, VIBRATION), 1983 - XRT_OUTPUT_NAME_VIVE_HAPTIC = XRT_OUTPUT_NAME(0x0040, VIBRATION), 1984 - XRT_OUTPUT_NAME_WMR_HAPTIC = XRT_OUTPUT_NAME(0x0050, VIBRATION), 1985 - 1986 - XRT_OUTPUT_NAME_XBOX_HAPTIC_LEFT = XRT_OUTPUT_NAME(0x0060, VIBRATION), 1987 - XRT_OUTPUT_NAME_XBOX_HAPTIC_RIGHT = XRT_OUTPUT_NAME(0x0061, VIBRATION), 1988 - XRT_OUTPUT_NAME_XBOX_HAPTIC_LEFT_TRIGGER = XRT_OUTPUT_NAME(0x0062, VIBRATION), 1989 - XRT_OUTPUT_NAME_XBOX_HAPTIC_RIGHT_TRIGGER = XRT_OUTPUT_NAME(0x0063, VIBRATION), 1990 - 1991 - XRT_OUTPUT_NAME_TOUCH_HAPTIC = XRT_OUTPUT_NAME(0x0070, VIBRATION), 1992 - 1993 - XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT = XRT_OUTPUT_NAME(0x0080, FORCE_FEEDBACK), 1994 - XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT = XRT_OUTPUT_NAME(0x0081, FORCE_FEEDBACK), 1995 - 1996 - XRT_OUTPUT_NAME_G2_CONTROLLER_HAPTIC = XRT_OUTPUT_NAME(0x0090, VIBRATION), 1997 - XRT_OUTPUT_NAME_ODYSSEY_CONTROLLER_HAPTIC = XRT_OUTPUT_NAME(0x00A0, VIBRATION), 1998 - XRT_OUTPUT_NAME_ML2_CONTROLLER_VIBRATION = XRT_OUTPUT_NAME(0x00B0, VIBRATION), 1999 - 2000 - XRT_OUTPUT_NAME_PSSENSE_VIBRATION = XRT_OUTPUT_NAME(0x00C0, VIBRATION), 2001 - XRT_OUTPUT_NAME_PSSENSE_TRIGGER_FEEDBACK = XRT_OUTPUT_NAME(0x00C1, FORCE_FEEDBACK), 2002 - 2003 - XRT_OUTPUT_NAME_VIVE_TRACKER_HAPTIC = XRT_OUTPUT_NAME(0x00D0, VIBRATION), 2004 - 2005 - XRT_OUTPUT_NAME_OPPO_MR_HAPTIC = XRT_OUTPUT_NAME(0x00E0, VIBRATION), 2006 - 2007 - XRT_OUTPUT_NAME_PICO_NEO3_HAPTIC = XRT_OUTPUT_NAME(0x00F0, VIBRATION), 2008 - XRT_OUTPUT_NAME_PICO4_HAPTIC = XRT_OUTPUT_NAME(0x0100, VIBRATION), 2009 - 2010 - XRT_OUTPUT_NAME_VIVE_COSMOS_HAPTIC = XRT_OUTPUT_NAME(0x0200, VIBRATION), 2011 - XRT_OUTPUT_NAME_VIVE_FOCUS3_HAPTIC = XRT_OUTPUT_NAME(0x0300, VIBRATION), 2012 - 2013 - XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC = XRT_OUTPUT_NAME(0x0400, VIBRATION), 2014 - XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC_TRIGGER = XRT_OUTPUT_NAME(0x0500, VIBRATION), 2015 - XRT_OUTPUT_NAME_TOUCH_PRO_HAPTIC_THUMB = XRT_OUTPUT_NAME(0x0600, VIBRATION), 2016 - XRT_OUTPUT_NAME_TOUCH_PLUS_HAPTIC = XRT_OUTPUT_NAME(0x0700, VIBRATION), 2017 - 2018 - XRT_OUTPUT_NAME_PSVR2_HAPTIC = XRT_OUTPUT_NAME(0x0800, VIBRATION), 2019 - // clang-format on 2020 2176 }; 2021 2177 2022 2178 /*!
+23
src/xrt/include/xrt/xrt_device.h
··· 406 406 struct xrt_facial_expression_set *out_value); 407 407 408 408 /*! 409 + * @brief Gets the face tracking calibration state 410 + * 411 + * @param[in] xdev The device. 412 + * @param[in] out_value Is face tracking calibrated? 413 + * 414 + * @see xrt_input_name 415 + */ 416 + xrt_result_t (*get_face_calibration_state_android)(struct xrt_device *xdev, bool *out_face_is_calibrated); 417 + 418 + /*! 409 419 * @brief Get the body skeleton in T-pose, used to query the skeleton hierarchy, scale, proportions etc 410 420 * 411 421 * @param[in] xdev The device. ··· 753 763 struct xrt_facial_expression_set *out_value) 754 764 { 755 765 return xdev->get_face_tracking(xdev, facial_expression_type, at_timestamp_ns, out_value); 766 + } 767 + 768 + /*! 769 + * Helper function for @ref xrt_device::get_face_calibration_state_android. 770 + * 771 + * @copydoc xrt_device::get_face_calibration_state_android 772 + * 773 + * @public @memberof xrt_device 774 + */ 775 + static inline xrt_result_t 776 + xrt_device_get_face_calibration_state_android(struct xrt_device *xdev, bool *out_face_is_calibrated) 777 + { 778 + return xdev->get_face_calibration_state_android(xdev, out_face_is_calibrated); 756 779 } 757 780 758 781 /*!
+1
src/xrt/include/xrt/xrt_instance.h
··· 82 82 bool fb_face_tracking2_enabled; 83 83 bool meta_body_tracking_full_body_enabled; 84 84 bool meta_body_tracking_calibration_enabled; 85 + bool android_face_tracking_enabled; 85 86 }; 86 87 87 88 /*!
+7
src/xrt/include/xrt/xrt_limits.h
··· 10 10 11 11 #pragma once 12 12 13 + #include "xrt/xrt_config_os.h" 13 14 #include "xrt/xrt_compiler.h" 14 15 15 16 ··· 72 73 /*! 73 74 * Max number of layers which can be handled at once. 74 75 */ 76 + #ifdef XRT_OS_ANDROID 77 + #define XRT_MAX_LAYERS 32 78 + #elif defined(XRT_OS_LINUX) || defined(XRT_OS_WINDOWS) 75 79 #define XRT_MAX_LAYERS 128 80 + #else 81 + #error "Unknown platform, define XRT_MAX_LAYERS for your OS" 82 + #endif 76 83 77 84 /*! 78 85 * @}
+6
src/xrt/include/xrt/xrt_results.h
··· 251 251 * Invoking complete on an already completed future 252 252 */ 253 253 XRT_ERROR_FUTURE_ALREADY_COMPLETE = -41, 254 + 255 + /*! 256 + * The device's tracking origin is not of type 257 + * XRT_TRACKING_TYPE_ATTACHABLE. 258 + */ 259 + XRT_ERROR_DEVICE_NOT_ATTACHABLE = -42, 254 260 } xrt_result_t;
+1
src/xrt/include/xrt/xrt_session.h
··· 80 80 enum xrt_session_event_type type; 81 81 bool visible; 82 82 bool focused; 83 + int64_t timestamp_ns; 83 84 }; 84 85 85 86 /*!
+80
src/xrt/include/xrt/xrt_space.h
··· 1 1 // Copyright 2019-2023, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 303 304 struct xrt_space **out_local_space, 304 305 struct xrt_space **out_local_floor_space); 305 306 307 + /* 308 + * 309 + * Special inter-monado component functions. 310 + * 311 + */ 312 + 313 + /*! 314 + * Add a new device to be tracked by the space overseer. The exact 315 + * semantic of the space is determined by the implementation of the 316 + * space overseer. And may be outright rejected by the implementation. 317 + * 318 + * After this call completes successfully, the device can be passed 319 + * into the @ref xrt_space_overseer::locate_device function, but may 320 + * not be locatable immediately. 321 + * 322 + * This function is not intended to be called by the OpenXR state 323 + * tracker, but by other monado components that need to add devices 324 + * but does not own the space overseer. Components like the fixer 325 + * uppers or for push devices. 326 + * 327 + * @param[in] xso The space overseer. 328 + * @param[in] xdev The device to be tracked. 329 + * @return XRT_SUCCESS if added, otherwise an error code. 330 + */ 331 + xrt_result_t (*add_device)(struct xrt_space_overseer *xso, struct xrt_device *xdev); 332 + 333 + /*! 334 + * Attach a device to a different space then it was associated with 335 + * originally, the space overseer might not support this operation. 336 + * 337 + * For some space overseer implementations this operation requires 338 + * that the device has the tracking origin type of 339 + * @ref XRT_TRACKING_TYPE_ATTACHABLE. Which space that becomes the 340 + * parent space of the device when @p space is NULL is undefined, 341 + * and the device might become un-trackable. 342 + * 343 + * @param[in] xso Owning space overseer. 344 + * @param[in] xdev Device to attach. 345 + * @param[in] space Space to attach the device to, may be NULL. 346 + * 347 + * @return XRT_SUCCESS on success. 348 + * @return XRT_ERROR_DEVICE_NOT_ATTACHABLE if the device does not have 349 + * the XRT_TRACKING_TYPE_ATTACHABLE tracking origin type. 350 + */ 351 + xrt_result_t (*attach_device)(struct xrt_space_overseer *xso, struct xrt_device *xdev, struct xrt_space *space); 352 + 353 + 354 + /* 355 + * 356 + * Destroy function always comes last. 357 + * 358 + */ 359 + 306 360 /*! 307 361 * Destroy function. 308 362 * ··· 513 567 struct xrt_space **out_local_floor_space) 514 568 { 515 569 return xso->create_local_space(xso, out_local_space, out_local_floor_space); 570 + } 571 + 572 + /*! 573 + * @copydoc xrt_space_overseer::add_device 574 + * 575 + * Helper for calling through the function pointer. 576 + * 577 + * @public @memberof xrt_space_overseer 578 + */ 579 + static inline xrt_result_t 580 + xrt_space_overseer_add_device(struct xrt_space_overseer *xso, struct xrt_device *xdev) 581 + { 582 + return xso->add_device(xso, xdev); 583 + } 584 + 585 + /*! 586 + * @copydoc xrt_space_overseer::attach_device 587 + * 588 + * Helper for calling through the function pointer. 589 + * 590 + * @public @memberof xrt_space_overseer 591 + */ 592 + static inline xrt_result_t 593 + xrt_space_overseer_attach_device(struct xrt_space_overseer *xso, struct xrt_device *xdev, struct xrt_space *space) 594 + { 595 + return xso->attach_device(xso, xdev, space); 516 596 } 517 597 518 598 /*!
+4
src/xrt/include/xrt/xrt_tracking.h
··· 1 1 // Copyright 2019, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 60 61 61 62 // The device(s) are tracked by other methods. 62 63 XRT_TRACKING_TYPE_OTHER, 64 + 65 + // The device(s) are (re)attachable. 66 + XRT_TRACKING_TYPE_ATTACHABLE, 63 67 }; 64 68 65 69 /*!
+31 -3
src/xrt/ipc/CMakeLists.txt
··· 1 1 # Copyright 2020-2021, Collabora, Ltd. 2 + # Copyright 2025, NVIDIA CORPORATION. 2 3 # SPDX-License-Identifier: BSL-1.0 3 4 4 5 ### 6 + # Merge split protocol JSON files into single proto.json 7 + file(GLOB PROTO_JSON_FILES "${CMAKE_CURRENT_SOURCE_DIR}/shared/proto/*.json") 8 + 9 + merge_json_files( 10 + OUTPUT 11 + "${CMAKE_CURRENT_BINARY_DIR}/proto.json" 12 + SOURCES 13 + ${PROTO_JSON_FILES} 14 + IGNORE_SCHEMA 15 + ) 16 + 17 + ### 5 18 # Generator 6 19 7 20 foreach( ··· 16 29 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${fn}" 17 30 COMMAND 18 31 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py 19 - ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.json 20 - "${CMAKE_CURRENT_BINARY_DIR}/${fn}" 32 + ${CMAKE_CURRENT_BINARY_DIR}/proto.json "${CMAKE_CURRENT_BINARY_DIR}/${fn}" 21 33 VERBATIM 22 34 DEPENDS 23 35 ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py 24 36 ${CMAKE_CURRENT_SOURCE_DIR}/shared/ipcproto/common.py 25 - ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.json 37 + ${CMAKE_CURRENT_BINARY_DIR}/proto.json 26 38 ${CMAKE_CURRENT_SOURCE_DIR}/shared/ipc_protocol_generated.h.template 27 39 COMMENT "Generating ${fn} from protocol JSON description" 28 40 ) 29 41 endforeach() 42 + 43 + # Generate IPC structures list in the build root 44 + add_custom_command( 45 + OUTPUT "${CMAKE_BINARY_DIR}/ipc-structs.txt" 46 + COMMAND 47 + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py 48 + ${CMAKE_CURRENT_BINARY_DIR}/proto.json "${CMAKE_BINARY_DIR}/ipc-structs.txt" 49 + VERBATIM 50 + DEPENDS 51 + ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py 52 + ${CMAKE_CURRENT_SOURCE_DIR}/shared/ipcproto/common.py 53 + ${CMAKE_CURRENT_BINARY_DIR}/proto.json 54 + COMMENT "Generating ipc-structs.txt from protocol JSON description" 55 + ) 56 + 57 + add_custom_target(ipc_structs_list ALL DEPENDS "${CMAKE_BINARY_DIR}/ipc-structs.txt") 30 58 31 59 set(IPC_COMMON_SOURCES 32 60 ${CMAKE_CURRENT_BINARY_DIR}/ipc_protocol_generated.h
+1 -4
src/xrt/ipc/client/ipc_client_device.c
··· 86 86 ipc_client_device_t *icd = U_DEVICE_ALLOCATE(ipc_client_device_t, flags, 0, 0); 87 87 88 88 // Fills in almost everything a regular device needs. 89 - ipc_client_xdev_init(icd, ipc_c, xtrack, device_id); 90 - 91 - // Need to set the destroy function. 92 - icd->base.destroy = ipc_client_device_destroy; 89 + ipc_client_xdev_init(icd, ipc_c, xtrack, device_id, ipc_client_device_destroy); 93 90 94 91 // Setup variable tracker. 95 92 u_var_add_root(icd, icd->base.str, true);
+1 -2
src/xrt/ipc/client/ipc_client_hmd.c
··· 321 321 ipc_client_hmd_t *ich = U_DEVICE_ALLOCATE(ipc_client_hmd_t, flags, 0, 0); 322 322 323 323 // Fills in almost everything a regular device needs. 324 - ipc_client_xdev_init(ich, ipc_c, xtrack, device_id); 324 + ipc_client_xdev_init(ich, ipc_c, xtrack, device_id, ipc_client_hmd_destroy); 325 325 326 326 // Fill in needed HMD functions, and destroy. 327 327 ich->base.get_view_poses = ipc_client_hmd_get_view_poses; 328 328 ich->base.compute_distortion = ipc_client_hmd_compute_distortion; 329 329 ich->base.is_form_factor_available = ipc_client_hmd_is_form_factor_available; 330 330 ich->base.get_visibility_mask = ipc_client_hmd_get_visibility_mask; 331 - ich->base.destroy = ipc_client_hmd_destroy; 332 331 ich->base.get_brightness = ipc_client_hmd_get_brightness; 333 332 ich->base.set_brightness = ipc_client_hmd_set_brightness; 334 333
+16
src/xrt/ipc/client/ipc_client_space_overseer.c
··· 318 318 return ipc_call_space_set_reference_space_offset(icspo->ipc_c, type, offset); 319 319 } 320 320 321 + static xrt_result_t 322 + add_device(struct xrt_space_overseer *xso, struct xrt_device *xdev) 323 + { 324 + return XRT_ERROR_NOT_IMPLEMENTED; 325 + } 326 + 327 + static xrt_result_t 328 + attach_device(struct xrt_space_overseer *xso, struct xrt_device *xdev, struct xrt_space *space) 329 + { 330 + // For IPC client, attachable devices are handled on the server side. 331 + // This should not be called from the client in the typical use case. 332 + return XRT_ERROR_NOT_IMPLEMENTED; 333 + } 334 + 321 335 static void 322 336 destroy(struct xrt_space_overseer *xso) 323 337 { ··· 374 388 icspo->base.set_tracking_origin_offset = set_tracking_origin_offset; 375 389 icspo->base.get_reference_space_offset = get_reference_space_offset; 376 390 icspo->base.set_reference_space_offset = set_reference_space_offset; 391 + icspo->base.add_device = add_device; 392 + icspo->base.attach_device = attach_device; 377 393 icspo->base.destroy = destroy; 378 394 icspo->ipc_c = ipc_c; 379 395
+8 -9
src/xrt/ipc/client/ipc_client_xdev.c
··· 391 391 ipc_client_xdev_init(struct ipc_client_xdev *icx, 392 392 struct ipc_connection *ipc_c, 393 393 struct xrt_tracking_origin *xtrack, 394 - uint32_t device_id) 394 + uint32_t device_id, 395 + u_device_destroy_function_t destroy_fn) 395 396 { 396 397 // Helpers. 397 398 struct ipc_shared_memory *ism = ipc_c->ism; ··· 400 401 // Important fields. 401 402 icx->ipc_c = ipc_c; 402 403 icx->device_id = device_id; 404 + 405 + /* 406 + * Fill in not implemented or noop versions first, 407 + * destroy gets filled in by either device or HMD. 408 + */ 409 + u_device_populate_function_pointers(&icx->base, ipc_client_xdev_get_tracked_pose, destroy_fn); 403 410 404 411 // Shared implemented functions. 405 412 icx->base.update_inputs = ipc_client_xdev_update_inputs; 406 - icx->base.get_tracked_pose = ipc_client_xdev_get_tracked_pose; 407 413 icx->base.get_hand_tracking = ipc_client_xdev_get_hand_tracking; 408 414 icx->base.get_face_tracking = ipc_client_xdev_get_face_tracking; 409 415 icx->base.get_body_skeleton = ipc_client_xdev_get_body_skeleton; ··· 420 426 icx->base.destroy_plane_detection_ext = ipc_client_xdev_destroy_plane_detection_ext; 421 427 icx->base.get_plane_detection_state_ext = ipc_client_xdev_get_plane_detection_state_ext; 422 428 icx->base.get_plane_detections_ext = ipc_client_xdev_get_plane_detections_ext; 423 - 424 - // Not implemented functions, some get overridden. 425 - icx->base.get_view_poses = u_device_ni_get_view_poses; 426 - icx->base.compute_distortion = u_device_ni_compute_distortion; 427 - icx->base.get_visibility_mask = u_device_ni_get_visibility_mask; 428 - icx->base.is_form_factor_available = u_device_ni_is_form_factor_available; 429 - icx->base.get_battery_status = u_device_ni_get_battery_status; 430 429 431 430 // Copying the information from the isdev. 432 431 icx->base.device_type = isdev->device_type;
+5 -1
src/xrt/ipc/client/ipc_client_xdev.h
··· 13 13 14 14 #pragma once 15 15 16 + #include "util/u_device.h" 17 + 18 + 16 19 #ifdef __cplusplus 17 20 extern "C" { 18 21 #endif ··· 58 61 ipc_client_xdev_init(struct ipc_client_xdev *icx, 59 62 struct ipc_connection *ipc_c, 60 63 struct xrt_tracking_origin *xtrack, 61 - uint32_t device_id); 64 + uint32_t device_id, 65 + u_device_destroy_function_t destroy_fn); 62 66 63 67 /*! 64 68 * Frees any memory that was allocated as part of init and resets some pointers.
-3
src/xrt/ipc/server/ipc_server.h
··· 194 194 { 195 195 //! The actual device. 196 196 struct xrt_device *xdev; 197 - 198 - //! Is the IO suppressed for this device. 199 - bool io_active; 200 197 }; 201 198 202 199 /*!
+17 -17
src/xrt/ipc/server/ipc_server_handler.c
··· 1 1 // Copyright 2020-2024, Collabora, Ltd. 2 + // Copyright 2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 387 388 EXT(meta_body_tracking_full_body_enabled); 388 389 EXT(meta_body_tracking_calibration_enabled); 389 390 EXT(fb_face_tracking2_enabled); 391 + EXT(android_face_tracking_enabled); 390 392 391 393 #undef EXT 392 394 #undef PTT ··· 459 461 ics->xc = &xcn->base; 460 462 461 463 xrt_syscomp_set_state(ics->server->xsysc, ics->xc, ics->client_state.session_visible, 462 - ics->client_state.session_focused); 464 + ics->client_state.session_focused, os_monotonic_get_ns()); 463 465 xrt_syscomp_set_z_order(ics->server->xsysc, ics->xc, ics->client_state.z_order); 464 466 465 467 return XRT_SUCCESS; ··· 504 506 .fb_face_tracking2_enabled = ics->client_state.info.fb_face_tracking2_enabled, 505 507 .meta_body_tracking_full_body_enabled = ics->client_state.info.meta_body_tracking_full_body_enabled, 506 508 .meta_body_tracking_calibration_enabled = ics->client_state.info.meta_body_tracking_calibration_enabled, 509 + .android_face_tracking_enabled = ics->client_state.info.android_face_tracking_enabled, 507 510 }; 508 511 509 512 return xrt_comp_begin_session(ics->xc, &begin_session_info); ··· 1642 1645 } 1643 1646 1644 1647 xrt_result_t 1645 - ipc_handle_system_toggle_io_device(volatile struct ipc_client_state *ics, uint32_t device_id) 1646 - { 1647 - if (device_id >= IPC_MAX_DEVICES) { 1648 - return XRT_ERROR_IPC_FAILURE; 1649 - } 1650 - 1651 - struct ipc_device *idev = &ics->server->idevs[device_id]; 1652 - 1653 - idev->io_active = !idev->io_active; 1654 - 1655 - return XRT_SUCCESS; 1656 - } 1657 - 1658 - xrt_result_t 1659 1648 ipc_handle_swapchain_get_properties(volatile struct ipc_client_state *ics, 1660 1649 const struct xrt_swapchain_create_info *info, 1661 1650 struct xrt_swapchain_create_properties *xsccp) ··· 1950 1939 struct xrt_input *dst = &ism->inputs[isdev->first_input_index]; 1951 1940 size_t size = sizeof(struct xrt_input) * isdev->input_count; 1952 1941 1953 - bool io_active = ics->io_active && idev->io_active; 1942 + bool io_active = ics->io_active; 1954 1943 if (io_active) { 1955 1944 memcpy(dst, src, size); 1956 1945 } else { ··· 2005 1994 } 2006 1995 2007 1996 // Special case the headpose. 2008 - bool disabled = (!isdev->io_active || !ics->io_active) && name != XRT_INPUT_GENERIC_HEAD_POSE; 1997 + bool disabled = !ics->io_active && name != XRT_INPUT_GENERIC_HEAD_POSE; 2009 1998 bool active_on_client = input->active; 2010 1999 2011 2000 // We have been disabled but the client hasn't called update. ··· 2580 2569 GET_XDEV_OR_RETURN(ics, device_id, xdev); 2581 2570 // Get facial expression data. 2582 2571 return xrt_device_get_face_tracking(xdev, facial_expression_type, at_timestamp_ns, out_value); 2572 + } 2573 + 2574 + xrt_result_t 2575 + ipc_handle_device_device_get_face_calibration_state_android(volatile struct ipc_client_state *ics, 2576 + uint32_t id, 2577 + bool *out_face_is_calibrated) 2578 + { 2579 + const uint32_t device_id = id; 2580 + struct xrt_device *xdev = NULL; 2581 + GET_XDEV_OR_RETURN(ics, device_id, xdev); 2582 + return xrt_device_get_face_calibration_state_android(xdev, out_face_is_calibrated); 2583 2583 } 2584 2584 2585 2585 xrt_result_t
+21 -22
src/xrt/ipc/server/ipc_server_process.c
··· 98 98 static void 99 99 init_idev(struct ipc_device *idev, struct xrt_device *xdev) 100 100 { 101 - if (xdev != NULL) { 102 - idev->io_active = true; 103 - idev->xdev = xdev; 104 - } else { 105 - idev->io_active = false; 106 - } 101 + idev->xdev = xdev; 107 102 } 108 103 109 104 static void 110 105 teardown_idev(struct ipc_device *idev) 111 106 { 112 - idev->io_active = false; 107 + idev->xdev = NULL; 113 108 } 114 109 115 110 static void ··· 422 417 423 418 // Setup the HMD 424 419 // set view count 425 - assert(s->xsysd->static_roles.head->hmd); 426 - ism->hmd.view_count = s->xsysd->static_roles.head->hmd->view_count; 427 - for (uint32_t view = 0; view < s->xsysd->static_roles.head->hmd->view_count; ++view) { 428 - ism->hmd.views[view].display.w_pixels = s->xsysd->static_roles.head->hmd->views[view].display.w_pixels; 429 - ism->hmd.views[view].display.h_pixels = s->xsysd->static_roles.head->hmd->views[view].display.h_pixels; 430 - } 420 + const struct xrt_device *xhead = s->xsysd->static_roles.head; 421 + const struct xrt_hmd_parts *xhmd = xhead != NULL ? xhead->hmd : NULL; 422 + U_ZERO(&ism->hmd); 423 + if (xhmd != NULL) { 424 + ism->hmd.view_count = xhmd->view_count; 425 + for (uint32_t view = 0; view < xhmd->view_count; ++view) { 426 + ism->hmd.views[view].display.w_pixels = xhmd->views[view].display.w_pixels; 427 + ism->hmd.views[view].display.h_pixels = xhmd->views[view].display.h_pixels; 428 + } 431 429 432 - for (size_t i = 0; i < s->xsysd->static_roles.head->hmd->blend_mode_count; i++) { 433 - // Not super necessary, we also do this assert in oxr_system.c 434 - assert(u_verify_blend_mode_valid(s->xsysd->static_roles.head->hmd->blend_modes[i])); 435 - ism->hmd.blend_modes[i] = s->xsysd->static_roles.head->hmd->blend_modes[i]; 430 + for (uint32_t i = 0; i < xhmd->blend_mode_count; i++) { 431 + // Not super necessary, we also do this assert in oxr_system.c 432 + assert(u_verify_blend_mode_valid(xhmd->blend_modes[i])); 433 + ism->hmd.blend_modes[i] = xhmd->blend_modes[i]; 434 + } 435 + ism->hmd.blend_mode_count = xhmd->blend_mode_count; 436 436 } 437 - ism->hmd.blend_mode_count = s->xsysd->static_roles.head->hmd->blend_mode_count; 438 437 439 438 // Finally tell the client how many devices we have. 440 439 ism->isdev_count = count; ··· 616 615 ics->client_state.z_order = z_order; 617 616 618 617 if (ics->xc != NULL) { 619 - xrt_syscomp_set_state(ics->server->xsysc, ics->xc, visible, focused); 618 + xrt_syscomp_set_state(ics->server->xsysc, ics->xc, visible, focused, os_monotonic_get_ns()); 620 619 xrt_syscomp_set_z_order(ics->server->xsysc, ics->xc, z_order); 621 620 } 622 621 } ··· 1104 1103 return -1; 1105 1104 } 1106 1105 1107 - // Start the debug UI now (if enabled). 1108 - u_debug_gui_start(s->debug_gui, s->xinst, s->xsysd); 1109 - 1110 1106 // Tell the callbacks we are entering the main-loop. 1111 1107 callbacks->mainloop_entering(s, s->xinst, data); 1112 1108 ··· 1118 1114 if (xret != XRT_SUCCESS) { 1119 1115 U_LOG_CHK_ONLY_PRINT(log_level, xret, "ipc_server_init_system_if_available_locked"); 1120 1116 } 1117 + 1118 + // Start the debug UI now (if enabled). 1119 + u_debug_gui_start(s->debug_gui, s->xinst, s->xsysd); 1121 1120 1122 1121 // Main loop. 1123 1122 ret = main_loop(s);
+5 -5
src/xrt/ipc/shared/ipc_protocol.h
··· 38 38 #define IPC_MAX_DEVICES 8 // max number of devices we will map using shared mem 39 39 #define IPC_MAX_LAYERS XRT_MAX_LAYERS 40 40 #define IPC_MAX_SLOTS 128 41 - #define IPC_MAX_CLIENTS 8 41 + #define IPC_MAX_CLIENTS 32 42 42 #define IPC_MAX_RAW_VIEWS 32 // Max views that we can get, artificial limit. 43 43 #define IPC_EVENT_QUEUE_SIZE 32 44 44 ··· 85 85 { 86 86 enum xrt_device_name name; 87 87 88 + //! Offset into the array of pairs where this input bindings starts. 89 + uint32_t first_input_index; 88 90 //! Number of inputs. 89 91 uint32_t input_count; 90 - //! Offset into the array of pairs where this input bindings starts. 91 - uint32_t first_input_index; 92 92 93 + //! Offset into the array of pairs where this output bindings starts. 94 + uint32_t first_output_index; 93 95 //! Number of outputs. 94 96 uint32_t output_count; 95 - //! Offset into the array of pairs where this output bindings starts. 96 - uint32_t first_output_index; 97 97 }; 98 98 99 99 /*!
+19
src/xrt/ipc/shared/proto/10-instance.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "instance_get_shm_fd": { 5 + "out_handles": {"type": "xrt_shmem_handle_t"} 6 + }, 7 + 8 + "instance_describe_client": { 9 + "in": [ 10 + {"name": "desc", "type": "struct ipc_client_description"} 11 + ] 12 + }, 13 + 14 + "instance_is_system_available": { 15 + "out": [ 16 + {"name": "available", "type": "bool"} 17 + ] 18 + } 19 + }
+3
src/xrt/ipc/shared/proto/10-instance.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+119
src/xrt/ipc/shared/proto/50-compositor.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "compositor_get_info": { 5 + "out": [ 6 + {"name": "info", "type": "struct xrt_compositor_info"} 7 + ] 8 + }, 9 + 10 + "compositor_predict_frame": { 11 + "out": [ 12 + {"name": "frame_id", "type": "int64_t"}, 13 + {"name": "wake_up_time", "type": "int64_t"}, 14 + {"name": "predicted_display_time", "type": "int64_t"}, 15 + {"name": "predicted_display_period", "type": "int64_t"} 16 + ] 17 + }, 18 + 19 + "compositor_wait_woke": { 20 + "in": [ 21 + {"name": "frame_id", "type": "int64_t"} 22 + ] 23 + }, 24 + 25 + "compositor_begin_frame": { 26 + "in": [ 27 + {"name": "frame_id", "type": "int64_t"} 28 + ] 29 + }, 30 + 31 + "compositor_discard_frame": { 32 + "in": [ 33 + {"name": "frame_id", "type": "int64_t"} 34 + ] 35 + }, 36 + 37 + "compositor_layer_sync": { 38 + "in": [ 39 + {"name": "slot_id", "type": "uint32_t"} 40 + ], 41 + "in_handles": {"type": "xrt_graphics_sync_handle_t"}, 42 + "out": [ 43 + {"name": "free_slot_id", "type": "uint32_t"} 44 + ] 45 + }, 46 + 47 + "compositor_layer_sync_with_semaphore": { 48 + "in": [ 49 + {"name": "slot_id", "type": "uint32_t"}, 50 + {"name": "semaphore_id", "type": "uint32_t"}, 51 + {"name": "semaphore_value", "type": "uint64_t"} 52 + ], 53 + "out": [ 54 + {"name": "free_slot_id", "type": "uint32_t"} 55 + ] 56 + }, 57 + 58 + "compositor_set_performance_level": { 59 + "in": [ 60 + {"name": "domain", "type": "enum xrt_perf_domain"}, 61 + {"name": "level", "type": "enum xrt_perf_set_level"} 62 + ] 63 + }, 64 + 65 + "compositor_set_thread_hint": { 66 + "in": [ 67 + {"name": "hint", "type": "enum xrt_thread_hint"}, 68 + {"name": "thread_id", "type": "uint32_t"} 69 + ] 70 + }, 71 + 72 + "compositor_get_display_refresh_rate": { 73 + "out": [ 74 + {"name": "out_display_refresh_rate_hz", "type": "float"} 75 + ] 76 + }, 77 + 78 + "compositor_request_display_refresh_rate": { 79 + "in": [ 80 + {"name": "display_refresh_rate_hz", "type": "float"} 81 + ] 82 + }, 83 + 84 + "compositor_get_reference_bounds_rect": { 85 + "in": [ 86 + {"name": "reference_space_type", "type": "enum xrt_reference_space_type"} 87 + ], 88 + "out": [ 89 + {"name": "bounds", "type": "struct xrt_vec2"} 90 + ] 91 + }, 92 + 93 + "compositor_create_passthrough": { 94 + "in": [ 95 + {"name": "info", "type": "struct xrt_passthrough_create_info"} 96 + ] 97 + }, 98 + 99 + "compositor_create_passthrough_layer": { 100 + "in": [ 101 + {"name": "info", "type": "struct xrt_passthrough_layer_create_info"} 102 + ] 103 + }, 104 + 105 + "compositor_destroy_passthrough": {}, 106 + 107 + "compositor_semaphore_create": { 108 + "out": [ 109 + {"name": "id", "type": "uint32_t"} 110 + ], 111 + "out_handles": {"type": "xrt_graphics_sync_handle_t"} 112 + }, 113 + 114 + "compositor_semaphore_destroy": { 115 + "in": [ 116 + {"name": "id", "type": "uint32_t"} 117 + ] 118 + } 119 + }
+3
src/xrt/ipc/shared/proto/50-compositor.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+254
src/xrt/ipc/shared/proto/50-device.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "device_update_input": { 5 + "in": [ 6 + {"name": "id", "type": "uint32_t"} 7 + ] 8 + }, 9 + 10 + "device_get_tracked_pose": { 11 + "in": [ 12 + {"name": "id", "type": "uint32_t"}, 13 + {"name": "name", "type": "enum xrt_input_name"}, 14 + {"name": "at_timestamp", "type": "int64_t"} 15 + ], 16 + "out": [ 17 + {"name": "relation", "type": "struct xrt_space_relation"} 18 + ] 19 + }, 20 + 21 + "device_get_hand_tracking": { 22 + "in": [ 23 + {"name": "id", "type": "uint32_t"}, 24 + {"name": "name", "type": "enum xrt_input_name"}, 25 + {"name": "at_timestamp", "type": "int64_t"} 26 + ], 27 + "out": [ 28 + {"name": "value", "type": "struct xrt_hand_joint_set"}, 29 + {"name": "timestamp", "type": "int64_t"} 30 + ] 31 + }, 32 + 33 + "device_get_view_poses": { 34 + "varlen": true, 35 + "in": [ 36 + {"name": "id", "type": "uint32_t"}, 37 + {"name": "fallback_eye_relation", "type": "struct xrt_vec3"}, 38 + {"name": "at_timestamp_ns", "type": "int64_t"}, 39 + {"name": "view_type", "type": "enum xrt_view_type"}, 40 + {"name": "view_count", "type": "uint32_t"} 41 + ], 42 + "out": [ 43 + {"name": "head_relation", "type": "struct xrt_space_relation"}, 44 + {"name": "view_count", "type": "uint32_t"} 45 + ] 46 + }, 47 + 48 + "device_get_view_poses_2": { 49 + "in": [ 50 + {"name": "id", "type": "uint32_t"}, 51 + {"name": "fallback_eye_relation", "type": "struct xrt_vec3"}, 52 + {"name": "at_timestamp_ns", "type": "int64_t"}, 53 + {"name": "view_type", "type": "enum xrt_view_type"}, 54 + {"name": "view_count", "type": "uint32_t"} 55 + ], 56 + "out": [ 57 + {"name": "info", "type": "struct ipc_info_get_view_poses_2"} 58 + ] 59 + }, 60 + 61 + "device_compute_distortion": { 62 + "in": [ 63 + {"name": "id", "type": "uint32_t"}, 64 + {"name": "view", "type": "uint32_t"}, 65 + {"name": "u", "type": "float"}, 66 + {"name": "v", "type": "float"} 67 + ], 68 + "out": [ 69 + {"name": "triplet", "type": "struct xrt_uv_triplet"} 70 + ] 71 + }, 72 + 73 + "device_begin_plane_detection_ext": { 74 + "in": [ 75 + {"name": "id", "type": "uint32_t"}, 76 + {"name": "plane_detection_id", "type": "uint64_t"} 77 + ], 78 + "out": [ 79 + {"name": "out_plane_detection_id", "type": "uint64_t"} 80 + ] 81 + }, 82 + 83 + "device_destroy_plane_detection_ext": { 84 + "in": [ 85 + {"name": "id", "type": "uint32_t"}, 86 + {"name": "plane_detection_id", "type": "uint64_t"} 87 + ] 88 + }, 89 + 90 + "device_get_plane_detection_state_ext": { 91 + "in": [ 92 + {"name": "id", "type": "uint32_t"}, 93 + {"name": "plane_detection_id", "type": "uint64_t"} 94 + ], 95 + "out": [ 96 + {"name": "state", "type": "enum xrt_plane_detector_state_ext"} 97 + ] 98 + }, 99 + 100 + "device_get_plane_detections_ext": { 101 + "varlen": true, 102 + "in": [ 103 + {"name": "id", "type": "uint32_t"}, 104 + {"name": "plane_detection_id", "type": "uint64_t"} 105 + ], 106 + "out": [ 107 + {"name": "location_size", "type": "uint32_t"}, 108 + {"name": "polygon_size", "type": "uint32_t"}, 109 + {"name": "vertex_size", "type": "uint32_t"} 110 + ] 111 + }, 112 + 113 + "device_get_presence": { 114 + "in": [ 115 + {"name": "id", "type": "uint32_t"} 116 + ], 117 + "out": [ 118 + {"name": "presence", "type": "bool"} 119 + ] 120 + }, 121 + 122 + "device_set_output": { 123 + "in": [ 124 + {"name": "id", "type": "uint32_t"}, 125 + {"name": "name", "type": "enum xrt_output_name"}, 126 + {"name": "value", "type": "struct xrt_output_value"} 127 + ] 128 + }, 129 + 130 + "device_set_haptic_output": { 131 + "varlen": true, 132 + "in": [ 133 + {"name": "id", "type": "uint32_t"}, 134 + {"name": "name", "type": "enum xrt_output_name"}, 135 + {"name": "samples", "type": "struct ipc_pcm_haptic_buffer"} 136 + ], 137 + "out":[ 138 + {"name": "samples_consumed", "type": "uint32_t"} 139 + ] 140 + }, 141 + 142 + "device_get_output_limits": { 143 + "in": [ 144 + {"name": "id", "type": "uint32_t"} 145 + ], 146 + "out":[ 147 + {"name": "limits", "type": "struct xrt_output_limits"} 148 + ] 149 + }, 150 + 151 + "device_get_visibility_mask": { 152 + "varlen": true, 153 + "in": [ 154 + {"name": "id", "type": "uint32_t"}, 155 + {"name": "type", "type": "enum xrt_visibility_mask_type"}, 156 + {"name": "view_index", "type": "uint32_t"} 157 + ], 158 + "out": [ 159 + {"name": "mask_size", "type": "uint32_t"} 160 + ] 161 + }, 162 + 163 + "device_is_form_factor_available": { 164 + "in": [ 165 + {"name": "id", "type": "uint32_t"}, 166 + {"name": "form_factor", "type": "enum xrt_form_factor"} 167 + ], 168 + "out": [ 169 + {"name": "available", "type": "bool"} 170 + ] 171 + }, 172 + 173 + "device_get_face_tracking": { 174 + "in": [ 175 + {"name": "id", "type": "uint32_t"}, 176 + {"name": "facial_expression_type", "type": "enum xrt_input_name"}, 177 + {"name": "at_timestamp_ns", "type": "int64_t"} 178 + ], 179 + "out": [ 180 + {"name": "value", "type": "struct xrt_facial_expression_set"} 181 + ] 182 + }, 183 + 184 + "device_device_get_face_calibration_state_android": { 185 + "in": [ 186 + {"name": "id", "type": "uint32_t"} 187 + ], 188 + "out": [ 189 + {"name": "face_is_calibrated", "type": "bool"} 190 + ] 191 + }, 192 + 193 + "device_get_body_skeleton": { 194 + "in": [ 195 + {"name": "id", "type": "uint32_t"}, 196 + {"name": "body_tracking_type", "type": "enum xrt_input_name"} 197 + ], 198 + "out": [ 199 + {"name": "value", "type": "struct xrt_body_skeleton"} 200 + ] 201 + }, 202 + 203 + "device_get_body_joints": { 204 + "in": [ 205 + {"name": "id", "type": "uint32_t"}, 206 + {"name": "body_tracking_type", "type": "enum xrt_input_name"}, 207 + {"name": "desired_timestamp_ns", "type": "int64_t"} 208 + ], 209 + "out": [ 210 + {"name": "value", "type": "struct xrt_body_joint_set"} 211 + ] 212 + }, 213 + 214 + "device_reset_body_tracking_calibration_meta": { 215 + "in": [ 216 + {"name": "id", "type": "uint32_t"} 217 + ] 218 + }, 219 + 220 + "device_set_body_tracking_calibration_override_meta": { 221 + "in": [ 222 + {"name": "id", "type": "uint32_t"}, 223 + {"name": "new_body_height", "type": "float"} 224 + ] 225 + }, 226 + 227 + "device_get_battery_status": { 228 + "in": [ 229 + {"name": "id", "type": "uint32_t"} 230 + ], 231 + "out": [ 232 + {"name": "present", "type": "bool"}, 233 + {"name": "charging", "type": "bool"}, 234 + {"name": "charge", "type": "float"} 235 + ] 236 + }, 237 + 238 + "device_get_brightness": { 239 + "in": [ 240 + {"name": "id", "type": "uint32_t"} 241 + ], 242 + "out": [ 243 + {"name": "brightness", "type": "float"} 244 + ] 245 + }, 246 + 247 + "device_set_brightness": { 248 + "in": [ 249 + {"name": "id", "type": "uint32_t"}, 250 + {"name": "brightness", "type": "float"}, 251 + {"name": "relative", "type": "bool"} 252 + ] 253 + } 254 + }
+3
src/xrt/ipc/shared/proto/50-device.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+33
src/xrt/ipc/shared/proto/50-future.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "future_get_state": { 5 + "in": [ 6 + {"name": "future_id", "type": "uint32_t"} 7 + ], 8 + "out": [ 9 + {"name": "out_state", "type": "enum xrt_future_state"} 10 + ] 11 + }, 12 + 13 + "future_cancel": { 14 + "in": [ 15 + {"name": "future_id", "type": "uint32_t"} 16 + ] 17 + }, 18 + 19 + "future_destroy": { 20 + "in": [ 21 + {"name": "future_id", "type": "uint32_t"} 22 + ] 23 + }, 24 + 25 + "future_get_result": { 26 + "in": [ 27 + {"name": "future_id", "type": "uint32_t"} 28 + ], 29 + "out": [ 30 + {"name": "out_ft_result", "type": "struct xrt_future_result"} 31 + ] 32 + } 33 + }
+3
src/xrt/ipc/shared/proto/50-future.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+22
src/xrt/ipc/shared/proto/50-session.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "session_create": { 5 + "in": [ 6 + {"name": "xsi", "type": "struct xrt_session_info"}, 7 + {"name": "create_native_compositor", "type": "bool"} 8 + ] 9 + }, 10 + 11 + "session_poll_events": { 12 + "out": [ 13 + {"name": "event", "type": "union xrt_session_event"} 14 + ] 15 + }, 16 + 17 + "session_begin": {}, 18 + 19 + "session_end": {}, 20 + 21 + "session_destroy": {} 22 + }
+3
src/xrt/ipc/shared/proto/50-session.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+122
src/xrt/ipc/shared/proto/50-space.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "space_create_semantic_ids": { 5 + "out": [ 6 + {"name": "root_id", "type": "uint32_t"}, 7 + {"name": "view_id", "type": "uint32_t"}, 8 + {"name": "local_id", "type": "uint32_t"}, 9 + {"name": "local_floor_id", "type": "uint32_t"}, 10 + {"name": "stage_id", "type": "uint32_t"}, 11 + {"name": "unbounded_id", "type": "uint32_t"} 12 + ] 13 + }, 14 + 15 + "space_create_offset": { 16 + "in": [ 17 + {"name": "parent_id", "type": "uint32_t"}, 18 + {"name": "offset", "type": "struct xrt_pose"} 19 + ], 20 + "out": [ 21 + {"name": "space_id", "type": "uint32_t"} 22 + ] 23 + }, 24 + 25 + "space_create_pose": { 26 + "in": [ 27 + {"name": "xdev_id", "type": "uint32_t"}, 28 + {"name": "name", "type": "enum xrt_input_name"} 29 + ], 30 + "out": [ 31 + {"name": "space_id", "type": "uint32_t"} 32 + ] 33 + }, 34 + 35 + "space_locate_space": { 36 + "in": [ 37 + {"name": "base_space_id", "type": "uint32_t"}, 38 + {"name": "base_offset", "type": "struct xrt_pose"}, 39 + {"name": "at_timestamp", "type": "int64_t"}, 40 + {"name": "space_id", "type": "uint32_t"}, 41 + {"name": "offset", "type": "struct xrt_pose"} 42 + ], 43 + "out": [ 44 + {"name": "relation", "type": "struct xrt_space_relation"} 45 + ] 46 + }, 47 + 48 + "space_locate_spaces": { 49 + "varlen": true, 50 + "in": [ 51 + {"name": "base_space_id", "type": "uint32_t"}, 52 + {"name": "base_offset", "type": "struct xrt_pose"}, 53 + {"name": "space_count", "type": "uint32_t"}, 54 + {"name": "at_timestamp", "type": "int64_t"} 55 + ] 56 + }, 57 + 58 + "space_locate_device": { 59 + "in": [ 60 + {"name": "base_space_id", "type": "uint32_t"}, 61 + {"name": "base_offset", "type": "struct xrt_pose"}, 62 + {"name": "at_timestamp", "type": "int64_t"}, 63 + {"name": "xdev_id", "type": "uint32_t"} 64 + ], 65 + "out": [ 66 + {"name": "relation", "type": "struct xrt_space_relation"} 67 + ] 68 + }, 69 + 70 + "space_destroy": { 71 + "in": [ 72 + {"name": "space_id", "type": "uint32_t"} 73 + ] 74 + }, 75 + 76 + "space_mark_ref_space_in_use": { 77 + "in": [ 78 + {"name": "type", "type": "enum xrt_reference_space_type"} 79 + ] 80 + }, 81 + 82 + "space_unmark_ref_space_in_use": { 83 + "in": [ 84 + {"name": "type", "type": "enum xrt_reference_space_type"} 85 + ] 86 + }, 87 + 88 + "space_recenter_local_spaces": { 89 + }, 90 + 91 + "space_get_tracking_origin_offset": { 92 + "in": [ 93 + {"name": "origin_id", "type": "uint32_t"} 94 + ], 95 + "out": [ 96 + {"name": "offset", "type": "struct xrt_pose"} 97 + ] 98 + }, 99 + 100 + "space_set_tracking_origin_offset": { 101 + "in": [ 102 + {"name": "origin_id", "type": "uint32_t"}, 103 + {"name": "offset", "type": "struct xrt_pose"} 104 + ] 105 + }, 106 + 107 + "space_get_reference_space_offset": { 108 + "in": [ 109 + {"name": "type", "type": "enum xrt_reference_space_type"} 110 + ], 111 + "out": [ 112 + {"name": "offset", "type": "struct xrt_pose"} 113 + ] 114 + }, 115 + 116 + "space_set_reference_space_offset": { 117 + "in": [ 118 + {"name": "type", "type": "enum xrt_reference_space_type"}, 119 + {"name": "offset", "type": "struct xrt_pose"} 120 + ] 121 + } 122 + }
+3
src/xrt/ipc/shared/proto/50-space.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+66
src/xrt/ipc/shared/proto/50-swapchain.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "swapchain_get_properties": { 5 + "in": [ 6 + {"name": "info", "type": "struct xrt_swapchain_create_info"} 7 + ], 8 + "out": [ 9 + {"name": "xsccp", "type": "struct xrt_swapchain_create_properties"} 10 + ] 11 + }, 12 + 13 + "swapchain_create": { 14 + "in": [ 15 + {"name": "info", "type": "struct xrt_swapchain_create_info"} 16 + ], 17 + "out": [ 18 + {"name": "id", "type": "uint32_t"}, 19 + {"name": "image_count", "type": "uint32_t"}, 20 + {"name": "size", "type": "uint64_t"}, 21 + {"name": "use_dedicated_allocation", "type": "bool"} 22 + ], 23 + "out_handles": {"type": "xrt_graphics_buffer_handle_t"} 24 + }, 25 + 26 + "swapchain_import": { 27 + "in": [ 28 + {"name": "info", "type": "struct xrt_swapchain_create_info"}, 29 + {"name": "args", "type": "struct ipc_arg_swapchain_from_native"} 30 + ], 31 + "out": [ 32 + {"name": "id", "type": "uint32_t"} 33 + ], 34 + "in_handles": {"type": "xrt_graphics_buffer_handle_t"} 35 + }, 36 + 37 + "swapchain_wait_image": { 38 + "in": [ 39 + {"name": "id", "type": "uint32_t"}, 40 + {"name": "timeout_ns", "type": "int64_t"}, 41 + {"name": "index", "type": "uint32_t"} 42 + ] 43 + }, 44 + 45 + "swapchain_acquire_image": { 46 + "in": [ 47 + {"name": "id", "type": "uint32_t"} 48 + ], 49 + "out": [ 50 + {"name": "index", "type": "uint32_t"} 51 + ] 52 + }, 53 + 54 + "swapchain_release_image": { 55 + "in": [ 56 + {"name": "id", "type": "uint32_t"}, 57 + {"name": "index", "type": "uint32_t"} 58 + ] 59 + }, 60 + 61 + "swapchain_destroy": { 62 + "in": [ 63 + {"name": "id", "type": "uint32_t"} 64 + ] 65 + } 66 + }
+3
src/xrt/ipc/shared/proto/50-swapchain.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
+66
src/xrt/ipc/shared/proto/50-system.json
··· 1 + { 2 + "$schema": "../proto.schema.json", 3 + 4 + "system_get_properties": { 5 + "out": [ 6 + {"name": "properties", "type": "struct xrt_system_properties"} 7 + ] 8 + }, 9 + 10 + "system_get_client_info": { 11 + "in": [ 12 + {"name": "id", "type": "uint32_t"} 13 + ], 14 + "out": [ 15 + {"name": "ias", "type": "struct ipc_app_state"} 16 + ] 17 + }, 18 + 19 + "system_get_clients": { 20 + "out": [ 21 + {"name": "clients", "type": "struct ipc_client_list"} 22 + ] 23 + }, 24 + 25 + "system_set_primary_client": { 26 + "in": [ 27 + {"name": "id", "type": "uint32_t"} 28 + ] 29 + }, 30 + 31 + "system_set_focused_client": { 32 + "in": [ 33 + {"name": "id", "type": "uint32_t"} 34 + ] 35 + }, 36 + 37 + "system_toggle_io_client": { 38 + "in": [ 39 + {"name": "id", "type": "uint32_t"} 40 + ] 41 + }, 42 + 43 + "system_devices_get_roles": { 44 + "out": [ 45 + {"name": "system_roles", "type": "struct xrt_system_roles"} 46 + ] 47 + }, 48 + 49 + "system_devices_begin_feature": { 50 + "in": [ 51 + {"name": "type", "type": "enum xrt_device_feature_type"} 52 + ] 53 + }, 54 + 55 + "system_devices_end_feature": { 56 + "in": [ 57 + {"name": "type", "type": "enum xrt_device_feature_type"} 58 + ] 59 + }, 60 + 61 + "system_compositor_get_info": { 62 + "out": [ 63 + {"name": "info", "type": "struct xrt_system_compositor_info"} 64 + ] 65 + } 66 + }
+3
src/xrt/ipc/shared/proto/50-system.json.license
··· 1 + Copyright 2018-2025, Collabora, Ltd. 2 + 3 + SPDX-License-Identifier: BSL-1.0
-677
src/xrt/ipc/shared/proto.json
··· 1 - { 2 - "$schema": "./proto.schema.json", 3 - 4 - "instance_get_shm_fd": { 5 - "out_handles": {"type": "xrt_shmem_handle_t"} 6 - }, 7 - 8 - "instance_describe_client": { 9 - "in": [ 10 - {"name": "desc", "type": "struct ipc_client_description"} 11 - ] 12 - }, 13 - 14 - "instance_is_system_available": { 15 - "out": [ 16 - {"name": "available", "type": "bool"} 17 - ] 18 - }, 19 - 20 - "system_get_properties": { 21 - "out": [ 22 - {"name": "properties", "type": "struct xrt_system_properties"} 23 - ] 24 - }, 25 - 26 - "system_get_client_info": { 27 - "in": [ 28 - {"name": "id", "type": "uint32_t"} 29 - ], 30 - "out": [ 31 - {"name": "ias", "type": "struct ipc_app_state"} 32 - ] 33 - }, 34 - 35 - "system_get_clients": { 36 - "out": [ 37 - {"name": "clients", "type": "struct ipc_client_list"} 38 - ] 39 - }, 40 - 41 - "system_set_primary_client": { 42 - "in": [ 43 - {"name": "id", "type": "uint32_t"} 44 - ] 45 - }, 46 - 47 - "system_set_focused_client": { 48 - "in": [ 49 - {"name": "id", "type": "uint32_t"} 50 - ] 51 - }, 52 - 53 - "system_toggle_io_client": { 54 - "in": [ 55 - {"name": "id", "type": "uint32_t"} 56 - ] 57 - }, 58 - 59 - "system_toggle_io_device": { 60 - "in": [ 61 - {"name": "id", "type": "uint32_t"} 62 - ] 63 - }, 64 - 65 - "system_devices_get_roles": { 66 - "out": [ 67 - {"name": "system_roles", "type": "struct xrt_system_roles"} 68 - ] 69 - }, 70 - 71 - "system_devices_begin_feature": { 72 - "in": [ 73 - {"name": "type", "type": "enum xrt_device_feature_type"} 74 - ] 75 - }, 76 - 77 - "system_devices_end_feature": { 78 - "in": [ 79 - {"name": "type", "type": "enum xrt_device_feature_type"} 80 - ] 81 - }, 82 - 83 - "system_compositor_get_info": { 84 - "out": [ 85 - {"name": "info", "type": "struct xrt_system_compositor_info"} 86 - ] 87 - }, 88 - 89 - "session_create": { 90 - "in": [ 91 - {"name": "xsi", "type": "struct xrt_session_info"}, 92 - {"name": "create_native_compositor", "type": "bool"} 93 - ] 94 - }, 95 - 96 - "session_poll_events": { 97 - "out": [ 98 - {"name": "event", "type": "union xrt_session_event"} 99 - ] 100 - }, 101 - 102 - "session_begin": {}, 103 - 104 - "session_end": {}, 105 - 106 - "session_destroy": {}, 107 - 108 - "space_create_semantic_ids": { 109 - "out": [ 110 - {"name": "root_id", "type": "uint32_t"}, 111 - {"name": "view_id", "type": "uint32_t"}, 112 - {"name": "local_id", "type": "uint32_t"}, 113 - {"name": "local_floor_id", "type": "uint32_t"}, 114 - {"name": "stage_id", "type": "uint32_t"}, 115 - {"name": "unbounded_id", "type": "uint32_t"} 116 - ] 117 - }, 118 - 119 - "space_create_offset": { 120 - "in": [ 121 - {"name": "parent_id", "type": "uint32_t"}, 122 - {"name": "offset", "type": "struct xrt_pose"} 123 - ], 124 - "out": [ 125 - {"name": "space_id", "type": "uint32_t"} 126 - ] 127 - }, 128 - 129 - "space_create_pose": { 130 - "in": [ 131 - {"name": "xdev_id", "type": "uint32_t"}, 132 - {"name": "name", "type": "enum xrt_input_name"} 133 - ], 134 - "out": [ 135 - {"name": "space_id", "type": "uint32_t"} 136 - ] 137 - }, 138 - 139 - "space_locate_space": { 140 - "in": [ 141 - {"name": "base_space_id", "type": "uint32_t"}, 142 - {"name": "base_offset", "type": "struct xrt_pose"}, 143 - {"name": "at_timestamp", "type": "int64_t"}, 144 - {"name": "space_id", "type": "uint32_t"}, 145 - {"name": "offset", "type": "struct xrt_pose"} 146 - ], 147 - "out": [ 148 - {"name": "relation", "type": "struct xrt_space_relation"} 149 - ] 150 - }, 151 - 152 - "space_locate_spaces": { 153 - "varlen": true, 154 - "in": [ 155 - {"name": "base_space_id", "type": "uint32_t"}, 156 - {"name": "base_offset", "type": "struct xrt_pose"}, 157 - {"name": "space_count", "type": "uint32_t"}, 158 - {"name": "at_timestamp", "type": "int64_t"} 159 - ] 160 - }, 161 - 162 - "space_locate_device": { 163 - "in": [ 164 - {"name": "base_space_id", "type": "uint32_t"}, 165 - {"name": "base_offset", "type": "struct xrt_pose"}, 166 - {"name": "at_timestamp", "type": "int64_t"}, 167 - {"name": "xdev_id", "type": "uint32_t"} 168 - ], 169 - "out": [ 170 - {"name": "relation", "type": "struct xrt_space_relation"} 171 - ] 172 - }, 173 - 174 - "space_destroy": { 175 - "in": [ 176 - {"name": "space_id", "type": "uint32_t"} 177 - ] 178 - }, 179 - 180 - "space_mark_ref_space_in_use": { 181 - "in": [ 182 - {"name": "type", "type": "enum xrt_reference_space_type"} 183 - ] 184 - }, 185 - 186 - "space_unmark_ref_space_in_use": { 187 - "in": [ 188 - {"name": "type", "type": "enum xrt_reference_space_type"} 189 - ] 190 - }, 191 - 192 - "space_recenter_local_spaces": { 193 - }, 194 - 195 - "space_get_tracking_origin_offset": { 196 - "in": [ 197 - {"name": "origin_id", "type": "uint32_t"} 198 - ], 199 - "out": [ 200 - {"name": "offset", "type": "struct xrt_pose"} 201 - ] 202 - }, 203 - 204 - "space_set_tracking_origin_offset": { 205 - "in": [ 206 - {"name": "origin_id", "type": "uint32_t"}, 207 - {"name": "offset", "type": "struct xrt_pose"} 208 - ] 209 - }, 210 - 211 - "space_get_reference_space_offset": { 212 - "in": [ 213 - {"name": "type", "type": "enum xrt_reference_space_type"} 214 - ], 215 - "out": [ 216 - {"name": "offset", "type": "struct xrt_pose"} 217 - ] 218 - }, 219 - 220 - "space_set_reference_space_offset": { 221 - "in": [ 222 - {"name": "type", "type": "enum xrt_reference_space_type"}, 223 - {"name": "offset", "type": "struct xrt_pose"} 224 - ] 225 - }, 226 - 227 - "compositor_get_info": { 228 - "out": [ 229 - {"name": "info", "type": "struct xrt_compositor_info"} 230 - ] 231 - }, 232 - 233 - "compositor_predict_frame": { 234 - "out": [ 235 - {"name": "frame_id", "type": "int64_t"}, 236 - {"name": "wake_up_time", "type": "int64_t"}, 237 - {"name": "predicted_display_time", "type": "int64_t"}, 238 - {"name": "predicted_display_period", "type": "int64_t"} 239 - ] 240 - }, 241 - 242 - "compositor_wait_woke": { 243 - "in": [ 244 - {"name": "frame_id", "type": "int64_t"} 245 - ] 246 - }, 247 - 248 - "compositor_begin_frame": { 249 - "in": [ 250 - {"name": "frame_id", "type": "int64_t"} 251 - ] 252 - }, 253 - 254 - "compositor_discard_frame": { 255 - "in": [ 256 - {"name": "frame_id", "type": "int64_t"} 257 - ] 258 - }, 259 - 260 - "compositor_layer_sync": { 261 - "in": [ 262 - {"name": "slot_id", "type": "uint32_t"} 263 - ], 264 - "in_handles": {"type": "xrt_graphics_sync_handle_t"}, 265 - "out": [ 266 - {"name": "free_slot_id", "type": "uint32_t"} 267 - ] 268 - }, 269 - 270 - "compositor_layer_sync_with_semaphore": { 271 - "in": [ 272 - {"name": "slot_id", "type": "uint32_t"}, 273 - {"name": "semaphore_id", "type": "uint32_t"}, 274 - {"name": "semaphore_value", "type": "uint64_t"} 275 - ], 276 - "out": [ 277 - {"name": "free_slot_id", "type": "uint32_t"} 278 - ] 279 - }, 280 - 281 - "compositor_set_performance_level": { 282 - "in": [ 283 - {"name": "domain", "type": "enum xrt_perf_domain"}, 284 - {"name": "level", "type": "enum xrt_perf_set_level"} 285 - ] 286 - }, 287 - 288 - "compositor_set_thread_hint": { 289 - "in": [ 290 - {"name": "hint", "type": "enum xrt_thread_hint"}, 291 - {"name": "thread_id", "type": "uint32_t"} 292 - ] 293 - }, 294 - 295 - "compositor_get_display_refresh_rate": { 296 - "out": [ 297 - {"name": "out_display_refresh_rate_hz", "type": "float"} 298 - ] 299 - }, 300 - 301 - "compositor_request_display_refresh_rate": { 302 - "in": [ 303 - {"name": "display_refresh_rate_hz", "type": "float"} 304 - ] 305 - }, 306 - 307 - "compositor_get_reference_bounds_rect": { 308 - "in": [ 309 - {"name": "reference_space_type", "type": "enum xrt_reference_space_type"} 310 - ], 311 - "out": [ 312 - {"name": "bounds", "type": "struct xrt_vec2"} 313 - ] 314 - }, 315 - 316 - "swapchain_get_properties": { 317 - "in": [ 318 - {"name": "info", "type": "struct xrt_swapchain_create_info"} 319 - ], 320 - "out": [ 321 - {"name": "xsccp", "type": "struct xrt_swapchain_create_properties"} 322 - ] 323 - }, 324 - 325 - "swapchain_create": { 326 - "in": [ 327 - {"name": "info", "type": "struct xrt_swapchain_create_info"} 328 - ], 329 - "out": [ 330 - {"name": "id", "type": "uint32_t"}, 331 - {"name": "image_count", "type": "uint32_t"}, 332 - {"name": "size", "type": "uint64_t"}, 333 - {"name": "use_dedicated_allocation", "type": "bool"} 334 - ], 335 - "out_handles": {"type": "xrt_graphics_buffer_handle_t"} 336 - }, 337 - 338 - "compositor_create_passthrough": { 339 - "in": [ 340 - {"name": "info", "type": "struct xrt_passthrough_create_info"} 341 - ] 342 - }, 343 - 344 - "compositor_create_passthrough_layer": { 345 - "in": [ 346 - {"name": "info", "type": "struct xrt_passthrough_layer_create_info"} 347 - ] 348 - }, 349 - 350 - "compositor_destroy_passthrough": {}, 351 - 352 - "swapchain_import": { 353 - "in": [ 354 - {"name": "info", "type": "struct xrt_swapchain_create_info"}, 355 - {"name": "args", "type": "struct ipc_arg_swapchain_from_native"} 356 - ], 357 - "out": [ 358 - {"name": "id", "type": "uint32_t"} 359 - ], 360 - "in_handles": {"type": "xrt_graphics_buffer_handle_t"} 361 - }, 362 - 363 - "swapchain_wait_image": { 364 - "in": [ 365 - {"name": "id", "type": "uint32_t"}, 366 - {"name": "timeout_ns", "type": "int64_t"}, 367 - {"name": "index", "type": "uint32_t"} 368 - ] 369 - }, 370 - 371 - "swapchain_acquire_image": { 372 - "in": [ 373 - {"name": "id", "type": "uint32_t"} 374 - ], 375 - "out": [ 376 - {"name": "index", "type": "uint32_t"} 377 - ] 378 - }, 379 - 380 - "swapchain_release_image": { 381 - "in": [ 382 - {"name": "id", "type": "uint32_t"}, 383 - {"name": "index", "type": "uint32_t"} 384 - ] 385 - }, 386 - 387 - "swapchain_destroy": { 388 - "in": [ 389 - {"name": "id", "type": "uint32_t"} 390 - ] 391 - }, 392 - 393 - "compositor_semaphore_create": { 394 - "out": [ 395 - {"name": "id", "type": "uint32_t"} 396 - ], 397 - "out_handles": {"type": "xrt_graphics_sync_handle_t"} 398 - }, 399 - 400 - "compositor_semaphore_destroy": { 401 - "in": [ 402 - {"name": "id", "type": "uint32_t"} 403 - ] 404 - }, 405 - 406 - "device_update_input": { 407 - "in": [ 408 - {"name": "id", "type": "uint32_t"} 409 - ] 410 - }, 411 - 412 - "device_get_tracked_pose": { 413 - "in": [ 414 - {"name": "id", "type": "uint32_t"}, 415 - {"name": "name", "type": "enum xrt_input_name"}, 416 - {"name": "at_timestamp", "type": "int64_t"} 417 - ], 418 - "out": [ 419 - {"name": "relation", "type": "struct xrt_space_relation"} 420 - ] 421 - }, 422 - 423 - "device_get_hand_tracking": { 424 - "in": [ 425 - {"name": "id", "type": "uint32_t"}, 426 - {"name": "name", "type": "enum xrt_input_name"}, 427 - {"name": "at_timestamp", "type": "int64_t"} 428 - ], 429 - "out": [ 430 - {"name": "value", "type": "struct xrt_hand_joint_set"}, 431 - {"name": "timestamp", "type": "int64_t"} 432 - ] 433 - }, 434 - 435 - "device_get_view_poses": { 436 - "varlen": true, 437 - "in": [ 438 - {"name": "id", "type": "uint32_t"}, 439 - {"name": "fallback_eye_relation", "type": "struct xrt_vec3"}, 440 - {"name": "at_timestamp_ns", "type": "int64_t"}, 441 - {"name": "view_type", "type": "enum xrt_view_type"}, 442 - {"name": "view_count", "type": "uint32_t"} 443 - ], 444 - "out": [ 445 - {"name": "head_relation", "type": "struct xrt_space_relation"}, 446 - {"name": "view_count", "type": "uint32_t"} 447 - ] 448 - }, 449 - 450 - "device_get_view_poses_2": { 451 - "in": [ 452 - {"name": "id", "type": "uint32_t"}, 453 - {"name": "fallback_eye_relation", "type": "struct xrt_vec3"}, 454 - {"name": "at_timestamp_ns", "type": "int64_t"}, 455 - {"name": "view_type", "type": "enum xrt_view_type"}, 456 - {"name": "view_count", "type": "uint32_t"} 457 - ], 458 - "out": [ 459 - {"name": "info", "type": "struct ipc_info_get_view_poses_2"} 460 - ] 461 - }, 462 - 463 - "device_compute_distortion": { 464 - "in": [ 465 - {"name": "id", "type": "uint32_t"}, 466 - {"name": "view", "type": "uint32_t"}, 467 - {"name": "u", "type": "float"}, 468 - {"name": "v", "type": "float"} 469 - ], 470 - "out": [ 471 - {"name": "triplet", "type": "struct xrt_uv_triplet"} 472 - ] 473 - }, 474 - 475 - "device_begin_plane_detection_ext": { 476 - "in": [ 477 - {"name": "id", "type": "uint32_t"}, 478 - {"name": "plane_detection_id", "type": "uint64_t"} 479 - ], 480 - "out": [ 481 - {"name": "out_plane_detection_id", "type": "uint64_t"} 482 - ] 483 - }, 484 - 485 - "device_destroy_plane_detection_ext": { 486 - "in": [ 487 - {"name": "id", "type": "uint32_t"}, 488 - {"name": "plane_detection_id", "type": "uint64_t"} 489 - ] 490 - }, 491 - 492 - "device_get_plane_detection_state_ext": { 493 - "in": [ 494 - {"name": "id", "type": "uint32_t"}, 495 - {"name": "plane_detection_id", "type": "uint64_t"} 496 - ], 497 - "out": [ 498 - {"name": "state", "type": "enum xrt_plane_detector_state_ext"} 499 - ] 500 - }, 501 - 502 - "device_get_plane_detections_ext": { 503 - "varlen": true, 504 - "in": [ 505 - {"name": "id", "type": "uint32_t"}, 506 - {"name": "plane_detection_id", "type": "uint64_t"} 507 - ], 508 - "out": [ 509 - {"name": "location_size", "type": "uint32_t"}, 510 - {"name": "polygon_size", "type": "uint32_t"}, 511 - {"name": "vertex_size", "type": "uint32_t"} 512 - ] 513 - }, 514 - 515 - "device_get_presence": { 516 - "in": [ 517 - {"name": "id", "type": "uint32_t"} 518 - ], 519 - "out": [ 520 - {"name": "presence", "type": "bool"} 521 - ] 522 - }, 523 - 524 - "device_set_output": { 525 - "in": [ 526 - {"name": "id", "type": "uint32_t"}, 527 - {"name": "name", "type": "enum xrt_output_name"}, 528 - {"name": "value", "type": "struct xrt_output_value"} 529 - ] 530 - }, 531 - 532 - "device_set_haptic_output": { 533 - "varlen": true, 534 - "in": [ 535 - {"name": "id", "type": "uint32_t"}, 536 - {"name": "name", "type": "enum xrt_output_name"}, 537 - {"name": "samples", "type": "struct ipc_pcm_haptic_buffer"} 538 - ], 539 - "out":[ 540 - {"name": "samples_consumed", "type": "uint32_t"} 541 - ] 542 - }, 543 - 544 - "device_get_output_limits": { 545 - "in": [ 546 - {"name": "id", "type": "uint32_t"} 547 - ], 548 - "out":[ 549 - {"name": "limits", "type": "struct xrt_output_limits"} 550 - ] 551 - }, 552 - 553 - "device_get_visibility_mask": { 554 - "varlen": true, 555 - "in": [ 556 - {"name": "id", "type": "uint32_t"}, 557 - {"name": "type", "type": "enum xrt_visibility_mask_type"}, 558 - {"name": "view_index", "type": "uint32_t"} 559 - ], 560 - "out": [ 561 - {"name": "mask_size", "type": "uint32_t"} 562 - ] 563 - }, 564 - 565 - "device_is_form_factor_available": { 566 - "in": [ 567 - {"name": "id", "type": "uint32_t"}, 568 - {"name": "form_factor", "type": "enum xrt_form_factor"} 569 - ], 570 - "out": [ 571 - {"name": "available", "type": "bool"} 572 - ] 573 - }, 574 - 575 - "device_get_face_tracking": { 576 - "in": [ 577 - {"name": "id", "type": "uint32_t"}, 578 - {"name": "facial_expression_type", "type": "enum xrt_input_name"}, 579 - {"name": "at_timestamp_ns", "type": "int64_t"} 580 - ], 581 - "out": [ 582 - {"name": "value", "type": "struct xrt_facial_expression_set"} 583 - ] 584 - }, 585 - 586 - "device_get_body_skeleton": { 587 - "in": [ 588 - {"name": "id", "type": "uint32_t"}, 589 - {"name": "body_tracking_type", "type": "enum xrt_input_name"} 590 - ], 591 - "out": [ 592 - {"name": "value", "type": "struct xrt_body_skeleton"} 593 - ] 594 - }, 595 - 596 - "device_get_body_joints": { 597 - "in": [ 598 - {"name": "id", "type": "uint32_t"}, 599 - {"name": "body_tracking_type", "type": "enum xrt_input_name"}, 600 - {"name": "desired_timestamp_ns", "type": "int64_t"} 601 - ], 602 - "out": [ 603 - {"name": "value", "type": "struct xrt_body_joint_set"} 604 - ] 605 - }, 606 - 607 - "device_reset_body_tracking_calibration_meta": { 608 - "in": [ 609 - {"name": "id", "type": "uint32_t"} 610 - ] 611 - }, 612 - 613 - "device_set_body_tracking_calibration_override_meta": { 614 - "in": [ 615 - {"name": "id", "type": "uint32_t"}, 616 - {"name": "new_body_height", "type": "float"} 617 - ] 618 - }, 619 - 620 - "device_get_battery_status": { 621 - "in": [ 622 - {"name": "id", "type": "uint32_t"} 623 - ], 624 - "out": [ 625 - {"name": "present", "type": "bool"}, 626 - {"name": "charging", "type": "bool"}, 627 - {"name": "charge", "type": "float"} 628 - ] 629 - }, 630 - 631 - "device_get_brightness": { 632 - "in": [ 633 - {"name": "id", "type": "uint32_t"} 634 - ], 635 - "out": [ 636 - {"name": "brightness", "type": "float"} 637 - ] 638 - }, 639 - 640 - "device_set_brightness": { 641 - "in": [ 642 - {"name": "id", "type": "uint32_t"}, 643 - {"name": "brightness", "type": "float"}, 644 - {"name": "relative", "type": "bool"} 645 - ] 646 - }, 647 - 648 - "future_get_state": { 649 - "in": [ 650 - {"name": "future_id", "type": "uint32_t"} 651 - ], 652 - "out": [ 653 - {"name": "out_state", "type": "enum xrt_future_state"} 654 - ] 655 - }, 656 - 657 - "future_cancel": { 658 - "in": [ 659 - {"name": "future_id", "type": "uint32_t"} 660 - ] 661 - }, 662 - 663 - "future_destroy": { 664 - "in": [ 665 - {"name": "future_id", "type": "uint32_t"} 666 - ] 667 - }, 668 - 669 - "future_get_result": { 670 - "in": [ 671 - {"name": "future_id", "type": "uint32_t"} 672 - ], 673 - "out": [ 674 - {"name": "out_ft_result", "type": "struct xrt_future_result"} 675 - ] 676 - } 677 - }
-3
src/xrt/ipc/shared/proto.json.license
··· 1 - Copyright 2018-2023, Collabora, Ltd. 2 - 3 - SPDX-License-Identifier: BSL-1.0
+1 -1
src/xrt/ipc/shared/proto.py
··· 520 520 generate_server_c(output, p) 521 521 if output.endswith("ipc_server_generated.h"): 522 522 generate_server_header(output, p) 523 - if output.endswith("structs.txt"): 523 + if output.endswith("structs.txt") or output.endswith("ipc-structs.txt"): 524 524 generate_struct_names(output, p) 525 525 526 526
+10 -1
src/xrt/state_trackers/gui/gui_scene_remote.c
··· 413 413 igBegin("Remote control", NULL, 0); 414 414 415 415 #ifdef XRT_BUILD_DRIVER_REMOTE 416 - if (gr->rc.fd < 0) { 416 + #ifdef XRT_OS_WINDOWS 417 + bool socket_invalid = gr->rc.fd == INVALID_SOCKET; 418 + #else 419 + bool socket_invalid = gr->rc.fd < 0; 420 + #endif 421 + if (socket_invalid) { 417 422 on_not_connected(gr, p); 418 423 } else { 419 424 on_connected(gr, p); ··· 451 456 452 457 gr->base.render = scene_render; 453 458 gr->base.destroy = scene_destroy; 459 + #ifdef XRT_OS_WINDOWS 460 + gr->rc.fd = INVALID_SOCKET; 461 + #else 454 462 gr->rc.fd = -1; 463 + #endif 455 464 456 465 // GUI input defaults. 457 466 if (address != NULL) {
+2 -2
src/xrt/state_trackers/gui/gui_scene_tracking_overrides.c
··· 11 11 #include "util/u_misc.h" 12 12 #include "util/u_format.h" 13 13 #include "util/u_logging.h" 14 + #include "util/u_pretty_print.h" 14 15 15 16 #include "util/u_config_json.h" 16 17 ··· 23 24 #include "gui_common.h" 24 25 #include "gui_imgui.h" 25 26 26 - #include "bindings/b_generated_bindings_helpers.h" 27 27 28 28 struct gui_tracking_overrides 29 29 { ··· 243 243 continue; 244 244 } 245 245 246 - const char *name_str = xrt_input_name_string(input_name); 246 + const char *name_str = u_str_xrt_input_name(input_name); 247 247 bool selected = o->input_name == input_name; 248 248 if (igCheckbox(name_str, &selected)) { 249 249 o->input_name = input_name;
+5 -1
src/xrt/state_trackers/oxr/CMakeLists.txt
··· 106 106 target_sources(st_oxr PRIVATE oxr_api_body_tracking.c oxr_body_tracking.c) 107 107 endif() 108 108 109 + if(XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID) 110 + target_sources(st_oxr PRIVATE oxr_api_face_tracking_android.c oxr_face_tracking_android.c) 111 + endif() 112 + 109 113 if(XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC) 110 - target_sources(st_oxr PRIVATE oxr_api_face_tracking.c oxr_face_tracking.c) 114 + target_sources(st_oxr PRIVATE oxr_api_face_tracking_htc.c oxr_face_tracking_htc.c) 111 115 endif() 112 116 113 117 if(XRT_FEATURE_OPENXR_FACE_TRACKING2_FB)
-90
src/xrt/state_trackers/oxr/oxr_api_face_tracking.c
··· 1 - // Copyright 2024, Collabora, Ltd. 2 - // SPDX-License-Identifier: BSL-1.0 3 - /*! 4 - * @file 5 - * @brief face tracking related API entrypoint functions. 6 - * @author Korcan Hussein <korcan.hussein@collabora.com> 7 - * @ingroup oxr_api 8 - */ 9 - 10 - #include <stdio.h> 11 - #include <stdlib.h> 12 - #include <string.h> 13 - 14 - #include "util/u_trace_marker.h" 15 - 16 - #include "oxr_objects.h" 17 - #include "oxr_logger.h" 18 - 19 - #include "oxr_api_funcs.h" 20 - #include "oxr_api_verify.h" 21 - #include "oxr_handle.h" 22 - 23 - XRAPI_ATTR XrResult XRAPI_CALL 24 - oxr_xrCreateFacialTrackerHTC(XrSession session, 25 - const XrFacialTrackerCreateInfoHTC *createInfo, 26 - XrFacialTrackerHTC *facialTracker) 27 - { 28 - OXR_TRACE_MARKER(); 29 - 30 - struct oxr_logger log; 31 - XrResult ret = XR_SUCCESS; 32 - struct oxr_session *sess = NULL; 33 - struct oxr_facial_tracker_htc *facial_tracker_htc = NULL; 34 - OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrCreateFacialTrackerHTC"); 35 - OXR_VERIFY_SESSION_NOT_LOST(&log, sess); 36 - OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, createInfo, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC); 37 - OXR_VERIFY_EXTENSION(&log, sess->sys->inst, HTC_facial_tracking); 38 - 39 - ret = oxr_facial_tracker_htc_create(&log, sess, createInfo, &facial_tracker_htc); 40 - if (ret != XR_SUCCESS) { 41 - return ret; 42 - } 43 - 44 - OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc); 45 - *facialTracker = oxr_facial_tracker_htc_to_openxr(facial_tracker_htc); 46 - 47 - return XR_SUCCESS; 48 - } 49 - 50 - XRAPI_ATTR XrResult XRAPI_CALL 51 - oxr_xrDestroyFacialTrackerHTC(XrFacialTrackerHTC facialTracker) 52 - { 53 - OXR_TRACE_MARKER(); 54 - 55 - struct oxr_logger log; 56 - struct oxr_facial_tracker_htc *facial_tracker_htc = NULL; 57 - OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialTracker, facial_tracker_htc, "xrDestroyFacialTrackerHTC"); 58 - 59 - return oxr_handle_destroy(&log, &facial_tracker_htc->handle); 60 - } 61 - 62 - XRAPI_ATTR XrResult XRAPI_CALL 63 - oxr_xrGetFacialExpressionsHTC(XrFacialTrackerHTC facialTracker, XrFacialExpressionsHTC *facialExpressions) 64 - { 65 - OXR_TRACE_MARKER(); 66 - 67 - struct oxr_logger log; 68 - struct oxr_facial_tracker_htc *facial_tracker_htc = NULL; 69 - OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialTracker, facial_tracker_htc, "xrGetFacialExpressionsHTC"); 70 - OXR_VERIFY_SESSION_NOT_LOST(&log, facial_tracker_htc->sess); 71 - OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc->xdev); 72 - OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, facialExpressions, XR_TYPE_FACIAL_EXPRESSIONS_HTC); 73 - OXR_VERIFY_ARG_NOT_NULL(&log, facialExpressions->expressionWeightings); 74 - 75 - #define OXR_VERIFY_FACE_EXPRESSION_COUNT(fttype) \ 76 - if (facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_##fttype##_DEFAULT_HTC && \ 77 - facialExpressions->expressionCount < XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC) { \ 78 - return oxr_error( \ 79 - &log, XR_ERROR_SIZE_INSUFFICIENT, \ 80 - "\"expressionCount\" (%d) size is less than the minimum size (%d) required for " #fttype \ 81 - " expressions.\n", \ 82 - facialExpressions->expressionCount, XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC); \ 83 - } 84 - 85 - OXR_VERIFY_FACE_EXPRESSION_COUNT(EYE) 86 - OXR_VERIFY_FACE_EXPRESSION_COUNT(LIP) 87 - #undef OXR_VERIFY_FACE_EXPRESSION_COUNT 88 - 89 - return oxr_get_facial_expressions_htc(&log, facial_tracker_htc, facialExpressions); 90 - }
+82
src/xrt/state_trackers/oxr/oxr_api_face_tracking_android.c
··· 1 + // Copyright 2025, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Android face tracking related API entrypoint functions. 6 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 + * @ingroup oxr_api 8 + */ 9 + 10 + #include <stdio.h> 11 + #include <stdlib.h> 12 + #include <string.h> 13 + 14 + #include "util/u_trace_marker.h" 15 + 16 + #include "oxr_objects.h" 17 + #include "oxr_logger.h" 18 + 19 + #include "oxr_api_funcs.h" 20 + #include "oxr_api_verify.h" 21 + #include "oxr_handle.h" 22 + 23 + XRAPI_ATTR XrResult XRAPI_CALL 24 + oxr_xrCreateFaceTrackerANDROID(XrSession session, 25 + const XrFaceTrackerCreateInfoANDROID *createInfo, 26 + XrFaceTrackerANDROID *faceTracker) 27 + { 28 + OXR_TRACE_MARKER(); 29 + struct oxr_logger log; 30 + struct oxr_session *sess = NULL; 31 + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrCreateFaceTrackerANDROID"); 32 + OXR_VERIFY_SESSION_NOT_LOST(&log, sess); 33 + OXR_VERIFY_EXTENSION(&log, sess->sys->inst, ANDROID_face_tracking); 34 + OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, createInfo, XR_TYPE_FACE_TRACKER_CREATE_INFO_ANDROID); 35 + return oxr_face_tracker_android_create(&log, sess, createInfo, faceTracker); 36 + } 37 + 38 + XRAPI_ATTR XrResult XRAPI_CALL 39 + oxr_xrDestroyFaceTrackerANDROID(XrFaceTrackerANDROID facialTracker) 40 + { 41 + OXR_TRACE_MARKER(); 42 + struct oxr_logger log; 43 + struct oxr_face_tracker_android *face_tracker_android = NULL; 44 + OXR_VERIFY_FACE_TRACKER_ANDROID_AND_INIT_LOG(&log, facialTracker, face_tracker_android, 45 + "xrDestroyFaceTrackerANDROID"); 46 + return oxr_handle_destroy(&log, &face_tracker_android->handle); 47 + } 48 + 49 + XRAPI_ATTR XrResult XRAPI_CALL 50 + oxr_xrGetFaceStateANDROID(XrFaceTrackerANDROID faceTracker, 51 + const XrFaceStateGetInfoANDROID *getInfo, 52 + XrFaceStateANDROID *faceStateOutput) 53 + { 54 + OXR_TRACE_MARKER(); 55 + struct oxr_logger log; 56 + struct oxr_face_tracker_android *face_tracker_android = NULL; 57 + OXR_VERIFY_FACE_TRACKER_ANDROID_AND_INIT_LOG(&log, faceTracker, face_tracker_android, "xrGetFaceStateANDROID"); 58 + OXR_VERIFY_SESSION_NOT_LOST(&log, face_tracker_android->sess); 59 + OXR_VERIFY_ARG_NOT_NULL(&log, face_tracker_android->xdev); 60 + OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, getInfo, XR_TYPE_FACE_STATE_GET_INFO_ANDROID); 61 + OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, faceStateOutput, XR_TYPE_FACE_STATE_ANDROID); 62 + OXR_VERIFY_ARG_TIME_NOT_ZERO(&log, getInfo->time); 63 + OXR_VERIFY_TWO_CALL_ARRAY(&log, faceStateOutput->parametersCapacityInput, 64 + (&faceStateOutput->parametersCountOutput), faceStateOutput->parameters); 65 + OXR_VERIFY_TWO_CALL_ARRAY(&log, faceStateOutput->regionConfidencesCapacityInput, 66 + (&faceStateOutput->regionConfidencesCountOutput), faceStateOutput->regionConfidences); 67 + return oxr_get_face_state_android(&log, face_tracker_android, getInfo, faceStateOutput); 68 + } 69 + 70 + XRAPI_ATTR XrResult XRAPI_CALL 71 + oxr_xrGetFaceCalibrationStateANDROID(XrFaceTrackerANDROID faceTracker, XrBool32 *faceIsCalibratedOutput) 72 + { 73 + OXR_TRACE_MARKER(); 74 + struct oxr_logger log; 75 + struct oxr_face_tracker_android *face_tracker_android = NULL; 76 + OXR_VERIFY_FACE_TRACKER_ANDROID_AND_INIT_LOG(&log, faceTracker, face_tracker_android, 77 + "xrGetFaceCalibrationStateANDROID"); 78 + OXR_VERIFY_SESSION_NOT_LOST(&log, face_tracker_android->sess); 79 + OXR_VERIFY_ARG_NOT_NULL(&log, face_tracker_android->xdev); 80 + OXR_VERIFY_ARG_NOT_NULL(&log, faceIsCalibratedOutput); 81 + return oxr_get_face_calibration_state_android(&log, face_tracker_android, faceIsCalibratedOutput); 82 + }
+90
src/xrt/state_trackers/oxr/oxr_api_face_tracking_htc.c
··· 1 + // Copyright 2024, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief face tracking related API entrypoint functions. 6 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 + * @ingroup oxr_api 8 + */ 9 + 10 + #include <stdio.h> 11 + #include <stdlib.h> 12 + #include <string.h> 13 + 14 + #include "util/u_trace_marker.h" 15 + 16 + #include "oxr_objects.h" 17 + #include "oxr_logger.h" 18 + 19 + #include "oxr_api_funcs.h" 20 + #include "oxr_api_verify.h" 21 + #include "oxr_handle.h" 22 + 23 + XRAPI_ATTR XrResult XRAPI_CALL 24 + oxr_xrCreateFacialTrackerHTC(XrSession session, 25 + const XrFacialTrackerCreateInfoHTC *createInfo, 26 + XrFacialTrackerHTC *facialTracker) 27 + { 28 + OXR_TRACE_MARKER(); 29 + 30 + struct oxr_logger log; 31 + XrResult ret = XR_SUCCESS; 32 + struct oxr_session *sess = NULL; 33 + struct oxr_facial_tracker_htc *facial_tracker_htc = NULL; 34 + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrCreateFacialTrackerHTC"); 35 + OXR_VERIFY_SESSION_NOT_LOST(&log, sess); 36 + OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, createInfo, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC); 37 + OXR_VERIFY_EXTENSION(&log, sess->sys->inst, HTC_facial_tracking); 38 + 39 + ret = oxr_facial_tracker_htc_create(&log, sess, createInfo, &facial_tracker_htc); 40 + if (ret != XR_SUCCESS) { 41 + return ret; 42 + } 43 + 44 + OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc); 45 + *facialTracker = oxr_facial_tracker_htc_to_openxr(facial_tracker_htc); 46 + 47 + return XR_SUCCESS; 48 + } 49 + 50 + XRAPI_ATTR XrResult XRAPI_CALL 51 + oxr_xrDestroyFacialTrackerHTC(XrFacialTrackerHTC facialTracker) 52 + { 53 + OXR_TRACE_MARKER(); 54 + 55 + struct oxr_logger log; 56 + struct oxr_facial_tracker_htc *facial_tracker_htc = NULL; 57 + OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialTracker, facial_tracker_htc, "xrDestroyFacialTrackerHTC"); 58 + 59 + return oxr_handle_destroy(&log, &facial_tracker_htc->handle); 60 + } 61 + 62 + XRAPI_ATTR XrResult XRAPI_CALL 63 + oxr_xrGetFacialExpressionsHTC(XrFacialTrackerHTC facialTracker, XrFacialExpressionsHTC *facialExpressions) 64 + { 65 + OXR_TRACE_MARKER(); 66 + 67 + struct oxr_logger log; 68 + struct oxr_facial_tracker_htc *facial_tracker_htc = NULL; 69 + OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialTracker, facial_tracker_htc, "xrGetFacialExpressionsHTC"); 70 + OXR_VERIFY_SESSION_NOT_LOST(&log, facial_tracker_htc->sess); 71 + OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc->xdev); 72 + OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, facialExpressions, XR_TYPE_FACIAL_EXPRESSIONS_HTC); 73 + OXR_VERIFY_ARG_NOT_NULL(&log, facialExpressions->expressionWeightings); 74 + 75 + #define OXR_VERIFY_FACE_EXPRESSION_COUNT(fttype) \ 76 + if (facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_##fttype##_DEFAULT_HTC && \ 77 + facialExpressions->expressionCount < XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC) { \ 78 + return oxr_error( \ 79 + &log, XR_ERROR_SIZE_INSUFFICIENT, \ 80 + "\"expressionCount\" (%d) size is less than the minimum size (%d) required for " #fttype \ 81 + " expressions.\n", \ 82 + facialExpressions->expressionCount, XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC); \ 83 + } 84 + 85 + OXR_VERIFY_FACE_EXPRESSION_COUNT(EYE) 86 + OXR_VERIFY_FACE_EXPRESSION_COUNT(LIP) 87 + #undef OXR_VERIFY_FACE_EXPRESSION_COUNT 88 + 89 + return oxr_get_facial_expressions_htc(&log, facial_tracker_htc, facialExpressions); 90 + }
+24
src/xrt/state_trackers/oxr/oxr_api_funcs.h
··· 779 779 oxr_xrCancelFutureEXT(XrInstance instance, const XrFutureCancelInfoEXT *cancelInfo); 780 780 #endif 781 781 782 + /* 783 + * 784 + * oxr_api_face_tracking_android.c 785 + * 786 + */ 787 + 788 + #ifdef OXR_HAVE_ANDROID_face_tracking 789 + XRAPI_ATTR XrResult XRAPI_CALL 790 + oxr_xrCreateFaceTrackerANDROID(XrSession session, 791 + const XrFaceTrackerCreateInfoANDROID *createInfo, 792 + XrFaceTrackerANDROID *faceTracker); 793 + 794 + XRAPI_ATTR XrResult XRAPI_CALL 795 + oxr_xrDestroyFaceTrackerANDROID(XrFaceTrackerANDROID facialTracker); 796 + 797 + XRAPI_ATTR XrResult XRAPI_CALL 798 + oxr_xrGetFaceStateANDROID(XrFaceTrackerANDROID faceTracker, 799 + const XrFaceStateGetInfoANDROID *getInfo, 800 + XrFaceStateANDROID *faceStateOutput); 801 + 802 + XRAPI_ATTR XrResult XRAPI_CALL 803 + oxr_xrGetFaceCalibrationStateANDROID(XrFaceTrackerANDROID faceTracker, XrBool32 *faceIsCalibratedOutput); 804 + #endif 805 + 782 806 /*! 783 807 * @} 784 808 */
+7
src/xrt/state_trackers/oxr/oxr_api_negotiate.c
··· 419 419 ENTRY_IF_EXT(xrCancelFutureEXT, EXT_future); 420 420 #endif // OXR_HAVE_EXT_future 421 421 422 + #ifdef OXR_HAVE_ANDROID_face_tracking 423 + ENTRY_IF_EXT(xrCreateFaceTrackerANDROID, ANDROID_face_tracking); 424 + ENTRY_IF_EXT(xrDestroyFaceTrackerANDROID, ANDROID_face_tracking); 425 + ENTRY_IF_EXT(xrGetFaceCalibrationStateANDROID, ANDROID_face_tracking); 426 + ENTRY_IF_EXT(xrGetFaceStateANDROID, ANDROID_face_tracking); 427 + #endif 428 + 422 429 #ifdef OXR_HAVE_KHR_extended_struct_name_lengths 423 430 ENTRY_IF_EXT(xrStructureTypeToString2KHR, KHR_extended_struct_name_lengths); 424 431 #endif // OXR_HAVE_KHR_extended_struct_name_lengths
+2
src/xrt/state_trackers/oxr/oxr_api_verify.h
··· 97 97 #define OXR_VERIFY_FUTURE_AND_INIT_LOG(log, thing, new_thing, name) \ 98 98 OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, oxr_future_ext, FUTURE, name, new_thing->inst); \ 99 99 OXR_VERIFY_FUTURE_VALID(log, new_thing) 100 + #define OXR_VERIFY_FACE_TRACKER_ANDROID_AND_INIT_LOG(log, thing, new_thing, name) \ 101 + OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, oxr_face_tracker_android, FTRACKER, name, new_thing->sess->sys->inst) 100 102 // clang-format on 101 103 102 104 #define OXR_VERIFY_INSTANCE_NOT_NULL(log, arg, new_arg) OXR_VERIFY_SET(log, arg, new_arg, oxr_instance, INSTANCE);
+12
src/xrt/state_trackers/oxr/oxr_extension_support.h
··· 475 475 476 476 477 477 /* 478 + * XR_ANDROID_face_tracking 479 + */ 480 + #if defined(XR_ANDROID_face_tracking) && defined(XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID) 481 + #define OXR_HAVE_ANDROID_face_tracking 482 + #define OXR_EXTENSION_SUPPORT_ANDROID_face_tracking(_) _(ANDROID_face_tracking, ANDROID_FACE_TRACKING) 483 + #else 484 + #define OXR_EXTENSION_SUPPORT_ANDROID_face_tracking(_) 485 + #endif 486 + 487 + 488 + /* 478 489 * XR_BD_controller_interaction 479 490 */ 480 491 #if defined(XR_BD_controller_interaction) && defined(XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE) ··· 936 947 OXR_EXTENSION_SUPPORT_EXT_plane_detection(_) \ 937 948 OXR_EXTENSION_SUPPORT_EXT_samsung_odyssey_controller(_) \ 938 949 OXR_EXTENSION_SUPPORT_EXT_user_presence(_) \ 950 + OXR_EXTENSION_SUPPORT_ANDROID_face_tracking(_) \ 939 951 OXR_EXTENSION_SUPPORT_BD_controller_interaction(_) \ 940 952 OXR_EXTENSION_SUPPORT_FB_body_tracking(_) \ 941 953 OXR_EXTENSION_SUPPORT_FB_composition_layer_alpha_blend(_) \
-119
src/xrt/state_trackers/oxr/oxr_face_tracking.c
··· 1 - // Copyright 2024, Collabora, Ltd. 2 - // SPDX-License-Identifier: BSL-1.0 3 - /*! 4 - * @file 5 - * @brief face tracking related API entrypoint functions. 6 - * @author Korcan Hussein <korcan.hussein@collabora.com> 7 - * @ingroup oxr_main 8 - */ 9 - 10 - #include <stdio.h> 11 - #include <stdlib.h> 12 - #include <string.h> 13 - 14 - #include "oxr_objects.h" 15 - #include "oxr_logger.h" 16 - #include "oxr_handle.h" 17 - 18 - static enum xrt_facial_tracking_type_htc 19 - oxr_to_xrt_facial_tracking_type_htc(enum XrFacialTrackingTypeHTC ft_type) 20 - { 21 - return (enum xrt_facial_tracking_type_htc)ft_type; 22 - } 23 - 24 - static enum xrt_input_name 25 - oxr_facial_tracking_type_htc_to_input_name(enum xrt_facial_tracking_type_htc ft_type) 26 - { 27 - switch (ft_type) { 28 - case XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC: return XRT_INPUT_HTC_LIP_FACE_TRACKING; 29 - case XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC: 30 - default: return XRT_INPUT_HTC_EYE_FACE_TRACKING; 31 - } 32 - } 33 - 34 - static XrResult 35 - oxr_facial_tracker_htc_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb) 36 - { 37 - struct oxr_facial_tracker_htc *face_tracker_htc = (struct oxr_facial_tracker_htc *)hb; 38 - free(face_tracker_htc); 39 - return XR_SUCCESS; 40 - } 41 - 42 - XrResult 43 - oxr_facial_tracker_htc_create(struct oxr_logger *log, 44 - struct oxr_session *sess, 45 - const XrFacialTrackerCreateInfoHTC *createInfo, 46 - struct oxr_facial_tracker_htc **out_face_tracker_htc) 47 - { 48 - bool supports_eye = false; 49 - bool supports_lip = false; 50 - oxr_system_get_face_tracking_htc_support(log, sess->sys->inst, &supports_eye, &supports_lip); 51 - 52 - const enum xrt_facial_tracking_type_htc facial_tracking_type = 53 - oxr_to_xrt_facial_tracking_type_htc(createInfo->facialTrackingType); 54 - 55 - if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC && !supports_eye) { 56 - return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC eye facial tracking"); 57 - } 58 - if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC && !supports_lip) { 59 - return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC lip facial tracking"); 60 - } 61 - 62 - struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, face); 63 - if (xdev == NULL) { 64 - return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "No device found for face tracking role"); 65 - } 66 - 67 - if (!xdev->supported.face_tracking) { 68 - return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "Device does not support HTC facial tracking"); 69 - } 70 - 71 - struct oxr_facial_tracker_htc *face_tracker_htc = NULL; 72 - OXR_ALLOCATE_HANDLE_OR_RETURN(log, face_tracker_htc, OXR_XR_DEBUG_FTRACKER, oxr_facial_tracker_htc_destroy_cb, 73 - &sess->handle); 74 - 75 - face_tracker_htc->sess = sess; 76 - face_tracker_htc->xdev = xdev; 77 - face_tracker_htc->facial_tracking_type = facial_tracking_type; 78 - 79 - *out_face_tracker_htc = face_tracker_htc; 80 - 81 - return XR_SUCCESS; 82 - } 83 - 84 - XrResult 85 - oxr_get_facial_expressions_htc(struct oxr_logger *log, 86 - struct oxr_facial_tracker_htc *facial_tracker_htc, 87 - XrFacialExpressionsHTC *facialExpressions) 88 - { 89 - const bool is_eye_tracking = 90 - facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC; 91 - const size_t expression_count = 92 - is_eye_tracking ? XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC : XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC; 93 - 94 - struct xrt_facial_expression_set facial_expression_set_result = {0}; 95 - float *expression_weights = is_eye_tracking 96 - ? facial_expression_set_result.eye_expression_set_htc.expression_weights 97 - : facial_expression_set_result.lip_expression_set_htc.expression_weights; 98 - memset(expression_weights, 0, sizeof(float) * expression_count); 99 - 100 - const enum xrt_input_name ft_input_name = 101 - oxr_facial_tracking_type_htc_to_input_name(facial_tracker_htc->facial_tracking_type); 102 - 103 - int64_t at_timestamp_ns = os_monotonic_get_ns(); 104 - 105 - xrt_device_get_face_tracking(facial_tracker_htc->xdev, ft_input_name, at_timestamp_ns, 106 - &facial_expression_set_result); 107 - 108 - facialExpressions->isActive = facial_expression_set_result.base_expression_set_htc.is_active; 109 - if (facialExpressions->isActive == XR_FALSE) 110 - return XR_SUCCESS; 111 - 112 - const struct oxr_instance *inst = facial_tracker_htc->sess->sys->inst; 113 - facialExpressions->sampleTime = time_state_monotonic_to_ts_ns( 114 - inst->timekeeping, facial_expression_set_result.base_expression_set_htc.sample_time_ns); 115 - 116 - memcpy(facialExpressions->expressionWeightings, expression_weights, sizeof(float) * expression_count); 117 - 118 - return XR_SUCCESS; 119 - }
+135
src/xrt/state_trackers/oxr/oxr_face_tracking_android.c
··· 1 + // Copyright 2025, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Android face tracking related API entrypoint functions. 6 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 + * @ingroup oxr_main 8 + */ 9 + 10 + #include <stdio.h> 11 + #include <stdlib.h> 12 + #include <string.h> 13 + 14 + #include "oxr_objects.h" 15 + #include "oxr_logger.h" 16 + #include "oxr_handle.h" 17 + #include "oxr_xret.h" 18 + #include "oxr_two_call.h" 19 + 20 + static XrResult 21 + oxr_face_tracker_android_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb) 22 + { 23 + struct oxr_face_tracker_android *face_tracker_android = (struct oxr_face_tracker_android *)hb; 24 + free(face_tracker_android); 25 + return XR_SUCCESS; 26 + } 27 + 28 + XrResult 29 + oxr_face_tracker_android_create(struct oxr_logger *log, 30 + struct oxr_session *sess, 31 + const XrFaceTrackerCreateInfoANDROID *createInfo, 32 + XrFaceTrackerANDROID *faceTracker) 33 + { 34 + bool supported = false; 35 + oxr_system_get_face_tracking_android_support(log, sess->sys->inst, &supported); 36 + if (!supported) { 37 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support Android face tracking"); 38 + } 39 + 40 + struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, face); 41 + if (xdev == NULL) { 42 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "No device found for face tracking role"); 43 + } 44 + 45 + if (!xdev->supported.face_tracking) { 46 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "Device does not support HTC facial tracking"); 47 + } 48 + 49 + struct oxr_face_tracker_android *face_tracker_android = NULL; 50 + OXR_ALLOCATE_HANDLE_OR_RETURN(log, face_tracker_android, OXR_XR_DEBUG_FTRACKER, 51 + oxr_face_tracker_android_destroy_cb, &sess->handle); 52 + 53 + face_tracker_android->sess = sess; 54 + face_tracker_android->xdev = xdev; 55 + 56 + *faceTracker = oxr_face_tracker_android_to_openxr(face_tracker_android); 57 + return oxr_session_success_result(sess); 58 + } 59 + 60 + XrResult 61 + oxr_get_face_state_android(struct oxr_logger *log, 62 + struct oxr_face_tracker_android *facial_tracker_android, 63 + const XrFaceStateGetInfoANDROID *getInfo, 64 + XrFaceStateANDROID *faceStateOutput) 65 + { 66 + /*! 67 + * OXR_TWO_CALL_CHECK_* macro usage here is not technically necessary because validation 68 + * is handled in the API layer before this function is called, but we still reuse them here 69 + * for declarative purposes of handling two-call patterns of setting capacities on the first call. 70 + */ 71 + 72 + /*! 73 + * Use the goto macro variant because a two-call check needs to happen with region confidences 74 + * as well; we can't early exit for only one of them. 75 + */ 76 + XrResult xres = XR_SUCCESS; 77 + OXR_TWO_CALL_CHECK_GOTO(log, faceStateOutput->parametersCapacityInput, 78 + (&faceStateOutput->parametersCountOutput), XRT_FACE_PARAMETER_COUNT_ANDROID, xres, 79 + region_confidences_check); 80 + region_confidences_check: 81 + if (xres != XR_SUCCESS) { 82 + return xres; 83 + } 84 + 85 + OXR_TWO_CALL_CHECK_ONLY(log, faceStateOutput->regionConfidencesCapacityInput, 86 + (&faceStateOutput->regionConfidencesCountOutput), 87 + XRT_FACE_REGION_CONFIDENCE_COUNT_ANDROID, xres); 88 + 89 + const struct oxr_instance *inst = facial_tracker_android->sess->sys->inst; 90 + const int64_t at_timestamp_ns = time_state_ts_to_monotonic_ns(inst->timekeeping, getInfo->time); 91 + 92 + struct xrt_facial_expression_set facial_expression_set_result = {0}; 93 + const xrt_result_t xret = 94 + xrt_device_get_face_tracking(facial_tracker_android->xdev, XRT_INPUT_ANDROID_FACE_TRACKING, at_timestamp_ns, 95 + &facial_expression_set_result); 96 + OXR_CHECK_XRET(log, facial_tracker_android->sess, xret, "oxr_get_face_state_android"); 97 + 98 + const struct xrt_facial_expression_set_android *face_expression_set_android = 99 + &facial_expression_set_result.face_expression_set_android; 100 + 101 + faceStateOutput->isValid = face_expression_set_android->is_valid; 102 + if (faceStateOutput->isValid == XR_FALSE) { 103 + return XR_SUCCESS; 104 + } 105 + 106 + faceStateOutput->sampleTime = 107 + time_state_monotonic_to_ts_ns(inst->timekeeping, face_expression_set_android->sample_time_ns); 108 + 109 + if (faceStateOutput->parametersCapacityInput) { 110 + memcpy(faceStateOutput->parameters, face_expression_set_android->parameters, 111 + sizeof(float) * faceStateOutput->parametersCapacityInput); 112 + } 113 + 114 + if (faceStateOutput->regionConfidencesCapacityInput) { 115 + memcpy(faceStateOutput->regionConfidences, face_expression_set_android->region_confidences, 116 + sizeof(float) * faceStateOutput->regionConfidencesCapacityInput); 117 + } 118 + 119 + return oxr_session_success_result(facial_tracker_android->sess); 120 + } 121 + 122 + XrResult 123 + oxr_get_face_calibration_state_android(struct oxr_logger *log, 124 + struct oxr_face_tracker_android *facial_tracker_android, 125 + XrBool32 *faceIsCalibratedOutput) 126 + { 127 + bool face_is_calibrated = false; 128 + const xrt_result_t xret = 129 + xrt_device_get_face_calibration_state_android(facial_tracker_android->xdev, &face_is_calibrated); 130 + OXR_CHECK_XRET(log, facial_tracker_android->sess, xret, "oxr_get_face_calibration_state_android"); 131 + 132 + *faceIsCalibratedOutput = face_is_calibrated; 133 + 134 + return oxr_session_success_result(facial_tracker_android->sess); 135 + }
+119
src/xrt/state_trackers/oxr/oxr_face_tracking_htc.c
··· 1 + // Copyright 2024, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief face tracking related API entrypoint functions. 6 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 + * @ingroup oxr_main 8 + */ 9 + 10 + #include <stdio.h> 11 + #include <stdlib.h> 12 + #include <string.h> 13 + 14 + #include "oxr_objects.h" 15 + #include "oxr_logger.h" 16 + #include "oxr_handle.h" 17 + 18 + static enum xrt_facial_tracking_type_htc 19 + oxr_to_xrt_facial_tracking_type_htc(enum XrFacialTrackingTypeHTC ft_type) 20 + { 21 + return (enum xrt_facial_tracking_type_htc)ft_type; 22 + } 23 + 24 + static enum xrt_input_name 25 + oxr_facial_tracking_type_htc_to_input_name(enum xrt_facial_tracking_type_htc ft_type) 26 + { 27 + switch (ft_type) { 28 + case XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC: return XRT_INPUT_HTC_LIP_FACE_TRACKING; 29 + case XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC: 30 + default: return XRT_INPUT_HTC_EYE_FACE_TRACKING; 31 + } 32 + } 33 + 34 + static XrResult 35 + oxr_facial_tracker_htc_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb) 36 + { 37 + struct oxr_facial_tracker_htc *face_tracker_htc = (struct oxr_facial_tracker_htc *)hb; 38 + free(face_tracker_htc); 39 + return XR_SUCCESS; 40 + } 41 + 42 + XrResult 43 + oxr_facial_tracker_htc_create(struct oxr_logger *log, 44 + struct oxr_session *sess, 45 + const XrFacialTrackerCreateInfoHTC *createInfo, 46 + struct oxr_facial_tracker_htc **out_face_tracker_htc) 47 + { 48 + bool supports_eye = false; 49 + bool supports_lip = false; 50 + oxr_system_get_face_tracking_htc_support(log, sess->sys->inst, &supports_eye, &supports_lip); 51 + 52 + const enum xrt_facial_tracking_type_htc facial_tracking_type = 53 + oxr_to_xrt_facial_tracking_type_htc(createInfo->facialTrackingType); 54 + 55 + if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC && !supports_eye) { 56 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC eye facial tracking"); 57 + } 58 + if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC && !supports_lip) { 59 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC lip facial tracking"); 60 + } 61 + 62 + struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, face); 63 + if (xdev == NULL) { 64 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "No device found for face tracking role"); 65 + } 66 + 67 + if (!xdev->supported.face_tracking) { 68 + return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "Device does not support HTC facial tracking"); 69 + } 70 + 71 + struct oxr_facial_tracker_htc *face_tracker_htc = NULL; 72 + OXR_ALLOCATE_HANDLE_OR_RETURN(log, face_tracker_htc, OXR_XR_DEBUG_FTRACKER, oxr_facial_tracker_htc_destroy_cb, 73 + &sess->handle); 74 + 75 + face_tracker_htc->sess = sess; 76 + face_tracker_htc->xdev = xdev; 77 + face_tracker_htc->facial_tracking_type = facial_tracking_type; 78 + 79 + *out_face_tracker_htc = face_tracker_htc; 80 + 81 + return XR_SUCCESS; 82 + } 83 + 84 + XrResult 85 + oxr_get_facial_expressions_htc(struct oxr_logger *log, 86 + struct oxr_facial_tracker_htc *facial_tracker_htc, 87 + XrFacialExpressionsHTC *facialExpressions) 88 + { 89 + const bool is_eye_tracking = 90 + facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC; 91 + const size_t expression_count = 92 + is_eye_tracking ? XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC : XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC; 93 + 94 + struct xrt_facial_expression_set facial_expression_set_result = {0}; 95 + float *expression_weights = is_eye_tracking 96 + ? facial_expression_set_result.eye_expression_set_htc.expression_weights 97 + : facial_expression_set_result.lip_expression_set_htc.expression_weights; 98 + memset(expression_weights, 0, sizeof(float) * expression_count); 99 + 100 + const enum xrt_input_name ft_input_name = 101 + oxr_facial_tracking_type_htc_to_input_name(facial_tracker_htc->facial_tracking_type); 102 + 103 + int64_t at_timestamp_ns = os_monotonic_get_ns(); 104 + 105 + xrt_device_get_face_tracking(facial_tracker_htc->xdev, ft_input_name, at_timestamp_ns, 106 + &facial_expression_set_result); 107 + 108 + facialExpressions->isActive = facial_expression_set_result.base_expression_set_htc.is_active; 109 + if (facialExpressions->isActive == XR_FALSE) 110 + return XR_SUCCESS; 111 + 112 + const struct oxr_instance *inst = facial_tracker_htc->sess->sys->inst; 113 + facialExpressions->sampleTime = time_state_monotonic_to_ts_ns( 114 + inst->timekeeping, facial_expression_set_result.base_expression_set_htc.sample_time_ns); 115 + 116 + memcpy(facialExpressions->expressionWeightings, expression_weights, sizeof(float) * expression_count); 117 + 118 + return XR_SUCCESS; 119 + }
+73 -31
src/xrt/state_trackers/oxr/oxr_input.c
··· 9 9 * @ingroup oxr_main 10 10 */ 11 11 12 - #include "b_generated_bindings_helpers.h" 13 12 #include "oxr_bindings/b_oxr_generated_bindings.h" 14 13 #include "util/u_debug.h" 15 14 #include "util/u_time.h" ··· 515 514 */ 516 515 517 516 static bool 517 + find_xdev_name_from_pairs(const struct xrt_device *xdev, 518 + const struct xrt_binding_profile *xbp, 519 + enum xrt_input_name from_name, 520 + enum xrt_input_name *out_name) 521 + { 522 + if (from_name == 0) { 523 + *out_name = 0; 524 + return true; // Not asking for anything, just keep going. 525 + } 526 + 527 + /* 528 + * For asymmetrical devices like PS Sense being re-bound to a symmetrical 529 + * "device" like simple controller can be problemantic as depending on 530 + * which hand it is menu is bound to different inputs. Instead of making 531 + * the driver have two completely unique binding mappings per hand, we 532 + * instead loop over all pairs finding the first match. In other words 533 + * this means there can be multiple of the same 'from' value in the 534 + * array of input pairs. 535 + */ 536 + for (size_t i = 0; i < xbp->input_count; i++) { 537 + if (from_name != xbp->inputs[i].from) { 538 + continue; 539 + } 540 + 541 + // What is the name on the xdev? 542 + enum xrt_input_name xdev_name = xbp->inputs[i].device; 543 + 544 + // See if we can't find it. 545 + for (uint32_t k = 0; k < xdev->input_count; k++) { 546 + if (xdev->inputs[k].name == xdev_name) { 547 + *out_name = xdev_name; 548 + return true; 549 + } 550 + } 551 + } 552 + 553 + return false; 554 + } 555 + 556 + static bool 518 557 do_inputs(struct oxr_binding *binding_point, 519 558 struct xrt_device *xdev, 520 559 struct xrt_binding_profile *xbp, ··· 523 562 uint32_t *input_count) 524 563 { 525 564 enum xrt_input_name name = 0; 526 - if (xbp == NULL) { 527 - name = binding_point->input; 528 - } else { 529 - for (size_t i = 0; i < xbp->input_count; i++) { 530 - if (binding_point->input != xbp->inputs[i].from) { 531 - continue; 532 - } 565 + enum xrt_input_name dpad_activate_name = 0; 533 566 534 - // We have found a device mapping. 535 - name = xbp->inputs[i].device; 536 - break; 537 - } 567 + if (xbp != NULL) { 568 + bool t1 = find_xdev_name_from_pairs(xdev, xbp, binding_point->input, &name); 569 + bool t2 = find_xdev_name_from_pairs(xdev, xbp, binding_point->dpad_activate, &dpad_activate_name); 538 570 539 - // Didn't find a mapping. 540 - if (name == 0) { 571 + // We couldn't find the needed inputs on the device. 572 + if (!t1 || !t2) { 541 573 return false; 542 574 } 575 + } else { 576 + name = binding_point->input; 577 + dpad_activate_name = binding_point->dpad_activate; 543 578 } 544 579 545 580 struct xrt_input *input = NULL; 546 - if (oxr_xdev_find_input(xdev, name, &input)) { 547 - uint32_t index = (*input_count)++; 548 - inputs[index].input = input; 549 - inputs[index].xdev = xdev; 550 - inputs[index].bound_path = matched_path; 551 - if (binding_point->dpad_activate != 0) { 552 - struct xrt_input *dpad_activate = NULL; 553 - if (!oxr_xdev_find_input(xdev, binding_point->dpad_activate, &dpad_activate)) { 554 - return false; 555 - } 556 - inputs[index].dpad_activate_name = binding_point->dpad_activate; 557 - inputs[index].dpad_activate = dpad_activate; 581 + struct xrt_input *dpad_activate_input = NULL; 582 + 583 + // Early out if there is no such input. 584 + if (!oxr_xdev_find_input(xdev, name, &input)) { 585 + return false; 586 + } 587 + 588 + // Check this before allocating an input. 589 + if (dpad_activate_name != 0) { 590 + if (!oxr_xdev_find_input(xdev, dpad_activate_name, &dpad_activate_input)) { 591 + return false; 558 592 } 559 - return true; 560 593 } 561 594 562 - return false; 595 + uint32_t index = (*input_count)++; 596 + inputs[index].input = input; 597 + inputs[index].xdev = xdev; 598 + inputs[index].bound_path = matched_path; 599 + if (dpad_activate_input != NULL) { 600 + inputs[index].dpad_activate_name = dpad_activate_name; 601 + inputs[index].dpad_activate = dpad_activate_input; 602 + } 603 + 604 + return true; 563 605 } 564 606 565 607 static bool ··· 771 813 if (found) { 772 814 if (xbp == NULL) { 773 815 oxr_slog(slog, "\t\t\t\tBound (xdev '%s'): %s!\n", xdev->str, 774 - xrt_input_name_string(binding_points[i]->input)); 816 + u_str_xrt_input_name(binding_points[i]->input)); 775 817 } else { 776 818 oxr_slog(slog, "\t\t\t\tBound (xbp)!\n"); 777 819 } ··· 1626 1668 // Only add the input if we can find a transform. 1627 1669 1628 1670 oxr_slog(slog, "\t\tFinding transforms for '%s' to action '%s' of type '%s'\n", 1629 - xrt_input_name_string(inputs[i].input->name), act_ref->name, 1671 + u_str_xrt_input_name(inputs[i].input->name), act_ref->name, 1630 1672 xr_action_type_to_str(act_ref->action_type)); 1631 1673 1632 1674 enum oxr_dpad_region dpad_region; ··· 1667 1709 struct xrt_input *input = cache->inputs[i].input; 1668 1710 enum xrt_input_type t = XRT_GET_INPUT_TYPE(input->name); 1669 1711 bool active = input->active; 1670 - oxr_slog(slog, "\t\t\t'%s' ('%s') on '%s' (%s)\n", xrt_input_name_string(input->name), 1712 + oxr_slog(slog, "\t\t\t'%s' ('%s') on '%s' (%s)\n", u_str_xrt_input_name(input->name), 1671 1713 xrt_input_type_to_str(t), cache->inputs[i].xdev->str, 1672 1714 active ? "active" : "inactive"); 1673 1715 }
+3
src/xrt/state_trackers/oxr/oxr_instance.c
··· 341 341 #ifdef OXR_HAVE_META_body_tracking_calibration 342 342 .meta_body_tracking_calibration_enabled = extensions->META_body_tracking_calibration, 343 343 #endif 344 + #ifdef OXR_HAVE_ANDROID_face_tracking 345 + .android_face_tracking_enabled = extensions->ANDROID_face_tracking, 346 + #endif 344 347 }; 345 348 snprintf(i_info.app_info.application_name, sizeof(i_info.app_info.application_name), "%s", 346 349 createInfo->applicationInfo.applicationName);
+58
src/xrt/state_trackers/oxr/oxr_objects.h
··· 127 127 struct oxr_action_set_ref; 128 128 struct oxr_action_ref; 129 129 struct oxr_hand_tracker; 130 + struct oxr_face_tracker_android; 130 131 struct oxr_facial_tracker_htc; 131 132 struct oxr_face_tracker2_fb; 132 133 struct oxr_body_tracker_fb; ··· 467 468 return XRT_CAST_PTR_TO_OXR_HANDLE(XrFaceTracker2FB, face_tracker2_fb); 468 469 } 469 470 #endif 471 + 472 + #ifdef OXR_HAVE_ANDROID_face_tracking 473 + /*! 474 + * To go back to a OpenXR object. 475 + * 476 + * @relates oxr_facial_tracker_htc 477 + */ 478 + static inline XrFaceTrackerANDROID 479 + oxr_face_tracker_android_to_openxr(struct oxr_face_tracker_android *face_tracker_android) 480 + { 481 + return XRT_CAST_PTR_TO_OXR_HANDLE(XrFaceTrackerANDROID, face_tracker_android); 482 + } 483 + #endif 484 + 470 485 /*! 471 486 * 472 487 * @name oxr_input.c ··· 1107 1122 1108 1123 bool 1109 1124 oxr_system_get_force_feedback_support(struct oxr_logger *log, struct oxr_instance *inst); 1125 + 1126 + void 1127 + oxr_system_get_face_tracking_android_support(struct oxr_logger *log, struct oxr_instance *inst, bool *supported); 1110 1128 1111 1129 void 1112 1130 oxr_system_get_face_tracking_htc_support(struct oxr_logger *log, ··· 3093 3111 XrResult 3094 3112 oxr_event_push_XrEventDataUserPresenceChangedEXT(struct oxr_logger *log, struct oxr_session *sess, bool isUserPresent); 3095 3113 #endif // OXR_HAVE_EXT_user_presence 3114 + 3115 + #ifdef OXR_HAVE_ANDROID_face_tracking 3116 + /*! 3117 + * Android specific Facial tracker. 3118 + * 3119 + * Parent type/handle is @ref oxr_instance 3120 + * 3121 + * 3122 + * @obj{XrFaceTrackerANDROID} 3123 + * @extends oxr_handle_base 3124 + */ 3125 + struct oxr_face_tracker_android 3126 + { 3127 + //! Common structure for things referred to by OpenXR handles. 3128 + struct oxr_handle_base handle; 3129 + 3130 + //! Owner of this face tracker. 3131 + struct oxr_session *sess; 3132 + 3133 + //! xrt_device backing this face tracker 3134 + struct xrt_device *xdev; 3135 + }; 3136 + 3137 + XrResult 3138 + oxr_face_tracker_android_create(struct oxr_logger *log, 3139 + struct oxr_session *sess, 3140 + const XrFaceTrackerCreateInfoANDROID *createInfo, 3141 + XrFaceTrackerANDROID *faceTracker); 3142 + 3143 + XrResult 3144 + oxr_get_face_state_android(struct oxr_logger *log, 3145 + struct oxr_face_tracker_android *facial_tracker_android, 3146 + const XrFaceStateGetInfoANDROID *getInfo, 3147 + XrFaceStateANDROID *faceStateOutput); 3148 + 3149 + XrResult 3150 + oxr_get_face_calibration_state_android(struct oxr_logger *log, 3151 + struct oxr_face_tracker_android *facial_tracker_android, 3152 + XrBool32 *faceIsCalibratedOutput); 3153 + #endif // OXR_HAVE_ANDROID_face_tracking 3096 3154 3097 3155 /*! 3098 3156 * @}
+145 -63
src/xrt/state_trackers/oxr/oxr_session.c
··· 317 317 #ifdef OXR_HAVE_META_body_tracking_calibration 318 318 .meta_body_tracking_calibration_enabled = extensions->META_body_tracking_calibration, 319 319 #endif 320 + #ifdef OXR_HAVE_ANDROID_face_tracking 321 + .android_face_tracking_enabled = extensions->ANDROID_face_tracking, 322 + #endif 320 323 }; 321 324 322 325 xrt_result_t xret = xrt_comp_begin_session(xc, &begin_session_info); ··· 336 339 sess->compositor_visible = true; 337 340 sess->compositor_focused = true; 338 341 342 + int64_t now = os_monotonic_get_ns(); 343 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 344 + if (now_xr <= 0) { 345 + // shouldn't happen but be sure to log if it does 346 + U_LOG_W("Time keeping oddity: XR_SESSION_STATE_SYNCHRONIZED state reached at XrTime %" PRIi64, 347 + now_xr); 348 + } 349 + 339 350 // Transition into focused. 340 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 341 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 342 - oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, 0); 351 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 352 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 353 + oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, now_xr); 343 354 } 344 355 XrResult ret = oxr_frame_sync_begin_session(&sess->frame_sync); 345 356 if (ret != XR_SUCCESS) { ··· 397 408 sess->compositor_focused = false; 398 409 } 399 410 400 - oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, 0); 411 + int64_t now = os_monotonic_get_ns(); 412 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 413 + if (now_xr <= 0) { 414 + // shouldn't happen but be sure to log if it does 415 + U_LOG_W("Time keeping oddity: ending session at XrTime %" PRIi64, now_xr); 416 + } 417 + 418 + oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, now_xr); 401 419 if (sess->exiting) { 402 - oxr_session_change_state(log, sess, XR_SESSION_STATE_EXITING, 0); 420 + oxr_session_change_state(log, sess, XR_SESSION_STATE_EXITING, now_xr); 403 421 } else { 404 422 #ifndef XRT_OS_ANDROID 405 423 // @todo In multi-clients scenario with a session being reused, changing session ··· 425 443 XrResult 426 444 oxr_session_request_exit(struct oxr_logger *log, struct oxr_session *sess) 427 445 { 446 + int64_t now = os_monotonic_get_ns(); 447 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 448 + if (now_xr <= 0) { 449 + // shouldn't happen but be sure to log if it does 450 + U_LOG_W("Time keeping oddity: Requesting exit at XrTime %" PRIi64, now_xr); 451 + } 452 + 428 453 if (sess->state == XR_SESSION_STATE_FOCUSED) { 429 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 454 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 430 455 } 431 456 if (sess->state == XR_SESSION_STATE_VISIBLE) { 432 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 457 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 433 458 } 434 459 if (!sess->has_ended_once && sess->state != XR_SESSION_STATE_SYNCHRONIZED) { 435 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 460 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 436 461 // Fake the synchronization. 437 462 sess->has_ended_once = true; 438 463 } 439 464 440 465 //! @todo start fading out the app. 441 - oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, 0); 466 + oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, now_xr); 442 467 sess->exiting = true; 443 468 return oxr_session_success_result(sess); 444 469 } ··· 474 499 return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "xrt_session is null"); 475 500 } 476 501 502 + int64_t now = os_monotonic_get_ns(); 503 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 504 + if (now_xr <= 0) { 505 + // shouldn't happen but be sure to log if it does 506 + U_LOG_W("Time keeping oddity: Polling session events at XrTime %" PRIi64, now_xr); 507 + } 508 + 477 509 #ifdef XRT_OS_ANDROID 478 510 // Most recent Android activity lifecycle event was OnPause: move toward stopping 479 511 if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_PAUSE) { 480 512 if (sess->state == XR_SESSION_STATE_FOCUSED) { 481 513 U_LOG_I("Activity paused: changing session state FOCUSED->VISIBLE"); 482 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 514 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 483 515 } 484 516 485 517 if (sess->state == XR_SESSION_STATE_VISIBLE) { 486 518 U_LOG_I("Activity paused: changing session state VISIBLE->SYNCHRONIZED"); 487 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 519 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 488 520 } 489 521 490 522 if (sess->state == XR_SESSION_STATE_SYNCHRONIZED) { 491 523 U_LOG_I("Activity paused: changing session state SYNCHRONIZED->STOPPING"); 492 - oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, 0); 524 + oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, now_xr); 493 525 } 494 526 // TODO return here to avoid polling other events? 495 527 // see https://gitlab.freedesktop.org/monado/monado/-/issues/419 ··· 499 531 if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_RESUME) { 500 532 if (sess->state == XR_SESSION_STATE_IDLE) { 501 533 U_LOG_I("Activity resumed: changing session state IDLE->READY"); 502 - oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, 0); 534 + oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, now_xr); 503 535 } 504 536 } 505 537 #endif // XRT_OS_ANDROID ··· 519 551 case XRT_SESSION_EVENT_STATE_CHANGE: 520 552 sess->compositor_visible = xse.state.visible; 521 553 sess->compositor_focused = xse.state.focused; 554 + 555 + // Do not use xse.state.timestamp_ns, server side focused / visible state does not correspond 556 + // 1:1 to the cycle we tell the app. In particular the compositor may have become focused / 557 + // visible much earlier than what we tell the app when it became so. 558 + 522 559 break; 523 560 case XRT_SESSION_EVENT_OVERLAY_CHANGE: 524 561 #ifdef OXR_HAVE_EXTX_overlay ··· 580 617 } 581 618 582 619 if (sess->state == XR_SESSION_STATE_SYNCHRONIZED && sess->compositor_visible) { 583 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 620 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 584 621 } 585 622 586 623 if (sess->state == XR_SESSION_STATE_VISIBLE && sess->compositor_focused) { 587 - oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, 0); 624 + oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, now_xr); 588 625 } 589 626 590 627 if (sess->state == XR_SESSION_STATE_FOCUSED && !sess->compositor_focused) { 591 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 628 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 592 629 } 593 630 594 631 if (sess->state == XR_SESSION_STATE_VISIBLE && !sess->compositor_visible) { 595 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 632 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 596 633 } 597 634 598 635 return XR_SUCCESS; ··· 1102 1139 } \ 1103 1140 } while (false) 1104 1141 1105 - #define OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(LOG, XSI, SESS) \ 1142 + #define OXR_CHECK_XR_SUCCESS(LOG, FUNC, MSG) \ 1106 1143 do { \ 1107 - if ((SESS)->sys->xsysc == NULL) { \ 1108 - return oxr_error((LOG), XR_ERROR_RUNTIME_FAILURE, \ 1109 - "The system compositor wasn't created, can't create native compositor!"); \ 1110 - } \ 1111 - xrt_result_t xret = xrt_system_create_session((SESS)->sys->xsys, (XSI), &(SESS)->xs, &(SESS)->xcn); \ 1112 - if (xret == XRT_ERROR_MULTI_SESSION_NOT_IMPLEMENTED) { \ 1113 - return oxr_error((LOG), XR_ERROR_LIMIT_REACHED, "Per instance multi-session not supported."); \ 1114 - } \ 1115 - if (xret != XRT_SUCCESS) { \ 1116 - return oxr_error((LOG), XR_ERROR_RUNTIME_FAILURE, \ 1117 - "Failed to create xrt_session and xrt_compositor_native! '%i'", xret); \ 1118 - } \ 1119 - if ((SESS)->sys->xsysc->xmcc != NULL) { \ 1120 - xrt_syscomp_set_state((SESS)->sys->xsysc, &(SESS)->xcn->base, true, true); \ 1121 - xrt_syscomp_set_z_order((SESS)->sys->xsysc, &(SESS)->xcn->base, 0); \ 1144 + XrResult _xr_result = FUNC; \ 1145 + if (_xr_result != XR_SUCCESS) { \ 1146 + return oxr_error(LOG, _xr_result, MSG); \ 1122 1147 } \ 1123 1148 } while (false) 1124 1149 1125 - #define OXR_SESSION_ALLOCATE_AND_INIT(LOG, SYS, GFX_TYPE, OUT) \ 1126 - do { \ 1127 - XrResult ret = oxr_session_allocate_and_init(LOG, SYS, GFX_TYPE, &OUT); \ 1128 - if (ret != XR_SUCCESS) { \ 1129 - return ret; \ 1130 - } \ 1131 - } while (0) 1150 + 1151 + 1152 + static XrResult 1153 + oxr_create_xrt_session_and_native_compositor(struct oxr_logger *log, 1154 + const struct xrt_session_info *xsi, 1155 + struct oxr_session *sess) 1156 + { 1157 + if (sess->sys->xsysc == NULL) { 1158 + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, 1159 + "The system compositor wasn't created, can't create native compositor!"); 1160 + } 1161 + xrt_result_t xret = xrt_system_create_session(sess->sys->xsys, xsi, &sess->xs, &sess->xcn); 1162 + if (xret == XRT_ERROR_MULTI_SESSION_NOT_IMPLEMENTED) { 1163 + return oxr_error(log, XR_ERROR_LIMIT_REACHED, "Per instance multi-session not supported."); 1164 + } 1165 + if (xret != XRT_SUCCESS) { 1166 + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, 1167 + "Failed to create xrt_session and xrt_compositor_native! '%i'", xret); 1168 + } 1169 + if (sess->sys->xsysc->xmcc != NULL) { 1170 + xrt_syscomp_set_state(sess->sys->xsysc, &sess->xcn->base, true, true, os_monotonic_get_ns()); 1171 + xrt_syscomp_set_z_order(sess->sys->xsysc, &sess->xcn->base, 0); 1172 + } 1173 + return XR_SUCCESS; 1174 + } 1175 + 1132 1176 1133 1177 1134 1178 /* ··· 1142 1186 const struct xrt_session_info *xsi, 1143 1187 struct oxr_session **out_session) 1144 1188 { 1189 + XrResult ret = XR_SUCCESS; 1190 + 1145 1191 #if defined(XR_USE_PLATFORM_XLIB) && defined(XR_USE_GRAPHICS_API_OPENGL) 1146 1192 XrGraphicsBindingOpenGLXlibKHR const *opengl_xlib = OXR_GET_INPUT_FROM_CHAIN( 1147 1193 createInfo, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR, XrGraphicsBindingOpenGLXlibKHR); ··· 1154 1200 "xrGetOpenGL[ES]GraphicsRequirementsKHR"); 1155 1201 } 1156 1202 1157 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_XLIB_GL, *out_session); 1158 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1203 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_XLIB_GL, out_session); 1204 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1205 + 1206 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1207 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1208 + 1159 1209 return oxr_session_populate_gl_xlib(log, sys, opengl_xlib, *out_session); 1160 1210 } 1161 1211 #endif ··· 1173 1223 "xrGetOpenGLESGraphicsRequirementsKHR"); 1174 1224 } 1175 1225 1176 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_ANDROID_GLES, *out_session); 1177 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1226 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_ANDROID_GLES, out_session); 1227 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1228 + 1229 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1230 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1231 + 1178 1232 return oxr_session_populate_gles_android(log, sys, opengles_android, *out_session); 1179 1233 } 1180 1234 #endif ··· 1190 1244 "Has not called xrGetOpenGLGraphicsRequirementsKHR"); 1191 1245 } 1192 1246 1193 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_WIN32_GL, *out_session); 1194 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1247 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_WIN32_GL, out_session); 1248 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1249 + 1250 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1251 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1252 + 1195 1253 return oxr_session_populate_gl_win32(log, sys, opengl_win32, *out_session); 1196 1254 } 1197 1255 #endif ··· 1229 1287 (void *)vulkan->physicalDevice, (void *)sys->suggested_vulkan_physical_device, fn); 1230 1288 } 1231 1289 1232 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_VULKAN, *out_session); 1233 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1290 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_VULKAN, out_session); 1291 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1292 + 1293 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1294 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1295 + 1234 1296 return oxr_session_populate_vk(log, sys, vulkan, *out_session); 1235 1297 } 1236 1298 #endif ··· 1247 1309 "xrGetOpenGL[ES]GraphicsRequirementsKHR"); 1248 1310 } 1249 1311 1250 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_EGL, *out_session); 1251 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1312 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_EGL, out_session); 1313 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1314 + 1315 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1316 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1317 + 1252 1318 return oxr_session_populate_egl(log, sys, egl, *out_session); 1253 1319 } 1254 1320 #endif ··· 1265 1331 return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING, 1266 1332 "Has not called xrGetD3D11GraphicsRequirementsKHR"); 1267 1333 } 1268 - XrResult result = oxr_d3d11_check_device(log, sys, d3d11->device); 1334 + ret = oxr_d3d11_check_device(log, sys, d3d11->device); 1269 1335 1270 - if (!XR_SUCCEEDED(result)) { 1271 - return result; 1336 + if (!XR_SUCCEEDED(ret)) { 1337 + return ret; 1272 1338 } 1273 1339 1340 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_D3D11, out_session); 1341 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1274 1342 1275 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_D3D11, *out_session); 1276 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1343 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1344 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1345 + 1277 1346 return oxr_session_populate_d3d11(log, sys, d3d11, *out_session); 1278 1347 } 1279 1348 #endif ··· 1290 1359 return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING, 1291 1360 "Has not called xrGetD3D12GraphicsRequirementsKHR"); 1292 1361 } 1293 - XrResult result = oxr_d3d12_check_device(log, sys, d3d12->device); 1362 + ret = oxr_d3d12_check_device(log, sys, d3d12->device); 1294 1363 1295 - if (!XR_SUCCEEDED(result)) { 1296 - return result; 1364 + if (!XR_SUCCEEDED(ret)) { 1365 + return ret; 1297 1366 } 1298 1367 1368 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_D3D12, out_session); 1369 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1370 + 1371 + ret = oxr_create_xrt_session_and_native_compositor(log, xsi, *out_session); 1372 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to create session/compositor"); 1299 1373 1300 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_D3D12, *out_session); 1301 - OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(log, xsi, *out_session); 1302 1374 return oxr_session_populate_d3d12(log, sys, d3d12, *out_session); 1303 1375 } 1304 1376 #endif ··· 1312 1384 1313 1385 #ifdef OXR_HAVE_MND_headless 1314 1386 if (sys->inst->extensions.MND_headless) { 1315 - OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_HEADLESS, *out_session); 1387 + 1388 + ret = oxr_session_allocate_and_init(log, sys, OXR_SESSION_GRAPHICS_EXT_HEADLESS, out_session); 1389 + OXR_CHECK_XR_SUCCESS(log, ret, "Failed to allocate session"); 1390 + 1316 1391 (*out_session)->compositor = NULL; 1317 1392 (*out_session)->create_swapchain = NULL; 1318 1393 ··· 1361 1436 return ret; 1362 1437 } 1363 1438 1439 + int64_t now = os_monotonic_get_ns(); 1440 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 1441 + if (now_xr <= 0) { 1442 + // shouldn't happen but be sure to log if it does 1443 + U_LOG_W("Time keeping oddity: XR_SESSION_STATE_IDLE reached at XrTime %" PRIi64, now_xr); 1444 + } 1445 + 1364 1446 // Everything is in order, start the state changes. 1365 - oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, 0); 1366 - oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, 0); 1447 + oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, now_xr); 1448 + oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, now_xr); 1367 1449 1368 1450 *out_session = sess; 1369 1451
+12 -5
src/xrt/state_trackers/oxr/oxr_session_frame_end.c
··· 1551 1551 } 1552 1552 1553 1553 static void 1554 - do_synchronize_state_change(struct oxr_logger *log, struct oxr_session *sess) 1554 + do_synchronize_state_change(struct oxr_logger *log, struct oxr_session *sess, XrTime time) 1555 1555 { 1556 1556 if (!sess->has_ended_once && sess->state < XR_SESSION_STATE_VISIBLE) { 1557 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 1557 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, time); 1558 1558 sess->has_ended_once = true; 1559 1559 } 1560 1560 } ··· 1663 1663 struct xrt_compositor *xc = sess->compositor; 1664 1664 1665 1665 1666 + int64_t now = os_monotonic_get_ns(); 1667 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 1668 + if (now_xr <= 0) { 1669 + // shouldn't happen but be sure to log if it does 1670 + U_LOG_W("Time keeping oddity: frame end at XrTime %" PRIi64, now_xr); 1671 + } 1672 + 1666 1673 /* 1667 1674 * Early out for headless sessions. 1668 1675 */ ··· 1673 1680 sess->active_wait_frames--; 1674 1681 os_mutex_unlock(&sess->active_wait_frames_lock); 1675 1682 1676 - do_synchronize_state_change(log, sess); 1683 + do_synchronize_state_change(log, sess, now_xr); 1677 1684 1678 1685 return oxr_session_success_result(sess); 1679 1686 } ··· 1716 1723 sess->frame_id.begun = -1; 1717 1724 sess->frame_started = false; 1718 1725 1719 - do_synchronize_state_change(log, sess); 1726 + do_synchronize_state_change(log, sess, now_xr); 1720 1727 1721 1728 return oxr_session_success_result(sess); 1722 1729 } ··· 1785 1792 */ 1786 1793 1787 1794 // Do state change if needed. 1788 - do_synchronize_state_change(log, sess); 1795 + do_synchronize_state_change(log, sess, now_xr); 1789 1796 1790 1797 struct xrt_layer_frame_data data = { 1791 1798 .frame_id = sess->frame_id.begun,
+36
src/xrt/state_trackers/oxr/oxr_system.c
··· 406 406 } 407 407 408 408 void 409 + oxr_system_get_face_tracking_android_support(struct oxr_logger *log, struct oxr_instance *inst, bool *supported) 410 + { 411 + assert(supported); 412 + 413 + *supported = false; 414 + struct oxr_system *sys = &inst->system; 415 + const struct xrt_device *face_xdev = GET_XDEV_BY_ROLE(sys, face); 416 + 417 + if (face_xdev == NULL || !face_xdev->supported.face_tracking || face_xdev->inputs == NULL) { 418 + return; 419 + } 420 + 421 + for (size_t input_idx = 0; input_idx < face_xdev->input_count; ++input_idx) { 422 + const struct xrt_input *input = &face_xdev->inputs[input_idx]; 423 + if (input->name == XRT_INPUT_ANDROID_FACE_TRACKING) { 424 + *supported = true; 425 + return; 426 + } 427 + } 428 + } 429 + 430 + void 409 431 oxr_system_get_face_tracking_htc_support(struct oxr_logger *log, 410 432 struct oxr_instance *inst, 411 433 bool *supports_eye, ··· 567 589 } 568 590 } 569 591 #endif 592 + 593 + #ifdef OXR_HAVE_ANDROID_face_tracking 594 + XrSystemFaceTrackingPropertiesANDROID *android_face_tracking_props = NULL; 595 + if (sys->inst->extensions.ANDROID_face_tracking) { 596 + android_face_tracking_props = OXR_GET_OUTPUT_FROM_CHAIN( 597 + properties, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_ANDROID, XrSystemFaceTrackingPropertiesANDROID); 598 + } 599 + 600 + if (android_face_tracking_props) { 601 + bool supported = false; 602 + oxr_system_get_face_tracking_android_support(log, sys->inst, &supported); 603 + android_face_tracking_props->supportsFaceTracking = supported; 604 + } 605 + #endif // OXR_HAVE_HTC_facial_tracking 570 606 571 607 #ifdef OXR_HAVE_HTC_facial_tracking 572 608 XrSystemFacialTrackingPropertiesHTC *htc_facial_tracking_props = NULL;
+7 -1
src/xrt/targets/sdl_test/sdl_compositor.c
··· 256 256 { 257 257 struct xrt_system_compositor_info *sys_info = &c->sys_info; 258 258 259 - // Required by OpenXR spec. 259 + /* 260 + * Required by OpenXR spec (minimum 16). 261 + * 262 + * NOTE: When using Vulkan compositor components (c/render, c/util), 263 + * call render_max_layers_capable() to clamp this value based on 264 + * actual device limits. 265 + */ 260 266 sys_info->max_layers = XRT_MAX_LAYERS; 261 267 262 268 // UUIDs and LUID already set in vk init.
-1
src/xrt/tracking/hand/mercury/hg_sync.cpp
··· 25 25 26 26 27 27 namespace xrt::tracking::hand::mercury { 28 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 29 28 30 29 DEBUG_GET_ONCE_LOG_OPTION(mercury_log, "MERCURY_LOG", U_LOGGING_WARN) 31 30 DEBUG_GET_ONCE_BOOL_OPTION(mercury_optimize_hand_size, "MERCURY_optimize_hand_size", true)
+4 -10
src/xrt/tracking/hand/t_hand_tracking_async.c
··· 137 137 struct xrt_space_relation wrist_rel = 138 138 hta->working.hands[i].values.hand_joint_set_default[XRT_HAND_JOINT_WRIST].relation; 139 139 140 - m_relation_history_estimate_motion( // 141 - hta->present.relation_hist[i], // 142 - &wrist_rel, // 143 - hta->working.timestamp, // 144 - &wrist_rel); // 145 - 146 - m_relation_history_push( // 147 - hta->present.relation_hist[i], // 148 - &wrist_rel, // 149 - hta->working.timestamp); // 140 + m_relation_history_push_with_motion_estimation( // 141 + hta->present.relation_hist[i], // 142 + &wrist_rel, // 143 + hta->working.timestamp); // 150 144 } 151 145 152 146 hta->hand_tracking_work_active = false;
+13 -15
tests/tests_aux_d3d_d3d11.cpp
··· 88 88 std::vector<xrt_image_native> xins; 89 89 xins.reserve(image_count); 90 90 91 - // Keep this around until after successful import, then detach all. 92 - std::vector<wil::unique_handle> handlesForImport; 93 - handlesForImport.reserve(image_count); 94 - 95 91 for (HANDLE handle : handles) { 96 - wil::unique_handle duped{u_graphics_buffer_ref(handle)}; 92 + /*! 93 + * If shared resources have been allocated without using NT handles we can't use DuplicateHandle 94 + *(like u_graphics_buffer_ref does internally) or CloseHandle (which wil::~unique_handle will call). 95 + * More info: 96 + * https://learn.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiresource-getsharedhandle#remarks 97 + * When using KMT handles, their validity is tied to the underlying video memory (I guess that means a 98 + * ID3D11Texture2D object). 99 + */ 97 100 xrt_image_native xin; 98 - xin.handle = duped.get(); 101 + xin.handle = handle; 99 102 xin.size = 0; 100 103 xin.use_dedicated_allocation = use_dedicated_allocation; 104 + xin.is_dxgi_handle = true; 101 105 102 - handlesForImport.emplace_back(std::move(duped)); 103 106 xins.emplace_back(xin); 104 107 } 105 108 106 109 // Import into a vulkan image collection 107 - bool result = VK_SUCCESS == vk_ic_from_natives(vk, &vk_info, xins.data(), (uint32_t)xins.size(), vkic.get()); 110 + const VkResult ret = vk_ic_from_natives(vk, &vk_info, xins.data(), (uint32_t)xins.size(), vkic.get()); 111 + VK_CHK_WITH_RET(ret, "vk_ic_from_natives", false); 108 112 109 - if (result) { 110 - // The imported swapchain took ownership of them now, release them from ownership here. 111 - for (auto &h : handlesForImport) { 112 - h.release(); 113 - } 114 - } 115 - return result; 113 + return true; 116 114 } 117 115 #else 118 116