Bug 1470528 - Implement CONTENT_FRAME_TIME for the webrender codepath. r=sotaro
This commit implements the CONTENT_FRAME_TIME metric for the webrender code path. It follows the same structure as the previous commit implementing it for the non-webrender code path. MozReview-Commit-ID: 6aI5uISjgge
This commit is contained in:
@@ -1874,7 +1874,7 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
|
||||
txn.SetRootPipeline(aPipelineId);
|
||||
api->SendTransaction(txn);
|
||||
RefPtr<CompositorAnimationStorage> animStorage = GetAnimationStorage();
|
||||
mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, std::move(api), std::move(asyncMgr), std::move(animStorage));
|
||||
mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, std::move(api), std::move(asyncMgr), std::move(animStorage), mVsyncRate);
|
||||
mWrBridge.get()->AddRef(); // IPDL reference
|
||||
|
||||
*aIdNamespace = mWrBridge->GetIdNamespace();
|
||||
|
||||
@@ -244,7 +244,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
|
||||
RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
|
||||
RefPtr<CompositorAnimationStorage> animStorage = cbp->GetAnimationStorage();
|
||||
WebRenderBridgeParent* parent = new WebRenderBridgeParent(
|
||||
this, aPipelineId, nullptr, root->CompositorScheduler(), std::move(api), std::move(holder), std::move(animStorage));
|
||||
this, aPipelineId, nullptr, root->CompositorScheduler(), std::move(api), std::move(holder), std::move(animStorage), cbp->GetVsyncInterval());
|
||||
parent->AddRef(); // IPDL reference
|
||||
|
||||
{ // scope lock
|
||||
|
||||
@@ -43,10 +43,10 @@ parent:
|
||||
LayoutSize aContentSize, ByteBuf aDL, BuiltDisplayListDescriptor aDLDesc,
|
||||
WebRenderScrollData aScrollData,
|
||||
OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems,
|
||||
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
|
||||
IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime);
|
||||
async EmptyTransaction(FocusTarget focusTarget, ScrollUpdatesMap scrollUpdates, uint32_t aPaintSequenceNumber,
|
||||
WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
|
||||
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
|
||||
IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime);
|
||||
async SetFocusTarget(FocusTarget focusTarget);
|
||||
async UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems);
|
||||
async ParentCommands(WebRenderParentCommand[] commands);
|
||||
|
||||
@@ -122,6 +122,7 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
|
||||
const gfx::IntSize& aSize,
|
||||
TransactionId aTransactionId,
|
||||
const WebRenderScrollData& aScrollData,
|
||||
const mozilla::TimeStamp& aRefreshStartTime,
|
||||
const mozilla::TimeStamp& aTxnStartTime)
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
@@ -145,7 +146,7 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
|
||||
GetFwdTransactionId(), aTransactionId,
|
||||
aContentSize, dlData, aDL.dl_desc, aScrollData,
|
||||
std::move(resourceUpdates), std::move(smallShmems), largeShmems,
|
||||
mIdNamespace, aTxnStartTime, fwdTime);
|
||||
mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime);
|
||||
|
||||
mParentCommands.Clear();
|
||||
mDestroyedActors.Clear();
|
||||
@@ -157,6 +158,7 @@ WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
|
||||
const ScrollUpdatesMap& aUpdates,
|
||||
uint32_t aPaintSequenceNumber,
|
||||
TransactionId aTransactionId,
|
||||
const mozilla::TimeStamp& aRefreshStartTime,
|
||||
const mozilla::TimeStamp& aTxnStartTime)
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
@@ -170,7 +172,7 @@ WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
|
||||
this->SendEmptyTransaction(aFocusTarget, aUpdates, aPaintSequenceNumber,
|
||||
mParentCommands, mDestroyedActors,
|
||||
GetFwdTransactionId(), aTransactionId,
|
||||
mIdNamespace, aTxnStartTime, fwdTime);
|
||||
mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime);
|
||||
mParentCommands.Clear();
|
||||
mDestroyedActors.Clear();
|
||||
mIsInTransaction = false;
|
||||
|
||||
@@ -74,11 +74,13 @@ public:
|
||||
const gfx::IntSize& aSize,
|
||||
TransactionId aTransactionId,
|
||||
const WebRenderScrollData& aScrollData,
|
||||
const mozilla::TimeStamp& aRefreshStartTime,
|
||||
const mozilla::TimeStamp& aTxnStartTime);
|
||||
void EndEmptyTransaction(const FocusTarget& aFocusTarget,
|
||||
const ScrollUpdatesMap& aUpdates,
|
||||
uint32_t aPaintSequenceNumber,
|
||||
TransactionId aTransactionId,
|
||||
const mozilla::TimeStamp& aRefreshStartTime,
|
||||
const mozilla::TimeStamp& aTxnStartTime);
|
||||
void ProcessWebRenderParentCommands();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "mozilla/layers/AsyncImagePipelineManager.h"
|
||||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
#include "mozilla/layers/WebRenderTextureHost.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
@@ -163,7 +164,8 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos
|
||||
CompositorVsyncScheduler* aScheduler,
|
||||
RefPtr<wr::WebRenderAPI>&& aApi,
|
||||
RefPtr<AsyncImagePipelineManager>&& aImageMgr,
|
||||
RefPtr<CompositorAnimationStorage>&& aAnimStorage)
|
||||
RefPtr<CompositorAnimationStorage>&& aAnimStorage,
|
||||
TimeDuration aVsyncRate)
|
||||
: mCompositorBridge(aCompositorBridge)
|
||||
, mPipelineId(aPipelineId)
|
||||
, mWidget(aWidget)
|
||||
@@ -171,6 +173,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos
|
||||
, mAsyncImageManager(aImageMgr)
|
||||
, mCompositorScheduler(aScheduler)
|
||||
, mAnimStorage(aAnimStorage)
|
||||
, mVsyncRate(aVsyncRate)
|
||||
, mChildLayerObserverEpoch(0)
|
||||
, mParentLayerObserverEpoch(0)
|
||||
, mWrEpoch{0}
|
||||
@@ -617,6 +620,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
|
||||
nsTArray<RefCountedShmem>&& aSmallShmems,
|
||||
nsTArray<ipc::Shmem>&& aLargeShmems,
|
||||
const wr::IdNamespace& aIdNamespace,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime)
|
||||
{
|
||||
@@ -690,7 +694,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
|
||||
}
|
||||
}
|
||||
|
||||
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
|
||||
HoldPendingTransactionId(wrEpoch, aTransactionId, aRefreshStartTime, aTxnStartTime, aFwdTime);
|
||||
|
||||
if (mIdNamespace != aIdNamespace) {
|
||||
// Pretend we composited since someone is wating for this event,
|
||||
@@ -717,6 +721,7 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const TransactionId& aTransactionId,
|
||||
const wr::IdNamespace& aIdNamespace,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime)
|
||||
{
|
||||
@@ -768,7 +773,7 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
|
||||
sendDidComposite = false;
|
||||
}
|
||||
|
||||
HoldPendingTransactionId(WrEpoch(), aTransactionId, aTxnStartTime, aFwdTime);
|
||||
HoldPendingTransactionId(WrEpoch(), aTransactionId, aRefreshStartTime, aTxnStartTime, aFwdTime);
|
||||
|
||||
if (scheduleComposite) {
|
||||
ScheduleGenerateFrame();
|
||||
@@ -1466,11 +1471,16 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
|
||||
void
|
||||
WebRenderBridgeParent::HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
|
||||
TransactionId aTransactionId,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime)
|
||||
{
|
||||
MOZ_ASSERT(aTransactionId > LastPendingTransactionId());
|
||||
mPendingTransactionIds.push(PendingTransactionId(aWrEpoch, aTransactionId, aTxnStartTime, aFwdTime));
|
||||
mPendingTransactionIds.push(PendingTransactionId(aWrEpoch,
|
||||
aTransactionId,
|
||||
aRefreshStartTime,
|
||||
aTxnStartTime,
|
||||
aFwdTime));
|
||||
}
|
||||
|
||||
TransactionId
|
||||
@@ -1502,13 +1512,21 @@ WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, cons
|
||||
if (aEpoch.mHandle < mPendingTransactionIds.front().mEpoch.mHandle) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsRootWebRenderBridgeParent() && !mVsyncRate.IsZero()) {
|
||||
double latencyMs = (aEndTime - mPendingTransactionIds.front().mTxnStartTime).ToMilliseconds();
|
||||
double latencyNorm = latencyMs / mVsyncRate.ToMilliseconds();
|
||||
int32_t fracLatencyNorm = lround(latencyNorm * 100.0);
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_FRAME_TIME, fracLatencyNorm);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FRAME_LATENCY_LOG)
|
||||
if (mPendingTransactionIds.front().mTxnStartTime) {
|
||||
uint32_t latencyMs = round((aEndTime - mPendingTransactionIds.front().mTxnStartTime).ToMilliseconds());
|
||||
if (mPendingTransactionIds.front().mRefreshStartTime) {
|
||||
int32_t latencyMs = lround((aEndTime - mPendingTransactionIds.front().mRefreshStartTime).ToMilliseconds());
|
||||
printf_stderr("From transaction start to end of generate frame latencyMs %d this %p\n", latencyMs, this);
|
||||
}
|
||||
if (mPendingTransactionIds.front().mFwdTime) {
|
||||
uint32_t latencyMs = round((aEndTime - mPendingTransactionIds.front().mFwdTime).ToMilliseconds());
|
||||
int32_t latencyMs = lround((aEndTime - mPendingTransactionIds.front().mFwdTime).ToMilliseconds());
|
||||
printf_stderr("From forwarding transaction to end of generate frame latencyMs %d this %p\n", latencyMs, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -53,7 +53,8 @@ public:
|
||||
CompositorVsyncScheduler* aScheduler,
|
||||
RefPtr<wr::WebRenderAPI>&& aApi,
|
||||
RefPtr<AsyncImagePipelineManager>&& aImageMgr,
|
||||
RefPtr<CompositorAnimationStorage>&& aAnimStorage);
|
||||
RefPtr<CompositorAnimationStorage>&& aAnimStorage,
|
||||
TimeDuration aVsyncRate);
|
||||
|
||||
static WebRenderBridgeParent* CreateDestroyed(const wr::PipelineId& aPipelineId);
|
||||
|
||||
@@ -87,6 +88,7 @@ public:
|
||||
nsTArray<RefCountedShmem>&& aSmallShmems,
|
||||
nsTArray<ipc::Shmem>&& aLargeShmems,
|
||||
const wr::IdNamespace& aIdNamespace,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime) override;
|
||||
mozilla::ipc::IPCResult RecvEmptyTransaction(const FocusTarget& aFocusTarget,
|
||||
@@ -97,6 +99,7 @@ public:
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const TransactionId& aTransactionId,
|
||||
const wr::IdNamespace& aIdNamespace,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime) override;
|
||||
mozilla::ipc::IPCResult RecvSetFocusTarget(const FocusTarget& aFocusTarget) override;
|
||||
@@ -150,6 +153,7 @@ public:
|
||||
|
||||
void HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
|
||||
TransactionId aTransactionId,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime);
|
||||
TransactionId LastPendingTransactionId();
|
||||
@@ -247,14 +251,20 @@ private:
|
||||
|
||||
private:
|
||||
struct PendingTransactionId {
|
||||
PendingTransactionId(const wr::Epoch& aEpoch, TransactionId aId, const TimeStamp& aTxnStartTime, const TimeStamp& aFwdTime)
|
||||
PendingTransactionId(const wr::Epoch& aEpoch,
|
||||
TransactionId aId,
|
||||
const TimeStamp& aRefreshStartTime,
|
||||
const TimeStamp& aTxnStartTime,
|
||||
const TimeStamp& aFwdTime)
|
||||
: mEpoch(aEpoch)
|
||||
, mId(aId)
|
||||
, mRefreshStartTime(aRefreshStartTime)
|
||||
, mTxnStartTime(aTxnStartTime)
|
||||
, mFwdTime(aFwdTime)
|
||||
{}
|
||||
wr::Epoch mEpoch;
|
||||
TransactionId mId;
|
||||
TimeStamp mRefreshStartTime;
|
||||
TimeStamp mTxnStartTime;
|
||||
TimeStamp mFwdTime;
|
||||
};
|
||||
@@ -284,6 +294,7 @@ private:
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mExternalImageIds;
|
||||
nsTHashtable<nsUint64HashKey> mSharedSurfaceIds;
|
||||
|
||||
TimeDuration mVsyncRate;
|
||||
TimeStamp mPreviousFrameTimeStamp;
|
||||
// These fields keep track of the latest layer observer epoch values in the child and the
|
||||
// parent. mChildLayerObserverEpoch is the latest epoch value received from the child.
|
||||
|
||||
@@ -168,6 +168,8 @@ WebRenderLayerManager::BeginTransaction()
|
||||
return false;
|
||||
}
|
||||
|
||||
mTransactionStart = TimeStamp::Now();
|
||||
|
||||
// Increment the paint sequence number even if test logging isn't
|
||||
// enabled in this process; it may be enabled in the parent process,
|
||||
// and the parent process expects unique sequence numbers.
|
||||
@@ -208,7 +210,7 @@ WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||
mWebRenderCommandBuilder.EmptyTransaction();
|
||||
|
||||
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
|
||||
TimeStamp transactionStart = mTransactionIdAllocator->GetTransactionStart();
|
||||
TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
|
||||
|
||||
// Skip the synchronization for buffer since we also skip the painting during
|
||||
// device-reset status.
|
||||
@@ -220,9 +222,11 @@ WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||
}
|
||||
|
||||
WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates,
|
||||
mPaintSequenceNumber, mLatestTransactionId, transactionStart);
|
||||
mPaintSequenceNumber, mLatestTransactionId, refreshStart, mTransactionStart);
|
||||
ClearPendingScrollInfoUpdate();
|
||||
|
||||
mTransactionStart = TimeStamp();
|
||||
|
||||
MakeSnapshotIfRequired(size);
|
||||
return true;
|
||||
}
|
||||
@@ -308,7 +312,7 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
|
||||
ClearPendingScrollInfoUpdate();
|
||||
|
||||
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
|
||||
TimeStamp transactionStart = mTransactionIdAllocator->GetTransactionStart();
|
||||
TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
|
||||
|
||||
for (const auto& key : mImageKeysToDelete) {
|
||||
resourceUpdates.DeleteImage(key);
|
||||
@@ -337,9 +341,11 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
|
||||
{
|
||||
AUTO_PROFILER_TRACING("Paint", "ForwardDPTransaction");
|
||||
WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(),
|
||||
mLatestTransactionId, mScrollData, transactionStart);
|
||||
mLatestTransactionId, mScrollData, refreshStart, mTransactionStart);
|
||||
}
|
||||
|
||||
mTransactionStart = TimeStamp();
|
||||
|
||||
MakeSnapshotIfRequired(size);
|
||||
mNeedsComposite = false;
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ private:
|
||||
// See equivalent field in ClientLayerManager
|
||||
APZTestData mApzTestData;
|
||||
|
||||
TimeStamp mTransactionStart;
|
||||
WebRenderCommandBuilder mWebRenderCommandBuilder;
|
||||
|
||||
size_t mLastDisplayListSize;
|
||||
|
||||
Reference in New Issue
Block a user