Bug 1481393 - Implement a listener for WebVR PresentationGenerationContext changes; r=kip,rbarker,nika
authorImanol Fernandez <imanol@mozilla.com>
Tue, 07 Aug 2018 23:09:42 +0000
changeset 430560 56bf1095268f090605f65190318d04521a75f1fc
parent 430559 8171af14faf2015a0a7b7d1c8346a0b5d65d6829
child 430561 cc99bd10a9ad36329858e730df04070674718e52
push id34409
push usertoros@mozilla.com
push dateThu, 09 Aug 2018 10:00:05 +0000
treeherdermozilla-central@eb9ff7de69ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip, rbarker, nika
bugs1481393
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1481393 - Implement a listener for WebVR PresentationGenerationContext changes; r=kip,rbarker,nika MozReview-Commit-ID: FAR1fYnNM0U Differential Revision: https://phabricator.services.mozilla.com/D2832
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/vr/VRDisplay.cpp
dom/vr/VRDisplay.h
dom/vr/VREventObserver.cpp
dom/vr/VREventObserver.h
gfx/vr/VRDisplayClient.cpp
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerChild.h
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -6858,16 +6858,25 @@ void
 nsGlobalWindowInner::NotifyActiveVRDisplaysChanged()
 {
   if (mNavigator) {
     mNavigator->NotifyActiveVRDisplaysChanged();
   }
 }
 
 void
+nsGlobalWindowInner::NotifyPresentationGenerationChanged(uint32_t aDisplayID) {
+  for (const auto& display : mVRDisplays) {
+    if (display->DisplayId() == aDisplayID) {
+      display->OnPresentationGenerationChanged();
+    }
+  }
+}
+
+void
 nsGlobalWindowInner::DispatchVRDisplayActivate(uint32_t aDisplayID,
                                                mozilla::dom::VRDisplayEventReason aReason)
 {
   // Ensure that our list of displays is up to date
   VRDisplay::UpdateVRDisplays(mVRDisplays, this);
 
   // Search for the display identified with aDisplayID and fire the
   // event if found.
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -560,16 +560,17 @@ public:
   void ResetVRTelemetry(bool aUpdate);
 
   // Update the VR displays for this window
   bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
 
   // Inner windows only.
   // Called to inform that the set of active VR displays has changed.
   void NotifyActiveVRDisplaysChanged();
+  void NotifyPresentationGenerationChanged(uint32_t aDisplayID);
 
   void DispatchVRDisplayActivate(uint32_t aDisplayID,
                                  mozilla::dom::VRDisplayEventReason aReason);
   void DispatchVRDisplayDeactivate(uint32_t aDisplayID,
                                    mozilla::dom::VRDisplayEventReason aReason);
   void DispatchVRDisplayConnect(uint32_t aDisplayID);
   void DispatchVRDisplayDisconnect(uint32_t aDisplayID);
   void DispatchVRDisplayPresentChange(uint32_t aDisplayID);
--- a/dom/vr/VRDisplay.cpp
+++ b/dom/vr/VRDisplay.cpp
@@ -537,16 +537,21 @@ VRDisplay::IsHandlingVRNavigationEvent()
   if (mHandlingVRNavigationEventStart.IsNull()) {
     return false;
   }
   TimeDuration timeout = TimeDuration::FromMilliseconds(gfxPrefs::VRNavigationTimeout());
   return timeout.ToMilliseconds() <= 0 ||
     (TimeStamp::Now() - mHandlingVRNavigationEventStart) <= timeout;
 }
 
+void
+VRDisplay::OnPresentationGenerationChanged() {
+  ExitPresentInternal();
+}
+
 already_AddRefed<Promise>
 VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers,
                           CallerType aCallerType,
                           ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
   if (!global) {
     aRv.Throw(NS_ERROR_FAILURE);
--- a/dom/vr/VRDisplay.h
+++ b/dom/vr/VRDisplay.h
@@ -362,16 +362,17 @@ public:
 
   int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
                                 mozilla::ErrorResult& aError);
   void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
   void StartVRNavigation();
   void StartHandlingVRNavigationEvent();
   void StopHandlingVRNavigationEvent();
   bool IsHandlingVRNavigationEvent();
+  void OnPresentationGenerationChanged();
 
 protected:
   VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient);
   virtual ~VRDisplay();
   virtual void LastRelease() override;
 
   void ExitPresentInternal();
   void Shutdown();
--- a/dom/vr/VREventObserver.cpp
+++ b/dom/vr/VREventObserver.cpp
@@ -159,10 +159,18 @@ VREventObserver::NotifyVRDisplayPresentC
 
   if (mWindow && mWindow->AsInner()->IsCurrentInnerWindow()) {
     mWindow->NotifyActiveVRDisplaysChanged();
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayPresentChange(aDisplayID);
   }
 }
 
+void
+VREventObserver::NotifyPresentationGenerationChanged(uint32_t aDisplayID) {
+  if (mWindow && mWindow->AsInner()->IsCurrentInnerWindow()) {
+    mWindow->NotifyPresentationGenerationChanged(aDisplayID);
+    MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
+  }
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/vr/VREventObserver.h
+++ b/dom/vr/VREventObserver.h
@@ -24,16 +24,17 @@ public:
   void NotifyAfterLoad();
   void NotifyVRDisplayMounted(uint32_t aDisplayID);
   void NotifyVRDisplayUnmounted(uint32_t aDisplayID);
   void NotifyVRDisplayNavigation(uint32_t aDisplayID);
   void NotifyVRDisplayRequested(uint32_t aDisplayID);
   void NotifyVRDisplayConnect(uint32_t aDisplayID);
   void NotifyVRDisplayDisconnect(uint32_t aDisplayID);
   void NotifyVRDisplayPresentChange(uint32_t aDisplayID);
+  void NotifyPresentationGenerationChanged(uint32_t aDisplayID);
 
   void DisconnectFromOwner();
   void UpdateSpentTimeIn2DTelemetry(bool aUpdate);
 
 private:
   ~VREventObserver();
 
   RefPtr<nsGlobalWindowInner> mWindow;
--- a/gfx/vr/VRDisplayClient.cpp
+++ b/gfx/vr/VRDisplayClient.cpp
@@ -122,16 +122,21 @@ VRDisplayClient::FireEvents()
   // Check if we need to trigger onvrdisplaydeactivate event
   if (bLastEventWasMounted && !mDisplayInfo.mDisplayState.mIsMounted) {
     bLastEventWasMounted = false;
     if (gfxPrefs::VRAutoActivateEnabled()) {
       vm->FireDOMVRDisplayUnmountedEvent(mDisplayInfo.mDisplayID);
     }
   }
 
+  if (mLastPresentingGeneration != mDisplayInfo.mDisplayState.mPresentingGeneration) {
+    mLastPresentingGeneration = mDisplayInfo.mDisplayState.mPresentingGeneration;
+    vm->NotifyPresentationGenerationChanged(mDisplayInfo.mDisplayID);
+  }
+
   // Check if we need to trigger VRDisplay.requestAnimationFrame
   if (mLastEventFrameId != mDisplayInfo.mFrameId) {
     mLastEventFrameId = mDisplayInfo.mFrameId;
     vm->RunFrameRequestCallbacks();
   }
 
   FireGamepadEvents();
 }
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -438,16 +438,25 @@ VRManagerChild::RunFrameRequestCallbacks
   callbacks.AppendElements(mFrameRequestCallbacks);
   mFrameRequestCallbacks.Clear();
   for (auto& callback : callbacks) {
     callback.mCallback->Call(timeStamp);
   }
 }
 
 void
+VRManagerChild::NotifyPresentationGenerationChanged(uint32_t aDisplayID) {
+  nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
+    "gfx::VRManagerChild::NotifyPresentationGenerationChangedInternal",
+    this,
+    &VRManagerChild::NotifyPresentationGenerationChangedInternal,
+    aDisplayID));
+}
+
+void
 VRManagerChild::FireDOMVRDisplayMountedEvent(uint32_t aDisplayID)
 {
   nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
     "gfx::VRManagerChild::FireDOMVRDisplayMountedEventInternal",
     this,
     &VRManagerChild::FireDOMVRDisplayMountedEventInternal,
     aDisplayID));
 }
@@ -550,16 +559,25 @@ VRManagerChild::FireDOMVRDisplayPresentC
 void
 VRManagerChild::FireDOMVRDisplayConnectEventsForLoadInternal(uint32_t aDisplayID,
                                                             dom::VREventObserver* aObserver)
 {
   aObserver->NotifyVRDisplayConnect(aDisplayID);
 }
 
 void
+VRManagerChild::NotifyPresentationGenerationChangedInternal(uint32_t aDisplayID) {
+  nsTArray<RefPtr<dom::VREventObserver>> listeners;
+  listeners = mListeners;
+  for (auto& listener : listeners) {
+    listener->NotifyPresentationGenerationChanged(aDisplayID);
+  }
+}
+
+void
 VRManagerChild::FireDOMVRDisplayConnectEventsForLoad(dom::VREventObserver* aObserver)
 {
   // We need to fire the VRDisplayConnect event when a page is loaded
   // for each VR Display that has already been enumerated
   nsTArray<RefPtr<VRDisplayClient>> displays;
   displays = mDisplays;
   for (auto& display : displays) {
     const VRDisplayInfo& info = display->GetDisplayInfo();
--- a/gfx/vr/ipc/VRManagerChild.h
+++ b/gfx/vr/ipc/VRManagerChild.h
@@ -64,16 +64,17 @@ public:
   static void IdentifyTextureHost(const layers::TextureFactoryIdentifier& aIdentifier);
   layers::LayersBackend GetBackendType() const;
   layers::SyncObjectClient* GetSyncObject() { return mSyncObject; }
 
   nsresult ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
     int32_t *aHandle);
   void CancelFrameRequestCallback(int32_t aHandle);
   void RunFrameRequestCallbacks();
+  void NotifyPresentationGenerationChanged(uint32_t aDisplayID);
 
   void UpdateDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayUpdates);
   void FireDOMVRDisplayMountedEvent(uint32_t aDisplayID);
   void FireDOMVRDisplayUnmountedEvent(uint32_t aDisplayID);
   void FireDOMVRDisplayConnectEvent(uint32_t aDisplayID);
   void FireDOMVRDisplayDisconnectEvent(uint32_t aDisplayID);
   void FireDOMVRDisplayPresentChangeEvent(uint32_t aDisplayID);
   void FireDOMVRDisplayConnectEventsForLoad(dom::VREventObserver* aObserver);
@@ -110,16 +111,17 @@ private:
 
   void FireDOMVRDisplayMountedEventInternal(uint32_t aDisplayID);
   void FireDOMVRDisplayUnmountedEventInternal(uint32_t aDisplayID);
   void FireDOMVRDisplayConnectEventInternal(uint32_t aDisplayID);
   void FireDOMVRDisplayDisconnectEventInternal(uint32_t aDisplayID);
   void FireDOMVRDisplayPresentChangeEventInternal(uint32_t aDisplayID);
   void FireDOMVRDisplayConnectEventsForLoadInternal(uint32_t aDisplayID,
                                                     dom::VREventObserver* aObserver);
+  void NotifyPresentationGenerationChangedInternal(uint32_t aDisplayID);
 
   nsTArray<RefPtr<VRDisplayClient> > mDisplays;
   bool mDisplaysInitialized;
   nsTArray<uint64_t> mNavigatorCallbacks;
 
   MessageLoop* mMessageLoop;
 
   struct FrameRequest;