From ccf22e27a56fb59e47f687bf8ff244b6cd49e55f Mon Sep 17 00:00:00 2001 From: kearwood <> Date: Fri, 8 Jan 2016 18:50:10 -0800 Subject: [PATCH] Bug 1237689 - Enable Oculus hardware latency tester r=daoshengmu - Generate and pass sequential frame indexes into the ovr_GetTrackingState call and the corresponding call to ovr_SubmitFrame MozReview-Commit-ID: 5tJl5YJt7Eo --- gfx/layers/Layers.cpp | 8 +++++--- gfx/layers/Layers.h | 9 +++++++++ gfx/layers/client/CanvasClient.cpp | 7 +++++++ gfx/layers/composite/CompositableHost.h | 3 +++ .../composite/ContainerLayerComposite.cpp | 17 ++++++++++++++--- gfx/layers/composite/ImageHost.cpp | 3 +++ gfx/layers/composite/ImageHost.h | 3 +++ gfx/layers/ipc/CompositableForwarder.h | 3 ++- .../ipc/CompositableTransactionParent.cpp | 1 + gfx/layers/ipc/ImageBridgeChild.cpp | 2 +- gfx/layers/ipc/LayerTransactionParent.cpp | 1 + gfx/layers/ipc/LayersMessages.ipdlh | 2 ++ gfx/layers/ipc/ShadowLayers.cpp | 2 +- gfx/vr/gfxVR.h | 3 ++- gfx/vr/gfxVROculus.cpp | 7 ++++--- gfx/vr/gfxVROculus.h | 3 ++- gfx/vr/ipc/VRManagerChild.cpp | 8 ++++++++ gfx/vr/ipc/VRManagerChild.h | 2 ++ gfx/vr/ipc/VRMessageUtils.h | 2 ++ layout/base/nsDisplayList.cpp | 1 + 20 files changed, 73 insertions(+), 14 deletions(-) diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 040c683e0909..15c29d9392a1 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -1117,7 +1117,8 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData) mMayHaveReadbackChild(false), mChildrenChanged(false), mEventRegionsOverride(EventRegionsOverride::NoOverride), - mVRDeviceID(0) + mVRDeviceID(0), + mInputFrameID(0) { MOZ_COUNT_CTOR(ContainerLayer); mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT @@ -1279,7 +1280,8 @@ ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs) mInheritedXScale, mInheritedYScale, mPresShellResolution, mScaleToResolution, mEventRegionsOverride, - mVRDeviceID); + mVRDeviceID, + mInputFrameID); } bool @@ -2146,7 +2148,7 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) aStream << " [force-ehr]"; } if (mVRDeviceID) { - aStream << nsPrintfCString(" [hmd=%lu]", mVRDeviceID).get(); + aStream << nsPrintfCString(" [hmd=%lu] [hmdframe=%l]", mVRDeviceID, mInputFrameID).get(); } } diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 27edef846da6..b2d317fb7ca0 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -2143,10 +2143,18 @@ public: */ void SetVRDeviceID(uint32_t aVRDeviceID) { mVRDeviceID = aVRDeviceID; + Mutated(); } uint32_t GetVRDeviceID() { return mVRDeviceID; } + void SetInputFrameID(int32_t aInputFrameID) { + mInputFrameID = aInputFrameID; + Mutated(); + } + int32_t GetInputFrameID() { + return mInputFrameID; + } /** * Replace the current effective transform with the given one, @@ -2223,6 +2231,7 @@ protected: bool mChildrenChanged; EventRegionsOverride mEventRegionsOverride; uint32_t mVRDeviceID; + int32_t mInputFrameID; }; /** diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index 2a5c991c457f..a11c8c35f4ab 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -25,6 +25,7 @@ #include "nsDebug.h" // for printf_stderr, NS_ASSERTION #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc #include "TextureClientSharedSurface.h" +#include "VRManagerChild.h" using namespace mozilla::gfx; using namespace mozilla::gl; @@ -125,6 +126,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) t->mTextureClient = mBuffer; t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mBuffer->GetSize()); t->mFrameID = mFrameID; + t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID(); GetForwarder()->UseTextures(this, textures); mBuffer->SyncWithObject(GetForwarder()->GetSyncObject()); } @@ -481,6 +483,11 @@ CanvasClientSharedSurface::Updated() t->mTextureClient = mFront; t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mFront->GetSize()); t->mFrameID = mFrameID; + // XXX TODO - This reference to VRManagerChild will be moved with the + // implementation of the WebVR 1.0 API, which will enable + // the inputFrameID to be passed through Javascript with + // the new VRDisplay API. + t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID(); forwarder->UseTextures(this, textures); } diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index d34a8b4648b7..a45f62167608 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -194,6 +194,7 @@ public: gfx::IntRect mPictureRect; int32_t mFrameID; int32_t mProducerID; + int32_t mInputFrameID; }; virtual void UseTextureHost(const nsTArray& aTextures); virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack, @@ -235,6 +236,8 @@ public: return nullptr; } + virtual int32_t GetLastInputFrameID() const { return -1; } + protected: TextureInfo mTextureInfo; uint64_t mAsyncID; diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 49a73b7560b0..28eb0db4a8d8 100755 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -139,8 +139,11 @@ template void ContainerRenderVR(ContainerT* aContainer, LayerManagerComposite* aManager, const gfx::IntRect& aClipRect, - RefPtr aHMD) + RefPtr aHMD, + int32_t aInputFrameID) { + int32_t inputFrameID = -1; + RefPtr surface; Compositor* compositor = aManager->GetCompositor(); @@ -265,6 +268,14 @@ ContainerRenderVR(ContainerT* aContainer, surfaceRect.width, surfaceRect.height)); layerToRender->RenderLayer(surfaceRect); + CompositableHost *ch = layerToRender->GetCompositableHost(); + if (ch) { + int32_t compositableInputFrameID = ch->GetLastInputFrameID(); + if (compositableInputFrameID != -1) { + inputFrameID = compositableInputFrameID; + } + } + if (restoreTransform) { layer->ReplaceEffectiveTransform(childTransform); } @@ -282,7 +293,7 @@ ContainerRenderVR(ContainerT* aContainer, compositor->SetRenderTarget(previousTarget); if (vrRendering) { - vrRendering->SubmitFrame(aContainer->mVRRenderTargetSet); + vrRendering->SubmitFrame(aContainer->mVRRenderTargetSet, inputFrameID); DUMP("<<< ContainerRenderVR [used vrRendering] [%p]\n", aContainer); if (!gfxPrefs::VRMirrorTextures()) { return; @@ -696,7 +707,7 @@ ContainerRender(ContainerT* aContainer, RefPtr hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID()); if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) { - ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo); + ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo, aContainer->GetInputFrameID()); aContainer->mPrepared = nullptr; return; } diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index 22b37cbbab74..418bdd8cc792 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -32,6 +32,7 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo) , mImageContainer(nullptr) , mLastFrameID(-1) , mLastProducerID(-1) + , mLastInputFrameID(-1) , mBias(BIAS_NONE) , mLocked(false) {} @@ -84,6 +85,7 @@ ImageHost::UseTextureHost(const nsTArray& aTextures) img.mPictureRect = t.mPictureRect; img.mFrameID = t.mFrameID; img.mProducerID = t.mProducerID; + img.mInputFrameID = t.mInputFrameID; } // Recycle any leftover mTextureSources and call PrepareTextureSource on all // images. @@ -357,6 +359,7 @@ ImageHost::Composite(LayerComposite* aLayer, } mLastFrameID = img->mFrameID; mLastProducerID = img->mProducerID; + mLastInputFrameID = img->mInputFrameID; } aEffectChain.mPrimaryEffect = effect; gfx::Rect pictureRect(0, 0, img->mPictureRect.width, img->mPictureRect.height); diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index c654018cd02f..ebde4cbc3f2f 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -100,6 +100,7 @@ public: int32_t GetLastFrameID() const { return mLastFrameID; } int32_t GetLastProducerID() const { return mLastProducerID; } + virtual int32_t GetLastInputFrameID() const override { return mLastInputFrameID; } enum Bias { // Don't apply bias to frame times @@ -118,6 +119,7 @@ protected: gfx::IntRect mPictureRect; int32_t mFrameID; int32_t mProducerID; + int32_t mInputFrameID; }; /** @@ -135,6 +137,7 @@ protected: ImageContainerParent* mImageContainer; int32_t mLastFrameID; int32_t mLastProducerID; + int32_t mLastInputFrameID; /** * Bias to apply to the next frame. */ diff --git a/gfx/layers/ipc/CompositableForwarder.h b/gfx/layers/ipc/CompositableForwarder.h index ce6f91948c30..f4fef20987b8 100644 --- a/gfx/layers/ipc/CompositableForwarder.h +++ b/gfx/layers/ipc/CompositableForwarder.h @@ -113,13 +113,14 @@ public: struct TimedTextureClient { TimedTextureClient() - : mTextureClient(nullptr), mFrameID(0), mProducerID(0) {} + : mTextureClient(nullptr), mFrameID(0), mProducerID(0), mInputFrameID(0) {} TextureClient* mTextureClient; TimeStamp mTimeStamp; nsIntRect mPictureRect; int32_t mFrameID; int32_t mProducerID; + int32_t mInputFrameID; }; /** * Tell the CompositableHost on the compositor side what textures to use for diff --git a/gfx/layers/ipc/CompositableTransactionParent.cpp b/gfx/layers/ipc/CompositableTransactionParent.cpp index 82327c8bee87..ff5f887e339a 100644 --- a/gfx/layers/ipc/CompositableTransactionParent.cpp +++ b/gfx/layers/ipc/CompositableTransactionParent.cpp @@ -182,6 +182,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation t->mPictureRect = timedTexture.picture(); t->mFrameID = timedTexture.frameID(); t->mProducerID = timedTexture.producerID(); + t->mInputFrameID = timedTexture.inputFrameID(); MOZ_ASSERT(ValidatePictureRect(t->mTexture->GetSize(), t->mPictureRect)); MaybeFence maybeFence = timedTexture.fence(); diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 46b3d8336f2d..7b730f56dc4d 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -191,7 +191,7 @@ ImageBridgeChild::UseTextures(CompositableClient* aCompositable, textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(), fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()), t.mTimeStamp, t.mPictureRect, - t.mFrameID, t.mProducerID)); + t.mFrameID, t.mProducerID, t.mInputFrameID)); } mTxn->AddNoSwapEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(), textures)); diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 01a35553bf94..0cadf2d24c2f 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -414,6 +414,7 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray&& cset, containerLayer->SetScaleToResolution(attrs.scaleToResolution(), attrs.presShellResolution()); containerLayer->SetEventRegionsOverride(attrs.eventRegionsOverride()); + containerLayer->SetInputFrameID(attrs.inputFrameID()); if (attrs.hmdDeviceID()) { containerLayer->SetVRDeviceID(attrs.hmdDeviceID()); diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 796426a67cc3..410dd96863d5 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -252,6 +252,7 @@ struct ContainerLayerAttributes { bool scaleToResolution; EventRegionsOverride eventRegionsOverride; uint32_t hmdDeviceID; + int32_t inputFrameID; }; struct ColorLayerAttributes { LayerColor color; IntRect bounds; }; struct CanvasLayerAttributes { Filter filter; IntRect bounds; }; @@ -396,6 +397,7 @@ struct TimedTexture { IntRect picture; uint32_t frameID; uint32_t producerID; + int32_t inputFrameID; }; /** diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 343dddb37099..459edc61b37b 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -396,7 +396,7 @@ ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable, textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(), fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()), t.mTimeStamp, t.mPictureRect, - t.mFrameID, t.mProducerID)); + t.mFrameID, t.mProducerID, t.mInputFrameID)); if ((t.mTextureClient->GetFlags() & TextureFlags::IMMEDIATE_UPLOAD) && t.mTextureClient->HasInternalBuffer()) { diff --git a/gfx/vr/gfxVR.h b/gfx/vr/gfxVR.h index ca111cb941f5..55c1890c85d9 100644 --- a/gfx/vr/gfxVR.h +++ b/gfx/vr/gfxVR.h @@ -161,6 +161,7 @@ struct VRDeviceInfo struct VRHMDSensorState { double timestamp; + int32_t inputFrameID; VRStateValidFlags flags; float orientation[4]; float position[3]; @@ -244,7 +245,7 @@ public: virtual already_AddRefed CreateRenderTargetSet(layers::Compositor *aCompositor, const IntSize& aSize) = 0; virtual void DestroyRenderTargetSet(RenderTargetSet *aRTSet) = 0; - virtual void SubmitFrame(RenderTargetSet *aRTSet) = 0; + virtual void SubmitFrame(RenderTargetSet *aRTSet, int32_t aInputFrameID) = 0; protected: VRHMDRenderingSupport() { } }; diff --git a/gfx/vr/gfxVROculus.cpp b/gfx/vr/gfxVROculus.cpp index e41b7d3441d5..87cbfd512c4d 100644 --- a/gfx/vr/gfxVROculus.cpp +++ b/gfx/vr/gfxVROculus.cpp @@ -246,6 +246,7 @@ FromFovPort(const ovrFovPort& aFOV) HMDInfoOculus::HMDInfoOculus(ovrSession aSession) : VRHMDInfo(VRHMDType::Oculus, false) , mSession(aSession) + , mInputFrameID(0) { MOZ_ASSERT(sizeof(HMDInfoOculus::DistortionVertex) == sizeof(VRDistortionVertex), "HMDInfoOculus::DistortionVertex must match the size of VRDistortionVertex"); @@ -345,7 +346,7 @@ HMDInfoOculus::KeepSensorTracking() void HMDInfoOculus::NotifyVsync(const mozilla::TimeStamp& aVsyncTimestamp) { - + ++mInputFrameID; } void @@ -518,7 +519,7 @@ HMDInfoOculus::DestroyRenderTargetSet(RenderTargetSet *aRTSet) } void -HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet) +HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet, int32_t aInputFrameID) { RenderTargetSetOculus *rts = static_cast(aRTSet); MOZ_ASSERT(rts->hmd != nullptr); @@ -547,7 +548,7 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet) do_CalcEyePoses(rts->hmd->mLastTrackingState.HeadPose.ThePose, hmdToEyeViewOffset, layer.RenderPose); ovrLayerHeader *layers = &layer.Header; - ovrResult orv = ovr_SubmitFrame(mSession, 0, nullptr, &layers, 1); + ovrResult orv = ovr_SubmitFrame(mSession, aInputFrameID, nullptr, &layers, 1); //printf_stderr("Submitted frame %d, result: %d\n", rts->textureSet->CurrentIndex, orv); if (orv != ovrSuccess) { // not visible? failed? diff --git a/gfx/vr/gfxVROculus.h b/gfx/vr/gfxVROculus.h index 8177b001b3dc..cf47660c1511 100644 --- a/gfx/vr/gfxVROculus.h +++ b/gfx/vr/gfxVROculus.h @@ -45,7 +45,7 @@ public: /* VRHMDRenderingSupport */ already_AddRefed CreateRenderTargetSet(layers::Compositor *aCompositor, const IntSize& aSize) override; void DestroyRenderTargetSet(RenderTargetSet *aRTSet) override; - void SubmitFrame(RenderTargetSet *aRTSet) override; + void SubmitFrame(RenderTargetSet *aRTSet, int32_t aInputFrameID) override; ovrSession GetOculusSession() const { return mSession; } @@ -68,6 +68,7 @@ protected: ovrHmdDesc mDesc; ovrFovPort mFOVPort[2]; ovrTrackingState mLastTrackingState; + int mInputFrameID; }; } // namespace impl diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index 0663839f54e2..1aba97532b26 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -24,6 +24,7 @@ void ReleaseVRManagerParentSingleton() { } VRManagerChild::VRManagerChild() + : mInputFrameID(-1) { MOZ_COUNT_CTOR(VRManagerChild); MOZ_ASSERT(NS_IsMainThread()); @@ -157,6 +158,7 @@ VRManagerChild::RecvUpdateDeviceSensors(nsTArray&& aDeviceSensor for (auto& device: mDevices) { if (device->GetDeviceInfo().GetDeviceID() == sensorUpdate.mDeviceID) { device->UpdateSensorState(sensorUpdate.mSensorState); + mInputFrameID = sensorUpdate.mSensorState.inputFrameID; break; } } @@ -182,5 +184,11 @@ VRManagerChild::RefreshVRDevicesWithCallback(dom::Navigator* aNavigator) return success; } +int +VRManagerChild::GetInputFrameID() +{ + return mInputFrameID; +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/vr/ipc/VRManagerChild.h b/gfx/vr/ipc/VRManagerChild.h index 293f7d783b0a..345349d2b68f 100644 --- a/gfx/vr/ipc/VRManagerChild.h +++ b/gfx/vr/ipc/VRManagerChild.h @@ -25,6 +25,7 @@ class VRManagerChild : public PVRManagerChild public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRManagerChild) + int GetInputFrameID(); bool GetVRDevices(nsTArray >& aDevices); bool RefreshVRDevicesWithCallback(dom::Navigator* aNavigator); static VRManagerChild* StartUpInChildProcess(Transport* aTransport, @@ -52,6 +53,7 @@ private: nsTArray > mDevices; nsTArray mNavigatorCallbacks; + int32_t mInputFrameID; }; } // namespace mozilla diff --git a/gfx/vr/ipc/VRMessageUtils.h b/gfx/vr/ipc/VRMessageUtils.h index 1c17f1eb61f0..1a5e8004dd3f 100644 --- a/gfx/vr/ipc/VRMessageUtils.h +++ b/gfx/vr/ipc/VRMessageUtils.h @@ -127,6 +127,7 @@ struct ParamTraits static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, aParam.timestamp); + WriteParam(aMsg, aParam.inputFrameID); WriteParam(aMsg, aParam.flags); WriteParam(aMsg, aParam.orientation[0]); WriteParam(aMsg, aParam.orientation[1]); @@ -152,6 +153,7 @@ struct ParamTraits static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) || + !ReadParam(aMsg, aIter, &(aResult->inputFrameID)) || !ReadParam(aMsg, aIter, &(aResult->flags)) || !ReadParam(aMsg, aIter, &(aResult->orientation[0])) || !ReadParam(aMsg, aIter, &(aResult->orientation[1])) || diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 34b9da69a2c8..7c8b033e1b98 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -6428,6 +6428,7 @@ nsDisplayVR::BuildLayer(nsDisplayListBuilder* aBuilder, newContainerParameters, nullptr, flags); container->SetVRDeviceID(mHMD->GetDeviceInfo().GetDeviceID()); + container->SetInputFrameID(mHMD->GetSensorState().inputFrameID); container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(), /*the value is irrelevant*/nullptr);