Unreviewed, silence -Wimplicit-fallthrough in openvr
[WebKit-https.git] / Source / ThirdParty / openvr / src / openvr_api_public.cpp
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 "vrpathregistry_public.h"
10 #include <mutex>
11
12 using vr::EVRInitError;
13 using vr::IVRSystem;
14 using vr::IVRClientCore;
15 using vr::VRInitError_None;
16
17 namespace vr
18 {
19
20 static void *g_pVRModule = NULL;
21 static IVRClientCore *g_pHmdSystem = NULL;
22 static std::recursive_mutex g_mutexSystem;
23
24
25 typedef void* (*VRClientCoreFactoryFn)(const char *pInterfaceName, int *pReturnCode);
26
27 static uint32_t g_nVRToken = 0;
28
29 uint32_t VR_GetInitToken()
30 {
31        return g_nVRToken;
32 }
33
34 EVRInitError VR_LoadHmdSystemInternal();
35 void CleanupInternalInterfaces();
36
37
38 uint32_t VR_InitInternal2( EVRInitError *peError, vr::EVRApplicationType eApplicationType, const char *pStartupInfo )
39 {
40        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
41
42        EVRInitError err = VR_LoadHmdSystemInternal();
43        if ( err == vr::VRInitError_None )
44        {
45               err = g_pHmdSystem->Init( eApplicationType, pStartupInfo );
46        }
47
48        if ( peError )
49               *peError = err;
50
51        if ( err != VRInitError_None )
52        {
53               SharedLib_Unload( g_pVRModule );
54               g_pHmdSystem = NULL;
55               g_pVRModule = NULL;
56
57               return 0;
58        }
59
60        return ++g_nVRToken;
61 }
62
63 VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
64
65 uint32_t VR_InitInternal( EVRInitError *peError, vr::EVRApplicationType eApplicationType )
66 {
67        return VR_InitInternal2( peError, eApplicationType, nullptr );
68 }
69
70 void VR_ShutdownInternal()
71 {
72        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
73        
74        if ( g_pHmdSystem )
75        {
76               g_pHmdSystem->Cleanup();
77               g_pHmdSystem = NULL;
78        }
79        if ( g_pVRModule )
80        {
81               SharedLib_Unload( g_pVRModule );
82               g_pVRModule = NULL;
83        }
84
85 #if !defined( VR_API_PUBLIC )
86        CleanupInternalInterfaces();
87 #endif
88
89        ++g_nVRToken;
90 }
91
92 EVRInitError VR_LoadHmdSystemInternal()
93 {
94        std::string sRuntimePath, sConfigPath, sLogPath;
95
96        bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
97        if( !bReadPathRegistry )
98        {
99               return vr::VRInitError_Init_PathRegistryNotFound;
100        }
101
102        // figure out where we're going to look for vrclient.dll
103        // see if the specified path actually exists.
104        if( !Path_IsDirectory( sRuntimePath ) )
105        {
106               return vr::VRInitError_Init_InstallationNotFound;
107        }
108
109        // Because we don't have a way to select debug vs. release yet we'll just
110        // use debug if it's there
111 #if defined( LINUX64 )
112        std::string sTestPath = Path_Join( sRuntimePath, "bin", PLATSUBDIR );
113 #else
114        std::string sTestPath = Path_Join( sRuntimePath, "bin" );
115 #endif
116        if( !Path_IsDirectory( sTestPath ) )
117        {
118               return vr::VRInitError_Init_InstallationCorrupt;
119        }
120
121 #if defined( WIN64 )
122        std::string sDLLPath = Path_Join( sTestPath, "vrclient_x64" DYNAMIC_LIB_EXT );
123 #else
124        std::string sDLLPath = Path_Join( sTestPath, "vrclient" DYNAMIC_LIB_EXT );
125 #endif
126
127        // only look in the override
128        void *pMod = SharedLib_Load( sDLLPath.c_str() );
129        // nothing more to do if we can't load the DLL
130        if( !pMod )
131        {
132               return vr::VRInitError_Init_VRClientDLLNotFound;
133        }
134
135        VRClientCoreFactoryFn fnFactory = ( VRClientCoreFactoryFn )( SharedLib_GetFunction( pMod, "VRClientCoreFactory" ) );
136        if( !fnFactory )
137        {
138               SharedLib_Unload( pMod );
139               return vr::VRInitError_Init_FactoryNotFound;
140        }
141
142        int nReturnCode = 0;
143        g_pHmdSystem = static_cast< IVRClientCore * > ( fnFactory( vr::IVRClientCore_Version, &nReturnCode ) );
144        if( !g_pHmdSystem )
145        {
146               SharedLib_Unload( pMod );
147               return vr::VRInitError_Init_InterfaceNotFound;
148        }
149
150        g_pVRModule = pMod;
151        return VRInitError_None;
152 }
153
154
155 void *VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError)
156 {
157        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
158
159        if (!g_pHmdSystem)
160        {
161               if (peError)
162                      *peError = vr::VRInitError_Init_NotInitialized;
163               return NULL;
164        }
165
166        return g_pHmdSystem->GetGenericInterface(pchInterfaceVersion, peError);
167 }
168
169 bool VR_IsInterfaceVersionValid(const char *pchInterfaceVersion)
170 {
171        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
172
173        if (!g_pHmdSystem)
174        {
175               return false;
176        }
177
178        return g_pHmdSystem->IsInterfaceVersionValid(pchInterfaceVersion) == VRInitError_None;
179 }
180
181 bool VR_IsHmdPresent()
182 {
183        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
184
185        if( g_pHmdSystem )
186        {
187               // if we're already initialized, just call through
188               return g_pHmdSystem->BIsHmdPresent();
189        }
190        else
191        {
192               // otherwise we need to do a bit more work
193               EVRInitError err = VR_LoadHmdSystemInternal();
194               if( err != VRInitError_None )
195                      return false;
196
197               bool bHasHmd = g_pHmdSystem->BIsHmdPresent();
198
199               g_pHmdSystem = NULL;
200               SharedLib_Unload( g_pVRModule );
201               g_pVRModule = NULL;
202
203               return bHasHmd;
204        }
205 }
206
207 /** Returns true if the OpenVR runtime is installed. */
208 bool VR_IsRuntimeInstalled()
209 {
210        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
211
212        if( g_pHmdSystem )
213        {
214               // if we're already initialized, OpenVR is obviously installed
215               return true;
216        }
217        else
218        {
219               // otherwise we need to do a bit more work
220               std::string sRuntimePath, sConfigPath, sLogPath;
221
222               bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
223               if( !bReadPathRegistry )
224               {
225                      return false;
226               }
227
228               // figure out where we're going to look for vrclient.dll
229               // see if the specified path actually exists.
230               if( !Path_IsDirectory( sRuntimePath ) )
231               {
232                      return false;
233               }
234
235               // the installation may be corrupt in some way, but it certainly looks installed
236               return true;
237        }
238 }
239
240
241 /** Returns where OpenVR runtime is installed. */
242 const char *VR_RuntimePath()
243 {
244        // otherwise we need to do a bit more work
245        static std::string sRuntimePath;
246        std::string sConfigPath, sLogPath;
247
248        bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
249        if ( !bReadPathRegistry )
250        {
251               return nullptr;
252        }
253
254        // figure out where we're going to look for vrclient.dll
255        // see if the specified path actually exists.
256        if ( !Path_IsDirectory( sRuntimePath ) )
257        {
258               return nullptr;
259        }
260
261        return sRuntimePath.c_str();
262 }
263
264
265 /** Returns the symbol version of an HMD error. */
266 const char *VR_GetVRInitErrorAsSymbol( EVRInitError error )
267 {
268        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
269
270        if( g_pHmdSystem )
271               return g_pHmdSystem->GetIDForVRInitError( error );
272        else
273               return GetIDForVRInitError( error );
274 }
275
276
277 /** Returns the english string version of an HMD error. */
278 const char *VR_GetVRInitErrorAsEnglishDescription( EVRInitError error )
279 {
280        std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
281
282        if ( g_pHmdSystem )
283               return g_pHmdSystem->GetEnglishStringForHmdError( error );
284        else
285               return GetEnglishStringForHmdError( error );
286 }
287
288
289 VR_INTERFACE const char *VR_CALLTYPE VR_GetStringForHmdError( vr::EVRInitError error );
290
291 /** Returns the english string version of an HMD error. */
292 const char *VR_GetStringForHmdError( EVRInitError error )
293 {
294        return VR_GetVRInitErrorAsEnglishDescription( error );
295 }
296
297 }
298