diff options
Diffstat (limited to 'gfx/vr/gfxVROSVR.cpp')
-rw-r--r-- | gfx/vr/gfxVROSVR.cpp | 529 |
1 files changed, 0 insertions, 529 deletions
diff --git a/gfx/vr/gfxVROSVR.cpp b/gfx/vr/gfxVROSVR.cpp deleted file mode 100644 index 8b275e923..000000000 --- a/gfx/vr/gfxVROSVR.cpp +++ /dev/null @@ -1,529 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <math.h> - -#include "prlink.h" -#include "prmem.h" -#include "prenv.h" -#include "gfxPrefs.h" -#include "nsString.h" -#include "mozilla/Preferences.h" - -#include "mozilla/gfx/Quaternion.h" - -#ifdef XP_WIN -#include "../layers/d3d11/CompositorD3D11.h" -#include "../layers/d3d11/TextureD3D11.h" -#endif - -#include "gfxVROSVR.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -using namespace mozilla::layers; -using namespace mozilla::gfx; -using namespace mozilla::gfx::impl; - -namespace { -// need to typedef functions that will be used in the code below -extern "C" { -typedef OSVR_ClientContext (*pfn_osvrClientInit)( - const char applicationIdentifier[], uint32_t flags); -typedef OSVR_ReturnCode (*pfn_osvrClientShutdown)(OSVR_ClientContext ctx); -typedef OSVR_ReturnCode (*pfn_osvrClientUpdate)(OSVR_ClientContext ctx); -typedef OSVR_ReturnCode (*pfn_osvrClientCheckStatus)(OSVR_ClientContext ctx); -typedef OSVR_ReturnCode (*pfn_osvrClientGetInterface)( - OSVR_ClientContext ctx, const char path[], OSVR_ClientInterface* iface); -typedef OSVR_ReturnCode (*pfn_osvrClientFreeInterface)( - OSVR_ClientContext ctx, OSVR_ClientInterface iface); -typedef OSVR_ReturnCode (*pfn_osvrGetOrientationState)( - OSVR_ClientInterface iface, OSVR_TimeValue* timestamp, - OSVR_OrientationState* state); -typedef OSVR_ReturnCode (*pfn_osvrGetPositionState)(OSVR_ClientInterface iface, - OSVR_TimeValue* timestamp, - OSVR_PositionState* state); -typedef OSVR_ReturnCode (*pfn_osvrClientGetDisplay)(OSVR_ClientContext ctx, - OSVR_DisplayConfig* disp); -typedef OSVR_ReturnCode (*pfn_osvrClientFreeDisplay)(OSVR_DisplayConfig disp); -typedef OSVR_ReturnCode (*pfn_osvrClientGetNumEyesForViewer)( - OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount* eyes); -typedef OSVR_ReturnCode (*pfn_osvrClientGetViewerEyePose)( - OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye, - OSVR_Pose3* pose); -typedef OSVR_ReturnCode (*pfn_osvrClientGetDisplayDimensions)( - OSVR_DisplayConfig disp, OSVR_DisplayInputCount displayInputIndex, - OSVR_DisplayDimension* width, OSVR_DisplayDimension* height); -typedef OSVR_ReturnCode ( - *pfn_osvrClientGetViewerEyeSurfaceProjectionClippingPlanes)( - OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye, - OSVR_SurfaceCount surface, double* left, double* right, double* bottom, - double* top); -typedef OSVR_ReturnCode (*pfn_osvrClientGetRelativeViewportForViewerEyeSurface)( - OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye, - OSVR_SurfaceCount surface, OSVR_ViewportDimension* left, - OSVR_ViewportDimension* bottom, OSVR_ViewportDimension* width, - OSVR_ViewportDimension* height); -typedef OSVR_ReturnCode (*pfn_osvrClientGetViewerEyeSurfaceProjectionMatrixf)( - OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye, - OSVR_SurfaceCount surface, float near, float far, - OSVR_MatrixConventions flags, float* matrix); -typedef OSVR_ReturnCode (*pfn_osvrClientCheckDisplayStartup)( - OSVR_DisplayConfig disp); -typedef OSVR_ReturnCode (*pfn_osvrClientSetRoomRotationUsingHead)( - OSVR_ClientContext ctx); -} - -static pfn_osvrClientInit osvr_ClientInit = nullptr; -static pfn_osvrClientShutdown osvr_ClientShutdown = nullptr; -static pfn_osvrClientUpdate osvr_ClientUpdate = nullptr; -static pfn_osvrClientCheckStatus osvr_ClientCheckStatus = nullptr; -static pfn_osvrClientGetInterface osvr_ClientGetInterface = nullptr; -static pfn_osvrClientFreeInterface osvr_ClientFreeInterface = nullptr; -static pfn_osvrGetOrientationState osvr_GetOrientationState = nullptr; -static pfn_osvrGetPositionState osvr_GetPositionState = nullptr; -static pfn_osvrClientGetDisplay osvr_ClientGetDisplay = nullptr; -static pfn_osvrClientFreeDisplay osvr_ClientFreeDisplay = nullptr; -static pfn_osvrClientGetNumEyesForViewer osvr_ClientGetNumEyesForViewer = - nullptr; -static pfn_osvrClientGetViewerEyePose osvr_ClientGetViewerEyePose = nullptr; -static pfn_osvrClientGetDisplayDimensions osvr_ClientGetDisplayDimensions = - nullptr; -static pfn_osvrClientGetViewerEyeSurfaceProjectionClippingPlanes - osvr_ClientGetViewerEyeSurfaceProjectionClippingPlanes = nullptr; -static pfn_osvrClientGetRelativeViewportForViewerEyeSurface - osvr_ClientGetRelativeViewportForViewerEyeSurface = nullptr; -static pfn_osvrClientGetViewerEyeSurfaceProjectionMatrixf - osvr_ClientGetViewerEyeSurfaceProjectionMatrixf = nullptr; -static pfn_osvrClientCheckDisplayStartup osvr_ClientCheckDisplayStartup = - nullptr; -static pfn_osvrClientSetRoomRotationUsingHead - osvr_ClientSetRoomRotationUsingHead = nullptr; - -bool -LoadOSVRRuntime() -{ - static PRLibrary* osvrUtilLib = nullptr; - static PRLibrary* osvrCommonLib = nullptr; - static PRLibrary* osvrClientLib = nullptr; - static PRLibrary* osvrClientKitLib = nullptr; - //this looks up the path in the about:config setting, from greprefs.js or modules\libpref\init\all.js - nsAdoptingCString osvrUtilPath = - mozilla::Preferences::GetCString("gfx.vr.osvr.utilLibPath"); - nsAdoptingCString osvrCommonPath = - mozilla::Preferences::GetCString("gfx.vr.osvr.commonLibPath"); - nsAdoptingCString osvrClientPath = - mozilla::Preferences::GetCString("gfx.vr.osvr.clientLibPath"); - nsAdoptingCString osvrClientKitPath = - mozilla::Preferences::GetCString("gfx.vr.osvr.clientKitLibPath"); - - //we need all the libs to be valid - if ((!osvrUtilPath) || (!osvrCommonPath) || (!osvrClientPath) || - (!osvrClientKitPath)) { - return false; - } - - osvrUtilLib = PR_LoadLibrary(osvrUtilPath.BeginReading()); - osvrCommonLib = PR_LoadLibrary(osvrCommonPath.BeginReading()); - osvrClientLib = PR_LoadLibrary(osvrClientPath.BeginReading()); - osvrClientKitLib = PR_LoadLibrary(osvrClientKitPath.BeginReading()); - - if (!osvrUtilLib) { - printf_stderr("[OSVR] Failed to load OSVR Util library!\n"); - return false; - } - if (!osvrCommonLib) { - printf_stderr("[OSVR] Failed to load OSVR Common library!\n"); - return false; - } - if (!osvrClientLib) { - printf_stderr("[OSVR] Failed to load OSVR Client library!\n"); - return false; - } - if (!osvrClientKitLib) { - printf_stderr("[OSVR] Failed to load OSVR ClientKit library!\n"); - return false; - } - -// make sure all functions that we'll be using are available -#define REQUIRE_FUNCTION(_x) \ - do { \ - *(void**) & osvr_##_x = \ - (void*)PR_FindSymbol(osvrClientKitLib, "osvr" #_x); \ - if (!osvr_##_x) { \ - printf_stderr("osvr" #_x " symbol missing\n"); \ - goto fail; \ - } \ - } while (0) - - REQUIRE_FUNCTION(ClientInit); - REQUIRE_FUNCTION(ClientShutdown); - REQUIRE_FUNCTION(ClientUpdate); - REQUIRE_FUNCTION(ClientCheckStatus); - REQUIRE_FUNCTION(ClientGetInterface); - REQUIRE_FUNCTION(ClientFreeInterface); - REQUIRE_FUNCTION(GetOrientationState); - REQUIRE_FUNCTION(GetPositionState); - REQUIRE_FUNCTION(ClientGetDisplay); - REQUIRE_FUNCTION(ClientFreeDisplay); - REQUIRE_FUNCTION(ClientGetNumEyesForViewer); - REQUIRE_FUNCTION(ClientGetViewerEyePose); - REQUIRE_FUNCTION(ClientGetDisplayDimensions); - REQUIRE_FUNCTION(ClientGetViewerEyeSurfaceProjectionClippingPlanes); - REQUIRE_FUNCTION(ClientGetRelativeViewportForViewerEyeSurface); - REQUIRE_FUNCTION(ClientGetViewerEyeSurfaceProjectionMatrixf); - REQUIRE_FUNCTION(ClientCheckDisplayStartup); - REQUIRE_FUNCTION(ClientSetRoomRotationUsingHead); - -#undef REQUIRE_FUNCTION - - return true; - -fail: - return false; -} - -} // namespace - -mozilla::gfx::VRFieldOfView -SetFromTanRadians(double left, double right, double bottom, double top) -{ - mozilla::gfx::VRFieldOfView fovInfo; - fovInfo.leftDegrees = atan(left) * 180.0 / M_PI; - fovInfo.rightDegrees = atan(right) * 180.0 / M_PI; - fovInfo.upDegrees = atan(top) * 180.0 / M_PI; - fovInfo.downDegrees = atan(bottom) * 180.0 / M_PI; - return fovInfo; -} - -VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context, - OSVR_ClientInterface* iface, - OSVR_DisplayConfig* display) - : VRDisplayHost(VRDeviceType::OSVR) - , m_ctx(context) - , m_iface(iface) - , m_display(display) -{ - - MOZ_COUNT_CTOR_INHERITED(VRDisplayOSVR, VRDisplayHost); - - mDisplayInfo.mIsConnected = true; - mDisplayInfo.mDisplayName.AssignLiteral("OSVR HMD"); - mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None; - mDisplayInfo.mCapabilityFlags = - VRDisplayCapabilityFlags::Cap_Orientation | VRDisplayCapabilityFlags::Cap_Position; - - mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External; - mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present; - - // XXX OSVR display topology allows for more than one viewer - // will assume only one viewer for now (most likely stay that way) - - OSVR_EyeCount numEyes; - osvr_ClientGetNumEyesForViewer(*m_display, 0, &numEyes); - - for (uint8_t eye = 0; eye < numEyes; eye++) { - double left, right, bottom, top; - // XXX for now there is only one surface per eye - osvr_ClientGetViewerEyeSurfaceProjectionClippingPlanes( - *m_display, 0, eye, 0, &left, &right, &bottom, &top); - mDisplayInfo.mEyeFOV[eye] = - SetFromTanRadians(-left, right, -bottom, top); - } - - // XXX Assuming there is only one display input for now - // however, it's possible to have more than one (dSight with 2 HDMI inputs) - OSVR_DisplayDimension width, height; - osvr_ClientGetDisplayDimensions(*m_display, 0, &width, &height); - - - for (uint8_t eye = 0; eye < numEyes; eye++) { - - OSVR_ViewportDimension l, b, w, h; - osvr_ClientGetRelativeViewportForViewerEyeSurface(*m_display, 0, eye, 0, &l, - &b, &w, &h); - mDisplayInfo.mEyeResolution.width = w; - mDisplayInfo.mEyeResolution.height = h; - OSVR_Pose3 eyePose; - // Viewer eye pose may not be immediately available, update client context until we get it - OSVR_ReturnCode ret = - osvr_ClientGetViewerEyePose(*m_display, 0, eye, &eyePose); - while (ret != OSVR_RETURN_SUCCESS) { - osvr_ClientUpdate(*m_ctx); - ret = osvr_ClientGetViewerEyePose(*m_display, 0, eye, &eyePose); - } - mDisplayInfo.mEyeTranslation[eye].x = eyePose.translation.data[0]; - mDisplayInfo.mEyeTranslation[eye].y = eyePose.translation.data[1]; - mDisplayInfo.mEyeTranslation[eye].z = eyePose.translation.data[2]; - } -} - -void -VRDisplayOSVR::Destroy() -{ - // destroy non-owning pointers - m_ctx = nullptr; - m_iface = nullptr; - m_display = nullptr; -} - -void -VRDisplayOSVR::ZeroSensor() -{ - // recenter pose aka reset yaw - osvr_ClientSetRoomRotationUsingHead(*m_ctx); -} - -VRHMDSensorState -VRDisplayOSVR::GetSensorState() -{ - - //update client context before anything - //this usually goes into app's mainloop - osvr_ClientUpdate(*m_ctx); - - VRHMDSensorState result; - OSVR_TimeValue timestamp; - result.Clear(); - - OSVR_OrientationState orientation; - - OSVR_ReturnCode ret = - osvr_GetOrientationState(*m_iface, ×tamp, &orientation); - - result.timestamp = timestamp.seconds; - - if (ret == OSVR_RETURN_SUCCESS) { - result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; - result.orientation[0] = orientation.data[1]; - result.orientation[1] = orientation.data[2]; - result.orientation[2] = orientation.data[3]; - result.orientation[3] = orientation.data[0]; - } - - OSVR_PositionState position; - ret = osvr_GetPositionState(*m_iface, ×tamp, &position); - if (ret == OSVR_RETURN_SUCCESS) { - result.flags |= VRDisplayCapabilityFlags::Cap_Position; - result.position[0] = position.data[0]; - result.position[1] = position.data[1]; - result.position[2] = position.data[2]; - } - - return result; -} - -VRHMDSensorState -VRDisplayOSVR::GetImmediateSensorState() -{ - return GetSensorState(); -} - -#if defined(XP_WIN) - -void -VRDisplayOSVR::SubmitFrame(TextureSourceD3D11* aSource, - const IntSize& aSize, - const VRHMDSensorState& aSensorState, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) -{ - // XXX Add code to submit frame -} - -#endif - -void -VRDisplayOSVR::StartPresentation() -{ - // XXX Add code to start VR Presentation -} - -void -VRDisplayOSVR::StopPresentation() -{ - // XXX Add code to end VR Presentation -} - -already_AddRefed<VRDisplayManagerOSVR> -VRDisplayManagerOSVR::Create() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!gfxPrefs::VREnabled() || !gfxPrefs::VROSVREnabled()) { - return nullptr; - } - if (!LoadOSVRRuntime()) { - return nullptr; - } - RefPtr<VRDisplayManagerOSVR> manager = new VRDisplayManagerOSVR(); - return manager.forget(); -} - -void -VRDisplayManagerOSVR::CheckOSVRStatus() -{ - if (mOSVRInitialized) { - return; - } - - // client context must be initialized first - InitializeClientContext(); - - // update client context - osvr_ClientUpdate(m_ctx); - - // initialize interface and display if they are not initialized yet - InitializeInterface(); - InitializeDisplay(); - - // OSVR is fully initialized now - if (mClientContextInitialized && mDisplayConfigInitialized && - mInterfaceInitialized) { - mOSVRInitialized = true; - } -} - -void -VRDisplayManagerOSVR::InitializeClientContext() -{ - // already initialized - if (mClientContextInitialized) { - return; - } - - // first time creating - if (!m_ctx) { - // get client context - m_ctx = osvr_ClientInit("com.osvr.webvr", 0); - // update context - osvr_ClientUpdate(m_ctx); - // verify we are connected - if (OSVR_RETURN_SUCCESS == osvr_ClientCheckStatus(m_ctx)) { - mClientContextInitialized = true; - } - } - // client context exists but not up and running yet - else { - // update context - osvr_ClientUpdate(m_ctx); - if (OSVR_RETURN_SUCCESS == osvr_ClientCheckStatus(m_ctx)) { - mClientContextInitialized = true; - } - } -} - -void -VRDisplayManagerOSVR::InitializeInterface() -{ - // already initialized - if (mInterfaceInitialized) { - return; - } - //Client context must be initialized before getting interface - if (mClientContextInitialized) { - // m_iface will remain nullptr if no interface is returned - if (OSVR_RETURN_SUCCESS == - osvr_ClientGetInterface(m_ctx, "/me/head", &m_iface)) { - mInterfaceInitialized = true; - } - } -} - -void -VRDisplayManagerOSVR::InitializeDisplay() -{ - // display is fully configured - if (mDisplayConfigInitialized) { - return; - } - - //Client context must be initialized before getting interface - if (mClientContextInitialized) { - // first time creating display object - if (m_display == nullptr) { - - OSVR_ReturnCode ret = osvr_ClientGetDisplay(m_ctx, &m_display); - - if (ret == OSVR_RETURN_SUCCESS) { - osvr_ClientUpdate(m_ctx); - // display object may have been created but not fully startup - if (OSVR_RETURN_SUCCESS == osvr_ClientCheckDisplayStartup(m_display)) { - mDisplayConfigInitialized = true; - } - } - - // Typically once we get Display object, pose data is available after - // clientUpdate but sometimes it takes ~ 200 ms to get - // a succesfull connection, so we might have to run a few update cycles - } else { - - if (OSVR_RETURN_SUCCESS == osvr_ClientCheckDisplayStartup(m_display)) { - mDisplayConfigInitialized = true; - } - } - } -} - -bool -VRDisplayManagerOSVR::Init() -{ - - // OSVR server should be running in the background - // It would load plugins and take care of detecting HMDs - if (!mOSVRInitialized) { - nsIThread* thread = nullptr; - NS_GetCurrentThread(&thread); - mOSVRThread = already_AddRefed<nsIThread>(thread); - - // initialize client context - InitializeClientContext(); - // try to initialize interface - InitializeInterface(); - // try to initialize display object - InitializeDisplay(); - // verify all components are initialized - CheckOSVRStatus(); - } - - return mOSVRInitialized; -} - -void -VRDisplayManagerOSVR::Destroy() -{ - if (mOSVRInitialized) { - MOZ_ASSERT(NS_GetCurrentThread() == mOSVRThread); - mOSVRThread = nullptr; - mHMDInfo = nullptr; - mOSVRInitialized = false; - } - // client context may not have been initialized - if (m_ctx) { - osvr_ClientFreeDisplay(m_display); - } - // osvr checks that m_ctx or m_iface are not null - osvr_ClientFreeInterface(m_ctx, m_iface); - osvr_ClientShutdown(m_ctx); -} - -void -VRDisplayManagerOSVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) -{ - // make sure context, interface and display are initialized - CheckOSVRStatus(); - - if (!mOSVRInitialized) { - return; - } - - mHMDInfo = new VRDisplayOSVR(&m_ctx, &m_iface, &m_display); - - if (mHMDInfo) { - aHMDResult.AppendElement(mHMDInfo); - } -} |