tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

openvr_api_public.cpp (8690B)


      1 //========= Copyright Valve Corporation ============//
      2 #define VR_API_EXPORT 1
      3 #include "openvr.h"
      4 #include "ivrclientcore.h"
      5 #include "pathtools_public.h"
      6 #include "sharedlibtools_public.h"
      7 #include "envvartools_public.h"
      8 #include "hmderrors_public.h"
      9 #include "strtools_public.h"
     10 #include "vrpathregistry_public.h"
     11 #include <mutex>
     12 
     13 using vr::EVRInitError;
     14 using vr::IVRSystem;
     15 using vr::IVRClientCore;
     16 using vr::VRInitError_None;
     17 
     18 // figure out how to import from the VR API dll
     19 #if defined(_WIN32)
     20 
     21 #if !defined(OPENVR_BUILD_STATIC)
     22 #define VR_EXPORT_INTERFACE extern "C" __declspec( dllexport )
     23 #else
     24 #define VR_EXPORT_INTERFACE extern "C"
     25 #endif
     26 
     27 #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__)
     28 
     29 #define VR_EXPORT_INTERFACE extern "C" __attribute__((visibility("default")))
     30 
     31 #else
     32 #error "Unsupported Platform."
     33 #endif
     34 
     35 namespace vr
     36 {
     37 
     38 static void *g_pVRModule = NULL;
     39 static IVRClientCore *g_pHmdSystem = NULL;
     40 static std::recursive_mutex g_mutexSystem;
     41 
     42 
     43 typedef void* (*VRClientCoreFactoryFn)(const char *pInterfaceName, int *pReturnCode);
     44 
     45 static uint32_t g_nVRToken = 0;
     46 
     47 uint32_t VR_GetInitToken()
     48 {
     49 return g_nVRToken;
     50 }
     51 
     52 EVRInitError VR_LoadHmdSystemInternal();
     53 void CleanupInternalInterfaces();
     54 
     55 
     56 uint32_t VR_InitInternal2( EVRInitError *peError, vr::EVRApplicationType eApplicationType, const char *pStartupInfo )
     57 {
     58 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
     59 
     60 EVRInitError err = VR_LoadHmdSystemInternal();
     61 if ( err == vr::VRInitError_None )
     62 {
     63 	err = g_pHmdSystem->Init( eApplicationType, pStartupInfo );
     64 }
     65 
     66 if ( peError )
     67 	*peError = err;
     68 
     69 if ( err != VRInitError_None )
     70 {
     71 	SharedLib_Unload( g_pVRModule );
     72 	g_pHmdSystem = NULL;
     73 	g_pVRModule = NULL;
     74 
     75 	return 0;
     76 }
     77 
     78 return ++g_nVRToken;
     79 }
     80 
     81 VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
     82 
     83 uint32_t VR_InitInternal( EVRInitError *peError, vr::EVRApplicationType eApplicationType )
     84 {
     85 return VR_InitInternal2( peError, eApplicationType, nullptr );
     86 }
     87 
     88 void VR_ShutdownInternal()
     89 {
     90 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
     91 
     92 if ( g_pHmdSystem )
     93 {
     94 	g_pHmdSystem->Cleanup();
     95 	g_pHmdSystem = NULL;
     96 }
     97 if ( g_pVRModule )
     98 {
     99 	SharedLib_Unload( g_pVRModule );
    100 	g_pVRModule = NULL;
    101 }
    102 
    103 #if !defined( VR_API_PUBLIC )
    104 CleanupInternalInterfaces();
    105 #endif
    106 
    107 ++g_nVRToken;
    108 }
    109 
    110 EVRInitError VR_LoadHmdSystemInternal()
    111 {
    112 std::string sRuntimePath, sConfigPath, sLogPath;
    113 
    114 bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
    115 if( !bReadPathRegistry )
    116 {
    117 	return vr::VRInitError_Init_PathRegistryNotFound;
    118 }
    119 
    120 // figure out where we're going to look for vrclient.dll
    121 // see if the specified path actually exists.
    122 if( !Path_IsDirectory( sRuntimePath ) )
    123 {
    124 	return vr::VRInitError_Init_InstallationNotFound;
    125 }
    126 
    127 // Because we don't have a way to select debug vs. release yet we'll just
    128 // use debug if it's there
    129 #if defined( LINUX64 ) || defined( LINUXARM64 )
    130 std::string sTestPath = Path_Join( sRuntimePath, "bin", PLATSUBDIR );
    131 #else
    132 std::string sTestPath = Path_Join( sRuntimePath, "bin" );
    133 #endif
    134 if( !Path_IsDirectory( sTestPath ) )
    135 {
    136 	return vr::VRInitError_Init_InstallationCorrupt;
    137 }
    138 
    139 #if defined( WIN64 )
    140 std::string sDLLPath = Path_Join( sTestPath, "vrclient_x64" DYNAMIC_LIB_EXT );
    141 #else
    142 std::string sDLLPath = Path_Join( sTestPath, "vrclient" DYNAMIC_LIB_EXT );
    143 #endif
    144 
    145 // only look in the override
    146 void *pMod = SharedLib_Load( sDLLPath.c_str() );
    147 // nothing more to do if we can't load the DLL
    148 if( !pMod )
    149 {
    150 	return vr::VRInitError_Init_VRClientDLLNotFound;
    151 }
    152 
    153 VRClientCoreFactoryFn fnFactory = ( VRClientCoreFactoryFn )( SharedLib_GetFunction( pMod, "VRClientCoreFactory" ) );
    154 if( !fnFactory )
    155 {
    156 	SharedLib_Unload( pMod );
    157 	return vr::VRInitError_Init_FactoryNotFound;
    158 }
    159 
    160 int nReturnCode = 0;
    161 g_pHmdSystem = static_cast< IVRClientCore * > ( fnFactory( vr::IVRClientCore_Version, &nReturnCode ) );
    162 if( !g_pHmdSystem )
    163 {
    164 	SharedLib_Unload( pMod );
    165 	return vr::VRInitError_Init_InterfaceNotFound;
    166 }
    167 
    168 g_pVRModule = pMod;
    169 return VRInitError_None;
    170 }
    171 
    172 
    173 void *VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError)
    174 {
    175 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
    176 
    177 if (!g_pHmdSystem)
    178 {
    179 	if (peError)
    180 		*peError = vr::VRInitError_Init_NotInitialized;
    181 	return NULL;
    182 }
    183 
    184 return g_pHmdSystem->GetGenericInterface(pchInterfaceVersion, peError);
    185 }
    186 
    187 bool VR_IsInterfaceVersionValid(const char *pchInterfaceVersion)
    188 {
    189 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
    190 
    191 if (!g_pHmdSystem)
    192 {
    193 	return false;
    194 }
    195 
    196 return g_pHmdSystem->IsInterfaceVersionValid(pchInterfaceVersion) == VRInitError_None;
    197 }
    198 
    199 bool VR_IsHmdPresent()
    200 {
    201 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
    202 
    203 if( g_pHmdSystem )
    204 {
    205 	// if we're already initialized, just call through
    206 	return g_pHmdSystem->BIsHmdPresent();
    207 }
    208 else
    209 {
    210 	// otherwise we need to do a bit more work
    211 	EVRInitError err = VR_LoadHmdSystemInternal();
    212 	if( err != VRInitError_None )
    213 		return false;
    214 
    215 	bool bHasHmd = g_pHmdSystem->BIsHmdPresent();
    216 
    217 	g_pHmdSystem = NULL;
    218 	SharedLib_Unload( g_pVRModule );
    219 	g_pVRModule = NULL;
    220 
    221 	return bHasHmd;
    222 }
    223 }
    224 
    225 /** Returns true if the OpenVR runtime is installed. */
    226 bool VR_IsRuntimeInstalled()
    227 {
    228 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
    229 
    230 if( g_pHmdSystem )
    231 {
    232 	// if we're already initialized, OpenVR is obviously installed
    233 	return true;
    234 }
    235 else
    236 {
    237 	// otherwise we need to do a bit more work
    238 	std::string sRuntimePath, sConfigPath, sLogPath;
    239 
    240 	bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
    241 	if( !bReadPathRegistry )
    242 	{
    243 		return false;
    244 	}
    245 
    246 	// figure out where we're going to look for vrclient.dll
    247 	// see if the specified path actually exists.
    248 	if( !Path_IsDirectory( sRuntimePath ) )
    249 	{
    250 		return false;
    251 	}
    252 
    253 	// the installation may be corrupt in some way, but it certainly looks installed
    254 	return true;
    255 }
    256 }
    257 
    258 
    259 // -------------------------------------------------------------------------------
    260 // Purpose: This is the old Runtime Path interface that is no longer exported in the
    261 //			latest header. We still want to export it from the DLL, though, so updating
    262 //			to a new DLL doesn't break old compiled code. This version was not thread 
    263 //			safe and could change the buffer pointer to by a previous result on a 
    264 //			subsequent call
    265 // -------------------------------------------------------------------------------
    266 VR_EXPORT_INTERFACE const char *VR_CALLTYPE VR_RuntimePath();
    267 
    268 /** Returns where OpenVR runtime is installed. */
    269 const char *VR_RuntimePath()
    270 {
    271 static char rchBuffer[1024];
    272 uint32_t unRequiredSize;
    273 if ( VR_GetRuntimePath( rchBuffer, sizeof( rchBuffer ), &unRequiredSize ) && unRequiredSize < sizeof( rchBuffer ) )
    274 {
    275 	return rchBuffer;
    276 }
    277 else
    278 {
    279 	return nullptr;
    280 }
    281 }
    282 
    283 
    284 /** Returns where OpenVR runtime is installed. */
    285 bool VR_GetRuntimePath( char *pchPathBuffer, uint32_t unBufferSize, uint32_t *punRequiredBufferSize )
    286 {
    287 // otherwise we need to do a bit more work
    288 std::string sRuntimePath;
    289 
    290 *punRequiredBufferSize = 0;
    291 
    292 bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, nullptr, nullptr, nullptr, nullptr );
    293 if ( !bReadPathRegistry )
    294 {
    295 	return false;
    296 }
    297 
    298 // figure out where we're going to look for vrclient.dll
    299 // see if the specified path actually exists.
    300 if ( !Path_IsDirectory( sRuntimePath ) )
    301 {
    302 	return false;
    303 }
    304 
    305 *punRequiredBufferSize = (uint32_t)sRuntimePath.size() + 1;
    306 if ( sRuntimePath.size() >= unBufferSize )
    307 {
    308 	*pchPathBuffer = '\0';
    309 }
    310 else
    311 {
    312 	strcpy_safe( pchPathBuffer, unBufferSize, sRuntimePath.c_str() );
    313 }
    314 
    315 return true;
    316 }
    317 
    318 
    319 /** Returns the symbol version of an HMD error. */
    320 const char *VR_GetVRInitErrorAsSymbol( EVRInitError error )
    321 {
    322 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
    323 
    324 if( g_pHmdSystem )
    325 	return g_pHmdSystem->GetIDForVRInitError( error );
    326 else
    327 	return GetIDForVRInitError( error );
    328 }
    329 
    330 
    331 /** Returns the english string version of an HMD error. */
    332 const char *VR_GetVRInitErrorAsEnglishDescription( EVRInitError error )
    333 {
    334 std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
    335 
    336 if ( g_pHmdSystem )
    337 	return g_pHmdSystem->GetEnglishStringForHmdError( error );
    338 else
    339 	return GetEnglishStringForHmdError( error );
    340 }
    341 
    342 
    343 VR_INTERFACE const char *VR_CALLTYPE VR_GetStringForHmdError( vr::EVRInitError error );
    344 
    345 /** Returns the english string version of an HMD error. */
    346 const char *VR_GetStringForHmdError( EVRInitError error )
    347 {
    348 return VR_GetVRInitErrorAsEnglishDescription( error );
    349 }
    350 
    351 }