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) { // 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::NotifyVsync(const TimeStamp& aVsyncTimestamp) { const double kVRDisplayRefreshMaxDuration = 5000; // milliseconds const double kVRDisplayInactiveMaxDuration = 30000; // milliseconds bool bHaveEventListener = false; bool bHaveControllerListener = false; for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { VRManagerParent *vmp = iter.Get()->GetKey(); bHaveEventListener |= vmp->HaveEventListener(); bHaveControllerListener |= vmp->HaveControllerListener(); } // VRDisplayHost::NotifyVSync may modify mVRDisplays, so we iterate // through a local copy here. nsTArray<RefPtr<VRDisplayHost>> displays; for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) { displays.AppendElement(iter.UserData()); } for (const auto& display: displays) { display->NotifyVSync(); } if (bHaveEventListener) { // 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(); if (bHaveControllerListener) { 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(); if (bHaveControllerListener) { RefreshVRControllers(); } mLastRefreshTime = TimeStamp::Now(); } } if (bHaveControllerListener) { for (const auto& manager: mManagers) { if (!manager->GetIsPresenting()) { manager->HandleInput(); } } } } // Shut down the VR devices when not in use if (bHaveEventListener || bHaveControllerListener) { // We are using a VR device, keep it alive mLastActiveTime = TimeStamp::Now(); } else if (mLastActiveTime.IsNull()) { Shutdown(); } else { TimeDuration duration = TimeStamp::Now() - mLastActiveTime; if (duration.ToMilliseconds() > kVRDisplayInactiveMaxDuration) { Shutdown(); } } }