+1
-2
.gitlab-ci/templates/.gitlab-ci.yml.jinja
+1
-2
.gitlab-ci/templates/.gitlab-ci.yml.jinja
···
142
- .gitlab-ci/ci-cmake-build.sh {{- make_cmake_args(job.cmake_defines) }}
143
{%- if job.pahole %}
144
145
-
- src/xrt/ipc/shared/proto.py src/xrt/ipc/shared/proto.json structs.txt
146
- 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 %}
148
149
{#- gradle builds -#}
150
{%- elif "android" in job.name %}
···
142
- .gitlab-ci/ci-cmake-build.sh {{- make_cmake_args(job.cmake_defines) }}
143
{%- if job.pahole %}
144
145
- mkdir -p "{{ job.name}}"
146
+
- pahole --sizes --class_name file://build/ipc-structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "{{ job.name}}/ipc-sizes.txt"{% endif %}
147
148
{#- gradle builds -#}
149
{%- elif "android" in job.name %}
+3
-3
.gitlab-ci/templates/include.win_containers.yml
+3
-3
.gitlab-ci/templates/include.win_containers.yml
···
1
# {#- included by .gitlab-ci.yml.jinja #}
2
# {#- SPDX-License-Identifier: CC0-1.0 #}
3
-
# {#- SPDX-FileCopyrightText: 2018-2022 Collabora, Ltd. and the Monado contributors #}
4
5
###
6
# Windows container-related jobs (prep and usage)
···
9
inherit:
10
default: false
11
variables:
12
-
MONADO_WIN_BASE_TAG: "20250418.0"
13
-
MONADO_WIN_MAIN_TAG: "20250418.0"
14
MONADO_BASE_IMAGE_PATH: "win2022/vs2022_base"
15
MONADO_MAIN_IMAGE_PATH: "win2022/vs2022"
16
···
1
# {#- included by .gitlab-ci.yml.jinja #}
2
# {#- SPDX-License-Identifier: CC0-1.0 #}
3
+
# {#- SPDX-FileCopyrightText: 2018-2025 Collabora, Ltd. and the Monado contributors #}
4
5
###
6
# Windows container-related jobs (prep and usage)
···
9
inherit:
10
default: false
11
variables:
12
+
MONADO_WIN_BASE_TAG: "20251127.3"
13
+
MONADO_WIN_MAIN_TAG: "20251127.3"
14
MONADO_BASE_IMAGE_PATH: "win2022/vs2022_base"
15
MONADO_MAIN_IMAGE_PATH: "win2022/vs2022"
16
+3
-3
.gitlab-ci/windows/monado_deps_build.ps1
+3
-3
.gitlab-ci/windows/monado_deps_build.ps1
···
1
# Copyright 2019-2022, Mesa contributors
2
-
# Copyright 2022, Collabora, Ltd.
3
# SPDX-License-Identifier: MIT
4
# Based on https://gitlab.freedesktop.org/mesa/mesa/-/blob/8396df5ad90aeb6ab2267811aba2187954562f81/.gitlab-ci/windows/mesa_deps_build.ps1
5
6
-
$VulkanRTVersion = "1.3.283.0"
7
8
# Download new TLS certs from Windows Update
9
Get-Date
···
28
Get-Date
29
Write-Host "Installing Vulkan runtime components"
30
$VulkanInstaller = "C:\VulkanRTInstaller.exe"
31
-
Invoke-WebRequest -Uri "https://sdk.lunarg.com/sdk/download/$VulkanRTVersion/windows/VulkanRT-$VulkanRTVersion-Installer.exe" -OutFile "$VulkanInstaller"
32
Start-Process -NoNewWindow -Wait "$VulkanInstaller" -ArgumentList "/S"
33
if (!$?) {
34
Write-Host "Failed to install Vulkan runtime components"
···
1
# Copyright 2019-2022, Mesa contributors
2
+
# Copyright 2022-2025, Collabora, Ltd.
3
# SPDX-License-Identifier: MIT
4
# Based on https://gitlab.freedesktop.org/mesa/mesa/-/blob/8396df5ad90aeb6ab2267811aba2187954562f81/.gitlab-ci/windows/mesa_deps_build.ps1
5
6
+
$VulkanRTVersion = "1.4.328.1"
7
8
# Download new TLS certs from Windows Update
9
Get-Date
···
28
Get-Date
29
Write-Host "Installing Vulkan runtime components"
30
$VulkanInstaller = "C:\VulkanRTInstaller.exe"
31
+
Invoke-WebRequest -Uri "https://sdk.lunarg.com/sdk/download/$VulkanRTVersion/windows/VulkanRT-X64-$VulkanRTVersion-Installer.exe" -OutFile "$VulkanInstaller"
32
Start-Process -NoNewWindow -Wait "$VulkanInstaller" -ArgumentList "/S"
33
if (!$?) {
34
Write-Host "Failed to install Vulkan runtime components"
+2
-2
.gitlab-ci/windows/monado_deps_vs2022.ps1
+2
-2
.gitlab-ci/windows/monado_deps_vs2022.ps1
···
1
# Copyright 2019-2022, Mesa contributors
2
-
# Copyright 2022, Collabora, Ltd.
3
# SPDX-License-Identifier: MIT
4
# Based on https://gitlab.freedesktop.org/mesa/mesa/-/blob/8396df5ad90aeb6ab2267811aba2187954562f81/.gitlab-ci/windows/mesa_deps_vs2019.ps1
5
···
29
"--add"
30
"Microsoft.VisualStudio.Component.Windows10SDK"
31
"--add"
32
-
"Microsoft.VisualStudio.Component.Windows11SDK.22000"
33
"--add"
34
"Component.Microsoft.Windows.CppWinRT"
35
"--add"
···
1
# Copyright 2019-2022, Mesa contributors
2
+
# Copyright 2022-2025, Collabora, Ltd.
3
# SPDX-License-Identifier: MIT
4
# Based on https://gitlab.freedesktop.org/mesa/mesa/-/blob/8396df5ad90aeb6ab2267811aba2187954562f81/.gitlab-ci/windows/mesa_deps_vs2019.ps1
5
···
29
"--add"
30
"Microsoft.VisualStudio.Component.Windows10SDK"
31
"--add"
32
+
"Microsoft.VisualStudio.Component.Windows11SDK.26100"
33
"--add"
34
"Component.Microsoft.Windows.CppWinRT"
35
"--add"
+4
-6
.gitlab-ci.yml
+4
-6
.gitlab-ci.yml
···
56
inherit:
57
default: false
58
variables:
59
-
MONADO_WIN_BASE_TAG: "20250418.0"
60
-
MONADO_WIN_MAIN_TAG: "20250418.0"
61
MONADO_BASE_IMAGE_PATH: "win2022/vs2022_base"
62
MONADO_MAIN_IMAGE_PATH: "win2022/vs2022"
63
···
369
370
- .gitlab-ci/prebuild.sh
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
- 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"
375
- cd build && ctest --output-on-failure
376
artifacts:
377
paths:
···
408
409
- .gitlab-ci/prebuild.sh
410
- .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
- 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"
414
- cd build && ctest --output-on-failure
415
artifacts:
416
paths:
···
56
inherit:
57
default: false
58
variables:
59
+
MONADO_WIN_BASE_TAG: "20251127.3"
60
+
MONADO_WIN_MAIN_TAG: "20251127.3"
61
MONADO_BASE_IMAGE_PATH: "win2022/vs2022_base"
62
MONADO_MAIN_IMAGE_PATH: "win2022/vs2022"
63
···
369
370
- .gitlab-ci/prebuild.sh
371
- .gitlab-ci/ci-cmake-build.sh -DCMAKE_BUILD_TYPE=Debug -DXRT_HAVE_OPENCV=OFF
372
- mkdir -p "debian:cmake-no-opencv"
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"
374
- cd build && ctest --output-on-failure
375
artifacts:
376
paths:
···
407
408
- .gitlab-ci/prebuild.sh
409
- .gitlab-ci/ci-cmake-build.sh -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=.gitlab-ci/i386.cmake -DXRT_HAVE_OPENCV=OFF
410
- mkdir -p "debian:cmake:32bit"
411
+
- pahole --sizes --class_name file://build/ipc-structs.txt build/src/xrt/targets/openxr/libopenxr_monado.so > "debian:cmake:32bit/ipc-sizes.txt"
412
- cd build && ctest --output-on-failure
413
artifacts:
414
paths:
+2
CMakeLists.txt
+2
CMakeLists.txt
···
58
include(OptionWithDeps)
59
include(SPIR-V)
60
include(GNUInstallDirs)
61
if(NOT GIT_DESC)
62
include(GetGitRevisionDescription)
63
git_describe(GIT_DESC "--always")
···
367
option(XRT_FEATURE_OPENXR_ACTIVE_ACTION_SET_PRIORITY "Enable XR_EXT_active_action_set_priority" ON)
368
option(XRT_FEATURE_OPENXR_BODY_TRACKING_FB "Enable XR_FB_body_tracking" OFF)
369
option(XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE "Enable XR_FB_display_refresh_rate" ON)
370
option(XRT_FEATURE_OPENXR_FACE_TRACKING2_FB "Enable XR_FB_face_tracking2" OFF)
371
option(XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC "Enable XR_HTC_facial_tracking" OFF)
372
option(XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL "Enable XR_MNDX_force_feedback_curl" ON)
···
58
include(OptionWithDeps)
59
include(SPIR-V)
60
include(GNUInstallDirs)
61
+
include(MergeJSON)
62
if(NOT GIT_DESC)
63
include(GetGitRevisionDescription)
64
git_describe(GIT_DESC "--always")
···
368
option(XRT_FEATURE_OPENXR_ACTIVE_ACTION_SET_PRIORITY "Enable XR_EXT_active_action_set_priority" ON)
369
option(XRT_FEATURE_OPENXR_BODY_TRACKING_FB "Enable XR_FB_body_tracking" OFF)
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)
372
option(XRT_FEATURE_OPENXR_FACE_TRACKING2_FB "Enable XR_FB_face_tracking2" OFF)
373
option(XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC "Enable XR_HTC_facial_tracking" OFF)
374
option(XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL "Enable XR_MNDX_force_feedback_curl" ON)
+77
cmake/MergeJSON.cmake
+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
+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
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
doc/changes/ipc/mr.2644.md
···
···
1
+
Bump IPC_MAX_CLIENTS from 8 to 32.
+2
doc/changes/misc_features/mr.2605.md
+2
doc/changes/misc_features/mr.2605.md
+1
doc/changes/misc_fixes/mr.2579.md
+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
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
+3
doc/changes/xrt/mr.2633.md
+1
scripts/generate_oxr_ext_support.py
+1
scripts/generate_oxr_ext_support.py
···
76
['XR_EXT_samsung_odyssey_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'],
77
['XR_EXT_user_presence', 'XRT_FEATURE_OPENXR_USER_PRESENCE'],
78
# Vendor extensions, sorted alphabetically.
79
['XR_BD_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE'],
80
['XR_FB_body_tracking', 'XRT_FEATURE_OPENXR_BODY_TRACKING_FB'],
81
['XR_FB_composition_layer_alpha_blend', 'XRT_FEATURE_OPENXR_LAYER_FB_ALPHA_BLEND'],
···
76
['XR_EXT_samsung_odyssey_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'],
77
['XR_EXT_user_presence', 'XRT_FEATURE_OPENXR_USER_PRESENCE'],
78
# Vendor extensions, sorted alphabetically.
79
+
['XR_ANDROID_face_tracking', 'XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID'],
80
['XR_BD_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE'],
81
['XR_FB_body_tracking', 'XRT_FEATURE_OPENXR_BODY_TRACKING_FB'],
82
['XR_FB_composition_layer_alpha_blend', 'XRT_FEATURE_OPENXR_LAYER_FB_ALPHA_BLEND'],
+1
scripts/mapping.imp
+1
scripts/mapping.imp
···
40
{ symbol: ["XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META", "public", "\"xrt/xrt_config_build.h\"", "public"] },
41
{ symbol: ["XRT_FEATURE_OPENXR_DEBUG_UTILS", "public", "\"xrt/xrt_config_build.h\"", "public"] },
42
{ symbol: ["XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE", "public", "\"xrt/xrt_config_build.h\"", "public"] },
43
{ symbol: ["XRT_FEATURE_OPENXR_FACE_TRACKING2_FB", "public", "\"xrt/xrt_config_build.h\"", "public"] },
44
{ symbol: ["XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC", "public", "\"xrt/xrt_config_build.h\"", "public"] },
45
{ symbol: ["XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL", "public", "\"xrt/xrt_config_build.h\"", "public"] },
···
40
{ symbol: ["XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META", "public", "\"xrt/xrt_config_build.h\"", "public"] },
41
{ symbol: ["XRT_FEATURE_OPENXR_DEBUG_UTILS", "public", "\"xrt/xrt_config_build.h\"", "public"] },
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"] },
44
{ symbol: ["XRT_FEATURE_OPENXR_FACE_TRACKING2_FB", "public", "\"xrt/xrt_config_build.h\"", "public"] },
45
{ symbol: ["XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC", "public", "\"xrt/xrt_config_build.h\"", "public"] },
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
-17
src/xrt/auxiliary/bindings/b_generated_bindings_helpers.c.template
···
14
15
// clang-format off
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
enum xrt_input_name
26
xrt_input_name_enum(const char *input)
27
{
28
$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
}
39
40
enum xrt_output_name
-6
src/xrt/auxiliary/bindings/b_generated_bindings_helpers.h
-6
src/xrt/auxiliary/bindings/b_generated_bindings_helpers.h
···
17
extern "C" {
18
#endif
19
20
-
const char *
21
-
xrt_input_name_string(enum xrt_input_name input);
22
-
23
enum xrt_input_name
24
xrt_input_name_enum(const char *input);
25
-
26
-
const char *
27
-
xrt_output_name_string(enum xrt_output_name output);
28
29
enum xrt_output_name
30
xrt_output_name_enum(const char *output);
-12
src/xrt/auxiliary/bindings/bindings.py
-12
src/xrt/auxiliary/bindings/bindings.py
···
588
inputs.add("XRT_INPUT_HT_CONFORMING_RIGHT")
589
inputs.add("XRT_INPUT_GENERIC_TRACKER_POSE")
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
xrt_input_name_enum_content = '\n'.join(
597
[f'\tif(strcmp("{input}", input) == 0) return {input};' for input in sorted(inputs)]
598
)
599
xrt_input_name_enum_content += f'\n\treturn XRT_INPUT_GENERIC_TRACKER_POSE;'
600
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
xrt_output_name_enum_content = '\n'.join(
607
[f'\tif(strcmp("{output}", output) == 0) return {output};' for output in sorted(outputs)]
608
)
···
614
615
with open(file, "w") as f:
616
filled = src.substitute(
617
-
xrt_input_name_string_switch=xrt_input_name_string_switch,
618
xrt_input_name_enum_content=xrt_input_name_enum_content,
619
-
xrt_output_name_string_switch=xrt_output_name_string_switch,
620
xrt_output_name_enum_content=xrt_output_name_enum_content
621
)
622
f.write(filled)
···
588
inputs.add("XRT_INPUT_HT_CONFORMING_RIGHT")
589
inputs.add("XRT_INPUT_GENERIC_TRACKER_POSE")
590
591
xrt_input_name_enum_content = '\n'.join(
592
[f'\tif(strcmp("{input}", input) == 0) return {input};' for input in sorted(inputs)]
593
)
594
xrt_input_name_enum_content += f'\n\treturn XRT_INPUT_GENERIC_TRACKER_POSE;'
595
596
xrt_output_name_enum_content = '\n'.join(
597
[f'\tif(strcmp("{output}", output) == 0) return {output};' for output in sorted(outputs)]
598
)
···
604
605
with open(file, "w") as f:
606
filled = src.substitute(
607
xrt_input_name_enum_content=xrt_input_name_enum_content,
608
xrt_output_name_enum_content=xrt_output_name_enum_content
609
)
610
f.write(filled)
+21
src/xrt/auxiliary/math/m_api.h
+21
src/xrt/auxiliary/math/m_api.h
···
18
19
#include "xrt/xrt_defines.h"
20
21
+
#include "math/m_mathinclude.h"
22
+
23
#ifdef __cplusplus
24
extern "C" {
25
#endif
···
76
* @ingroup aux_math
77
*/
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
98
99
100
/*
+37
-33
src/xrt/auxiliary/math/m_relation_history.cpp
+37
-33
src/xrt/auxiliary/math/m_relation_history.cpp
···
183
}
184
}
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)
191
{
192
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
-
};
198
199
-
float dt = (float)time_ns_to_s(timestamp - last_time_ns);
200
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);
212
213
-
outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT);
214
215
-
out_relation->linear_velocity = (in_relation->pose.position - last_relation.pose.position) / dt;
216
}
217
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);
221
222
-
outf = (enum xrt_space_relation_flags)(outf | XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT);
223
224
-
math_quat_finite_difference(&last_relation.pose.orientation, &in_relation->pose.orientation, dt,
225
-
&out_relation->angular_velocity);
226
}
227
228
-
out_relation->pose = in_relation->pose;
229
-
230
-
return true;
231
}
232
233
bool
···
183
}
184
}
185
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)
193
{
194
+
assert(dt != 0.0f);
195
196
+
enum xrt_space_relation_flags shared_flags =
197
+
(enum xrt_space_relation_flags)(old_relation.relation_flags & new_relation.relation_flags);
198
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);
202
203
+
out_linear_velocity = (new_relation.pose.position - old_relation.pose.position) / dt;
204
+
}
205
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);
209
210
+
math_quat_finite_difference(&old_relation.pose.orientation, &new_relation.pose.orientation, dt,
211
+
&out_angular_velocity);
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);
222
223
+
struct xrt_space_relation final_relation = *in_relation;
224
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);
229
230
+
m_relation_history_estimate_motion(last_relation, *in_relation, dt, final_relation.linear_velocity,
231
+
final_relation.angular_velocity, final_relation.relation_flags);
232
}
233
234
+
return m_relation_history_push(rh, &final_relation, timestamp);
235
}
236
237
bool
+15
-17
src/xrt/auxiliary/math/m_relation_history.h
+15
-17
src/xrt/auxiliary/math/m_relation_history.h
···
63
m_relation_history_push(struct m_relation_history *rh, struct xrt_space_relation const *in_relation, int64_t timestamp);
64
65
/*!
66
-
* Interpolates or extrapolates to the desired timestamp.
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.
70
*
71
* @public @memberof m_relation_history
72
*/
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);
77
78
/*!
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).
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.
85
*
86
* @public @memberof m_relation_history
87
*/
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);
93
94
/*!
95
* Get the latest report in the buffer, if any.
···
63
m_relation_history_push(struct m_relation_history *rh, struct xrt_space_relation const *in_relation, int64_t timestamp);
64
65
/*!
66
+
* Pushes a new pose to the history, estimating linear and angular velocity based on the previous entry.
67
*
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
71
*
72
* @public @memberof m_relation_history
73
*/
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);
78
79
/*!
80
+
* Interpolates or extrapolates to the desired timestamp.
81
*
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.
84
*
85
* @public @memberof m_relation_history
86
*/
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);
91
92
/*!
93
* Get the latest report in the buffer, if any.
+2
src/xrt/auxiliary/util/CMakeLists.txt
+2
src/xrt/auxiliary/util/CMakeLists.txt
+2
-1
src/xrt/auxiliary/util/u_config_json.c
+2
-1
src/xrt/auxiliary/util/u_config_json.c
···
14
#include "util/u_file.h"
15
#include "util/u_json.h"
16
#include "util/u_debug.h"
17
18
#include "u_config_json.h"
19
···
504
505
cJSON_AddItemToObject(entry, "offset", make_pose(&overrides[i].offset));
506
507
-
const char *input_name_string = xrt_input_name_string(overrides[i].input_name);
508
cJSON_AddStringToObject(entry, "xrt_input_name", input_name_string);
509
510
cJSON_AddItemToArray(o, entry);
···
14
#include "util/u_file.h"
15
#include "util/u_json.h"
16
#include "util/u_debug.h"
17
+
#include "util/u_pretty_print.h"
18
19
#include "u_config_json.h"
20
···
505
506
cJSON_AddItemToObject(entry, "offset", make_pose(&overrides[i].offset));
507
508
+
const char *input_name_string = u_str_xrt_input_name(overrides[i].input_name);
509
cJSON_AddStringToObject(entry, "xrt_input_name", input_name_string);
510
511
cJSON_AddItemToArray(o, entry);
+50
-189
src/xrt/auxiliary/util/u_device.c
+50
-189
src/xrt/auxiliary/util/u_device.c
···
11
*/
12
13
#include "util/u_device.h"
14
#include "util/u_logging.h"
15
#include "util/u_misc.h"
16
#include "util/u_visibility_mask.h"
···
511
512
/*
513
*
514
-
* Not implemented function helpers.
515
*
516
*/
517
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)
639
{
640
-
E(get_view_poses);
641
-
return XRT_ERROR_NOT_IMPLEMENTED;
642
-
}
643
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
-
}
651
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
-
}
661
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
-
}
671
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
-
}
678
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;
712
}
···
11
*/
12
13
#include "util/u_device.h"
14
+
#include "util/u_device_ni.h"
15
#include "util/u_logging.h"
16
#include "util/u_misc.h"
17
#include "util/u_visibility_mask.h"
···
512
513
/*
514
*
515
+
* Helper function to fill in defaults.
516
*
517
*/
518
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)
523
{
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
+
}
528
529
+
if (destroy_fn == NULL) {
530
+
U_LOG_E("Got destroy_fn == NULL!");
531
+
assert(destroy_fn != NULL);
532
+
}
533
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;
539
540
+
// This must be implemented by the driver.
541
+
xdev->get_tracked_pose = get_tracked_pose_fn;
542
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;
570
571
+
// This must be implemented by the driver.
572
+
xdev->destroy = destroy_fn;
573
}
+21
-203
src/xrt/auxiliary/util/u_device.h
+21
-203
src/xrt/auxiliary/util/u_device.h
···
206
207
/*
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.
392
*
393
-
* @ingroup aux_util
394
*/
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
398
/*!
399
-
* Not implemented function for @ref xrt_device::get_brightness.
400
*
401
* @ingroup aux_util
402
*/
403
-
xrt_result_t
404
-
u_device_ni_get_brightness(struct xrt_device *xdev, float *out_brightness);
405
406
/*!
407
-
* Not implemented function for @ref xrt_device::set_brightness.
408
*
409
* @ingroup aux_util
410
*/
411
-
xrt_result_t
412
-
u_device_ni_set_brightness(struct xrt_device *xdev, float brightness, bool relative);
413
414
/*!
415
-
* Not implemented function for @ref xrt_device::begin_feature.
416
*
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.
424
*
425
* @ingroup aux_util
426
*/
427
-
xrt_result_t
428
-
u_device_ni_end_feature(struct xrt_device *xdev, enum xrt_device_feature_type type);
429
-
430
431
#ifdef __cplusplus
432
}
···
206
207
/*
208
*
209
+
* Helper function to fill in defaults.
210
*
211
*/
212
213
/*!
214
+
* Function pointer type for the device's get_tracked_pose function.
215
*
216
* @ingroup aux_util
217
*/
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);
222
223
/*!
224
+
* Function pointer type for the device's destroy function.
225
*
226
* @ingroup aux_util
227
*/
228
+
typedef void (*u_device_destroy_function_t)(struct xrt_device *xdev);
229
230
/*!
231
+
* Populate the device's function pointers with default implementations.
232
*
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.
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.
242
* @ingroup aux_util
243
*/
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);
248
249
#ifdef __cplusplus
250
}
+217
src/xrt/auxiliary/util/u_device_ni.c
+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
+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
-2
src/xrt/auxiliary/util/u_hand_simulation.c
-2
src/xrt/auxiliary/util/u_hand_tracking.c
-2
src/xrt/auxiliary/util/u_hand_tracking.c
+86
-52
src/xrt/auxiliary/util/u_pretty_print.c
+86
-52
src/xrt/auxiliary/util/u_pretty_print.c
···
1
// Copyright 2022-2024, Collabora, Ltd.
2
// SPDX-License-Identifier: BSL-1.0
3
/*!
4
* @file
···
39
case XRT_INPUT_TYPE_HAND_TRACKING: return "HAND_TRACKING";
40
case XRT_INPUT_TYPE_FACE_TRACKING: return "FACE_TRACKING";
41
case XRT_INPUT_TYPE_BODY_TRACKING: return "BODY_TRACKING";
42
-
default: return "<UNKNOWN>";
43
}
44
}
45
46
void
···
70
71
/*
72
*
73
* 'Exported' functions.
74
*
75
*/
···
112
void
113
u_pp_xrt_input_name(struct u_pp_delegate dg, enum xrt_input_name name)
114
{
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)
120
}
121
122
-
#undef XRT_INPUT_LIST_TO_CASE
123
-
124
/*
125
-
* No default case so we get warnings of missing entries.
126
* Invalid values handled below.
127
*/
128
···
136
void
137
u_pp_xrt_output_name(struct u_pp_delegate dg, enum xrt_output_name name)
138
{
139
-
#define XRT_OUTPUT_CASE(NAME) \
140
-
case NAME: DG(#NAME); return
141
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);
148
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);
153
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
185
}
186
187
void
···
234
case XRT_OPERATION_CANCELLED: DG("XRT_OPERATION_CANCELLED"); return;
235
case XRT_ERROR_FUTURE_RESULT_NOT_READY: DG("XRT_ERROR_FUTURE_RESULT_NOT_READY"); return;
236
case XRT_ERROR_FUTURE_ALREADY_COMPLETE: DG("XRT_ERROR_FUTURE_ALREADY_COMPLETE"); return;
237
}
238
// clang-format on
239
···
1
// Copyright 2022-2024, Collabora, Ltd.
2
+
// Copyright 2025, NVIDIA CORPORATION.
3
// SPDX-License-Identifier: BSL-1.0
4
/*!
5
* @file
···
40
case XRT_INPUT_TYPE_HAND_TRACKING: return "HAND_TRACKING";
41
case XRT_INPUT_TYPE_FACE_TRACKING: return "FACE_TRACKING";
42
case XRT_INPUT_TYPE_BODY_TRACKING: return "BODY_TRACKING";
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>";
57
}
58
59
void
···
83
84
/*
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
+
*
141
* 'Exported' functions.
142
*
143
*/
···
180
void
181
u_pp_xrt_input_name(struct u_pp_delegate dg, enum xrt_input_name name)
182
{
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;
187
}
188
189
/*
190
* Invalid values handled below.
191
*/
192
···
200
void
201
u_pp_xrt_output_name(struct u_pp_delegate dg, enum xrt_output_name name)
202
{
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
+
}
208
209
+
/*
210
+
* Invalid values handled below.
211
+
*/
212
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);
216
217
+
u_pp(dg, "XRT_OUTPUT_0x%04x_%s", id, str);
218
}
219
220
void
···
267
case XRT_OPERATION_CANCELLED: DG("XRT_OPERATION_CANCELLED"); return;
268
case XRT_ERROR_FUTURE_RESULT_NOT_READY: DG("XRT_ERROR_FUTURE_RESULT_NOT_READY"); return;
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;
271
}
272
// clang-format on
273
+43
src/xrt/auxiliary/util/u_pretty_print.h
+43
src/xrt/auxiliary/util/u_pretty_print.h
···
29
* they can easily be chained together to form a debug message printing out
30
* various information. Most of the final logging functions in Monado inserts a
31
* newline at the end of the message and we don't want two to be inserted.
32
*/
33
34
/*!
35
* Function prototype for receiving pretty printed strings.
···
29
* they can easily be chained together to form a debug message printing out
30
* various information. Most of the final logging functions in Monado inserts a
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.
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
+
76
77
/*!
78
* Function prototype for receiving pretty printed strings.
+132
-18
src/xrt/auxiliary/util/u_space_overseer.c
+132
-18
src/xrt/auxiliary/util/u_space_overseer.c
···
1
// Copyright 2023, Collabora, Ltd.
2
// SPDX-License-Identifier: BSL-1.0
3
/*!
4
* @file
···
42
U_SPACE_TYPE_POSE,
43
U_SPACE_TYPE_OFFSET,
44
U_SPACE_TYPE_ROOT,
45
};
46
47
/*!
···
330
m_relation_chain_push_relation(xrc, &xsr);
331
} break;
332
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.
334
}
335
336
// Please tail-call optimise this miss compiler.
···
352
case U_SPACE_TYPE_NULL: break;
353
case U_SPACE_TYPE_POSE: break;
354
case U_SPACE_TYPE_OFFSET: break;
355
-
case U_SPACE_TYPE_ROOT: return; // Stops the traversing.
356
}
357
358
// Can't tail-call optimise this one :(
···
371
} break;
372
case U_SPACE_TYPE_OFFSET: m_relation_chain_push_inverted_pose_if_not_identity(xrc, &space->offset.pose); break;
373
case U_SPACE_TYPE_ROOT: assert(false); // Should not get here.
374
}
375
}
376
···
469
470
// Created with one reference.
471
uso->base.semantic.root = &us->base;
472
}
473
474
···
1033
return xret;
1034
}
1035
1036
static void
1037
destroy(struct xrt_space_overseer *xso)
1038
{
···
1089
uso->base.set_tracking_origin_offset = set_tracking_origin_offset;
1090
uso->base.get_reference_space_offset = get_reference_space_offset;
1091
uso->base.set_reference_space_offset = set_reference_space_offset;
1092
uso->base.destroy = destroy;
1093
uso->broadcast = broadcast;
1094
···
1117
bool root_is_unbounded,
1118
bool per_app_local_spaces)
1119
{
1120
-
struct xrt_space *root = uso->base.semantic.root; // Convenience
1121
uso->per_app_local_spaces = per_app_local_spaces;
1122
1123
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);
1137
}
1138
-
1139
-
u_space_overseer_link_space_to_device(uso, xs, xdev);
1140
}
1141
1142
// If these are set something is probably wrong, but just in case unset them.
···
1
// Copyright 2023, Collabora, Ltd.
2
+
// Copyright 2025, NVIDIA CORPORATION.
3
// SPDX-License-Identifier: BSL-1.0
4
/*!
5
* @file
···
43
U_SPACE_TYPE_POSE,
44
U_SPACE_TYPE_OFFSET,
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,
53
};
54
55
/*!
···
338
m_relation_chain_push_relation(xrc, &xsr);
339
} break;
340
case U_SPACE_TYPE_OFFSET: m_relation_chain_push_pose_if_not_identity(xrc, &space->offset.pose); break;
341
+
case U_SPACE_TYPE_ROOT: return; // Stops the traversing.
342
+
case U_SPACE_TYPE_ATTACHABLE: break; // No-op
343
}
344
345
// Please tail-call optimise this miss compiler.
···
361
case U_SPACE_TYPE_NULL: break;
362
case U_SPACE_TYPE_POSE: break;
363
case U_SPACE_TYPE_OFFSET: break;
364
+
case U_SPACE_TYPE_ROOT: return; // Stops the traversing.
365
+
case U_SPACE_TYPE_ATTACHABLE: break; // No-op
366
}
367
368
// Can't tail-call optimise this one :(
···
381
} break;
382
case U_SPACE_TYPE_OFFSET: m_relation_chain_push_inverted_pose_if_not_identity(xrc, &space->offset.pose); break;
383
case U_SPACE_TYPE_ROOT: assert(false); // Should not get here.
384
+
case U_SPACE_TYPE_ATTACHABLE: break; // No-op
385
}
386
}
387
···
480
481
// Created with one reference.
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;
542
}
543
544
···
1103
return xret;
1104
}
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
+
1160
static void
1161
destroy(struct xrt_space_overseer *xso)
1162
{
···
1213
uso->base.set_tracking_origin_offset = set_tracking_origin_offset;
1214
uso->base.get_reference_space_offset = get_reference_space_offset;
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;
1218
uso->base.destroy = destroy;
1219
uso->broadcast = broadcast;
1220
···
1243
bool root_is_unbounded,
1244
bool per_app_local_spaces)
1245
{
1246
uso->per_app_local_spaces = per_app_local_spaces;
1247
1248
+
// Add all devices to the space overseer.
1249
for (uint32_t i = 0; i < xdev_count; i++) {
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);
1253
}
1254
}
1255
1256
// If these are set something is probably wrong, but just in case unset them.
-2
src/xrt/auxiliary/vive/vive_poses.c
-2
src/xrt/auxiliary/vive/vive_poses.c
+8
-2
src/xrt/auxiliary/vk/vk_bundle_init.c
+8
-2
src/xrt/auxiliary/vk/vk_bundle_init.c
···
241
242
vk->features.timestamp_compute_and_graphics = pdp.limits.timestampComputeAndGraphics;
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;
246
247
248
/*
···
241
242
vk->features.timestamp_compute_and_graphics = pdp.limits.timestampComputeAndGraphics;
243
vk->features.timestamp_period = pdp.limits.timestampPeriod;
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;
252
253
254
/*
+24
-6
src/xrt/auxiliary/vk/vk_helpers.h
+24
-6
src/xrt/auxiliary/vk/vk_helpers.h
···
200
//! Were timeline semaphore requested, available, and enabled?
201
bool timeline_semaphore;
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
//! Was synchronization2 requested, available, and enabled?
210
bool synchronization_2;
211
···
215
//! Was KHR_video_maintenance1 requested, available, and enabled?
216
bool video_maintenance_1;
217
} features;
218
219
//! Is the GPU a tegra device.
220
bool is_tegra;
···
200
//! Were timeline semaphore requested, available, and enabled?
201
bool timeline_semaphore;
202
203
//! Was synchronization2 requested, available, and enabled?
204
bool synchronization_2;
205
···
209
//! Was KHR_video_maintenance1 requested, available, and enabled?
210
bool video_maintenance_1;
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;
236
237
//! Is the GPU a tegra device.
238
bool is_tegra;
+5
-2
src/xrt/compositor/main/comp_compositor.c
+5
-2
src/xrt/compositor/main/comp_compositor.c
···
1132
struct xrt_system_compositor_info sys_info_storage = {0};
1133
struct xrt_system_compositor_info *sys_info = &sys_info_storage;
1134
1135
-
// Required by OpenXR spec.
1136
-
sys_info->max_layers = XRT_MAX_LAYERS;
1137
sys_info->compositor_vk_deviceUUID = c->settings.selected_gpu_deviceUUID;
1138
sys_info->client_vk_deviceUUID = c->settings.client_gpu_deviceUUID;
1139
sys_info->client_d3d_deviceLUID = c->settings.client_gpu_deviceLUID;
···
1132
struct xrt_system_compositor_info sys_info_storage = {0};
1133
struct xrt_system_compositor_info *sys_info = &sys_info_storage;
1134
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); //
1140
sys_info->compositor_vk_deviceUUID = c->settings.selected_gpu_deviceUUID;
1141
sys_info->client_vk_deviceUUID = c->settings.client_gpu_deviceUUID;
1142
sys_info->client_d3d_deviceLUID = c->settings.client_gpu_deviceLUID;
+4
-1
src/xrt/compositor/multi/comp_multi_system.c
+4
-1
src/xrt/compositor/multi/comp_multi_system.c
···
423
.fb_face_tracking2_enabled = false,
424
.meta_body_tracking_full_body_enabled = false,
425
.meta_body_tracking_calibration_enabled = false,
426
};
427
428
switch (msc->sessions.state) {
···
591
*/
592
593
static xrt_result_t
594
-
system_compositor_set_state(struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused)
595
{
596
struct multi_system_compositor *msc = multi_system_compositor(xsc);
597
struct multi_compositor *mc = multi_compositor(xc);
···
606
xse.type = XRT_SESSION_EVENT_STATE_CHANGE;
607
xse.state.visible = visible;
608
xse.state.focused = focused;
609
610
return multi_compositor_push_event(mc, &xse);
611
}
···
423
.fb_face_tracking2_enabled = false,
424
.meta_body_tracking_full_body_enabled = false,
425
.meta_body_tracking_calibration_enabled = false,
426
+
.android_face_tracking_enabled = false,
427
};
428
429
switch (msc->sessions.state) {
···
592
*/
593
594
static xrt_result_t
595
+
system_compositor_set_state(
596
+
struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused, int64_t timestamp_ns)
597
{
598
struct multi_system_compositor *msc = multi_system_compositor(xsc);
599
struct multi_compositor *mc = multi_compositor(xc);
···
608
xse.type = XRT_SESSION_EVENT_STATE_CHANGE;
609
xse.state.visible = visible;
610
xse.state.focused = focused;
611
+
xse.state.timestamp_ns = timestamp_ns;
612
613
return multi_compositor_push_event(mc, &xse);
614
}
+7
-1
src/xrt/compositor/null/null_compositor.c
+7
-1
src/xrt/compositor/null/null_compositor.c
···
268
{
269
struct xrt_system_compositor_info *sys_info = &c->sys_info;
270
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
+
*/
278
sys_info->max_layers = XRT_MAX_LAYERS;
279
280
uint32_t view_count = xdev->hmd->view_count;
+25
-2
src/xrt/compositor/render/render_interface.h
+25
-2
src/xrt/compositor/render/render_interface.h
···
59
#define RENDER_MAX_LAYERS (XRT_MAX_LAYERS)
60
61
/*!
62
* Max number of images that can be given at a single time to the layer
63
* squasher in a single dispatch.
64
*/
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)
67
68
/*!
69
* Maximum number of times that the layer squasher shader can run per
···
88
//! The binding that the shared layer fragment shader has its source on.
89
#define RENDER_BINDING_LAYER_SHARED_SRC 1
90
91
92
/*
93
*
94
* Util functions.
95
*
96
*/
97
98
/*!
99
* Create a simplified projection matrix for timewarp.
···
59
#define RENDER_MAX_LAYERS (XRT_MAX_LAYERS)
60
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
+
/*!
68
* Max number of images that can be given at a single time to the layer
69
* squasher in a single dispatch.
70
*/
71
+
#define RENDER_MAX_IMAGES_SIZE (RENDER_MAX_LAYERS * RENDER_CS_MAX_SAMPLERS_PER_VIEW)
72
73
/*!
74
* Maximum number of times that the layer squasher shader can run per
···
93
//! The binding that the shared layer fragment shader has its source on.
94
#define RENDER_BINDING_LAYER_SHARED_SRC 1
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
101
102
/*
103
*
104
* Util functions.
105
*
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);
120
121
/*!
122
* Create a simplified projection matrix for timewarp.
+1
-1
src/xrt/compositor/render/render_resources.c
+1
-1
src/xrt/compositor/render/render_resources.c
+49
src/xrt/compositor/render/render_util.c
+49
src/xrt/compositor/render/render_util.c
···
87
*
88
*/
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
+
139
void
140
render_calc_time_warp_matrix(const struct xrt_pose *src_pose,
141
const struct xrt_fov *src_fov,
+1
-6
src/xrt/drivers/android/android_sensors.c
+1
-6
src/xrt/drivers/android/android_sensors.c
···
133
args->tray_to_lens_distance_meters = params.tray_to_lens_distance;
134
}
135
136
-
#define DEG_TO_RAD(x) (float)(x * M_PI / 180.0)
137
args->fov = (struct xrt_fov){.angle_left = -DEG_TO_RAD(angles[0]),
138
.angle_right = DEG_TO_RAD(angles[1]),
139
.angle_down = -DEG_TO_RAD(angles[2]),
140
.angle_up = DEG_TO_RAD(angles[3])};
141
-
#undef DEG_TO_RAD
142
143
ANDROID_INFO(d, "loaded calibration for device %s (%s)", model, vendor);
144
···
354
struct android_device *d = U_DEVICE_ALLOCATE(struct android_device, flags, 1, 0);
355
356
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;
361
d->base.get_view_poses = u_device_get_view_poses;
362
d->base.get_visibility_mask = u_device_get_visibility_mask;
363
d->base.compute_distortion = android_device_compute_distortion;
···
133
args->tray_to_lens_distance_meters = params.tray_to_lens_distance;
134
}
135
136
args->fov = (struct xrt_fov){.angle_left = -DEG_TO_RAD(angles[0]),
137
.angle_right = DEG_TO_RAD(angles[1]),
138
.angle_down = -DEG_TO_RAD(angles[2]),
139
.angle_up = DEG_TO_RAD(angles[3])};
140
141
ANDROID_INFO(d, "loaded calibration for device %s (%s)", model, vendor);
142
···
352
struct android_device *d = U_DEVICE_ALLOCATE(struct android_device, flags, 1, 0);
353
354
d->base.name = XRT_DEVICE_GENERIC_HMD;
355
+
u_device_populate_function_pointers(&d->base, android_device_get_tracked_pose, android_device_destroy);
356
d->base.get_view_poses = u_device_get_view_poses;
357
d->base.get_visibility_mask = u_device_get_visibility_mask;
358
d->base.compute_distortion = android_device_compute_distortion;
+2
-2
src/xrt/drivers/arduino/arduino_device.c
+2
-2
src/xrt/drivers/arduino/arduino_device.c
···
405
406
m_imu_3dof_init(&ad->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_300MS);
407
408
-
#define DEG_TO_RAD ((double)M_PI / 180.0)
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;
411
412
m_imu_pre_filter_init(&ad->pre_filter, accel_ticks_to_float, gyro_ticks_to_float);
413
m_imu_pre_filter_set_switch_x_and_y(&ad->pre_filter);
···
405
406
m_imu_3dof_init(&ad->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_300MS);
407
408
+
#define DEG_TO_RAD_MULTIPLIER ((double)M_PI / 180.0)
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_MULTIPLIER) / INT16_MAX;
411
412
m_imu_pre_filter_init(&ad->pre_filter, accel_ticks_to_float, gyro_ticks_to_float);
413
m_imu_pre_filter_set_switch_x_and_y(&ad->pre_filter);
+1
-5
src/xrt/drivers/euroc/euroc_device.c
+1
-5
src/xrt/drivers/euroc/euroc_device.c
···
206
xd->inputs[0].name = XRT_INPUT_SIMPLE_GRIP_POSE;
207
}
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;
212
if (is_hmd) {
213
xd->get_view_poses = u_device_get_view_poses;
214
-
} else {
215
-
xd->get_view_poses = u_device_ni_get_view_poses;
216
}
217
218
u_var_add_root(ed, dev_name, false);
+1
-3
src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp
+1
-3
src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp
···
513
cemud[i]->base.inputs[CEMU_INDEX_GRIP].name = XRT_INPUT_HAND_CTRL_EMU_GRIP_POSE;
514
cemud[i]->base.inputs[CEMU_INDEX_AIM].name = XRT_INPUT_HAND_CTRL_EMU_AIM_POSE;
515
516
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
cemud[i]->base.get_hand_tracking = cemu_device_get_hand_tracking;
520
-
cemud[i]->base.destroy = cemu_device_destroy;
521
522
cemud[i]->base.device_type =
523
i ? XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER : XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER;
···
513
cemud[i]->base.inputs[CEMU_INDEX_GRIP].name = XRT_INPUT_HAND_CTRL_EMU_GRIP_POSE;
514
cemud[i]->base.inputs[CEMU_INDEX_AIM].name = XRT_INPUT_HAND_CTRL_EMU_AIM_POSE;
515
516
+
u_device_populate_function_pointers(&cemud[i]->base, cemu_device_get_tracked_pose, cemu_device_destroy);
517
cemud[i]->base.update_inputs = cemu_device_update_inputs;
518
cemud[i]->base.get_hand_tracking = cemu_device_get_hand_tracking;
519
520
cemud[i]->base.device_type =
521
i ? XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER : XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER;
+2
-6
src/xrt/drivers/hydra/hydra_driver.c
+2
-6
src/xrt/drivers/hydra/hydra_driver.c
···
345
(XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) |
346
(XRT_SPACE_RELATION_POSITION_TRACKED_BIT | XRT_SPACE_RELATION_POSITION_VALID_BIT);
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);
351
352
state->buttons = hydra_read_uint8(&buf);
353
···
799
for (size_t i = 0; i < 2; ++i) {
800
struct hydra_device *hd = hs->devs[i];
801
802
-
hd->base.destroy = hydra_device_destroy;
803
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
hd->base.name = XRT_DEVICE_HYDRA;
807
snprintf(hd->base.str, XRT_DEVICE_NAME_LEN, "%s %i", "Razer Hydra Controller", (int)(i + 1));
808
snprintf(hd->base.serial, XRT_DEVICE_NAME_LEN, "%s%i", "RZRHDRC", (int)(i + 1));
···
345
(XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) |
346
(XRT_SPACE_RELATION_POSITION_TRACKED_BIT | XRT_SPACE_RELATION_POSITION_VALID_BIT);
347
348
+
m_relation_history_push_with_motion_estimation(state->relation_history, &space_relation, now);
349
350
state->buttons = hydra_read_uint8(&buf);
351
···
797
for (size_t i = 0; i < 2; ++i) {
798
struct hydra_device *hd = hs->devs[i];
799
800
+
u_device_populate_function_pointers(&hd->base, hydra_device_get_tracked_pose, hydra_device_destroy);
801
hd->base.update_inputs = hydra_device_update_inputs;
802
hd->base.name = XRT_DEVICE_HYDRA;
803
snprintf(hd->base.str, XRT_DEVICE_NAME_LEN, "%s %i", "Razer Hydra Controller", (int)(i + 1));
804
snprintf(hd->base.serial, XRT_DEVICE_NAME_LEN, "%s%i", "RZRHDRC", (int)(i + 1));
+2
-5
src/xrt/drivers/ohmd/oh_device.c
+2
-5
src/xrt/drivers/ohmd/oh_device.c
···
757
758
enum u_device_alloc_flags flags = U_DEVICE_ALLOC_HMD;
759
struct oh_device *ohd = U_DEVICE_ALLOCATE(struct oh_device, flags, 1, 0);
760
ohd->base.update_inputs = oh_device_update_inputs;
761
-
ohd->base.get_tracked_pose = oh_device_get_tracked_pose;
762
ohd->base.get_view_poses = u_device_get_view_poses;
763
-
ohd->base.destroy = oh_device_destroy;
764
ohd->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE;
765
ohd->base.name = XRT_DEVICE_GENERIC_HMD;
766
ohd->ctx = ctx;
···
1074
1075
enum u_device_alloc_flags flags = 0;
1076
struct oh_device *ohd = U_DEVICE_ALLOCATE(struct oh_device, flags, input_count, output_count);
1077
ohd->base.update_inputs = oh_device_update_inputs;
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
if (oculus_touch) {
1083
ohd->ohmd_device_type = OPENHMD_OCULUS_RIFT_CONTROLLER;
1084
ohd->base.name = XRT_DEVICE_TOUCH_CONTROLLER;
···
757
758
enum u_device_alloc_flags flags = U_DEVICE_ALLOC_HMD;
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);
761
ohd->base.update_inputs = oh_device_update_inputs;
762
ohd->base.get_view_poses = u_device_get_view_poses;
763
ohd->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE;
764
ohd->base.name = XRT_DEVICE_GENERIC_HMD;
765
ohd->ctx = ctx;
···
1073
1074
enum u_device_alloc_flags flags = 0;
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
ohd->base.update_inputs = oh_device_update_inputs;
1078
ohd->base.set_output = oh_device_set_output;
1079
if (oculus_touch) {
1080
ohd->ohmd_device_type = OPENHMD_OCULUS_RIFT_CONTROLLER;
1081
ohd->base.name = XRT_DEVICE_TOUCH_CONTROLLER;
-2
src/xrt/drivers/pssense/pssense_driver.c
-2
src/xrt/drivers/pssense/pssense_driver.c
···
43
44
DEBUG_GET_ONCE_LOG_OPTION(pssense_log, "PSSENSE_LOG", U_LOGGING_INFO)
45
46
-
#define DEG_TO_RAD(DEG) (DEG * M_PI / 180.)
47
-
48
static struct xrt_binding_input_pair simple_inputs_pssense[4] = {
49
{XRT_INPUT_SIMPLE_SELECT_CLICK, XRT_INPUT_PSSENSE_TRIGGER_VALUE},
50
{XRT_INPUT_SIMPLE_MENU_CLICK, XRT_INPUT_PSSENSE_OPTIONS_CLICK},
+1
-4
src/xrt/drivers/realsense/rs_ddev.c
+1
-4
src/xrt/drivers/realsense/rs_ddev.c
···
448
449
U_LOG_D("Realsense opts are %i %i %i %i %i\n", rs->enable_mapping, rs->enable_pose_jumping,
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;
455
rs->base.name = XRT_DEVICE_REALSENSE;
456
rs->base.tracking_origin->type = XRT_TRACKING_TYPE_EXTERNAL_SLAM;
457
···
448
449
U_LOG_D("Realsense opts are %i %i %i %i %i\n", rs->enable_mapping, rs->enable_pose_jumping,
450
rs->enable_relocalization, rs->enable_pose_prediction, rs->enable_pose_filtering);
451
+
u_device_populate_function_pointers(&rs->base, rs_ddev_get_tracked_pose, rs_ddev_destroy);
452
rs->base.name = XRT_DEVICE_REALSENSE;
453
rs->base.tracking_origin->type = XRT_TRACKING_TYPE_EXTERNAL_SLAM;
454
+1
-4
src/xrt/drivers/remote/r_device.c
+1
-4
src/xrt/drivers/remote/r_device.c
···
193
struct r_device, flags, input_count, output_count);
194
195
// Setup the basics.
196
rd->base.update_inputs = r_device_update_inputs;
197
-
rd->base.get_tracked_pose = r_device_get_tracked_pose;
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
rd->base.tracking_origin = &r->origin;
203
rd->base.supported.orientation_tracking = true;
204
rd->base.supported.position_tracking = true;
···
193
struct r_device, flags, input_count, output_count);
194
195
// Setup the basics.
196
+
u_device_populate_function_pointers(&rd->base, r_device_get_tracked_pose, r_device_destroy);
197
rd->base.update_inputs = r_device_update_inputs;
198
rd->base.get_hand_tracking = r_device_get_hand_tracking;
199
rd->base.tracking_origin = &r->origin;
200
rd->base.supported.orientation_tracking = true;
201
rd->base.supported.position_tracking = true;
+1
-5
src/xrt/drivers/remote/r_hmd.c
+1
-5
src/xrt/drivers/remote/r_hmd.c
···
124
struct r_hmd, flags, input_count, output_count);
125
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;
130
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
rh->base.tracking_origin = &r->origin;
134
rh->base.supported.orientation_tracking = true;
135
rh->base.supported.position_tracking = true;
···
124
struct r_hmd, flags, input_count, output_count);
125
126
// Setup the basics.
127
+
u_device_populate_function_pointers(&rh->base, r_hmd_get_tracked_pose, r_hmd_destroy);
128
rh->base.get_view_poses = r_hmd_get_view_poses;
129
rh->base.tracking_origin = &r->origin;
130
rh->base.supported.orientation_tracking = true;
131
rh->base.supported.position_tracking = true;
-1
src/xrt/drivers/rift/rift_interface.h
-1
src/xrt/drivers/rift/rift_interface.h
+1
-5
src/xrt/drivers/rift_s/rift_s_controller.c
+1
-5
src/xrt/drivers/rift_s/rift_s_controller.c
···
40
/* Set to 1 to print controller states continuously */
41
#define DUMP_CONTROLLER_STATE 0
42
43
-
#define DEG_TO_RAD(D) ((D)*M_PI / 180.)
44
-
45
static struct xrt_binding_input_pair simple_inputs_rift_s[4] = {
46
{XRT_INPUT_SIMPLE_SELECT_CLICK, XRT_INPUT_TOUCH_TRIGGER_VALUE},
47
{XRT_INPUT_SIMPLE_MENU_CLICK, XRT_INPUT_TOUCH_MENU_CLICK},
···
606
607
os_mutex_init(&ctrl->mutex);
608
609
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
ctrl->base.get_view_poses = u_device_get_view_poses;
613
-
ctrl->base.destroy = rift_s_controller_destroy;
614
ctrl->base.name = XRT_DEVICE_TOUCH_CONTROLLER;
615
ctrl->base.device_type = device_type;
616
···
40
/* Set to 1 to print controller states continuously */
41
#define DUMP_CONTROLLER_STATE 0
42
43
static struct xrt_binding_input_pair simple_inputs_rift_s[4] = {
44
{XRT_INPUT_SIMPLE_SELECT_CLICK, XRT_INPUT_TOUCH_TRIGGER_VALUE},
45
{XRT_INPUT_SIMPLE_MENU_CLICK, XRT_INPUT_TOUCH_MENU_CLICK},
···
604
605
os_mutex_init(&ctrl->mutex);
606
607
+
u_device_populate_function_pointers(&ctrl->base, rift_s_controller_get_tracked_pose, rift_s_controller_destroy);
608
ctrl->base.update_inputs = rift_s_controller_update_inputs;
609
ctrl->base.get_view_poses = u_device_get_view_poses;
610
ctrl->base.name = XRT_DEVICE_TOUCH_CONTROLLER;
611
ctrl->base.device_type = device_type;
612
-2
src/xrt/drivers/rift_s/rift_s_hmd.c
-2
src/xrt/drivers/rift_s/rift_s_hmd.c
-2
src/xrt/drivers/simula/svr_hmd.c
-2
src/xrt/drivers/simula/svr_hmd.c
+1
-5
src/xrt/drivers/simulated/simulated_controller.c
+1
-5
src/xrt/drivers/simulated/simulated_controller.c
···
347
348
// Allocate.
349
struct simulated_device *sd = U_DEVICE_ALLOCATE(struct simulated_device, flags, input_count, output_count);
350
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
sd->base.tracking_origin = origin;
357
sd->base.supported.orientation_tracking = true;
358
sd->base.supported.position_tracking = true;
···
347
348
// Allocate.
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);
351
sd->base.update_inputs = simulated_device_update_inputs;
352
sd->base.tracking_origin = origin;
353
sd->base.supported.orientation_tracking = true;
354
sd->base.supported.position_tracking = true;
+14
-22
src/xrt/drivers/steamvr_lh/device.cpp
+14
-22
src/xrt/drivers/steamvr_lh/device.cpp
···
662
const auto it = std::ranges::lower_bound(joint_history, desired_timestamp_ns, {},
663
[](const JointsWithTimestamp &joint) { return joint.timestamp; });
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
if (it == joint_history.end()) {
683
// Timestamp is newer than anything in history
684
-
predict_joint_set(joint_history.back());
685
} else if (desired_timestamp_ns == it->timestamp) {
686
*out_value = it->joint_set;
687
*out_timestamp_ns = it->timestamp;
688
} else if (it == joint_history.begin()) {
689
// Timestamp is older than anything in history
690
-
predict_joint_set(joint_history.front());
691
} else {
692
// Interpolate
693
auto it_previous = it - 1;
···
1061
relation.linear_velocity = copy_vec3(newPose.vecVelocity);
1062
relation.angular_velocity = copy_vec3(newPose.vecAngularVelocity);
1063
1064
-
math_quat_rotate_vec3(&relation.pose.orientation, &relation.angular_velocity, &relation.angular_velocity);
1065
1066
-
// apply over local transform
1067
-
const xrt_pose local = copy_pose(newPose.qDriverFromHeadRotation, newPose.vecDriverFromHeadTranslation);
1068
math_pose_transform(&relation.pose, &local, &relation.pose);
1069
1070
// apply world transform
···
662
const auto it = std::ranges::lower_bound(joint_history, desired_timestamp_ns, {},
663
[](const JointsWithTimestamp &joint) { return joint.timestamp; });
664
665
if (it == joint_history.end()) {
666
// Timestamp is newer than anything in history
667
+
*out_value = joint_history.back().joint_set;
668
+
*out_timestamp_ns = it->timestamp;
669
} else if (desired_timestamp_ns == it->timestamp) {
670
*out_value = it->joint_set;
671
*out_timestamp_ns = it->timestamp;
672
} else if (it == joint_history.begin()) {
673
// Timestamp is older than anything in history
674
+
*out_value = joint_history.front().joint_set;
675
+
*out_timestamp_ns = it->timestamp;
676
} else {
677
// Interpolate
678
auto it_previous = it - 1;
···
1046
relation.linear_velocity = copy_vec3(newPose.vecVelocity);
1047
relation.angular_velocity = copy_vec3(newPose.vecAngularVelocity);
1048
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);
1057
1058
+
// apply local transform
1059
+
math_quat_rotate_vec3(&relation.pose.orientation, &relation.angular_velocity, &relation.angular_velocity);
1060
math_pose_transform(&relation.pose, &local, &relation.pose);
1061
1062
// apply world transform
+1
-4
src/xrt/drivers/twrap/twrap_slam.c
+1
-4
src/xrt/drivers/twrap/twrap_slam.c
···
159
160
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;
166
dx->base.name = name;
167
dx->base.tracking_origin->type = XRT_TRACKING_TYPE_OTHER;
168
dx->base.inputs[0].name = XRT_INPUT_GENERIC_TRACKER_POSE;
+4
-2
src/xrt/drivers/wmr/wmr_controller_base.c
+4
-2
src/xrt/drivers/wmr/wmr_controller_base.c
···
526
wmr_controller_base_init(struct wmr_controller_base *wcb,
527
struct wmr_controller_connection *conn,
528
enum xrt_device_type controller_type,
529
-
enum u_logging_level log_level)
530
{
531
DRV_TRACE_MARKER();
532
···
544
snprintf(wcb->base.serial, XRT_DEVICE_NAME_LEN, "Right Controller");
545
}
546
547
-
wcb->base.get_tracked_pose = wmr_controller_base_get_tracked_pose;
548
549
wcb->base.name = XRT_DEVICE_WMR_CONTROLLER;
550
wcb->base.device_type = controller_type;
···
526
wmr_controller_base_init(struct wmr_controller_base *wcb,
527
struct wmr_controller_connection *conn,
528
enum xrt_device_type controller_type,
529
+
enum u_logging_level log_level,
530
+
u_device_destroy_function_t destroy_fn)
531
{
532
DRV_TRACE_MARKER();
533
···
545
snprintf(wcb->base.serial, XRT_DEVICE_NAME_LEN, "Right Controller");
546
}
547
548
+
// Set all functions.
549
+
u_device_populate_function_pointers(&wcb->base, wmr_controller_base_get_tracked_pose, destroy_fn);
550
551
wcb->base.name = XRT_DEVICE_WMR_CONTROLLER;
552
wcb->base.device_type = controller_type;
+3
-1
src/xrt/drivers/wmr/wmr_controller_base.h
+3
-1
src/xrt/drivers/wmr/wmr_controller_base.h
···
16
17
#include "os/os_threading.h"
18
#include "math/m_imu_3dof.h"
19
#include "util/u_logging.h"
20
#include "xrt/xrt_device.h"
21
···
129
wmr_controller_base_init(struct wmr_controller_base *wcb,
130
struct wmr_controller_connection *conn,
131
enum xrt_device_type controller_type,
132
-
enum u_logging_level log_level);
133
134
void
135
wmr_controller_base_deinit(struct wmr_controller_base *wcb);
···
16
17
#include "os/os_threading.h"
18
#include "math/m_imu_3dof.h"
19
+
#include "util/u_device.h"
20
#include "util/u_logging.h"
21
#include "xrt/xrt_device.h"
22
···
130
wmr_controller_base_init(struct wmr_controller_base *wcb,
131
struct wmr_controller_connection *conn,
132
enum xrt_device_type controller_type,
133
+
enum u_logging_level log_level,
134
+
u_device_destroy_function_t destroy_fn);
135
136
void
137
wmr_controller_base_deinit(struct wmr_controller_base *wcb);
+3
-5
src/xrt/drivers/wmr/wmr_controller_hp.c
+3
-5
src/xrt/drivers/wmr/wmr_controller_hp.c
···
360
U_DEVICE_ALLOCATE(struct wmr_controller_hp, flags, WMR_CONTROLLER_INDEX_COUNT, 1);
361
struct wmr_controller_base *wcb = (struct wmr_controller_base *)(ctrl);
362
363
-
if (!wmr_controller_base_init(wcb, conn, controller_type, log_level)) {
364
wmr_controller_hp_destroy(&wcb->base);
365
return NULL;
366
}
367
368
wcb->handle_input_packet = handle_input_packet;
369
370
wcb->base.name = XRT_DEVICE_HP_REVERB_G2_CONTROLLER;
371
372
if (controller_type == XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER) {
···
374
} else {
375
snprintf(wcb->base.str, ARRAY_SIZE(wcb->base.str), "HP Reverb G2 Right Controller");
376
}
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
382
SET_INPUT(wcb, MENU_CLICK, MENU_CLICK);
383
SET_INPUT(wcb, HOME_CLICK, HOME_CLICK);
···
360
U_DEVICE_ALLOCATE(struct wmr_controller_hp, flags, WMR_CONTROLLER_INDEX_COUNT, 1);
361
struct wmr_controller_base *wcb = (struct wmr_controller_base *)(ctrl);
362
363
+
if (!wmr_controller_base_init(wcb, conn, controller_type, log_level, wmr_controller_hp_destroy)) {
364
wmr_controller_hp_destroy(&wcb->base);
365
return NULL;
366
}
367
368
wcb->handle_input_packet = handle_input_packet;
369
370
+
// Only set those we want to overwrite.
371
+
wcb->base.update_inputs = wmr_controller_hp_update_inputs;
372
wcb->base.name = XRT_DEVICE_HP_REVERB_G2_CONTROLLER;
373
374
if (controller_type == XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER) {
···
376
} else {
377
snprintf(wcb->base.str, ARRAY_SIZE(wcb->base.str), "HP Reverb G2 Right Controller");
378
}
379
380
SET_INPUT(wcb, MENU_CLICK, MENU_CLICK);
381
SET_INPUT(wcb, HOME_CLICK, HOME_CLICK);
+4
-4
src/xrt/drivers/wmr/wmr_controller_og.c
+4
-4
src/xrt/drivers/wmr/wmr_controller_og.c
···
413
struct wmr_controller_og *ctrl = U_DEVICE_ALLOCATE(struct wmr_controller_og, flags, 11, 1);
414
struct wmr_controller_base *wcb = (struct wmr_controller_base *)(ctrl);
415
416
-
if (!wmr_controller_base_init(wcb, conn, controller_type, log_level)) {
417
wmr_controller_og_destroy(&wcb->base);
418
return NULL;
419
}
420
421
wcb->handle_input_packet = handle_input_packet;
422
423
if (pid == ODYSSEY_CONTROLLER_PID) {
424
wcb->base.name = XRT_DEVICE_SAMSUNG_ODYSSEY_CONTROLLER;
425
} else {
426
wcb->base.name = XRT_DEVICE_WMR_CONTROLLER;
427
}
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
432
if (pid == ODYSSEY_CONTROLLER_PID) {
433
SET_ODYSSEY_INPUT(wcb, MENU_CLICK);
···
413
struct wmr_controller_og *ctrl = U_DEVICE_ALLOCATE(struct wmr_controller_og, flags, 11, 1);
414
struct wmr_controller_base *wcb = (struct wmr_controller_base *)(ctrl);
415
416
+
if (!wmr_controller_base_init(wcb, conn, controller_type, log_level, wmr_controller_og_destroy)) {
417
wmr_controller_og_destroy(&wcb->base);
418
return NULL;
419
}
420
421
wcb->handle_input_packet = handle_input_packet;
422
423
+
// Only set those we want to overwrite.
424
+
wcb->base.update_inputs = wmr_controller_og_update_inputs;
425
+
426
if (pid == ODYSSEY_CONTROLLER_PID) {
427
wcb->base.name = XRT_DEVICE_SAMSUNG_ODYSSEY_CONTROLLER;
428
} else {
429
wcb->base.name = XRT_DEVICE_WMR_CONTROLLER;
430
}
431
432
if (pid == ODYSSEY_CONTROLLER_PID) {
433
SET_ODYSSEY_INPUT(wcb, MENU_CLICK);
+6
-3
src/xrt/include/xrt/xrt_compositor.h
+6
-3
src/xrt/include/xrt/xrt_compositor.h
···
966
bool fb_face_tracking2_enabled;
967
bool meta_body_tracking_full_body_enabled;
968
bool meta_body_tracking_calibration_enabled;
969
};
970
971
/*!
···
2390
xrt_result_t (*set_state)(struct xrt_system_compositor *xsc,
2391
struct xrt_compositor *xc,
2392
bool visible,
2393
-
bool focused);
2394
2395
/*!
2396
* Set the rendering Z order for rendering, visible has higher priority
···
2490
* @public @memberof xrt_system_compositor
2491
*/
2492
static inline xrt_result_t
2493
-
xrt_syscomp_set_state(struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused)
2494
{
2495
if (xsc->xmcc == NULL) {
2496
return XRT_ERROR_MULTI_SESSION_NOT_IMPLEMENTED;
2497
}
2498
2499
-
return xsc->xmcc->set_state(xsc, xc, visible, focused);
2500
}
2501
2502
/*!
···
966
bool fb_face_tracking2_enabled;
967
bool meta_body_tracking_full_body_enabled;
968
bool meta_body_tracking_calibration_enabled;
969
+
bool android_face_tracking_enabled;
970
};
971
972
/*!
···
2391
xrt_result_t (*set_state)(struct xrt_system_compositor *xsc,
2392
struct xrt_compositor *xc,
2393
bool visible,
2394
+
bool focused,
2395
+
int64_t timestamp_ns);
2396
2397
/*!
2398
* Set the rendering Z order for rendering, visible has higher priority
···
2492
* @public @memberof xrt_system_compositor
2493
*/
2494
static inline xrt_result_t
2495
+
xrt_syscomp_set_state(
2496
+
struct xrt_system_compositor *xsc, struct xrt_compositor *xc, bool visible, bool focused, int64_t timestamp_ns)
2497
{
2498
if (xsc->xmcc == NULL) {
2499
return XRT_ERROR_MULTI_SESSION_NOT_IMPLEMENTED;
2500
}
2501
2502
+
return xsc->xmcc->set_state(xsc, xc, visible, focused, timestamp_ns);
2503
}
2504
2505
/*!
+1
src/xrt/include/xrt/xrt_config_build.h.cmake_in
+1
src/xrt/include/xrt/xrt_config_build.h.cmake_in
···
37
#cmakedefine XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META
38
#cmakedefine XRT_FEATURE_OPENXR_DEBUG_UTILS
39
#cmakedefine XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE
40
#cmakedefine XRT_FEATURE_OPENXR_FACE_TRACKING2_FB
41
#cmakedefine XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC
42
#cmakedefine XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL
···
37
#cmakedefine XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META
38
#cmakedefine XRT_FEATURE_OPENXR_DEBUG_UTILS
39
#cmakedefine XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE
40
+
#cmakedefine XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID
41
#cmakedefine XRT_FEATURE_OPENXR_FACE_TRACKING2_FB
42
#cmakedefine XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC
43
#cmakedefine XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL
+277
-121
src/xrt/include/xrt/xrt_defines.h
+277
-121
src/xrt/include/xrt/xrt_defines.h
···
716
*
717
*/
718
719
/*!
720
* A enum that is used to name devices so that the
721
* state trackers can reason about the devices easier.
722
*/
723
enum xrt_device_name
724
{
725
-
XRT_DEVICE_INVALID = 0,
726
727
-
XRT_DEVICE_GENERIC_HMD = 1,
728
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,
796
};
797
798
/*!
···
1170
_(XRT_INPUT_HTC_LIP_FACE_TRACKING , XRT_INPUT_NAME(0x0602, FACE_TRACKING)) \
1171
_(XRT_INPUT_FB_FACE_TRACKING2_AUDIO , XRT_INPUT_NAME(0x0603, FACE_TRACKING)) \
1172
_(XRT_INPUT_FB_FACE_TRACKING2_VISUAL , XRT_INPUT_NAME(0x0604, FACE_TRACKING)) \
1173
\
1174
_(XRT_INPUT_GENERIC_BODY_TRACKING , XRT_INPUT_NAME(0x0700, BODY_TRACKING)) \
1175
_(XRT_INPUT_FB_BODY_TRACKING , XRT_INPUT_NAME(0x0701, BODY_TRACKING)) \
···
1481
#define XRT_OUTPUT_TYPE_BITMASK 0xffu
1482
1483
/*!
1484
* Base type of this output.
1485
*
1486
* @ingroup xrt_iface
···
1493
// clang-format on
1494
};
1495
1496
-
#define XRT_OUTPUT_NAME(id, type) ((UINT32_C(id) << XRT_OUTPUT_TYPE_BITWIDTH) | (uint32_t)XRT_OUTPUT_TYPE_##type)
1497
1498
enum xrt_face_expression2_fb
1499
{
···
1660
#define XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC 14
1661
#define XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC 37
1662
1663
struct xrt_facial_base_expression_set_htc
1664
{
1665
int64_t sample_time_ns;
···
1692
bool is_eye_following_blendshapes_valid;
1693
};
1694
1695
struct xrt_facial_expression_set
1696
{
1697
union {
···
1699
struct xrt_facial_eye_expression_set_htc eye_expression_set_htc;
1700
struct xrt_facial_lip_expression_set_htc lip_expression_set_htc;
1701
struct xrt_facial_expression_set2_fb face_expression_set2_fb;
1702
};
1703
};
1704
···
1966
};
1967
// in driver global space, without tracking_origin offset
1968
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
};
2021
2022
/*!
···
716
*
717
*/
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
+
796
/*!
797
* A enum that is used to name devices so that the
798
* state trackers can reason about the devices easier.
799
*/
800
enum xrt_device_name
801
{
802
+
#define XRT_DEVICE_NAME_TO_ENUM(NAME) NAME,
803
804
+
XRT_DEVICE_NAME_LIST(XRT_DEVICE_NAME_TO_ENUM)
805
806
+
#undef XRT_DEVICE_NAME_TO_ENUM
807
};
808
809
/*!
···
1181
_(XRT_INPUT_HTC_LIP_FACE_TRACKING , XRT_INPUT_NAME(0x0602, FACE_TRACKING)) \
1182
_(XRT_INPUT_FB_FACE_TRACKING2_AUDIO , XRT_INPUT_NAME(0x0603, FACE_TRACKING)) \
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)) \
1185
\
1186
_(XRT_INPUT_GENERIC_BODY_TRACKING , XRT_INPUT_NAME(0x0700, BODY_TRACKING)) \
1187
_(XRT_INPUT_FB_BODY_TRACKING , XRT_INPUT_NAME(0x0701, BODY_TRACKING)) \
···
1493
#define XRT_OUTPUT_TYPE_BITMASK 0xffu
1494
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
+
/*!
1531
* Base type of this output.
1532
*
1533
* @ingroup xrt_iface
···
1540
// clang-format on
1541
};
1542
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
+
};
1602
1603
enum xrt_face_expression2_fb
1604
{
···
1765
#define XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC 14
1766
#define XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC 37
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
+
1858
struct xrt_facial_base_expression_set_htc
1859
{
1860
int64_t sample_time_ns;
···
1887
bool is_eye_following_blendshapes_valid;
1888
};
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
+
1901
struct xrt_facial_expression_set
1902
{
1903
union {
···
1905
struct xrt_facial_eye_expression_set_htc eye_expression_set_htc;
1906
struct xrt_facial_lip_expression_set_htc lip_expression_set_htc;
1907
struct xrt_facial_expression_set2_fb face_expression_set2_fb;
1908
+
struct xrt_facial_expression_set_android face_expression_set_android;
1909
};
1910
};
1911
···
2173
};
2174
// in driver global space, without tracking_origin offset
2175
struct xrt_space_relation body_pose;
2176
};
2177
2178
/*!
+23
src/xrt/include/xrt/xrt_device.h
+23
src/xrt/include/xrt/xrt_device.h
···
406
struct xrt_facial_expression_set *out_value);
407
408
/*!
409
* @brief Get the body skeleton in T-pose, used to query the skeleton hierarchy, scale, proportions etc
410
*
411
* @param[in] xdev The device.
···
753
struct xrt_facial_expression_set *out_value)
754
{
755
return xdev->get_face_tracking(xdev, facial_expression_type, at_timestamp_ns, out_value);
756
}
757
758
/*!
···
406
struct xrt_facial_expression_set *out_value);
407
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
+
/*!
419
* @brief Get the body skeleton in T-pose, used to query the skeleton hierarchy, scale, proportions etc
420
*
421
* @param[in] xdev The device.
···
763
struct xrt_facial_expression_set *out_value)
764
{
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);
779
}
780
781
/*!
+1
src/xrt/include/xrt/xrt_instance.h
+1
src/xrt/include/xrt/xrt_instance.h
+7
src/xrt/include/xrt/xrt_limits.h
+7
src/xrt/include/xrt/xrt_limits.h
···
10
11
#pragma once
12
13
+
#include "xrt/xrt_config_os.h"
14
#include "xrt/xrt_compiler.h"
15
16
···
73
/*!
74
* Max number of layers which can be handled at once.
75
*/
76
+
#ifdef XRT_OS_ANDROID
77
+
#define XRT_MAX_LAYERS 32
78
+
#elif defined(XRT_OS_LINUX) || defined(XRT_OS_WINDOWS)
79
#define XRT_MAX_LAYERS 128
80
+
#else
81
+
#error "Unknown platform, define XRT_MAX_LAYERS for your OS"
82
+
#endif
83
84
/*!
85
* @}
+6
src/xrt/include/xrt/xrt_results.h
+6
src/xrt/include/xrt/xrt_results.h
+1
src/xrt/include/xrt/xrt_session.h
+1
src/xrt/include/xrt/xrt_session.h
+80
src/xrt/include/xrt/xrt_space.h
+80
src/xrt/include/xrt/xrt_space.h
···
1
// Copyright 2019-2023, Collabora, Ltd.
2
// SPDX-License-Identifier: BSL-1.0
3
/*!
4
* @file
···
303
struct xrt_space **out_local_space,
304
struct xrt_space **out_local_floor_space);
305
306
/*!
307
* Destroy function.
308
*
···
513
struct xrt_space **out_local_floor_space)
514
{
515
return xso->create_local_space(xso, out_local_space, out_local_floor_space);
516
}
517
518
/*!
···
1
// Copyright 2019-2023, Collabora, Ltd.
2
+
// Copyright 2025, NVIDIA CORPORATION.
3
// SPDX-License-Identifier: BSL-1.0
4
/*!
5
* @file
···
304
struct xrt_space **out_local_space,
305
struct xrt_space **out_local_floor_space);
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
+
360
/*!
361
* Destroy function.
362
*
···
567
struct xrt_space **out_local_floor_space)
568
{
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);
596
}
597
598
/*!
+4
src/xrt/include/xrt/xrt_tracking.h
+4
src/xrt/include/xrt/xrt_tracking.h
···
1
// Copyright 2019, Collabora, Ltd.
2
+
// Copyright 2025, NVIDIA CORPORATION.
3
// SPDX-License-Identifier: BSL-1.0
4
/*!
5
* @file
···
61
62
// The device(s) are tracked by other methods.
63
XRT_TRACKING_TYPE_OTHER,
64
+
65
+
// The device(s) are (re)attachable.
66
+
XRT_TRACKING_TYPE_ATTACHABLE,
67
};
68
69
/*!
+31
-3
src/xrt/ipc/CMakeLists.txt
+31
-3
src/xrt/ipc/CMakeLists.txt
···
1
# Copyright 2020-2021, Collabora, Ltd.
2
# SPDX-License-Identifier: BSL-1.0
3
4
###
5
# Generator
6
7
foreach(
···
16
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${fn}"
17
COMMAND
18
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py
19
-
${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.json
20
-
"${CMAKE_CURRENT_BINARY_DIR}/${fn}"
21
VERBATIM
22
DEPENDS
23
${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py
24
${CMAKE_CURRENT_SOURCE_DIR}/shared/ipcproto/common.py
25
-
${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.json
26
${CMAKE_CURRENT_SOURCE_DIR}/shared/ipc_protocol_generated.h.template
27
COMMENT "Generating ${fn} from protocol JSON description"
28
)
29
endforeach()
30
31
set(IPC_COMMON_SOURCES
32
${CMAKE_CURRENT_BINARY_DIR}/ipc_protocol_generated.h
···
1
# Copyright 2020-2021, Collabora, Ltd.
2
+
# Copyright 2025, NVIDIA CORPORATION.
3
# SPDX-License-Identifier: BSL-1.0
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
+
###
18
# Generator
19
20
foreach(
···
29
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${fn}"
30
COMMAND
31
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py
32
+
${CMAKE_CURRENT_BINARY_DIR}/proto.json "${CMAKE_CURRENT_BINARY_DIR}/${fn}"
33
VERBATIM
34
DEPENDS
35
${CMAKE_CURRENT_SOURCE_DIR}/shared/proto.py
36
${CMAKE_CURRENT_SOURCE_DIR}/shared/ipcproto/common.py
37
+
${CMAKE_CURRENT_BINARY_DIR}/proto.json
38
${CMAKE_CURRENT_SOURCE_DIR}/shared/ipc_protocol_generated.h.template
39
COMMENT "Generating ${fn} from protocol JSON description"
40
)
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")
58
59
set(IPC_COMMON_SOURCES
60
${CMAKE_CURRENT_BINARY_DIR}/ipc_protocol_generated.h
+1
-4
src/xrt/ipc/client/ipc_client_device.c
+1
-4
src/xrt/ipc/client/ipc_client_device.c
···
86
ipc_client_device_t *icd = U_DEVICE_ALLOCATE(ipc_client_device_t, flags, 0, 0);
87
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;
93
94
// Setup variable tracker.
95
u_var_add_root(icd, icd->base.str, true);
···
86
ipc_client_device_t *icd = U_DEVICE_ALLOCATE(ipc_client_device_t, flags, 0, 0);
87
88
// Fills in almost everything a regular device needs.
89
+
ipc_client_xdev_init(icd, ipc_c, xtrack, device_id, ipc_client_device_destroy);
90
91
// Setup variable tracker.
92
u_var_add_root(icd, icd->base.str, true);
+1
-2
src/xrt/ipc/client/ipc_client_hmd.c
+1
-2
src/xrt/ipc/client/ipc_client_hmd.c
···
321
ipc_client_hmd_t *ich = U_DEVICE_ALLOCATE(ipc_client_hmd_t, flags, 0, 0);
322
323
// Fills in almost everything a regular device needs.
324
-
ipc_client_xdev_init(ich, ipc_c, xtrack, device_id);
325
326
// Fill in needed HMD functions, and destroy.
327
ich->base.get_view_poses = ipc_client_hmd_get_view_poses;
328
ich->base.compute_distortion = ipc_client_hmd_compute_distortion;
329
ich->base.is_form_factor_available = ipc_client_hmd_is_form_factor_available;
330
ich->base.get_visibility_mask = ipc_client_hmd_get_visibility_mask;
331
-
ich->base.destroy = ipc_client_hmd_destroy;
332
ich->base.get_brightness = ipc_client_hmd_get_brightness;
333
ich->base.set_brightness = ipc_client_hmd_set_brightness;
334
···
321
ipc_client_hmd_t *ich = U_DEVICE_ALLOCATE(ipc_client_hmd_t, flags, 0, 0);
322
323
// Fills in almost everything a regular device needs.
324
+
ipc_client_xdev_init(ich, ipc_c, xtrack, device_id, ipc_client_hmd_destroy);
325
326
// Fill in needed HMD functions, and destroy.
327
ich->base.get_view_poses = ipc_client_hmd_get_view_poses;
328
ich->base.compute_distortion = ipc_client_hmd_compute_distortion;
329
ich->base.is_form_factor_available = ipc_client_hmd_is_form_factor_available;
330
ich->base.get_visibility_mask = ipc_client_hmd_get_visibility_mask;
331
ich->base.get_brightness = ipc_client_hmd_get_brightness;
332
ich->base.set_brightness = ipc_client_hmd_set_brightness;
333
+16
src/xrt/ipc/client/ipc_client_space_overseer.c
+16
src/xrt/ipc/client/ipc_client_space_overseer.c
···
318
return ipc_call_space_set_reference_space_offset(icspo->ipc_c, type, offset);
319
}
320
321
static void
322
destroy(struct xrt_space_overseer *xso)
323
{
···
374
icspo->base.set_tracking_origin_offset = set_tracking_origin_offset;
375
icspo->base.get_reference_space_offset = get_reference_space_offset;
376
icspo->base.set_reference_space_offset = set_reference_space_offset;
377
icspo->base.destroy = destroy;
378
icspo->ipc_c = ipc_c;
379
···
318
return ipc_call_space_set_reference_space_offset(icspo->ipc_c, type, offset);
319
}
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
+
335
static void
336
destroy(struct xrt_space_overseer *xso)
337
{
···
388
icspo->base.set_tracking_origin_offset = set_tracking_origin_offset;
389
icspo->base.get_reference_space_offset = get_reference_space_offset;
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;
393
icspo->base.destroy = destroy;
394
icspo->ipc_c = ipc_c;
395
+8
-9
src/xrt/ipc/client/ipc_client_xdev.c
+8
-9
src/xrt/ipc/client/ipc_client_xdev.c
···
391
ipc_client_xdev_init(struct ipc_client_xdev *icx,
392
struct ipc_connection *ipc_c,
393
struct xrt_tracking_origin *xtrack,
394
-
uint32_t device_id)
395
{
396
// Helpers.
397
struct ipc_shared_memory *ism = ipc_c->ism;
···
400
// Important fields.
401
icx->ipc_c = ipc_c;
402
icx->device_id = device_id;
403
404
// Shared implemented functions.
405
icx->base.update_inputs = ipc_client_xdev_update_inputs;
406
-
icx->base.get_tracked_pose = ipc_client_xdev_get_tracked_pose;
407
icx->base.get_hand_tracking = ipc_client_xdev_get_hand_tracking;
408
icx->base.get_face_tracking = ipc_client_xdev_get_face_tracking;
409
icx->base.get_body_skeleton = ipc_client_xdev_get_body_skeleton;
···
420
icx->base.destroy_plane_detection_ext = ipc_client_xdev_destroy_plane_detection_ext;
421
icx->base.get_plane_detection_state_ext = ipc_client_xdev_get_plane_detection_state_ext;
422
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
431
// Copying the information from the isdev.
432
icx->base.device_type = isdev->device_type;
···
391
ipc_client_xdev_init(struct ipc_client_xdev *icx,
392
struct ipc_connection *ipc_c,
393
struct xrt_tracking_origin *xtrack,
394
+
uint32_t device_id,
395
+
u_device_destroy_function_t destroy_fn)
396
{
397
// Helpers.
398
struct ipc_shared_memory *ism = ipc_c->ism;
···
401
// Important fields.
402
icx->ipc_c = ipc_c;
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);
410
411
// Shared implemented functions.
412
icx->base.update_inputs = ipc_client_xdev_update_inputs;
413
icx->base.get_hand_tracking = ipc_client_xdev_get_hand_tracking;
414
icx->base.get_face_tracking = ipc_client_xdev_get_face_tracking;
415
icx->base.get_body_skeleton = ipc_client_xdev_get_body_skeleton;
···
426
icx->base.destroy_plane_detection_ext = ipc_client_xdev_destroy_plane_detection_ext;
427
icx->base.get_plane_detection_state_ext = ipc_client_xdev_get_plane_detection_state_ext;
428
icx->base.get_plane_detections_ext = ipc_client_xdev_get_plane_detections_ext;
429
430
// Copying the information from the isdev.
431
icx->base.device_type = isdev->device_type;
+5
-1
src/xrt/ipc/client/ipc_client_xdev.h
+5
-1
src/xrt/ipc/client/ipc_client_xdev.h
···
13
14
#pragma once
15
16
#ifdef __cplusplus
17
extern "C" {
18
#endif
···
58
ipc_client_xdev_init(struct ipc_client_xdev *icx,
59
struct ipc_connection *ipc_c,
60
struct xrt_tracking_origin *xtrack,
61
-
uint32_t device_id);
62
63
/*!
64
* Frees any memory that was allocated as part of init and resets some pointers.
···
13
14
#pragma once
15
16
+
#include "util/u_device.h"
17
+
18
+
19
#ifdef __cplusplus
20
extern "C" {
21
#endif
···
61
ipc_client_xdev_init(struct ipc_client_xdev *icx,
62
struct ipc_connection *ipc_c,
63
struct xrt_tracking_origin *xtrack,
64
+
uint32_t device_id,
65
+
u_device_destroy_function_t destroy_fn);
66
67
/*!
68
* Frees any memory that was allocated as part of init and resets some pointers.
-3
src/xrt/ipc/server/ipc_server.h
-3
src/xrt/ipc/server/ipc_server.h
+17
-17
src/xrt/ipc/server/ipc_server_handler.c
+17
-17
src/xrt/ipc/server/ipc_server_handler.c
···
1
// Copyright 2020-2024, Collabora, Ltd.
2
// SPDX-License-Identifier: BSL-1.0
3
/*!
4
* @file
···
387
EXT(meta_body_tracking_full_body_enabled);
388
EXT(meta_body_tracking_calibration_enabled);
389
EXT(fb_face_tracking2_enabled);
390
391
#undef EXT
392
#undef PTT
···
459
ics->xc = &xcn->base;
460
461
xrt_syscomp_set_state(ics->server->xsysc, ics->xc, ics->client_state.session_visible,
462
-
ics->client_state.session_focused);
463
xrt_syscomp_set_z_order(ics->server->xsysc, ics->xc, ics->client_state.z_order);
464
465
return XRT_SUCCESS;
···
504
.fb_face_tracking2_enabled = ics->client_state.info.fb_face_tracking2_enabled,
505
.meta_body_tracking_full_body_enabled = ics->client_state.info.meta_body_tracking_full_body_enabled,
506
.meta_body_tracking_calibration_enabled = ics->client_state.info.meta_body_tracking_calibration_enabled,
507
};
508
509
return xrt_comp_begin_session(ics->xc, &begin_session_info);
···
1642
}
1643
1644
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
ipc_handle_swapchain_get_properties(volatile struct ipc_client_state *ics,
1660
const struct xrt_swapchain_create_info *info,
1661
struct xrt_swapchain_create_properties *xsccp)
···
1950
struct xrt_input *dst = &ism->inputs[isdev->first_input_index];
1951
size_t size = sizeof(struct xrt_input) * isdev->input_count;
1952
1953
-
bool io_active = ics->io_active && idev->io_active;
1954
if (io_active) {
1955
memcpy(dst, src, size);
1956
} else {
···
2005
}
2006
2007
// Special case the headpose.
2008
-
bool disabled = (!isdev->io_active || !ics->io_active) && name != XRT_INPUT_GENERIC_HEAD_POSE;
2009
bool active_on_client = input->active;
2010
2011
// We have been disabled but the client hasn't called update.
···
2580
GET_XDEV_OR_RETURN(ics, device_id, xdev);
2581
// Get facial expression data.
2582
return xrt_device_get_face_tracking(xdev, facial_expression_type, at_timestamp_ns, out_value);
2583
}
2584
2585
xrt_result_t
···
1
// Copyright 2020-2024, Collabora, Ltd.
2
+
// Copyright 2025, NVIDIA CORPORATION.
3
// SPDX-License-Identifier: BSL-1.0
4
/*!
5
* @file
···
388
EXT(meta_body_tracking_full_body_enabled);
389
EXT(meta_body_tracking_calibration_enabled);
390
EXT(fb_face_tracking2_enabled);
391
+
EXT(android_face_tracking_enabled);
392
393
#undef EXT
394
#undef PTT
···
461
ics->xc = &xcn->base;
462
463
xrt_syscomp_set_state(ics->server->xsysc, ics->xc, ics->client_state.session_visible,
464
+
ics->client_state.session_focused, os_monotonic_get_ns());
465
xrt_syscomp_set_z_order(ics->server->xsysc, ics->xc, ics->client_state.z_order);
466
467
return XRT_SUCCESS;
···
506
.fb_face_tracking2_enabled = ics->client_state.info.fb_face_tracking2_enabled,
507
.meta_body_tracking_full_body_enabled = ics->client_state.info.meta_body_tracking_full_body_enabled,
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,
510
};
511
512
return xrt_comp_begin_session(ics->xc, &begin_session_info);
···
1645
}
1646
1647
xrt_result_t
1648
ipc_handle_swapchain_get_properties(volatile struct ipc_client_state *ics,
1649
const struct xrt_swapchain_create_info *info,
1650
struct xrt_swapchain_create_properties *xsccp)
···
1939
struct xrt_input *dst = &ism->inputs[isdev->first_input_index];
1940
size_t size = sizeof(struct xrt_input) * isdev->input_count;
1941
1942
+
bool io_active = ics->io_active;
1943
if (io_active) {
1944
memcpy(dst, src, size);
1945
} else {
···
1994
}
1995
1996
// Special case the headpose.
1997
+
bool disabled = !ics->io_active && name != XRT_INPUT_GENERIC_HEAD_POSE;
1998
bool active_on_client = input->active;
1999
2000
// We have been disabled but the client hasn't called update.
···
2569
GET_XDEV_OR_RETURN(ics, device_id, xdev);
2570
// Get facial expression data.
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
}
2584
2585
xrt_result_t
+21
-22
src/xrt/ipc/server/ipc_server_process.c
+21
-22
src/xrt/ipc/server/ipc_server_process.c
···
98
static void
99
init_idev(struct ipc_device *idev, struct xrt_device *xdev)
100
{
101
-
if (xdev != NULL) {
102
-
idev->io_active = true;
103
-
idev->xdev = xdev;
104
-
} else {
105
-
idev->io_active = false;
106
-
}
107
}
108
109
static void
110
teardown_idev(struct ipc_device *idev)
111
{
112
-
idev->io_active = false;
113
}
114
115
static void
···
422
423
// Setup the HMD
424
// 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
-
}
431
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];
436
}
437
-
ism->hmd.blend_mode_count = s->xsysd->static_roles.head->hmd->blend_mode_count;
438
439
// Finally tell the client how many devices we have.
440
ism->isdev_count = count;
···
616
ics->client_state.z_order = z_order;
617
618
if (ics->xc != NULL) {
619
-
xrt_syscomp_set_state(ics->server->xsysc, ics->xc, visible, focused);
620
xrt_syscomp_set_z_order(ics->server->xsysc, ics->xc, z_order);
621
}
622
}
···
1104
return -1;
1105
}
1106
1107
-
// Start the debug UI now (if enabled).
1108
-
u_debug_gui_start(s->debug_gui, s->xinst, s->xsysd);
1109
-
1110
// Tell the callbacks we are entering the main-loop.
1111
callbacks->mainloop_entering(s, s->xinst, data);
1112
···
1118
if (xret != XRT_SUCCESS) {
1119
U_LOG_CHK_ONLY_PRINT(log_level, xret, "ipc_server_init_system_if_available_locked");
1120
}
1121
1122
// Main loop.
1123
ret = main_loop(s);
···
98
static void
99
init_idev(struct ipc_device *idev, struct xrt_device *xdev)
100
{
101
+
idev->xdev = xdev;
102
}
103
104
static void
105
teardown_idev(struct ipc_device *idev)
106
{
107
+
idev->xdev = NULL;
108
}
109
110
static void
···
417
418
// Setup the HMD
419
// set view count
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
+
}
429
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
}
437
438
// Finally tell the client how many devices we have.
439
ism->isdev_count = count;
···
615
ics->client_state.z_order = z_order;
616
617
if (ics->xc != NULL) {
618
+
xrt_syscomp_set_state(ics->server->xsysc, ics->xc, visible, focused, os_monotonic_get_ns());
619
xrt_syscomp_set_z_order(ics->server->xsysc, ics->xc, z_order);
620
}
621
}
···
1103
return -1;
1104
}
1105
1106
// Tell the callbacks we are entering the main-loop.
1107
callbacks->mainloop_entering(s, s->xinst, data);
1108
···
1114
if (xret != XRT_SUCCESS) {
1115
U_LOG_CHK_ONLY_PRINT(log_level, xret, "ipc_server_init_system_if_available_locked");
1116
}
1117
+
1118
+
// Start the debug UI now (if enabled).
1119
+
u_debug_gui_start(s->debug_gui, s->xinst, s->xsysd);
1120
1121
// Main loop.
1122
ret = main_loop(s);
+10
-1
src/xrt/state_trackers/gui/gui_scene_remote.c
+10
-1
src/xrt/state_trackers/gui/gui_scene_remote.c
···
413
igBegin("Remote control", NULL, 0);
414
415
#ifdef XRT_BUILD_DRIVER_REMOTE
416
-
if (gr->rc.fd < 0) {
417
on_not_connected(gr, p);
418
} else {
419
on_connected(gr, p);
···
451
452
gr->base.render = scene_render;
453
gr->base.destroy = scene_destroy;
454
gr->rc.fd = -1;
455
456
// GUI input defaults.
457
if (address != NULL) {
···
413
igBegin("Remote control", NULL, 0);
414
415
#ifdef XRT_BUILD_DRIVER_REMOTE
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) {
422
on_not_connected(gr, p);
423
} else {
424
on_connected(gr, p);
···
456
457
gr->base.render = scene_render;
458
gr->base.destroy = scene_destroy;
459
+
#ifdef XRT_OS_WINDOWS
460
+
gr->rc.fd = INVALID_SOCKET;
461
+
#else
462
gr->rc.fd = -1;
463
+
#endif
464
465
// GUI input defaults.
466
if (address != NULL) {
+2
-2
src/xrt/state_trackers/gui/gui_scene_tracking_overrides.c
+2
-2
src/xrt/state_trackers/gui/gui_scene_tracking_overrides.c
···
11
#include "util/u_misc.h"
12
#include "util/u_format.h"
13
#include "util/u_logging.h"
14
15
#include "util/u_config_json.h"
16
···
23
#include "gui_common.h"
24
#include "gui_imgui.h"
25
26
-
#include "bindings/b_generated_bindings_helpers.h"
27
28
struct gui_tracking_overrides
29
{
···
243
continue;
244
}
245
246
-
const char *name_str = xrt_input_name_string(input_name);
247
bool selected = o->input_name == input_name;
248
if (igCheckbox(name_str, &selected)) {
249
o->input_name = input_name;
···
11
#include "util/u_misc.h"
12
#include "util/u_format.h"
13
#include "util/u_logging.h"
14
+
#include "util/u_pretty_print.h"
15
16
#include "util/u_config_json.h"
17
···
24
#include "gui_common.h"
25
#include "gui_imgui.h"
26
27
28
struct gui_tracking_overrides
29
{
···
243
continue;
244
}
245
246
+
const char *name_str = u_str_xrt_input_name(input_name);
247
bool selected = o->input_name == input_name;
248
if (igCheckbox(name_str, &selected)) {
249
o->input_name = input_name;
+5
-1
src/xrt/state_trackers/oxr/CMakeLists.txt
+5
-1
src/xrt/state_trackers/oxr/CMakeLists.txt
···
106
target_sources(st_oxr PRIVATE oxr_api_body_tracking.c oxr_body_tracking.c)
107
endif()
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
+
113
if(XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC)
114
+
target_sources(st_oxr PRIVATE oxr_api_face_tracking_htc.c oxr_face_tracking_htc.c)
115
endif()
116
117
if(XRT_FEATURE_OPENXR_FACE_TRACKING2_FB)
-90
src/xrt/state_trackers/oxr/oxr_api_face_tracking.c
-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
+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
+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
+24
src/xrt/state_trackers/oxr/oxr_api_funcs.h
···
779
oxr_xrCancelFutureEXT(XrInstance instance, const XrFutureCancelInfoEXT *cancelInfo);
780
#endif
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
+
806
/*!
807
* @}
808
*/
+7
src/xrt/state_trackers/oxr/oxr_api_negotiate.c
+7
src/xrt/state_trackers/oxr/oxr_api_negotiate.c
···
419
ENTRY_IF_EXT(xrCancelFutureEXT, EXT_future);
420
#endif // OXR_HAVE_EXT_future
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
+
429
#ifdef OXR_HAVE_KHR_extended_struct_name_lengths
430
ENTRY_IF_EXT(xrStructureTypeToString2KHR, KHR_extended_struct_name_lengths);
431
#endif // OXR_HAVE_KHR_extended_struct_name_lengths
+2
src/xrt/state_trackers/oxr/oxr_api_verify.h
+2
src/xrt/state_trackers/oxr/oxr_api_verify.h
···
97
#define OXR_VERIFY_FUTURE_AND_INIT_LOG(log, thing, new_thing, name) \
98
OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, oxr_future_ext, FUTURE, name, new_thing->inst); \
99
OXR_VERIFY_FUTURE_VALID(log, new_thing)
100
// clang-format on
101
102
#define OXR_VERIFY_INSTANCE_NOT_NULL(log, arg, new_arg) OXR_VERIFY_SET(log, arg, new_arg, oxr_instance, INSTANCE);
···
97
#define OXR_VERIFY_FUTURE_AND_INIT_LOG(log, thing, new_thing, name) \
98
OXR_VERIFY_AND_SET_AND_INIT(log, thing, new_thing, oxr_future_ext, FUTURE, name, new_thing->inst); \
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)
102
// clang-format on
103
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
+12
src/xrt/state_trackers/oxr/oxr_extension_support.h
···
475
476
477
/*
478
* XR_BD_controller_interaction
479
*/
480
#if defined(XR_BD_controller_interaction) && defined(XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE)
···
936
OXR_EXTENSION_SUPPORT_EXT_plane_detection(_) \
937
OXR_EXTENSION_SUPPORT_EXT_samsung_odyssey_controller(_) \
938
OXR_EXTENSION_SUPPORT_EXT_user_presence(_) \
939
OXR_EXTENSION_SUPPORT_BD_controller_interaction(_) \
940
OXR_EXTENSION_SUPPORT_FB_body_tracking(_) \
941
OXR_EXTENSION_SUPPORT_FB_composition_layer_alpha_blend(_) \
···
475
476
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
+
/*
489
* XR_BD_controller_interaction
490
*/
491
#if defined(XR_BD_controller_interaction) && defined(XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE)
···
947
OXR_EXTENSION_SUPPORT_EXT_plane_detection(_) \
948
OXR_EXTENSION_SUPPORT_EXT_samsung_odyssey_controller(_) \
949
OXR_EXTENSION_SUPPORT_EXT_user_presence(_) \
950
+
OXR_EXTENSION_SUPPORT_ANDROID_face_tracking(_) \
951
OXR_EXTENSION_SUPPORT_BD_controller_interaction(_) \
952
OXR_EXTENSION_SUPPORT_FB_body_tracking(_) \
953
OXR_EXTENSION_SUPPORT_FB_composition_layer_alpha_blend(_) \
-119
src/xrt/state_trackers/oxr/oxr_face_tracking.c
-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
+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
+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
+73
-31
src/xrt/state_trackers/oxr/oxr_input.c
···
9
* @ingroup oxr_main
10
*/
11
12
-
#include "b_generated_bindings_helpers.h"
13
#include "oxr_bindings/b_oxr_generated_bindings.h"
14
#include "util/u_debug.h"
15
#include "util/u_time.h"
···
515
*/
516
517
static bool
518
do_inputs(struct oxr_binding *binding_point,
519
struct xrt_device *xdev,
520
struct xrt_binding_profile *xbp,
···
523
uint32_t *input_count)
524
{
525
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
-
}
533
534
-
// We have found a device mapping.
535
-
name = xbp->inputs[i].device;
536
-
break;
537
-
}
538
539
-
// Didn't find a mapping.
540
-
if (name == 0) {
541
return false;
542
}
543
}
544
545
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;
558
}
559
-
return true;
560
}
561
562
-
return false;
563
}
564
565
static bool
···
771
if (found) {
772
if (xbp == NULL) {
773
oxr_slog(slog, "\t\t\t\tBound (xdev '%s'): %s!\n", xdev->str,
774
-
xrt_input_name_string(binding_points[i]->input));
775
} else {
776
oxr_slog(slog, "\t\t\t\tBound (xbp)!\n");
777
}
···
1626
// Only add the input if we can find a transform.
1627
1628
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,
1630
xr_action_type_to_str(act_ref->action_type));
1631
1632
enum oxr_dpad_region dpad_region;
···
1667
struct xrt_input *input = cache->inputs[i].input;
1668
enum xrt_input_type t = XRT_GET_INPUT_TYPE(input->name);
1669
bool active = input->active;
1670
-
oxr_slog(slog, "\t\t\t'%s' ('%s') on '%s' (%s)\n", xrt_input_name_string(input->name),
1671
xrt_input_type_to_str(t), cache->inputs[i].xdev->str,
1672
active ? "active" : "inactive");
1673
}
···
9
* @ingroup oxr_main
10
*/
11
12
#include "oxr_bindings/b_oxr_generated_bindings.h"
13
#include "util/u_debug.h"
14
#include "util/u_time.h"
···
514
*/
515
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
557
do_inputs(struct oxr_binding *binding_point,
558
struct xrt_device *xdev,
559
struct xrt_binding_profile *xbp,
···
562
uint32_t *input_count)
563
{
564
enum xrt_input_name name = 0;
565
+
enum xrt_input_name dpad_activate_name = 0;
566
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);
570
571
+
// We couldn't find the needed inputs on the device.
572
+
if (!t1 || !t2) {
573
return false;
574
}
575
+
} else {
576
+
name = binding_point->input;
577
+
dpad_activate_name = binding_point->dpad_activate;
578
}
579
580
struct xrt_input *input = NULL;
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;
592
}
593
}
594
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;
605
}
606
607
static bool
···
813
if (found) {
814
if (xbp == NULL) {
815
oxr_slog(slog, "\t\t\t\tBound (xdev '%s'): %s!\n", xdev->str,
816
+
u_str_xrt_input_name(binding_points[i]->input));
817
} else {
818
oxr_slog(slog, "\t\t\t\tBound (xbp)!\n");
819
}
···
1668
// Only add the input if we can find a transform.
1669
1670
oxr_slog(slog, "\t\tFinding transforms for '%s' to action '%s' of type '%s'\n",
1671
+
u_str_xrt_input_name(inputs[i].input->name), act_ref->name,
1672
xr_action_type_to_str(act_ref->action_type));
1673
1674
enum oxr_dpad_region dpad_region;
···
1709
struct xrt_input *input = cache->inputs[i].input;
1710
enum xrt_input_type t = XRT_GET_INPUT_TYPE(input->name);
1711
bool active = input->active;
1712
+
oxr_slog(slog, "\t\t\t'%s' ('%s') on '%s' (%s)\n", u_str_xrt_input_name(input->name),
1713
xrt_input_type_to_str(t), cache->inputs[i].xdev->str,
1714
active ? "active" : "inactive");
1715
}
+3
src/xrt/state_trackers/oxr/oxr_instance.c
+3
src/xrt/state_trackers/oxr/oxr_instance.c
···
341
#ifdef OXR_HAVE_META_body_tracking_calibration
342
.meta_body_tracking_calibration_enabled = extensions->META_body_tracking_calibration,
343
#endif
344
};
345
snprintf(i_info.app_info.application_name, sizeof(i_info.app_info.application_name), "%s",
346
createInfo->applicationInfo.applicationName);
···
341
#ifdef OXR_HAVE_META_body_tracking_calibration
342
.meta_body_tracking_calibration_enabled = extensions->META_body_tracking_calibration,
343
#endif
344
+
#ifdef OXR_HAVE_ANDROID_face_tracking
345
+
.android_face_tracking_enabled = extensions->ANDROID_face_tracking,
346
+
#endif
347
};
348
snprintf(i_info.app_info.application_name, sizeof(i_info.app_info.application_name), "%s",
349
createInfo->applicationInfo.applicationName);
+58
src/xrt/state_trackers/oxr/oxr_objects.h
+58
src/xrt/state_trackers/oxr/oxr_objects.h
···
127
struct oxr_action_set_ref;
128
struct oxr_action_ref;
129
struct oxr_hand_tracker;
130
struct oxr_facial_tracker_htc;
131
struct oxr_face_tracker2_fb;
132
struct oxr_body_tracker_fb;
···
467
return XRT_CAST_PTR_TO_OXR_HANDLE(XrFaceTracker2FB, face_tracker2_fb);
468
}
469
#endif
470
/*!
471
*
472
* @name oxr_input.c
···
1107
1108
bool
1109
oxr_system_get_force_feedback_support(struct oxr_logger *log, struct oxr_instance *inst);
1110
1111
void
1112
oxr_system_get_face_tracking_htc_support(struct oxr_logger *log,
···
3093
XrResult
3094
oxr_event_push_XrEventDataUserPresenceChangedEXT(struct oxr_logger *log, struct oxr_session *sess, bool isUserPresent);
3095
#endif // OXR_HAVE_EXT_user_presence
3096
3097
/*!
3098
* @}
···
127
struct oxr_action_set_ref;
128
struct oxr_action_ref;
129
struct oxr_hand_tracker;
130
+
struct oxr_face_tracker_android;
131
struct oxr_facial_tracker_htc;
132
struct oxr_face_tracker2_fb;
133
struct oxr_body_tracker_fb;
···
468
return XRT_CAST_PTR_TO_OXR_HANDLE(XrFaceTracker2FB, face_tracker2_fb);
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
+
485
/*!
486
*
487
* @name oxr_input.c
···
1122
1123
bool
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);
1128
1129
void
1130
oxr_system_get_face_tracking_htc_support(struct oxr_logger *log,
···
3111
XrResult
3112
oxr_event_push_XrEventDataUserPresenceChangedEXT(struct oxr_logger *log, struct oxr_session *sess, bool isUserPresent);
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
3154
3155
/*!
3156
* @}
+145
-63
src/xrt/state_trackers/oxr/oxr_session.c
+145
-63
src/xrt/state_trackers/oxr/oxr_session.c
···
317
#ifdef OXR_HAVE_META_body_tracking_calibration
318
.meta_body_tracking_calibration_enabled = extensions->META_body_tracking_calibration,
319
#endif
320
};
321
322
xrt_result_t xret = xrt_comp_begin_session(xc, &begin_session_info);
···
336
sess->compositor_visible = true;
337
sess->compositor_focused = true;
338
339
// 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);
343
}
344
XrResult ret = oxr_frame_sync_begin_session(&sess->frame_sync);
345
if (ret != XR_SUCCESS) {
···
397
sess->compositor_focused = false;
398
}
399
400
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, 0);
401
if (sess->exiting) {
402
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_EXITING, 0);
403
} else {
404
#ifndef XRT_OS_ANDROID
405
// @todo In multi-clients scenario with a session being reused, changing session
···
425
XrResult
426
oxr_session_request_exit(struct oxr_logger *log, struct oxr_session *sess)
427
{
428
if (sess->state == XR_SESSION_STATE_FOCUSED) {
429
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0);
430
}
431
if (sess->state == XR_SESSION_STATE_VISIBLE) {
432
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0);
433
}
434
if (!sess->has_ended_once && sess->state != XR_SESSION_STATE_SYNCHRONIZED) {
435
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0);
436
// Fake the synchronization.
437
sess->has_ended_once = true;
438
}
439
440
//! @todo start fading out the app.
441
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, 0);
442
sess->exiting = true;
443
return oxr_session_success_result(sess);
444
}
···
474
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "xrt_session is null");
475
}
476
477
#ifdef XRT_OS_ANDROID
478
// Most recent Android activity lifecycle event was OnPause: move toward stopping
479
if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_PAUSE) {
480
if (sess->state == XR_SESSION_STATE_FOCUSED) {
481
U_LOG_I("Activity paused: changing session state FOCUSED->VISIBLE");
482
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0);
483
}
484
485
if (sess->state == XR_SESSION_STATE_VISIBLE) {
486
U_LOG_I("Activity paused: changing session state VISIBLE->SYNCHRONIZED");
487
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0);
488
}
489
490
if (sess->state == XR_SESSION_STATE_SYNCHRONIZED) {
491
U_LOG_I("Activity paused: changing session state SYNCHRONIZED->STOPPING");
492
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, 0);
493
}
494
// TODO return here to avoid polling other events?
495
// see https://gitlab.freedesktop.org/monado/monado/-/issues/419
···
499
if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_RESUME) {
500
if (sess->state == XR_SESSION_STATE_IDLE) {
501
U_LOG_I("Activity resumed: changing session state IDLE->READY");
502
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, 0);
503
}
504
}
505
#endif // XRT_OS_ANDROID
···
519
case XRT_SESSION_EVENT_STATE_CHANGE:
520
sess->compositor_visible = xse.state.visible;
521
sess->compositor_focused = xse.state.focused;
522
break;
523
case XRT_SESSION_EVENT_OVERLAY_CHANGE:
524
#ifdef OXR_HAVE_EXTX_overlay
···
580
}
581
582
if (sess->state == XR_SESSION_STATE_SYNCHRONIZED && sess->compositor_visible) {
583
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0);
584
}
585
586
if (sess->state == XR_SESSION_STATE_VISIBLE && sess->compositor_focused) {
587
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, 0);
588
}
589
590
if (sess->state == XR_SESSION_STATE_FOCUSED && !sess->compositor_focused) {
591
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0);
592
}
593
594
if (sess->state == XR_SESSION_STATE_VISIBLE && !sess->compositor_visible) {
595
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0);
596
}
597
598
return XR_SUCCESS;
···
1102
} \
1103
} while (false)
1104
1105
-
#define OXR_CREATE_XRT_SESSION_AND_NATIVE_COMPOSITOR(LOG, XSI, SESS) \
1106
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); \
1122
} \
1123
} while (false)
1124
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)
1132
1133
1134
/*
···
1142
const struct xrt_session_info *xsi,
1143
struct oxr_session **out_session)
1144
{
1145
#if defined(XR_USE_PLATFORM_XLIB) && defined(XR_USE_GRAPHICS_API_OPENGL)
1146
XrGraphicsBindingOpenGLXlibKHR const *opengl_xlib = OXR_GET_INPUT_FROM_CHAIN(
1147
createInfo, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR, XrGraphicsBindingOpenGLXlibKHR);
···
1154
"xrGetOpenGL[ES]GraphicsRequirementsKHR");
1155
}
1156
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);
1159
return oxr_session_populate_gl_xlib(log, sys, opengl_xlib, *out_session);
1160
}
1161
#endif
···
1173
"xrGetOpenGLESGraphicsRequirementsKHR");
1174
}
1175
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);
1178
return oxr_session_populate_gles_android(log, sys, opengles_android, *out_session);
1179
}
1180
#endif
···
1190
"Has not called xrGetOpenGLGraphicsRequirementsKHR");
1191
}
1192
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);
1195
return oxr_session_populate_gl_win32(log, sys, opengl_win32, *out_session);
1196
}
1197
#endif
···
1229
(void *)vulkan->physicalDevice, (void *)sys->suggested_vulkan_physical_device, fn);
1230
}
1231
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);
1234
return oxr_session_populate_vk(log, sys, vulkan, *out_session);
1235
}
1236
#endif
···
1247
"xrGetOpenGL[ES]GraphicsRequirementsKHR");
1248
}
1249
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);
1252
return oxr_session_populate_egl(log, sys, egl, *out_session);
1253
}
1254
#endif
···
1265
return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING,
1266
"Has not called xrGetD3D11GraphicsRequirementsKHR");
1267
}
1268
-
XrResult result = oxr_d3d11_check_device(log, sys, d3d11->device);
1269
1270
-
if (!XR_SUCCEEDED(result)) {
1271
-
return result;
1272
}
1273
1274
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);
1277
return oxr_session_populate_d3d11(log, sys, d3d11, *out_session);
1278
}
1279
#endif
···
1290
return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING,
1291
"Has not called xrGetD3D12GraphicsRequirementsKHR");
1292
}
1293
-
XrResult result = oxr_d3d12_check_device(log, sys, d3d12->device);
1294
1295
-
if (!XR_SUCCEEDED(result)) {
1296
-
return result;
1297
}
1298
1299
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
return oxr_session_populate_d3d12(log, sys, d3d12, *out_session);
1303
}
1304
#endif
···
1312
1313
#ifdef OXR_HAVE_MND_headless
1314
if (sys->inst->extensions.MND_headless) {
1315
-
OXR_SESSION_ALLOCATE_AND_INIT(log, sys, OXR_SESSION_GRAPHICS_EXT_HEADLESS, *out_session);
1316
(*out_session)->compositor = NULL;
1317
(*out_session)->create_swapchain = NULL;
1318
···
1361
return ret;
1362
}
1363
1364
// 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);
1367
1368
*out_session = sess;
1369
···
317
#ifdef OXR_HAVE_META_body_tracking_calibration
318
.meta_body_tracking_calibration_enabled = extensions->META_body_tracking_calibration,
319
#endif
320
+
#ifdef OXR_HAVE_ANDROID_face_tracking
321
+
.android_face_tracking_enabled = extensions->ANDROID_face_tracking,
322
+
#endif
323
};
324
325
xrt_result_t xret = xrt_comp_begin_session(xc, &begin_session_info);
···
339
sess->compositor_visible = true;
340
sess->compositor_focused = true;
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
+
350
// Transition into focused.
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);
354
}
355
XrResult ret = oxr_frame_sync_begin_session(&sess->frame_sync);
356
if (ret != XR_SUCCESS) {
···
408
sess->compositor_focused = false;
409
}
410
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);
419
if (sess->exiting) {
420
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_EXITING, now_xr);
421
} else {
422
#ifndef XRT_OS_ANDROID
423
// @todo In multi-clients scenario with a session being reused, changing session
···
443
XrResult
444
oxr_session_request_exit(struct oxr_logger *log, struct oxr_session *sess)
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
+
453
if (sess->state == XR_SESSION_STATE_FOCUSED) {
454
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr);
455
}
456
if (sess->state == XR_SESSION_STATE_VISIBLE) {
457
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr);
458
}
459
if (!sess->has_ended_once && sess->state != XR_SESSION_STATE_SYNCHRONIZED) {
460
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr);
461
// Fake the synchronization.
462
sess->has_ended_once = true;
463
}
464
465
//! @todo start fading out the app.
466
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, now_xr);
467
sess->exiting = true;
468
return oxr_session_success_result(sess);
469
}
···
499
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "xrt_session is null");
500
}
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
+
509
#ifdef XRT_OS_ANDROID
510
// Most recent Android activity lifecycle event was OnPause: move toward stopping
511
if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_PAUSE) {
512
if (sess->state == XR_SESSION_STATE_FOCUSED) {
513
U_LOG_I("Activity paused: changing session state FOCUSED->VISIBLE");
514
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr);
515
}
516
517
if (sess->state == XR_SESSION_STATE_VISIBLE) {
518
U_LOG_I("Activity paused: changing session state VISIBLE->SYNCHRONIZED");
519
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr);
520
}
521
522
if (sess->state == XR_SESSION_STATE_SYNCHRONIZED) {
523
U_LOG_I("Activity paused: changing session state SYNCHRONIZED->STOPPING");
524
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, now_xr);
525
}
526
// TODO return here to avoid polling other events?
527
// see https://gitlab.freedesktop.org/monado/monado/-/issues/419
···
531
if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_RESUME) {
532
if (sess->state == XR_SESSION_STATE_IDLE) {
533
U_LOG_I("Activity resumed: changing session state IDLE->READY");
534
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, now_xr);
535
}
536
}
537
#endif // XRT_OS_ANDROID
···
551
case XRT_SESSION_EVENT_STATE_CHANGE:
552
sess->compositor_visible = xse.state.visible;
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
+
559
break;
560
case XRT_SESSION_EVENT_OVERLAY_CHANGE:
561
#ifdef OXR_HAVE_EXTX_overlay
···
617
}
618
619
if (sess->state == XR_SESSION_STATE_SYNCHRONIZED && sess->compositor_visible) {
620
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr);
621
}
622
623
if (sess->state == XR_SESSION_STATE_VISIBLE && sess->compositor_focused) {
624
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, now_xr);
625
}
626
627
if (sess->state == XR_SESSION_STATE_FOCUSED && !sess->compositor_focused) {
628
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr);
629
}
630
631
if (sess->state == XR_SESSION_STATE_VISIBLE && !sess->compositor_visible) {
632
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr);
633
}
634
635
return XR_SUCCESS;
···
1139
} \
1140
} while (false)
1141
1142
+
#define OXR_CHECK_XR_SUCCESS(LOG, FUNC, MSG) \
1143
do { \
1144
+
XrResult _xr_result = FUNC; \
1145
+
if (_xr_result != XR_SUCCESS) { \
1146
+
return oxr_error(LOG, _xr_result, MSG); \
1147
} \
1148
} while (false)
1149
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
+
1176
1177
1178
/*
···
1186
const struct xrt_session_info *xsi,
1187
struct oxr_session **out_session)
1188
{
1189
+
XrResult ret = XR_SUCCESS;
1190
+
1191
#if defined(XR_USE_PLATFORM_XLIB) && defined(XR_USE_GRAPHICS_API_OPENGL)
1192
XrGraphicsBindingOpenGLXlibKHR const *opengl_xlib = OXR_GET_INPUT_FROM_CHAIN(
1193
createInfo, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR, XrGraphicsBindingOpenGLXlibKHR);
···
1200
"xrGetOpenGL[ES]GraphicsRequirementsKHR");
1201
}
1202
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
+
1209
return oxr_session_populate_gl_xlib(log, sys, opengl_xlib, *out_session);
1210
}
1211
#endif
···
1223
"xrGetOpenGLESGraphicsRequirementsKHR");
1224
}
1225
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
+
1232
return oxr_session_populate_gles_android(log, sys, opengles_android, *out_session);
1233
}
1234
#endif
···
1244
"Has not called xrGetOpenGLGraphicsRequirementsKHR");
1245
}
1246
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
+
1253
return oxr_session_populate_gl_win32(log, sys, opengl_win32, *out_session);
1254
}
1255
#endif
···
1287
(void *)vulkan->physicalDevice, (void *)sys->suggested_vulkan_physical_device, fn);
1288
}
1289
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
+
1296
return oxr_session_populate_vk(log, sys, vulkan, *out_session);
1297
}
1298
#endif
···
1309
"xrGetOpenGL[ES]GraphicsRequirementsKHR");
1310
}
1311
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
+
1318
return oxr_session_populate_egl(log, sys, egl, *out_session);
1319
}
1320
#endif
···
1331
return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING,
1332
"Has not called xrGetD3D11GraphicsRequirementsKHR");
1333
}
1334
+
ret = oxr_d3d11_check_device(log, sys, d3d11->device);
1335
1336
+
if (!XR_SUCCEEDED(ret)) {
1337
+
return ret;
1338
}
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");
1342
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
+
1346
return oxr_session_populate_d3d11(log, sys, d3d11, *out_session);
1347
}
1348
#endif
···
1359
return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING,
1360
"Has not called xrGetD3D12GraphicsRequirementsKHR");
1361
}
1362
+
ret = oxr_d3d12_check_device(log, sys, d3d12->device);
1363
1364
+
if (!XR_SUCCEEDED(ret)) {
1365
+
return ret;
1366
}
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");
1373
1374
return oxr_session_populate_d3d12(log, sys, d3d12, *out_session);
1375
}
1376
#endif
···
1384
1385
#ifdef OXR_HAVE_MND_headless
1386
if (sys->inst->extensions.MND_headless) {
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
+
1391
(*out_session)->compositor = NULL;
1392
(*out_session)->create_swapchain = NULL;
1393
···
1436
return ret;
1437
}
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
+
1446
// Everything is in order, start the state changes.
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);
1449
1450
*out_session = sess;
1451
+12
-5
src/xrt/state_trackers/oxr/oxr_session_frame_end.c
+12
-5
src/xrt/state_trackers/oxr/oxr_session_frame_end.c
···
1551
}
1552
1553
static void
1554
-
do_synchronize_state_change(struct oxr_logger *log, struct oxr_session *sess)
1555
{
1556
if (!sess->has_ended_once && sess->state < XR_SESSION_STATE_VISIBLE) {
1557
-
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0);
1558
sess->has_ended_once = true;
1559
}
1560
}
···
1663
struct xrt_compositor *xc = sess->compositor;
1664
1665
1666
/*
1667
* Early out for headless sessions.
1668
*/
···
1673
sess->active_wait_frames--;
1674
os_mutex_unlock(&sess->active_wait_frames_lock);
1675
1676
-
do_synchronize_state_change(log, sess);
1677
1678
return oxr_session_success_result(sess);
1679
}
···
1716
sess->frame_id.begun = -1;
1717
sess->frame_started = false;
1718
1719
-
do_synchronize_state_change(log, sess);
1720
1721
return oxr_session_success_result(sess);
1722
}
···
1785
*/
1786
1787
// Do state change if needed.
1788
-
do_synchronize_state_change(log, sess);
1789
1790
struct xrt_layer_frame_data data = {
1791
.frame_id = sess->frame_id.begun,
···
1551
}
1552
1553
static void
1554
+
do_synchronize_state_change(struct oxr_logger *log, struct oxr_session *sess, XrTime time)
1555
{
1556
if (!sess->has_ended_once && sess->state < XR_SESSION_STATE_VISIBLE) {
1557
+
oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, time);
1558
sess->has_ended_once = true;
1559
}
1560
}
···
1663
struct xrt_compositor *xc = sess->compositor;
1664
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
+
1673
/*
1674
* Early out for headless sessions.
1675
*/
···
1680
sess->active_wait_frames--;
1681
os_mutex_unlock(&sess->active_wait_frames_lock);
1682
1683
+
do_synchronize_state_change(log, sess, now_xr);
1684
1685
return oxr_session_success_result(sess);
1686
}
···
1723
sess->frame_id.begun = -1;
1724
sess->frame_started = false;
1725
1726
+
do_synchronize_state_change(log, sess, now_xr);
1727
1728
return oxr_session_success_result(sess);
1729
}
···
1792
*/
1793
1794
// Do state change if needed.
1795
+
do_synchronize_state_change(log, sess, now_xr);
1796
1797
struct xrt_layer_frame_data data = {
1798
.frame_id = sess->frame_id.begun,
+36
src/xrt/state_trackers/oxr/oxr_system.c
+36
src/xrt/state_trackers/oxr/oxr_system.c
···
406
}
407
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
431
oxr_system_get_face_tracking_htc_support(struct oxr_logger *log,
432
struct oxr_instance *inst,
433
bool *supports_eye,
···
589
}
590
}
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
606
607
#ifdef OXR_HAVE_HTC_facial_tracking
608
XrSystemFacialTrackingPropertiesHTC *htc_facial_tracking_props = NULL;
+7
-1
src/xrt/targets/sdl_test/sdl_compositor.c
+7
-1
src/xrt/targets/sdl_test/sdl_compositor.c
···
256
{
257
struct xrt_system_compositor_info *sys_info = &c->sys_info;
258
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
+
*/
266
sys_info->max_layers = XRT_MAX_LAYERS;
267
268
// UUIDs and LUID already set in vk init.
-1
src/xrt/tracking/hand/mercury/hg_sync.cpp
-1
src/xrt/tracking/hand/mercury/hg_sync.cpp
+4
-10
src/xrt/tracking/hand/t_hand_tracking_async.c
+4
-10
src/xrt/tracking/hand/t_hand_tracking_async.c
···
137
struct xrt_space_relation wrist_rel =
138
hta->working.hands[i].values.hand_joint_set_default[XRT_HAND_JOINT_WRIST].relation;
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); //
150
}
151
152
hta->hand_tracking_work_active = false;
···
137
struct xrt_space_relation wrist_rel =
138
hta->working.hands[i].values.hand_joint_set_default[XRT_HAND_JOINT_WRIST].relation;
139
140
+
m_relation_history_push_with_motion_estimation( //
141
+
hta->present.relation_hist[i], //
142
+
&wrist_rel, //
143
+
hta->working.timestamp); //
144
}
145
146
hta->hand_tracking_work_active = false;
+13
-15
tests/tests_aux_d3d_d3d11.cpp
+13
-15
tests/tests_aux_d3d_d3d11.cpp
···
88
std::vector<xrt_image_native> xins;
89
xins.reserve(image_count);
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
for (HANDLE handle : handles) {
96
-
wil::unique_handle duped{u_graphics_buffer_ref(handle)};
97
xrt_image_native xin;
98
-
xin.handle = duped.get();
99
xin.size = 0;
100
xin.use_dedicated_allocation = use_dedicated_allocation;
101
102
-
handlesForImport.emplace_back(std::move(duped));
103
xins.emplace_back(xin);
104
}
105
106
// 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());
108
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;
116
}
117
#else
118
···
88
std::vector<xrt_image_native> xins;
89
xins.reserve(image_count);
90
91
for (HANDLE handle : handles) {
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
+
*/
100
xrt_image_native xin;
101
+
xin.handle = handle;
102
xin.size = 0;
103
xin.use_dedicated_allocation = use_dedicated_allocation;
104
+
xin.is_dxgi_handle = true;
105
106
xins.emplace_back(xin);
107
}
108
109
// Import into a vulkan image collection
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);
112
113
+
return true;
114
}
115
#else
116