steamvr: Implement basic SteamVR driver

v3:
  targets: Add Monado-SteamVR driver target
  st/ovrd: Add OpenVR driver header
  build: Factor out sdl hack into lib_sdl2_hack and update steamvr build
  build: Revert lib_sdl2_refactor
  steamvr: Emulate Index Controller by default
  steamvr: Use oxr_handle_destroy instead of exposing oxr_instance_destroy
  steamvr: don't use oxr internals
  steamvr: communicate 3dof tracking to steamvr
  steamvr: use util functions for device assignment and tracking origin setup
  steamvr: Install plugin to <prefix>/share/steamvr-monado
  steamvr: Use thread for updating poses every 1ms

Makes a big difference for the Index @144Hz on the vive driver.
Still somewhat choppy on survive driver - prediction should solve it.

Main-author: Christoph Haag <christoph.haag@collabora.com>
Co-author: Jakob Bornecrantz <jakob@collabora.com>
This commit is contained in:
Christoph Haag 2020-06-10 14:48:43 +01:00 committed by Jakob Bornecrantz
parent b6c3475352
commit cb62514fd0
40 changed files with 2002 additions and 1 deletions

View file

@ -123,6 +123,8 @@ option(XRT_FEATURE_SERVICE "Enable separate service module for OpenXR runtime" O
cmake_dependent_option(XRT_HAVE_SYSTEMD "Enable systemd support (for socket activation of service)" ON "Systemd_FOUND AND XRT_FEATURE_SERVICE" OFF)
cmake_dependent_option(XRT_INSTALL_SYSTEMD_UNIT_FILES "Install user unit files for systemd socket activation on installation" ON "XRT_HAVE_SYSTEMD" OFF)
cmake_dependent_option(XRT_INSTALL_ABSOLUTE_SYSTEMD_UNIT_FILES "Use an absolute path to monado-system in installed user unit files for systemd socket activation" ON "XRT_INSTALL_SYSTEMD_UNIT_FILES" OFF)
option(XRT_FEATURE_STEAMVR_PLUGIN "Build SteamVR plugin" ON)
if(NOT DEFINED XRT_FEATURE_OPENXR_LAYER_DEPTH)
set(XRT_FEATURE_OPENXR_LAYER_DEPTH ON)
endif()
@ -283,6 +285,7 @@ message(STATUS "# FEATURE_OPENXR_LAYER_CUBE: ${XRT_FEATURE_OPENXR_
message(STATUS "# FEATURE_OPENXR_LAYER_CYLINDER: ${XRT_FEATURE_OPENXR_LAYER_CYLINDER}")
message(STATUS "# FEATURE_OPENXR_LAYER_EQUIRECT: ${XRT_FEATURE_OPENXR_LAYER_EQUIRECT}")
message(STATUS "# FEATURE_OPENXR_LAYER_EQUIRECT_LEGACY: ${XRT_FEATURE_OPENXR_LAYER_EQUIRECT_LEGACY}")
message(STATUS "# FEATURE_STEAMVR_PLUGIN: ${XRT_FEATURE_STEAMVR_PLUGIN}")
message(STATUS "#")
message(STATUS "# DRIVER_ANDROID: ${XRT_BUILD_DRIVER_ANDROID}")
message(STATUS "# DRIVER_ARDUINO: ${XRT_BUILD_DRIVER_ARDUINO}")

View file

@ -245,3 +245,9 @@ if build_tracking
else
message(' tracking: no')
endif
if get_option('steamvr_plugin')
message('steamvr plugin: yes')
else
message('steamvr plugin: no')
endif

View file

@ -107,3 +107,10 @@ option('layer_equirect2',
value: true,
description: 'Enable support for Equirect2 Layers'
)
option('steamvr_plugin',
type: 'boolean',
value: true,
description: 'Enable SteamVR Plugin'
)

View file

@ -1,7 +1,7 @@
# Copyright 2019-2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
openvr_include = include_directories('openvr_includes')
openvr_include = include_directories('openvr_includes', is_system: true)
cjson_include = include_directories('cjson')
flexkalman_include = include_directories('flexkalman')
glad_include = include_directories('glad/include')

View file

@ -1,4 +1,6 @@
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
xrt_include = include_directories('.')
subdir('xrt')

View file

@ -6,3 +6,7 @@ if(XRT_HAVE_OPENGL)
endif()
add_subdirectory(oxr)
add_subdirectory(prober)
if(XRT_FEATURE_STEAMVR_PLUGIN)
add_subdirectory(steamvr_drv)
endif()

View file

@ -6,3 +6,7 @@ st_include = include_directories('.')
subdir('gui')
subdir('oxr')
subdir('prober')
if get_option('steamvr_plugin')
subdir('steamvr_drv')
endif

View file

@ -0,0 +1,19 @@
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
set(OVRD_SOURCE_FILES
ovrd_driver.cpp
ovrd_interface.h
)
add_library(st_ovrd STATIC
${OVRD_SOURCE_FILES}
)
target_include_directories(st_ovrd INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries(st_ovrd PRIVATE
xrt-interfaces
xrt-external-openvr
aux_math
)

View file

@ -0,0 +1,20 @@
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
st_ovrd_include = include_directories('.')
lib_st_ovrd = static_library(
'st_ovrd',
files(
'ovrd_driver.cpp',
'ovrd_interface.h'
),
include_directories: [
openvr_include,
st_include, # Sigh debian meson requires this.
xrt_include,
],
dependencies: aux_util,
c_args: compile_args,
cpp_args: compile_args,
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
// Copyright 2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Interface to the Monado SteamVR Driver exporter.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup st_ovrd
*/
#pragma once
#include "xrt/xrt_defines.h"
/*!
* @defgroup st_ovrd SteamVR driver provider
*
* Wraps a @ref xrt_instance and one or more @ref xrt_device and exposes those
* to SteamVR via the OpenVR driver interface.
*
* @ingroup xrt
*/
/*!
* Implementation of the HmdDriverFactory function.
*
* @ingroup st_ovrd
*/
void *
ovrd_hmd_driver_impl(const char *pInterfaceName, int *pReturnCode);

View file

@ -0,0 +1,62 @@
// Copyright 2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Logger code.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup st_ovrd
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include "xrt/xrt_compiler.h"
#ifdef __cplusplus
}
#endif
#include "openvr_driver.h"
static vr::IVRDriverLog *s_pLogFile = NULL;
static inline void
ovrd_log_init(vr::IVRDriverLog *pDriverLog)
{
// Noop
s_pLogFile = vr::VRDriverLog();
}
// Can not use the XRT_PRINTF_FORMAT macro on a function definition.
static inline void
ovrd_log(const char *fmt, ...) XRT_PRINTF_FORMAT(1, 2);
static inline void
ovrd_log(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
char buf[1024];
#if defined(WIN32)
vsprintf_s(buf, pMsgFormat, args);
#else
vsnprintf(buf, sizeof(buf), fmt, args);
#endif
if (s_pLogFile)
s_pLogFile->Log(buf);
va_end(args);
}
static inline void
ovrd_log_cleanup()
{
s_pLogFile = nullptr;
}

View file

@ -29,3 +29,7 @@ if(XRT_FEATURE_SERVICE AND XRT_FEATURE_OPENXR)
add_subdirectory(service)
endif()
endif()
if(XRT_FEATURE_STEAMVR_PLUGIN)
add_subdirectory(steamvr_drv)
endif()

View file

@ -78,3 +78,6 @@ if get_option('service')
subdir('ctl')
endif
if get_option('steamvr_plugin')
subdir('steamvr_drv')
endif

View file

@ -0,0 +1,51 @@
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
add_library(driver_monado MODULE
main.c
)
target_link_libraries(driver_monado PRIVATE
xrt-external-openvr
aux_util
st_ovrd
st_prober
target_lists
target_instance_no_comp
)
# meta data that the steamvr plugin needs in the base directory of the steamvr plugin
file(COPY driver.vrdrivermanifest DESTINATION ${CMAKE_BINARY_DIR}/steamvr-monado)
file(COPY resources DESTINATION ${CMAKE_BINARY_DIR}/steamvr-monado)
#determine the output directory for the steamvr plugin
if (WIN32)
# FIXME need to account for different architectures
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(PLUGINDIR ${CMAKE_BINARY_DIR}/steamvr-monado/bin/win64 CACHE TYPE INTERNAL)
else()
set(PLUGINDIR ${CMAKE_BINARY_DIR}/steamvr-monado/bin/win32 CACHE TYPE INTERNAL)
endif()
elseif(APPLE)
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(PLUGINDIR ${CMAKE_BINARY_DIR}/steamvr-monado/bin/osx64 CACHE STRING INTERNAL)
else()
set(PLUGINDIR ${CMAKE_BINARY_DIR}/steamvr-monado/bin/osx32 CACHE STRING INTERNAL)
endif()
elseif(NOT ANDROID)
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(PLUGINDIR ${CMAKE_BINARY_DIR}/steamvr-monado/bin/linux64 CACHE STRING INTERNAL)
else()
set(PLUGINDIR ${CMAKE_BINARY_DIR}/steamvr-monado/bin/linux32 CACHE STRING INTERNAL)
endif()
endif()
MESSAGE("SteamVR plugin path: ${PLUGINDIR}")
set_target_properties(driver_monado PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PLUGINDIR}")
# don't add lib prefix to driver_monado.so
SET_TARGET_PROPERTIES(driver_monado PROPERTIES PREFIX "")
install(DIRECTORY "${PROJECT_BINARY_DIR}/steamvr-monado" DESTINATION "${CMAKE_INSTALL_PREFIX}/share")

View file

@ -0,0 +1,31 @@
#!/usr/bin/env python3
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
import os, sys, shutil
print(sys.argv[1], sys.argv[2], sys.argv[3])
is_file = sys.argv[1] == "FILE"
is_dir = sys.argv[1] == "DIRECTORY"
# get absolute input and output paths
input_path = os.path.join(
os.getenv('MESON_SOURCE_ROOT'),
os.getenv('MESON_SUBDIR'),
sys.argv[2])
output_path = os.path.join(
os.getenv('MESON_BUILD_ROOT'),
sys.argv[3])
# make sure destination directory exists
os.makedirs(os.path.dirname(output_path), exist_ok=True)
if is_file:
shutil.copyfile(input_path, output_path)
elif is_dir:
shutil.copytree(input_path, output_path)
print("Copying asset " + str(input_path) + " to " + str(output_path))

View file

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
import os, sys, shutil
# get absolute input and output paths
input_path = os.path.join(
sys.argv[1])
output_path = os.path.join(
sys.argv[2])
# make sure destination directory exists
os.makedirs(os.path.dirname(output_path), exist_ok=True)
shutil.copyfile(input_path, output_path)
print("Copying plugin " + str(input_path) + " to " + str(output_path))

View file

@ -0,0 +1,11 @@
{
"alwaysActivate": false,
"name" : "monado",
"directory" : "",
"resourceOnly" : false,
"hmd_presence" :
[
"*.*"
]
}

View file

@ -0,0 +1,28 @@
// Copyright 2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Very simple target main file to export the right symbol.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Christoph Haag <christoph.haag@collabora.com>
* @ingroup st_ovrd
*/
#include "ovrd_interface.h"
#if defined(_WIN32)
#define HMD_DLL_EXPORT __declspec(dllexport)
#define HMD_DLL_IMPORT __declspec(dllimport)
#elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__)
#define HMD_DLL_EXPORT __attribute__((visibility("default")))
#define HMD_DLL_IMPORT
#else
#error "Unsupported Platform."
#endif
HMD_DLL_EXPORT void *
HmdDriverFactory(const char *pInterfaceName, int *pReturnCode)
{
return ovrd_hmd_driver_impl(pInterfaceName, pReturnCode);
}

View file

@ -0,0 +1,65 @@
# Copyright 2020, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
plugin_dir = 'steamvr-monado'
driver_monado = shared_library(
'driver_monado',
files(
'main.c'
),
link_whole: [
lib_target_instance_no_comp,
lib_st_ovrd,
],
include_directories: [
openvr_include,
st_ovrd_include,
openvr_include,
aux_include,
xrt_include,
],
link_with : driver_libs,
dependencies : [pthreads, libjpeg],
# build 'driver_monado.so' instead of 'libdriver_monado.so'
name_prefix: '',
)
copy_asset = find_program('copy_assets.py')
copy_plugin = find_program('copy_plugin.py')
run_command(copy_asset, 'FILE', 'driver.vrdrivermanifest', join_paths(plugin_dir, 'driver.vrdrivermanifest'))
run_command(copy_asset, 'DIRECTORY', 'resources', join_paths(plugin_dir, 'resources'))
plugin_archdir = ''
if host_machine.system() == 'windows'
if host_machine.cpu_family() == 'x86'
plugin_archdir = 'win32'
elif host_machine.cpu_family() == 'x86_64'
plugin_archdir = 'win64'
endif
elif host_machine.system() == 'linux'
if host_machine.cpu_family() == 'x86'
plugin_archdir = 'linux32'
elif host_machine.cpu_family() == 'x86_64'
plugin_archdir = 'linux64'
endif
endif
custom_target(
'plugin_copy',
depends : driver_monado,
input : driver_monado,
output : 'fake_plugin',
command : [copy_plugin, '@INPUT@', join_paths(plugin_dir, 'bin', plugin_archdir, '@PLAINNAME@')],
build_by_default : true
)
if meson.version().version_compare('<0.56')
build_root = meson.build_root()
else
build_root = meson.project_build_root()
endif
install_subdir(join_paths(build_root, plugin_dir), install_dir: join_paths(get_option('prefix'), 'share'))

View file

@ -0,0 +1,47 @@
{
"jsonid" : "vrresources",
"statusicons" : {
"HMD" : {
"Prop_NamedIconPathDeviceOff_String" : "{monado}/icons/headset_monado_status_off.png",
"Prop_NamedIconPathDeviceSearching_String" : "{monado}/icons/headset_monado_status_searching.gif",
"Prop_NamedIconPathDeviceSearchingAlert_String" : "{monado}/icons/headset_monado_status_searching_alert.gif",
"Prop_NamedIconPathDeviceReady_String" : "{monado}/icons/headset_monado_status_ready.png",
"Prop_NamedIconPathDeviceReadyAlert_String" : "{monado}/icons/headset_monado_status_ready_alert.png",
"Prop_NamedIconPathDeviceNotReady_String" : "{monado}/icons/headset_monado_status_error.png",
"Prop_NamedIconPathDeviceStandby_String" : "{monado}/icons/headset_monado_status_standby.png",
"Prop_NamedIconPathDeviceAlertLow_String" : "{monado}/icons/headset_monado_status_ready_low.png"
},
"Model-v Defaults" : {
"Prop_NamedIconPathDeviceOff_String" : "{monado}/icons/headset_monado_status_off.png",
"Prop_NamedIconPathDeviceSearching_String" : "Prop_NamedIconPathDeviceOff_String",
"Prop_NamedIconPathDeviceSearchingAlert_String" : "Prop_NamedIconPathDeviceOff_String",
"Prop_NamedIconPathDeviceReady_String" : "Prop_NamedIconPathDeviceOff_String",
"Prop_NamedIconPathDeviceReadyAlert_String" : "Prop_NamedIconPathDeviceOff_String",
"Prop_NamedIconPathDeviceNotReady_String" : "Prop_NamedIconPathDeviceOff_String",
"Prop_NamedIconPathDeviceStandby_String" : "Prop_NamedIconPathDeviceOff_String",
"Prop_NamedIconPathDeviceAlertLow_String" : "Prop_NamedIconPathDeviceOff_String"
},
"Model-v1.0" : {
"Alias" : "Model-v Defaults",
"Prop_NamedIconPathDeviceAlertLow_String" : "{monado}/icons/headset_model1_alertlow.png"
},
"Model-v2.0" : {
"Alias" : "Model-v1.0",
"Prop_NamedIconPathDeviceAlertLow_String" : "{monado}/icons/headset_model2_alertlow.png"
},
"Controller" : {
"Prop_NamedIconPathDeviceOff_String" : "{monado}/icons/controller_status_off.png",
"Prop_NamedIconPathDeviceSearching_String" : "{monado}/icons/controller_status_searching.gif",
"Prop_NamedIconPathDeviceSearchingAlert_String" : "{monado}/icons/controller_status_searching_alert.gif",
"Prop_NamedIconPathDeviceReady_String" : "{monado}/icons/controller_status_ready.png",
"Prop_NamedIconPathDeviceReadyAlert_String" : "{monado}/icons/controller_status_ready_alert.png",
"Prop_NamedIconPathDeviceNotReady_String" : "{monado}/icons/controller_status_error.png",
"Prop_NamedIconPathDeviceStandby_String" : "{monado}/icons/controller_status_standby.png",
"Prop_NamedIconPathDeviceAlertLow_String" : "{monado}/icons/controller_status_ready_low.png"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,6 @@
[
{
"language_tag": "en_US",
"monado_controller" : "Monado Driver Controller"
}
]

View file

@ -0,0 +1,5 @@
{
"driver_monado" : {
"enable" : true
}
}

View file

@ -0,0 +1,16 @@
{
"jsonid" : "vrsettings",
"driver_lighthouse": {
"enable": false
},
"driver_oculus": {
"enable": false
},
"driver_oculus_legacy": {
"enable": false
},
"driver_monado" : {
"enable": true
},
"version" : "1"
}