Bug 1394561 - Ensure WebVR content can catch up when IPC messages are delayed r=daoshengmu,kanru
authorKearwood "Kip" Gilbert <kgilbert@mozilla.com>
Thu, 31 Aug 2017 16:29:14 -0700
changeset 429901 7d20f9d48e02e895bc022eaa20b788f351db9463
parent 429900 557720a6eb3148dae6ad79f77620109d9ef16ef3
child 429902 83cf26e442840c8024233057efb3f55c09364d0a
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaoshengmu, kanru
bugs1394561
milestone57.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 1394561 - Ensure WebVR content can catch up when IPC messages are delayed r=daoshengmu,kanru MozReview-Commit-ID: F4NKtyaNwEo
gfx/vr/VRDisplayHost.cpp
gfx/vr/VRDisplayHost.h
gfx/vr/VRDisplayPresentation.cpp
gfx/vr/VRManager.cpp
gfx/vr/VRManager.h
gfx/vr/ipc/PVRLayer.ipdl
gfx/vr/ipc/VRLayerChild.cpp
gfx/vr/ipc/VRLayerChild.h
gfx/vr/ipc/VRLayerParent.cpp
gfx/vr/ipc/VRLayerParent.h
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -157,28 +157,29 @@ VRDisplayHost::NotifyVSync()
     VRManager *vm = VRManager::Get();
     MOZ_ASSERT(vm);
     vm->NotifyVRVsync(mDisplayInfo.mDisplayID);
   }
 }
 
 void
 VRDisplayHost::SubmitFrame(VRLayerParent* aLayer, PTextureParent* aTexture,
+                           uint64_t aFrameId,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect)
 {
   AutoProfilerTracing tracing("VR", "SubmitFrameAtVRDisplayHost");
 
   if ((mDisplayInfo.mGroupMask & aLayer->GetGroup()) == 0) {
     // Suppress layers hidden by the group mask
     return;
   }
 
   // Ensure that we only accept the first SubmitFrame call per RAF cycle.
-  if (!mFrameStarted) {
+  if (!mFrameStarted || aFrameId != mDisplayInfo.mFrameId) {
     return;
   }
   mFrameStarted = false;
 
 #if defined(XP_WIN)
 
   TextureHost* th = TextureHost::AsTextureHost(aTexture);
 
--- a/gfx/vr/VRDisplayHost.h
+++ b/gfx/vr/VRDisplayHost.h
@@ -43,16 +43,17 @@ public:
   virtual void ZeroSensor() = 0;
   virtual void StartPresentation() = 0;
   virtual void StopPresentation() = 0;
   virtual void NotifyVSync();
 
   void StartFrame();
   void SubmitFrame(VRLayerParent* aLayer,
                    mozilla::layers::PTextureParent* aTexture,
+                   uint64_t aFrameId,
                    const gfx::Rect& aLeftEyeRect,
                    const gfx::Rect& aRightEyeRect);
 
   bool CheckClearDisplayInfoDirty();
   void SetGroupMask(uint32_t aGroupMask);
   bool GetIsConnected();
 
 protected:
--- a/gfx/vr/VRDisplayPresentation.cpp
+++ b/gfx/vr/VRDisplayPresentation.cpp
@@ -122,12 +122,12 @@ VRDisplayPresentation::~VRDisplayPresent
 {
   DestroyLayers();
   mDisplayClient->PresentationDestroyed();
 }
 
 void VRDisplayPresentation::SubmitFrame()
 {
   for (VRLayerChild *layer : mLayers) {
-    layer->SubmitFrame();
+    layer->SubmitFrame(mDisplayClient->GetDisplayInfo().GetFrameId());
     break; // Currently only one layer supported, submit only the first
   }
 }
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -340,24 +340,25 @@ VRManager::GetDisplay(const uint32_t& aD
   if (mVRDisplays.Get(aDisplayID, getter_AddRefs(display))) {
     return display;
   }
   return nullptr;
 }
 
 void
 VRManager::SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
+                       uint64_t aFrameId,
                        const gfx::Rect& aLeftEyeRect,
                        const gfx::Rect& aRightEyeRect)
 {
   TextureHost* th = TextureHost::AsTextureHost(aTexture);
   mLastFrame = th;
   RefPtr<VRDisplayHost> display = GetDisplay(aLayer->GetDisplayID());
   if (display) {
-    display->SubmitFrame(aLayer, aTexture, aLeftEyeRect, aRightEyeRect);
+    display->SubmitFrame(aLayer, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
   }
 }
 
 RefPtr<gfx::VRControllerHost>
 VRManager::GetController(const uint32_t& aControllerID)
 {
   RefPtr<gfx::VRControllerHost> controller;
   if (mVRControllers.Get(aControllerID, getter_AddRefs(controller))) {
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -40,16 +40,17 @@ public:
   void RefreshVRControllers();
   void ScanForControllers();
   void RemoveControllers();
   template<class T> void NotifyGamepadChange(uint32_t aIndex, const T& aInfo);
   RefPtr<gfx::VRDisplayHost> GetDisplay(const uint32_t& aDisplayID);
   void GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo);
 
   void SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
+                   uint64_t aFrameId,
                    const gfx::Rect& aLeftEyeRect,
                    const gfx::Rect& aRightEyeRect);
   RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
   void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
   void CreateVRTestSystem();
   void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
                      double aIntensity, double aDuration, uint32_t aPromiseID);
   void StopVibrateHaptic(uint32_t aControllerIdx);
--- a/gfx/vr/ipc/PVRLayer.ipdl
+++ b/gfx/vr/ipc/PVRLayer.ipdl
@@ -11,17 +11,17 @@ include protocol PTexture;
 namespace mozilla {
 namespace gfx {
 
 async protocol PVRLayer
 {
   manager PVRManager;
 
 parent:
-  async SubmitFrame(PTexture aTexture);
+  async SubmitFrame(PTexture aTexture, uint64_t aFrameId);
   async Destroy();
 
 child:
   async __delete__();
 };
 
 } // gfx
 } // mozilla
--- a/gfx/vr/ipc/VRLayerChild.cpp
+++ b/gfx/vr/ipc/VRLayerChild.cpp
@@ -42,17 +42,17 @@ VRLayerChild::Initialize(dom::HTMLCanvas
   mCanvasElement = aCanvasElement;
   mCanvasElement->StartVRPresentation();
 
   VRManagerChild *vrmc = VRManagerChild::Get();
   vrmc->RunFrameRequestCallbacks();
 }
 
 void
-VRLayerChild::SubmitFrame()
+VRLayerChild::SubmitFrame(uint64_t aFrameId)
 {
   if (!mCanvasElement) {
     return;
   }
 
   mShSurfClient = mCanvasElement->GetVRFrame();
   if (!mShSurfClient) {
     return;
@@ -67,17 +67,17 @@ VRLayerChild::SubmitFrame()
   mFront = mShSurfClient;
   mShSurfClient = nullptr;
 
   mFront->SetAddedToCompositableClient();
   VRManagerChild* vrmc = VRManagerChild::Get();
   mFront->SyncWithObject(vrmc->GetSyncObject());
   MOZ_ALWAYS_TRUE(mFront->InitIPDLActor(vrmc));
 
-  SendSubmitFrame(mFront->GetIPDLActor());
+  SendSubmitFrame(mFront->GetIPDLActor(), aFrameId);
 }
 
 bool
 VRLayerChild::IsIPCOpen()
 {
   return mIPCOpen;
 }
 
--- a/gfx/vr/ipc/VRLayerChild.h
+++ b/gfx/vr/ipc/VRLayerChild.h
@@ -31,17 +31,17 @@ namespace gfx {
 class VRLayerChild : public PVRLayerChild {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRLayerChild)
 
 public:
   static PVRLayerChild* CreateIPDLActor();
   static bool DestroyIPDLActor(PVRLayerChild* actor);
 
   void Initialize(dom::HTMLCanvasElement* aCanvasElement);
-  void SubmitFrame();
+  void SubmitFrame(uint64_t aFrameId);
   bool IsIPCOpen();
 
 private:
   VRLayerChild();
   virtual ~VRLayerChild();
   void ClearSurfaces();
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
--- a/gfx/vr/ipc/VRLayerParent.cpp
+++ b/gfx/vr/ipc/VRLayerParent.cpp
@@ -52,21 +52,22 @@ VRLayerParent::Destroy()
   }
 
   if (mIPCOpen) {
     Unused << PVRLayerParent::Send__delete__(this);
   }
 }
 
 mozilla::ipc::IPCResult
-VRLayerParent::RecvSubmitFrame(PTextureParent* texture)
+VRLayerParent::RecvSubmitFrame(PTextureParent* texture,
+                               const uint64_t& aFrameId)
 {
   if (mVRDisplayID) {
     VRManager* vm = VRManager::Get();
-    vm->SubmitFrame(this, texture, mLeftEyeRect, mRightEyeRect);
+    vm->SubmitFrame(this, texture, aFrameId, mLeftEyeRect, mRightEyeRect);
   }
 
   return IPC_OK();
 }
 
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/vr/ipc/VRLayerParent.h
+++ b/gfx/vr/ipc/VRLayerParent.h
@@ -16,17 +16,18 @@ namespace mozilla {
 namespace gfx {
 
 class VRLayerParent : public PVRLayerParent {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRLayerParent)
 
 public:
   VRLayerParent(uint32_t aVRDisplayID, const Rect& aLeftEyeRect,
                 const Rect& aRightEyeRect, const uint32_t aGroup);
-  virtual mozilla::ipc::IPCResult RecvSubmitFrame(PTextureParent* texture) override;
+  virtual mozilla::ipc::IPCResult RecvSubmitFrame(PTextureParent* texture,
+                                                  const uint64_t& aFrameId) override;
   virtual mozilla::ipc::IPCResult RecvDestroy() override;
   uint32_t GetDisplayID() const { return mVRDisplayID; }
   uint32_t GetGroup() const { return mGroup; }
 protected:
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual ~VRLayerParent();
   void Destroy();