Bug 1478504 - Use NotifyPipelineRendered instead of DidComposite for WebRender. r?sotaro
MozReview-Commit-ID: 4eaMTEPD9NY
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1800,26 +1800,24 @@ CompositorBridgeParent::RecvAdoptChild(c
if (scheduleComposition) {
ScheduleComposition();
}
if (childWrBridge) {
MOZ_ASSERT(mWrBridge);
RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI();
api = api->Clone();
- childWrBridge->UpdateWebRender(mWrBridge->CompositorScheduler(),
+ wr::Epoch newEpoch = childWrBridge->UpdateWebRender(mWrBridge->CompositorScheduler(),
api,
mWrBridge->AsyncImageManager(),
GetAnimationStorage(),
mWrBridge->GetTextureFactoryIdentifier());
// Pretend we composited, since parent CompositorBridgeParent was replaced.
- if (cpcp) {
- TimeStamp now = TimeStamp::Now();
- cpcp->DidComposite(child, now, now);
- }
+ TimeStamp now = TimeStamp::Now();
+ NotifyPipelineRendered(childWrBridge->PipelineId(), newEpoch, now, now);
}
if (oldApzUpdater) {
// We don't support moving a child from an APZ-enabled compositor to a
// APZ-disabled compositor. The mOptions assertion above should already
// ensure this, since APZ-ness is one of the things in mOptions. Note
// however it is possible for mApzUpdater to be non-null here with
// oldApzUpdater null, because the child may not have been previously
@@ -2127,17 +2125,17 @@ CompositorBridgeParent::DidComposite(Lay
DidComposite(aCompositeStart, aCompositeEnd);
}
void
CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
{
if (mWrBridge) {
- NotifyDidComposite(mWrBridge->FlushPendingTransactionIds(), aCompositeStart, aCompositeEnd);
+ MOZ_ASSERT(false); // This should never get called for a WR compositor
} else {
NotifyDidComposite(mPendingTransaction, aCompositeStart, aCompositeEnd);
#if defined(ENABLE_FRAME_LATENCY_LOG)
if (mPendingTransaction.IsValid()) {
if (mRefreshStartTime) {
int32_t latencyMs = lround((aCompositeEnd - mRefreshStartTime).ToMilliseconds());
printf_stderr("From transaction start to end of generate frame latencyMs %d this %p\n", latencyMs, this);
}
@@ -2201,34 +2199,28 @@ RefPtr<AsyncImagePipelineManager>
CompositorBridgeParent::GetAsyncImagePipelineManager() const
{
return mAsyncImageManager;
}
void
CompositorBridgeParent::NotifyDidComposite(TransactionId aTransactionId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd)
{
+ MOZ_ASSERT(!mWrBridge); // We should be going through NotifyPipelineRendered instead
+
Unused << SendDidComposite(LayersId{0}, aTransactionId, aCompositeStart, aCompositeEnd);
if (mLayerManager) {
nsTArray<ImageCompositeNotificationInfo> notifications;
mLayerManager->ExtractImageCompositeNotifications(¬ifications);
if (!notifications.IsEmpty()) {
Unused << ImageBridgeParent::NotifyImageComposites(notifications);
}
}
- if (mWrBridge) {
- nsTArray<ImageCompositeNotificationInfo> notifications;
- mWrBridge->ExtractImageCompositeNotifications(¬ifications);
- if (!notifications.IsEmpty()) {
- Unused << ImageBridgeParent::NotifyImageComposites(notifications);
- }
- }
-
MonitorAutoLock lock(*sIndirectLayerTreesLock);
ForEachIndirectLayerTree([&] (LayerTreeState* lts, const LayersId& aLayersId) -> void {
if (lts->mCrossProcessParent && lts->mParent == this) {
CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
cpcp->DidCompositeLocked(aLayersId, aCompositeStart, aCompositeEnd);
}
});
}
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -393,21 +393,18 @@ CrossProcessCompositorBridgeParent::DidC
TimeStamp& aCompositeEnd)
{
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
if (LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree) {
TransactionId transactionId = layerTree->FlushTransactionId(aCompositeEnd);
if (transactionId.IsValid()) {
Unused << SendDidComposite(aId, transactionId, aCompositeStart, aCompositeEnd);
}
- } else if (WebRenderBridgeParent* wrbridge = sIndirectLayerTrees[aId].mWrBridge) {
- TransactionId transactionId = wrbridge->FlushPendingTransactionIds();
- if (transactionId.IsValid()) {
- Unused << SendDidComposite(aId, transactionId, aCompositeStart, aCompositeEnd);
- }
+ } else if (sIndirectLayerTrees[aId].mWrBridge) {
+ MOZ_ASSERT(false); // this should never get called for a WR compositor
}
}
void
CrossProcessCompositorBridgeParent::ScheduleComposite(LayerTransactionParent* aLayerTree)
{
LayersId id = aLayerTree->GetId();
MOZ_ASSERT(id.IsValid());
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -817,18 +817,20 @@ WebRenderBridgeParent::RecvSetDisplayLis
// build is done, so we don't need to do it here.
}
HoldPendingTransactionId(wrEpoch, aTransactionId, aRefreshStartTime, aTxnStartTime, aFwdTime);
if (mIdNamespace != aIdNamespace) {
// Pretend we composited since someone is wating for this event,
// though DisplayList was not pushed to webrender.
- TimeStamp now = TimeStamp::Now();
- mCompositorBridge->DidComposite(GetLayersId(), now, now);
+ if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
+ TimeStamp now = TimeStamp::Now();
+ cbp->NotifyPipelineRendered(mPipelineId, wrEpoch, now, now);
+ }
}
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
@@ -896,18 +898,23 @@ WebRenderBridgeParent::RecvEmptyTransact
sendDidComposite = false;
}
HoldPendingTransactionId(WrEpoch(), aTransactionId, aRefreshStartTime, aTxnStartTime, aFwdTime);
if (scheduleComposite) {
ScheduleGenerateFrame();
} else if (sendDidComposite) {
- TimeStamp now = TimeStamp::Now();
- mCompositorBridge->DidComposite(GetLayersId(), now, now);
+ // The only thing in the pending transaction id queue should be the entry
+ // we just added, and now we're going to pretend we rendered it
+ MOZ_ASSERT(mPendingTransactionIds.size() == 1);
+ if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
+ TimeStamp now = TimeStamp::Now();
+ cbp->NotifyPipelineRendered(mPipelineId, WrEpoch(), now, now);
+ }
}
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
return IPC_OK();
}
@@ -1241,31 +1248,31 @@ WebRenderBridgeParent::RecvClearCachedRe
for (const auto& id : mActiveAnimations) {
mAnimStorage->ClearById(id);
}
mActiveAnimations.clear();
std::queue<CompositorAnimationIdsForEpoch>().swap(mCompositorAnimationsToDelete); // clear queue
return IPC_OK();
}
-void
+wr::Epoch
WebRenderBridgeParent::UpdateWebRender(CompositorVsyncScheduler* aScheduler,
wr::WebRenderAPI* aApi,
AsyncImagePipelineManager* aImageMgr,
CompositorAnimationStorage* aAnimStorage,
const TextureFactoryIdentifier& aTextureFactoryIdentifier)
{
MOZ_ASSERT(!IsRootWebRenderBridgeParent());
MOZ_ASSERT(aScheduler);
MOZ_ASSERT(aApi);
MOZ_ASSERT(aImageMgr);
MOZ_ASSERT(aAnimStorage);
if (mDestroyed) {
- return;
+ return mWrEpoch;
}
// Update id name space to identify obsoleted keys.
// Since usage of invalid keys could cause crash in webrender.
mIdNamespace = aApi->GetNamespace();
// XXX Remove it when webrender supports sharing/moving Keys between different webrender instances.
// XXX It requests client to update/reallocate webrender related resources,
// but parent side does not wait end of the update.
@@ -1279,19 +1286,20 @@ WebRenderBridgeParent::UpdateWebRender(C
// XXX Stop to clear resources if webreder supports resources sharing between different webrender instances.
ClearResources();
mCompositorBridge = cBridge;
mCompositorScheduler = aScheduler;
mApi = aApi;
mAsyncImageManager = aImageMgr;
mAnimStorage = aAnimStorage;
- Unused << GetNextWrEpoch(); // Update webrender epoch
// Register pipeline to updated AsyncImageManager.
mAsyncImageManager->AddPipeline(mPipelineId);
+
+ return GetNextWrEpoch(); // Update webrender epoch
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvScheduleComposite()
{
if (mDestroyed) {
return IPC_OK();
}
@@ -1607,27 +1615,16 @@ WebRenderBridgeParent::LastPendingTransa
TransactionId id{0};
if (!mPendingTransactionIds.empty()) {
id = mPendingTransactionIds.back().mId;
}
return id;
}
TransactionId
-WebRenderBridgeParent::FlushPendingTransactionIds()
-{
- TransactionId id{0};
- if (!mPendingTransactionIds.empty()) {
- id = mPendingTransactionIds.back().mId;
- std::queue<PendingTransactionId>().swap(mPendingTransactionIds); // clear queue
- }
- return id;
-}
-
-TransactionId
WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime)
{
TransactionId id{0};
while (!mPendingTransactionIds.empty()) {
if (aEpoch.mHandle < mPendingTransactionIds.front().mEpoch.mHandle) {
break;
}
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -153,17 +153,16 @@ public:
void SetAboutToSendAsyncMessages() override;
void HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
TransactionId aTransactionId,
const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime);
TransactionId LastPendingTransactionId();
- TransactionId FlushPendingTransactionIds();
TransactionId FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime);
TextureFactoryIdentifier GetTextureFactoryIdentifier();
void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications);
wr::IdNamespace GetIdNamespace()
{
@@ -181,21 +180,21 @@ public:
* to generate frame. If we need to generate new frame at next composite timing,
* call this method.
*
* Call CompositorVsyncScheduler::ScheduleComposition() directly, if we just
* want to trigger AsyncImagePipelines update checks.
*/
void ScheduleGenerateFrame();
- void UpdateWebRender(CompositorVsyncScheduler* aScheduler,
- wr::WebRenderAPI* aApi,
- AsyncImagePipelineManager* aImageMgr,
- CompositorAnimationStorage* aAnimStorage,
- const TextureFactoryIdentifier& aTextureFactoryIdentifier);
+ wr::Epoch UpdateWebRender(CompositorVsyncScheduler* aScheduler,
+ wr::WebRenderAPI* aApi,
+ AsyncImagePipelineManager* aImageMgr,
+ CompositorAnimationStorage* aAnimStorage,
+ const TextureFactoryIdentifier& aTextureFactoryIdentifier);
void RemoveEpochDataPriorTo(const wr::Epoch& aRenderedEpoch);
private:
explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId);
virtual ~WebRenderBridgeParent();
void UpdateAPZFocusState(const FocusTarget& aFocus);