Bug 1355654 - VRManager will now wait for 30 seconds of inactivity before releasing VR displays, rather than doing it instantaneously. draft
authorKearwood Gilbert <kgilbert@mozilla.com>
Tue, 11 Apr 2017 22:12:22 -0700
changeset 561046 c3c31075bd2ac1d7f49f8c5f3b9d9adecbc52aaa
parent 560546 abf145ebd05fe105efbc78b761858c34f7690154
child 623860 70dc118ad6a2037b161a5cb4475feb4d04872016
push id53605
push userbmo:kgilbert@mozilla.com
push dateWed, 12 Apr 2017 05:14:35 +0000
bugs1355654
milestone55.0a1
Bug 1355654 - VRManager will now wait for 30 seconds of inactivity before releasing VR displays, rather than doing it instantaneously. - This corrects link traversal and improves performance when entering and exiting VR very often. MozReview-Commit-ID: D30NQdnpzMF
gfx/vr/VRManager.cpp
gfx/vr/VRManager.h
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -157,36 +157,33 @@ VRManager::RemoveVRManagerParent(VRManag
     Destroy();
   }
 }
 
 void
 VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp)
 {
   const double kVRDisplayRefreshMaxDuration = 5000; // milliseconds
+  const double kVRDisplayInactiveMaxDuration = 30000; // milliseconds
 
   bool bHaveEventListener = false;
   bool bHaveControllerListener = false;
-  bool bHaveActiveDisplay = false;
 
   for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
     VRManagerParent *vmp = iter.Get()->GetKey();
     if (mVRDisplays.Count()) {
       Unused << vmp->SendNotifyVSync();
     }
     bHaveEventListener |= vmp->HaveEventListener();
     bHaveControllerListener |= vmp->HaveControllerListener();
   }
 
   for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) {
     gfx::VRDisplayHost* display = iter.UserData();
     display->NotifyVSync();
-    if (display->GetDisplayInfo().GetIsPresenting()) {
-      bHaveActiveDisplay = true;
-    }
   }
 
   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
@@ -215,19 +212,27 @@ VRManager::NotifyVsync(const TimeStamp& 
       for (const auto& manager: mManagers) {
         if (!manager->GetIsPresenting()) {
           manager->HandleInput();
         }
       }
     }
   }
 
-  if (!bHaveEventListener && !bHaveControllerListener && !bHaveActiveDisplay) {
-    // Shut down the VR devices when not in use
+  // 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();
+    }
   }
 }
 
 void
 VRManager::NotifyVRVsync(const uint32_t& aDisplayID)
 {
   for (const auto& manager: mManagers) {
     if (manager->GetIsPresenting()) {
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -78,15 +78,16 @@ private:
   VRDisplayHostHashMap mVRDisplays;
 
   typedef nsRefPtrHashtable<nsUint32HashKey, gfx::VRControllerHost> VRControllerHostHashMap;
   VRControllerHostHashMap mVRControllers;
 
   Atomic<bool> mInitialized;
 
   TimeStamp mLastRefreshTime;
+  TimeStamp mLastActiveTime;
   bool mVRTestSystemCreated;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif // GFX_VR_MANAGER_H