From 09b5ef8f6669d0cbd6eb89f40cddb30af6383289 Mon Sep 17 00:00:00 2001 From: Daosheng Mu Date: Sun, 28 Oct 2018 22:49:15 +0000 Subject: [PATCH] Bug 1501869 - Part 2: Stop calling VR tasks when they are at background. r=kip Differential Revision: https://phabricator.services.mozilla.com/D9880 --HG-- extra : moz-landing-system : lando --- dom/base/nsGlobalWindowInner.cpp | 16 ++++++++++++++++ dom/base/nsGlobalWindowInner.h | 3 +++ dom/base/nsGlobalWindowOuter.cpp | 2 ++ dom/vr/VREventObserver.cpp | 24 ++++++++++++++++++++++++ dom/vr/VREventObserver.h | 4 ++++ gfx/vr/VRManager.h | 1 - gfx/vr/ipc/PVRManager.ipdl | 2 ++ gfx/vr/ipc/VRManagerChild.cpp | 19 +++++++++++++++++++ gfx/vr/ipc/VRManagerChild.h | 2 ++ gfx/vr/ipc/VRManagerParent.cpp | 25 +++++++++++++++++++++++++ gfx/vr/ipc/VRManagerParent.h | 8 ++++++++ 11 files changed, 105 insertions(+), 1 deletion(-) diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 9f6d2a0311e6..47520c99140a 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -4446,6 +4446,22 @@ nsGlobalWindowInner::ResetVRTelemetry(bool aUpdate) } } +void +nsGlobalWindowInner::StartVRActivity() +{ + if (mVREventObserver) { + mVREventObserver->StartActivity(); + } +} + +void +nsGlobalWindowInner::StopVRActivity() +{ + if (mVREventObserver) { + mVREventObserver->StopActivity(); + } +} + #ifndef XP_WIN // This guard should match the guard at the callsite. static bool ShouldShowFocusRingIfFocusedByMouse(nsIContent* aNode) { diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index e70e13da21da..d5061beaceea 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -559,6 +559,9 @@ public: // false for only resetting the timestamp. void ResetVRTelemetry(bool aUpdate); + void StartVRActivity(); + void StopVRActivity(); + // Update the VR displays for this window bool UpdateVRDisplays(nsTArray>& aDisplays); diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index cab6e234c76e..f246fd66a882 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -6641,6 +6641,7 @@ nsGlobalWindowOuter::SetIsBackground(bool aIsBackground) // the background window. if (inner && changed) { inner->StopGamepadHaptics(); + inner->StopVRActivity(); // true is for asking to set the delta time to // the telemetry. inner->ResetVRTelemetry(true); @@ -6653,6 +6654,7 @@ nsGlobalWindowOuter::SetIsBackground(bool aIsBackground) // false is for only resetting the timestamp. inner->ResetVRTelemetry(false); inner->SyncGamepadState(); + inner->StartVRActivity(); } } diff --git a/dom/vr/VREventObserver.cpp b/dom/vr/VREventObserver.cpp index 9f316f11843a..b3f69e58fa46 100644 --- a/dom/vr/VREventObserver.cpp +++ b/dom/vr/VREventObserver.cpp @@ -26,6 +26,7 @@ VREventObserver::VREventObserver(nsGlobalWindowInner* aGlobalWindow) : mWindow(aGlobalWindow) , mIs2DView(true) , mHasReset(false) + , mStopActivity(false) { MOZ_ASSERT(aGlobalWindow); @@ -55,6 +56,7 @@ VREventObserver::DisconnectFromOwner() VRManagerChild* vmc = VRManagerChild::Get(); vmc->RemoveListener(this); } + mStopActivity = true; } void @@ -77,6 +79,28 @@ VREventObserver::UpdateSpentTimeIn2DTelemetry(bool aUpdate) } } +void +VREventObserver::StartActivity() +{ + mStopActivity = false; + VRManagerChild* vmc = VRManagerChild::Get(); + vmc->StartActivity(); +} + +void +VREventObserver::StopActivity() +{ + mStopActivity = true; + VRManagerChild* vmc = VRManagerChild::Get(); + vmc->StopActivity(); +} + +bool +VREventObserver::GetStopActivityStatus() +{ + return mStopActivity; +} + void VREventObserver::NotifyAfterLoad() { diff --git a/dom/vr/VREventObserver.h b/dom/vr/VREventObserver.h index 8ec02a2399b7..07e61a5394a1 100644 --- a/dom/vr/VREventObserver.h +++ b/dom/vr/VREventObserver.h @@ -33,6 +33,9 @@ public: void DisconnectFromOwner(); void UpdateSpentTimeIn2DTelemetry(bool aUpdate); + void StartActivity(); + void StopActivity(); + bool GetStopActivityStatus(); private: ~VREventObserver(); @@ -43,6 +46,7 @@ private: TimeStamp mSpendTimeIn2DView; bool mIs2DView; bool mHasReset; + bool mStopActivity; }; } // namespace dom diff --git a/gfx/vr/VRManager.h b/gfx/vr/VRManager.h index 858001838381..93fb0233d743 100644 --- a/gfx/vr/VRManager.h +++ b/gfx/vr/VRManager.h @@ -33,7 +33,6 @@ class VRSystemManagerExternal; class VRManager { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRManager) - friend class VRManagerParent; public: static void ManagerInit(); diff --git a/gfx/vr/ipc/PVRManager.ipdl b/gfx/vr/ipc/PVRManager.ipdl index 771fee3eacfc..8b1d16b954fd 100644 --- a/gfx/vr/ipc/PVRManager.ipdl +++ b/gfx/vr/ipc/PVRManager.ipdl @@ -67,6 +67,8 @@ parent: async NewPoseMoveToMockController(uint32_t aDeviceID, GamepadPoseState aPose); async StartVRNavigation(uint32_t aDeviceID); async StopVRNavigation(uint32_t aDeviceID, TimeDuration aDuration); + async StartActivity(); + async StopActivity(); child: // Notify children of updated VR display enumeration and details. This will diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index 98ca57f1c968..b7b41372f807 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -618,6 +618,25 @@ VRManagerChild::RemoveListener(dom::VREventObserver* aObserver) } } +void +VRManagerChild::StartActivity() +{ + Unused << SendStartActivity(); +} + +void +VRManagerChild::StopActivity() +{ + for (auto& listener : mListeners) { + if (!listener->GetStopActivityStatus()) { + // We are still showing VR in the active window. + return; + } + } + + Unused << SendStopActivity(); +} + void VRManagerChild::HandleFatalError(const char* aMsg) const { diff --git a/gfx/vr/ipc/VRManagerChild.h b/gfx/vr/ipc/VRManagerChild.h index 2e9669da2d29..72f0a979136f 100644 --- a/gfx/vr/ipc/VRManagerChild.h +++ b/gfx/vr/ipc/VRManagerChild.h @@ -42,6 +42,8 @@ public: void AddListener(dom::VREventObserver* aObserver); // Indicate that an observer should no longer receive VR events. void RemoveListener(dom::VREventObserver* aObserver); + void StartActivity(); + void StopActivity(); bool GetVRDisplays(nsTArray >& aDisplays); bool RefreshVRDisplaysWithCallback(uint64_t aWindowId); diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp index 213f9117d997..aa8db5b1247c 100644 --- a/gfx/vr/ipc/VRManagerParent.cpp +++ b/gfx/vr/ipc/VRManagerParent.cpp @@ -24,6 +24,7 @@ VRManagerParent::VRManagerParent(ProcessId aChildProcessId, bool aIsContentChild , mHaveEventListener(false) , mHaveControllerListener(false) , mIsContentChild(aIsContentChild) + , mVRActiveStatus(true) { MOZ_COUNT_CTOR(VRManagerParent); MOZ_ASSERT(NS_IsMainThread()); @@ -204,6 +205,10 @@ VRManagerParent::RecvSetGroupMask(const uint32_t& aDisplayID, const uint32_t& aG bool VRManagerParent::HaveEventListener() { + if (!mVRActiveStatus) { + return false; + } + return mHaveEventListener; } @@ -213,6 +218,12 @@ VRManagerParent::HaveControllerListener() return mHaveControllerListener; } +bool +VRManagerParent::GetVRActiveStatus() +{ + return mVRActiveStatus; +} + mozilla::ipc::IPCResult VRManagerParent::RecvSetHaveEventListener(const bool& aHaveEventListener) { @@ -469,5 +480,19 @@ VRManagerParent::RecvStopVRNavigation(const uint32_t& aDeviceID, const TimeDurat return IPC_OK(); } +mozilla::ipc::IPCResult +VRManagerParent::RecvStartActivity() +{ + mVRActiveStatus = true; + return IPC_OK(); +} + +mozilla::ipc::IPCResult +VRManagerParent::RecvStopActivity() +{ + mVRActiveStatus = false; + return IPC_OK(); +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/vr/ipc/VRManagerParent.h b/gfx/vr/ipc/VRManagerParent.h index 1bf153478017..b33c1674df26 100644 --- a/gfx/vr/ipc/VRManagerParent.h +++ b/gfx/vr/ipc/VRManagerParent.h @@ -39,6 +39,7 @@ public: bool IsSameProcess() const; bool HaveEventListener(); bool HaveControllerListener(); + bool GetVRActiveStatus(); bool SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent); bool SendReplyGamepadVibrateHaptic(const uint32_t& aPromiseID); @@ -75,6 +76,9 @@ protected: virtual mozilla::ipc::IPCResult RecvNewPoseMoveToMockController(const uint32_t& aDeviceID, const GamepadPoseState& pose) override; virtual mozilla::ipc::IPCResult RecvStartVRNavigation(const uint32_t& aDeviceID) override; virtual mozilla::ipc::IPCResult RecvStopVRNavigation(const uint32_t& aDeviceID, const TimeDuration& aTimeout) override; + virtual mozilla::ipc::IPCResult RecvStartActivity() override; + virtual mozilla::ipc::IPCResult RecvStopActivity() override; + private: void RegisterWithManager(); void UnregisterFromManager(); @@ -99,6 +103,10 @@ private: bool mHaveEventListener; bool mHaveControllerListener; bool mIsContentChild; + + // When VR tabs are switched the background, we won't need to + // initialize its session in VRService thread. + bool mVRActiveStatus; }; class VRManagerPromise final