summaryrefslogtreecommitdiffstats
path: root/gfx/vr/service/openvr/src/openvr_api_public.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/vr/service/openvr/src/openvr_api_public.cpp')
-rw-r--r--gfx/vr/service/openvr/src/openvr_api_public.cpp352
1 files changed, 352 insertions, 0 deletions
diff --git a/gfx/vr/service/openvr/src/openvr_api_public.cpp b/gfx/vr/service/openvr/src/openvr_api_public.cpp
new file mode 100644
index 0000000000..54aa555955
--- /dev/null
+++ b/gfx/vr/service/openvr/src/openvr_api_public.cpp
@@ -0,0 +1,352 @@
+//========= Copyright Valve Corporation ============//
+#define VR_API_EXPORT 1
+#include "openvr.h"
+#include "ivrclientcore.h"
+#include "pathtools_public.h"
+#include "sharedlibtools_public.h"
+#include "envvartools_public.h"
+#include "hmderrors_public.h"
+#include "strtools_public.h"
+#include "vrpathregistry_public.h"
+#include <mutex>
+
+using vr::EVRInitError;
+using vr::IVRSystem;
+using vr::IVRClientCore;
+using vr::VRInitError_None;
+
+// figure out how to import from the VR API dll
+#if defined(_WIN32)
+
+#if !defined(OPENVR_BUILD_STATIC)
+#define VR_EXPORT_INTERFACE extern "C" __declspec( dllexport )
+#else
+#define VR_EXPORT_INTERFACE extern "C"
+#endif
+
+#elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__)
+
+#define VR_EXPORT_INTERFACE extern "C" __attribute__((visibility("default")))
+
+#else
+#error "Unsupported Platform."
+#endif
+
+namespace vr
+{
+
+static void *g_pVRModule = NULL;
+static IVRClientCore *g_pHmdSystem = NULL;
+static std::recursive_mutex g_mutexSystem;
+
+
+typedef void* (*VRClientCoreFactoryFn)(const char *pInterfaceName, int *pReturnCode);
+
+static uint32_t g_nVRToken = 0;
+
+uint32_t VR_GetInitToken()
+{
+ return g_nVRToken;
+}
+
+EVRInitError VR_LoadHmdSystemInternal();
+void CleanupInternalInterfaces();
+
+
+uint32_t VR_InitInternal2( EVRInitError *peError, vr::EVRApplicationType eApplicationType, const char *pStartupInfo )
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ EVRInitError err = VR_LoadHmdSystemInternal();
+ if ( err == vr::VRInitError_None )
+ {
+ err = g_pHmdSystem->Init( eApplicationType, pStartupInfo );
+ }
+
+ if ( peError )
+ *peError = err;
+
+ if ( err != VRInitError_None )
+ {
+ SharedLib_Unload( g_pVRModule );
+ g_pHmdSystem = NULL;
+ g_pVRModule = NULL;
+
+ return 0;
+ }
+
+ return ++g_nVRToken;
+}
+
+VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
+
+uint32_t VR_InitInternal( EVRInitError *peError, vr::EVRApplicationType eApplicationType )
+{
+ return VR_InitInternal2( peError, eApplicationType, nullptr );
+}
+
+void VR_ShutdownInternal()
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if ( g_pHmdSystem )
+ {
+ g_pHmdSystem->Cleanup();
+ g_pHmdSystem = NULL;
+ }
+ if ( g_pVRModule )
+ {
+ SharedLib_Unload( g_pVRModule );
+ g_pVRModule = NULL;
+ }
+
+#if !defined( VR_API_PUBLIC )
+ CleanupInternalInterfaces();
+#endif
+
+ ++g_nVRToken;
+}
+
+EVRInitError VR_LoadHmdSystemInternal()
+{
+ std::string sRuntimePath, sConfigPath, sLogPath;
+
+ bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
+ if( !bReadPathRegistry )
+ {
+ return vr::VRInitError_Init_PathRegistryNotFound;
+ }
+
+ // figure out where we're going to look for vrclient.dll
+ // see if the specified path actually exists.
+ if( !Path_IsDirectory( sRuntimePath ) )
+ {
+ return vr::VRInitError_Init_InstallationNotFound;
+ }
+
+ // Because we don't have a way to select debug vs. release yet we'll just
+ // use debug if it's there
+#if defined( LINUX64 ) || defined( LINUXARM64 )
+ std::string sTestPath = Path_Join( sRuntimePath, "bin", PLATSUBDIR );
+#else
+ std::string sTestPath = Path_Join( sRuntimePath, "bin" );
+#endif
+ if( !Path_IsDirectory( sTestPath ) )
+ {
+ return vr::VRInitError_Init_InstallationCorrupt;
+ }
+
+#if defined( WIN64 )
+ std::string sDLLPath = Path_Join( sTestPath, "vrclient_x64" DYNAMIC_LIB_EXT );
+#else
+ std::string sDLLPath = Path_Join( sTestPath, "vrclient" DYNAMIC_LIB_EXT );
+#endif
+
+ // only look in the override
+ void *pMod = SharedLib_Load( sDLLPath.c_str() );
+ // nothing more to do if we can't load the DLL
+ if( !pMod )
+ {
+ return vr::VRInitError_Init_VRClientDLLNotFound;
+ }
+
+ VRClientCoreFactoryFn fnFactory = ( VRClientCoreFactoryFn )( SharedLib_GetFunction( pMod, "VRClientCoreFactory" ) );
+ if( !fnFactory )
+ {
+ SharedLib_Unload( pMod );
+ return vr::VRInitError_Init_FactoryNotFound;
+ }
+
+ int nReturnCode = 0;
+ g_pHmdSystem = static_cast< IVRClientCore * > ( fnFactory( vr::IVRClientCore_Version, &nReturnCode ) );
+ if( !g_pHmdSystem )
+ {
+ SharedLib_Unload( pMod );
+ return vr::VRInitError_Init_InterfaceNotFound;
+ }
+
+ g_pVRModule = pMod;
+ return VRInitError_None;
+}
+
+
+void *VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError)
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if (!g_pHmdSystem)
+ {
+ if (peError)
+ *peError = vr::VRInitError_Init_NotInitialized;
+ return NULL;
+ }
+
+ return g_pHmdSystem->GetGenericInterface(pchInterfaceVersion, peError);
+}
+
+bool VR_IsInterfaceVersionValid(const char *pchInterfaceVersion)
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if (!g_pHmdSystem)
+ {
+ return false;
+ }
+
+ return g_pHmdSystem->IsInterfaceVersionValid(pchInterfaceVersion) == VRInitError_None;
+}
+
+bool VR_IsHmdPresent()
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if( g_pHmdSystem )
+ {
+ // if we're already initialized, just call through
+ return g_pHmdSystem->BIsHmdPresent();
+ }
+ else
+ {
+ // otherwise we need to do a bit more work
+ EVRInitError err = VR_LoadHmdSystemInternal();
+ if( err != VRInitError_None )
+ return false;
+
+ bool bHasHmd = g_pHmdSystem->BIsHmdPresent();
+
+ g_pHmdSystem = NULL;
+ SharedLib_Unload( g_pVRModule );
+ g_pVRModule = NULL;
+
+ return bHasHmd;
+ }
+}
+
+/** Returns true if the OpenVR runtime is installed. */
+bool VR_IsRuntimeInstalled()
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if( g_pHmdSystem )
+ {
+ // if we're already initialized, OpenVR is obviously installed
+ return true;
+ }
+ else
+ {
+ // otherwise we need to do a bit more work
+ std::string sRuntimePath, sConfigPath, sLogPath;
+
+ bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
+ if( !bReadPathRegistry )
+ {
+ return false;
+ }
+
+ // figure out where we're going to look for vrclient.dll
+ // see if the specified path actually exists.
+ if( !Path_IsDirectory( sRuntimePath ) )
+ {
+ return false;
+ }
+
+ // the installation may be corrupt in some way, but it certainly looks installed
+ return true;
+ }
+}
+
+
+// -------------------------------------------------------------------------------
+// Purpose: This is the old Runtime Path interface that is no longer exported in the
+// latest header. We still want to export it from the DLL, though, so updating
+// to a new DLL doesn't break old compiled code. This version was not thread
+// safe and could change the buffer pointer to by a previous result on a
+// subsequent call
+// -------------------------------------------------------------------------------
+VR_EXPORT_INTERFACE const char *VR_CALLTYPE VR_RuntimePath();
+
+/** Returns where OpenVR runtime is installed. */
+const char *VR_RuntimePath()
+{
+ static char rchBuffer[1024];
+ uint32_t unRequiredSize;
+ if ( VR_GetRuntimePath( rchBuffer, sizeof( rchBuffer ), &unRequiredSize ) && unRequiredSize < sizeof( rchBuffer ) )
+ {
+ return rchBuffer;
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+
+/** Returns where OpenVR runtime is installed. */
+bool VR_GetRuntimePath( char *pchPathBuffer, uint32_t unBufferSize, uint32_t *punRequiredBufferSize )
+{
+ // otherwise we need to do a bit more work
+ std::string sRuntimePath;
+
+ *punRequiredBufferSize = 0;
+
+ bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, nullptr, nullptr, nullptr, nullptr );
+ if ( !bReadPathRegistry )
+ {
+ return false;
+ }
+
+ // figure out where we're going to look for vrclient.dll
+ // see if the specified path actually exists.
+ if ( !Path_IsDirectory( sRuntimePath ) )
+ {
+ return false;
+ }
+
+ *punRequiredBufferSize = (uint32_t)sRuntimePath.size() + 1;
+ if ( sRuntimePath.size() >= unBufferSize )
+ {
+ *pchPathBuffer = '\0';
+ }
+ else
+ {
+ strcpy_safe( pchPathBuffer, unBufferSize, sRuntimePath.c_str() );
+ }
+
+ return true;
+}
+
+
+/** Returns the symbol version of an HMD error. */
+const char *VR_GetVRInitErrorAsSymbol( EVRInitError error )
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if( g_pHmdSystem )
+ return g_pHmdSystem->GetIDForVRInitError( error );
+ else
+ return GetIDForVRInitError( error );
+}
+
+
+/** Returns the english string version of an HMD error. */
+const char *VR_GetVRInitErrorAsEnglishDescription( EVRInitError error )
+{
+ std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
+
+ if ( g_pHmdSystem )
+ return g_pHmdSystem->GetEnglishStringForHmdError( error );
+ else
+ return GetEnglishStringForHmdError( error );
+}
+
+
+VR_INTERFACE const char *VR_CALLTYPE VR_GetStringForHmdError( vr::EVRInitError error );
+
+/** Returns the english string version of an HMD error. */
+const char *VR_GetStringForHmdError( EVRInitError error )
+{
+ return VR_GetVRInitErrorAsEnglishDescription( error );
+}
+
+}
+