diff options
Diffstat (limited to 'gfx/vr/VRManager.cpp')
-rw-r--r-- | gfx/vr/VRManager.cpp | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/gfx/vr/VRManager.cpp b/gfx/vr/VRManager.cpp deleted file mode 100644 index 672e9e3a1..000000000 --- a/gfx/vr/VRManager.cpp +++ /dev/null @@ -1,393 +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 "VRManager.h" -#include "VRManagerParent.h" -#include "gfxVR.h" -#include "gfxVROpenVR.h" -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/dom/VRDisplay.h" -#include "mozilla/dom/GamepadEventTypes.h" -#include "mozilla/layers/TextureHost.h" -#include "mozilla/Unused.h" - -#include "gfxPrefs.h" -#include "gfxVR.h" -#if defined(XP_WIN) -#include "gfxVROculus.h" -#endif -#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX) -#include "gfxVROSVR.h" -#endif -#include "ipc/VRLayerParent.h" - -using namespace mozilla; -using namespace mozilla::gfx; -using namespace mozilla::layers; -using namespace mozilla::gl; - -namespace mozilla { -namespace gfx { - -static StaticRefPtr<VRManager> sVRManagerSingleton; - -/*static*/ void -VRManager::ManagerInit() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (sVRManagerSingleton == nullptr) { - sVRManagerSingleton = new VRManager(); - ClearOnShutdown(&sVRManagerSingleton); - } -} - -VRManager::VRManager() - : mInitialized(false) -{ - MOZ_COUNT_CTOR(VRManager); - MOZ_ASSERT(sVRManagerSingleton == nullptr); - - RefPtr<VRDisplayManager> mgr; - RefPtr<VRControllerManager> controllerMgr; - - /** - * We must add the VRDisplayManager's to mManagers in a careful order to - * ensure that we don't detect the same VRDisplay from multiple API's. - * - * Oculus comes first, as it will only enumerate Oculus HMD's and is the - * native interface for Oculus HMD's. - * - * OpenvR comes second, as it is the native interface for HTC Vive - * which is the most common HMD at this time. - * - * OSVR will be used if Oculus SDK and OpenVR don't detect any HMDS, - * to support everyone else. - */ - -#if defined(XP_WIN) - // The Oculus runtime is supported only on Windows - mgr = VRDisplayManagerOculus::Create(); - if (mgr) { - mManagers.AppendElement(mgr); - } -#endif - -#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX) - // OpenVR is cross platform compatible - mgr = VRDisplayManagerOpenVR::Create(); - if (mgr) { - mManagers.AppendElement(mgr); - } - - controllerMgr = VRControllerManagerOpenVR::Create(); - if (mgr) { - mControllerManagers.AppendElement(controllerMgr); - } - - // OSVR is cross platform compatible - mgr = VRDisplayManagerOSVR::Create(); - if (mgr) { - mManagers.AppendElement(mgr); - } -#endif - // Enable gamepad extensions while VR is enabled. - if (gfxPrefs::VREnabled()) { - Preferences::SetBool("dom.gamepad.extensions.enabled", true); - } -} - -VRManager::~VRManager() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!mInitialized); - MOZ_COUNT_DTOR(VRManager); -} - -void -VRManager::Destroy() -{ - mVRDisplays.Clear(); - for (uint32_t i = 0; i < mManagers.Length(); ++i) { - mManagers[i]->Destroy(); - } - - mVRControllers.Clear(); - for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) { - mControllerManagers[i]->Destroy(); - } - mInitialized = false; -} - -void -VRManager::Init() -{ - for (uint32_t i = 0; i < mManagers.Length(); ++i) { - mManagers[i]->Init(); - } - - for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) { - mControllerManagers[i]->Init(); - } - mInitialized = true; -} - -/* static */VRManager* -VRManager::Get() -{ - MOZ_ASSERT(sVRManagerSingleton != nullptr); - - return sVRManagerSingleton; -} - -void -VRManager::AddVRManagerParent(VRManagerParent* aVRManagerParent) -{ - if (mVRManagerParents.IsEmpty()) { - Init(); - } - mVRManagerParents.PutEntry(aVRManagerParent); -} - -void -VRManager::RemoveVRManagerParent(VRManagerParent* aVRManagerParent) -{ - mVRManagerParents.RemoveEntry(aVRManagerParent); - if (mVRManagerParents.IsEmpty()) { - Destroy(); - } -} - -void -VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp) -{ - const double kVRDisplayRefreshMaxDuration = 5000; // milliseconds - - bool bHaveEventListener = false; - - for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { - VRManagerParent *vmp = iter.Get()->GetKey(); - if (mVRDisplays.Count()) { - Unused << vmp->SendNotifyVSync(); - } - bHaveEventListener |= vmp->HaveEventListener(); - } - - for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) { - gfx::VRDisplayHost* display = iter.UserData(); - display->NotifyVSync(); - } - - if (bHaveEventListener) { - for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) { - mControllerManagers[i]->HandleInput(); - } - // If content has set an EventHandler to be notified of VR display events - // we must continually refresh the VR display enumeration to check - // for events that we must fire such as Window.onvrdisplayconnect - // Note that enumeration itself may activate display hardware, such - // as Oculus, so we only do this when we know we are displaying content - // that is looking for VR displays. - if (mLastRefreshTime.IsNull()) { - // This is the first vsync, must refresh VR displays - RefreshVRDisplays(); - RefreshVRControllers(); - mLastRefreshTime = TimeStamp::Now(); - } else { - // We don't have to do this every frame, so check if we - // have refreshed recently. - TimeDuration duration = TimeStamp::Now() - mLastRefreshTime; - if (duration.ToMilliseconds() > kVRDisplayRefreshMaxDuration) { - RefreshVRDisplays(); - RefreshVRControllers(); - mLastRefreshTime = TimeStamp::Now(); - } - } - } -} - -void -VRManager::NotifyVRVsync(const uint32_t& aDisplayID) -{ - for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { - Unused << iter.Get()->GetKey()->SendNotifyVRVSync(aDisplayID); - } -} - -void -VRManager::RefreshVRDisplays(bool aMustDispatch) -{ - nsTArray<RefPtr<gfx::VRDisplayHost> > displays; - - /** We don't wish to enumerate the same display from multiple managers, - * so stop as soon as we get a display. - * It is still possible to get multiple displays from a single manager, - * but do not wish to mix-and-match for risk of reporting a duplicate. - * - * XXX - Perhaps there will be a better way to detect duplicate displays - * in the future. - */ - for (uint32_t i = 0; i < mManagers.Length() && displays.Length() == 0; ++i) { - mManagers[i]->GetHMDs(displays); - } - - bool displayInfoChanged = false; - - if (displays.Length() != mVRDisplays.Count()) { - // Catch cases where a VR display has been removed - displayInfoChanged = true; - } - - for (const auto& display: displays) { - if (!GetDisplay(display->GetDisplayInfo().GetDisplayID())) { - // This is a new display - displayInfoChanged = true; - break; - } - - if (display->CheckClearDisplayInfoDirty()) { - // This display's info has changed - displayInfoChanged = true; - break; - } - } - - if (displayInfoChanged) { - mVRDisplays.Clear(); - for (const auto& display: displays) { - mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display); - } - } - - if (displayInfoChanged || aMustDispatch) { - DispatchVRDisplayInfoUpdate(); - } -} - -void -VRManager::DispatchVRDisplayInfoUpdate() -{ - nsTArray<VRDisplayInfo> update; - GetVRDisplayInfo(update); - - for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { - Unused << iter.Get()->GetKey()->SendUpdateDisplayInfo(update); - } -} - - -/** - * Get any VR displays that have already been enumerated without - * activating any new devices. - */ -void -VRManager::GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo) -{ - aDisplayInfo.Clear(); - for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) { - gfx::VRDisplayHost* display = iter.UserData(); - aDisplayInfo.AppendElement(VRDisplayInfo(display->GetDisplayInfo())); - } -} - -RefPtr<gfx::VRDisplayHost> -VRManager::GetDisplay(const uint32_t& aDisplayID) -{ - RefPtr<gfx::VRDisplayHost> display; - if (mVRDisplays.Get(aDisplayID, getter_AddRefs(display))) { - return display; - } - return nullptr; -} - -void -VRManager::SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) -{ - TextureHost* th = TextureHost::AsTextureHost(aTexture); - mLastFrame = th; - RefPtr<VRDisplayHost> display = GetDisplay(aLayer->GetDisplayID()); - if (display) { - display->SubmitFrame(aLayer, 0, aTexture, aLeftEyeRect, aRightEyeRect); - } -} - -RefPtr<gfx::VRControllerHost> -VRManager::GetController(const uint32_t& aControllerID) -{ - RefPtr<gfx::VRControllerHost> controller; - if (mVRControllers.Get(aControllerID, getter_AddRefs(controller))) { - return controller; - } - return nullptr; -} - -void -VRManager::GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo) -{ - aControllerInfo.Clear(); - for (auto iter = mVRControllers.Iter(); !iter.Done(); iter.Next()) { - gfx::VRControllerHost* controller = iter.UserData(); - aControllerInfo.AppendElement(VRControllerInfo(controller->GetControllerInfo())); - } -} - -void -VRManager::RefreshVRControllers() -{ - nsTArray<RefPtr<gfx::VRControllerHost>> controllers; - - for (uint32_t i = 0; i < mControllerManagers.Length() - && controllers.Length() == 0; ++i) { - mControllerManagers[i]->GetControllers(controllers); - } - - bool controllerInfoChanged = false; - - if (controllers.Length() != mVRControllers.Count()) { - // Catch cases where VR controllers has been removed - controllerInfoChanged = true; - } - - for (const auto& controller : controllers) { - if (!GetController(controller->GetControllerInfo().GetControllerID())) { - // This is a new controller - controllerInfoChanged = true; - break; - } - } - - if (controllerInfoChanged) { - mVRControllers.Clear(); - for (const auto& controller : controllers) { - mVRControllers.Put(controller->GetControllerInfo().GetControllerID(), - controller); - } - } -} - -void -VRManager::ScanForDevices() -{ - for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) { - mControllerManagers[i]->ScanForDevices(); - } -} - -template<class T> -void -VRManager::NotifyGamepadChange(const T& aInfo) -{ - dom::GamepadChangeEvent e(aInfo); - - for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { - Unused << iter.Get()->GetKey()->SendGamepadUpdate(e); - } -} - -} // namespace gfx -} // namespace mozilla |