Bug 1406327 - Part 4: RefreshVRDisplays needs to be at VRListenerThread; r?kip
MozReview-Commit-ID: KuhPFqMhTDB
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -254,16 +254,33 @@ VRManager::NotifyVRVsync(const uint32_t&
}
RefreshVRDisplays();
}
void
VRManager::RefreshVRDisplays(bool aMustDispatch)
{
+ if (VRListenerThreadHolder::IsInVRListenerThread()) {
+ RefreshVRDisplaysInternal(aMustDispatch);
+ } else {
+ if (VRListenerThreadHolder::IsActive()) {
+ MessageLoop* loop = VRListenerThreadHolder::Loop();
+ loop->PostTask(NewRunnableMethod<bool>(
+ "gfx::VRManager::RefreshVRDisplaysInternal",
+ this, &VRManager::RefreshVRDisplaysInternal, aMustDispatch
+ ));
+ }
+ }
+}
+
+void
+VRManager::RefreshVRDisplaysInternal(bool aMustDispatch)
+{
+ MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
nsTArray<RefPtr<gfx::VRDisplayHost> > displays;
mLastVRListenerThreadActiveTime = TimeStamp::Now();
/** 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
@@ -441,16 +458,24 @@ VRManager::CreateVRTestSystem()
return;
}
RefPtr<VRSystemManager> mgr = VRSystemManagerPuppet::Create();
if (mgr) {
mManagers.AppendElement(mgr);
mVRTestSystemCreated = true;
}
+
+ // Force to refresh VRPuppet display here
+ // because we need it to setup data early.
+ nsTArray<RefPtr<gfx::VRDisplayHost> > displays;
+ mgr->GetHMDs(displays);
+ for (const auto& display: displays) {
+ mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
+ }
}
template<class T>
void
VRManager::NotifyGamepadChange(uint32_t aIndex, const T& aInfo)
{
dom::GamepadChangeEventBody body(aInfo);
dom::GamepadChangeEvent e(aIndex, dom::GamepadServiceType::VR, body);
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -60,16 +60,17 @@ protected:
private:
void Init();
void Destroy();
void Shutdown();
void DispatchVRDisplayInfoUpdate();
+ void RefreshVRDisplaysInternal(bool aMustDispatch);
void NotifyGamepadChangeEventsToContent(const dom::GamepadChangeEvent& aEvent);
void NotifyVibrateHapticCompletedToContent(uint32_t aPromiseID);
typedef nsTHashtable<nsRefPtrHashKey<VRManagerParent>> VRManagerParentSet;
VRManagerParentSet mVRManagerParents;
typedef nsTArray<RefPtr<VRSystemManager>> VRSystemManagerArray;
VRSystemManagerArray mManagers;
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -631,23 +631,16 @@ VRSystemManagerOpenVR::Shutdown()
}
RemoveControllers();
mVRSystem = nullptr;
}
bool
VRSystemManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
{
- // When running VR tests on local machines which have SteamVR runtime.
- // VR_IsHmdPresent() would have chance to be true. Then, it makes us can't
- // get the VRPuppet display.
- if (gfxPrefs::VRPuppetEnabled()) {
- return false;
- }
-
if (!::vr::VR_IsHmdPresent() ||
(mOpenVRHMD && !mOpenVRHMD->GetIsHmdPresent())) {
// OpenVR runtime could be quit accidentally,
// and we make it re-initialize.
mOpenVRHMD = nullptr;
mVRSystem = nullptr;
} else if (mOpenVRHMD == nullptr) {
::vr::HmdError err;
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -277,17 +277,16 @@ VRManagerParent::RecvCreateVRTestSystem(
}
mozilla::ipc::IPCResult
VRManagerParent::RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID)
{
nsTArray<VRDisplayInfo> displayInfoArray;
impl::VRDisplayPuppet* displayPuppet = nullptr;
VRManager* vm = VRManager::Get();
- vm->RefreshVRDisplays();
// Get VRDisplayPuppet from VRManager
vm->GetVRDisplayInfo(displayInfoArray);
for (auto& displayInfo : displayInfoArray) {
if (displayInfo.GetType() == VRDeviceType::Puppet) {
displayPuppet = static_cast<impl::VRDisplayPuppet*>(
vm->GetDisplay(displayInfo.GetDisplayID()).get());
break;
--- a/xpcom/threads/nsThreadUtils.h
+++ b/xpcom/threads/nsThreadUtils.h
@@ -339,18 +339,16 @@ SpinEventLoopUntil(Pred&& aPredicate, ns
* Returns true if we're in the compositor thread.
*
* We declare this here because the headers required to invoke
* CompositorThreadHolder::IsInCompositorThread() also pull in a bunch of system
* headers that #define various tokens in a way that can break the build.
*/
extern bool NS_IsInCompositorThread();
-extern bool NS_IsInVRThread();
-
//-----------------------------------------------------------------------------
// Helpers that work with nsCOMPtr:
inline already_AddRefed<nsIThread>
do_GetCurrentThread()
{
nsIThread* thread = nullptr;
NS_GetCurrentThread(&thread);