Bug 1394561 - Ensure WebVR content can catch up when IPC messages are delayed
MozReview-Commit-ID: F4NKtyaNwEo
--- 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();