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:
Ryan Hunt
2018-06-26 13:43:14 -05:00
parent 18528405a6
commit baa3cde25f
9 changed files with 59 additions and 19 deletions

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -211,6 +211,7 @@ private:
// See equivalent field in ClientLayerManager
APZTestData mApzTestData;
TimeStamp mTransactionStart;
WebRenderCommandBuilder mWebRenderCommandBuilder;
size_t mLastDisplayListSize;