diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 48cb09de7863..45ca48d138fe 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -949,6 +949,7 @@ WebRenderBridgeParent::RecvGetSnapshot(PTextureParent* aTexture) return IPC_FAIL_NO_REASON(this); } + TimeStamp start = TimeStamp::Now(); MOZ_ASSERT(bufferTexture->GetBufferDescriptor().type() == BufferDescriptor::TRGBDescriptor); DebugOnly stride = ImageDataSerializer::GetRGBStride(bufferTexture->GetBufferDescriptor().get_RGBDescriptor()); uint8_t* buffer = bufferTexture->GetBuffer(); @@ -964,7 +965,7 @@ WebRenderBridgeParent::RecvGetSnapshot(PTextureParent* aTexture) FlushSceneBuilds(); FlushFrameGeneration(); - mApi->Readback(size, buffer, buffer_size); + mApi->Readback(start, size, buffer, buffer_size); return IPC_OK(); } diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index a8430a8a002c..9201eb125a32 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -225,7 +225,18 @@ RenderThread::NewFrameReady(wr::WindowId aWindowId) return; } - UpdateAndRender(aWindowId); + TimeStamp startTime; + + { // scope lock + MutexAutoLock lock(mFrameCountMapLock); + auto it = mWindowInfos.find(AsUint64(aWindowId)); + MOZ_ASSERT(it != mWindowInfos.end()); + WindowInfo* info = it->second; + MOZ_ASSERT(info->mPendingCount > 0); + startTime = info->mStartTimes.front(); + } + + UpdateAndRender(aWindowId, startTime); FrameRenderingComplete(aWindowId); } @@ -296,7 +307,9 @@ NotifyDidRender(layers::CompositorBridgeParent* aBridge, } void -RenderThread::UpdateAndRender(wr::WindowId aWindowId, bool aReadback) +RenderThread::UpdateAndRender(wr::WindowId aWindowId, + const TimeStamp& aStartTime, + bool aReadback) { AUTO_PROFILER_TRACING("Paint", "Composite"); MOZ_ASSERT(IsInRenderThread()); @@ -308,7 +321,6 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId, bool aReadback) } auto& renderer = it->second; - TimeStamp start = TimeStamp::Now(); bool ret = renderer->UpdateAndRender(aReadback); if (!ret) { @@ -334,7 +346,7 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId, bool aReadback) &NotifyDidRender, renderer->GetCompositorBridge(), info, - start, end + aStartTime, end )); } diff --git a/gfx/webrender_bindings/RenderThread.h b/gfx/webrender_bindings/RenderThread.h index db56c871b106..d155df35470f 100644 --- a/gfx/webrender_bindings/RenderThread.h +++ b/gfx/webrender_bindings/RenderThread.h @@ -131,7 +131,7 @@ public: void RunEvent(wr::WindowId aWindowId, UniquePtr aCallBack); /// Can only be called from the render thread. - void UpdateAndRender(wr::WindowId aWindowId, bool aReadback = false); + void UpdateAndRender(wr::WindowId aWindowId, const TimeStamp& aStartTime, bool aReadback = false); void Pause(wr::WindowId aWindowId); bool Resume(wr::WindowId aWindowId); diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 86c91da6d98f..d5be744586dd 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -365,7 +365,8 @@ WebRenderAPI::HitTest(const wr::WorldPoint& aPoint, } void -WebRenderAPI::Readback(gfx::IntSize size, +WebRenderAPI::Readback(const TimeStamp& aStartTime, + gfx::IntSize size, uint8_t *buffer, uint32_t buffer_size) { @@ -373,8 +374,10 @@ WebRenderAPI::Readback(gfx::IntSize size, { public: explicit Readback(layers::SynchronousTask* aTask, + TimeStamp aStartTime, gfx::IntSize aSize, uint8_t *aBuffer, uint32_t aBufferSize) : mTask(aTask) + , mStartTime(aStartTime) , mSize(aSize) , mBuffer(aBuffer) , mBufferSize(aBufferSize) @@ -389,20 +392,21 @@ WebRenderAPI::Readback(gfx::IntSize size, virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override { - aRenderThread.UpdateAndRender(aWindowId, /* aReadback */ true); + aRenderThread.UpdateAndRender(aWindowId, mStartTime, /* aReadback */ true); wr_renderer_readback(aRenderThread.GetRenderer(aWindowId)->GetRenderer(), mSize.width, mSize.height, mBuffer, mBufferSize); layers::AutoCompleteTask complete(mTask); } layers::SynchronousTask* mTask; + TimeStamp mStartTime; gfx::IntSize mSize; uint8_t *mBuffer; uint32_t mBufferSize; }; layers::SynchronousTask task("Readback"); - auto event = MakeUnique(&task, size, buffer, buffer_size); + auto event = MakeUnique(&task, aStartTime, size, buffer, buffer_size); // This event will be passed from wr_backend thread to renderer thread. That // implies that all frame data have been processed when the renderer runs this // read-back event. Then, we could make sure this read-back event gets the diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 954d7d867214..023594592eaa 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -187,7 +187,7 @@ public: void RunOnRenderThread(UniquePtr aEvent); - void Readback(gfx::IntSize aSize, uint8_t *aBuffer, uint32_t aBufferSize); + void Readback(const TimeStamp& aStartTime, gfx::IntSize aSize, uint8_t *aBuffer, uint32_t aBufferSize); void Pause(); bool Resume();