Bug 1405481 - Push canvas updates to the compositor on empty transactions r=jrmuizel

This commit is contained in:
sotaro
2017-10-12 10:13:10 +09:00
parent 3b77bd1f61
commit b197f1f95b
8 changed files with 113 additions and 12 deletions

View File

@@ -59,6 +59,9 @@ parent:
WebRenderScrollData aScrollData,
OpUpdateResource[] aResourceUpdates, Shmem[] aSmallShmems, Shmem[] aLargeShmems,
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
async EmptyTransaction(FocusTarget focusTarget,
WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
async SetFocusTarget(FocusTarget focusTarget);
async UpdateResources(OpUpdateResource[] aResourceUpdates, Shmem[] aSmallShmems, Shmem[] aLargeShmems);
async ParentCommands(WebRenderParentCommand[] commands);

View File

@@ -157,6 +157,28 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
mIsInTransaction = false;
}
void
WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
uint64_t aTransactionId,
const mozilla::TimeStamp& aTxnStartTime)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
TimeStamp fwdTime;
#if defined(ENABLE_FRAME_LATENCY_LOG)
fwdTime = TimeStamp::Now();
#endif
this->SendEmptyTransaction(aFocusTarget,
mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId,
mIdNamespace, aTxnStartTime, fwdTime);
mParentCommands.Clear();
mDestroyedActors.Clear();
mIsInTransaction = false;
}
void
WebRenderBridgeChild::ProcessWebRenderParentCommands()
{

View File

@@ -75,6 +75,9 @@ public:
bool aIsSync, uint64_t aTransactionId,
const WebRenderScrollData& aScrollData,
const mozilla::TimeStamp& aTxnStartTime);
void EndEmptyTransaction(const FocusTarget& aFocusTarget,
uint64_t aTransactionId,
const mozilla::TimeStamp& aTxnStartTime);
void ProcessWebRenderParentCommands();
CompositorBridgeChild* GetCompositorBridgeChild();

View File

@@ -614,6 +614,48 @@ WebRenderBridgeParent::RecvSetDisplayListSync(const gfx::IntSize &aSize,
aIdNamespace, aTxnStartTime, aFwdTime);
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
InfallibleTArray<WebRenderParentCommand>&& aCommands,
InfallibleTArray<OpDestroy>&& aToDestroy,
const uint64_t& aFwdTransactionId,
const uint64_t& aTransactionId,
const wr::IdNamespace& aIdNamespace,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime)
{
if (mDestroyed) {
for (const auto& op : aToDestroy) {
DestroyActor(op);
}
return IPC_OK();
}
AutoProfilerTracing tracing("Paint", "EmptyTransaction");
UpdateFwdTransactionId(aFwdTransactionId);
AutoClearReadLocks clearLocks(mReadLocks);
// This ensures that destroy operations are always processed. It is not safe
// to early-return without doing so.
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
if (!aCommands.IsEmpty()) {
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
ProcessWebRenderParentCommands(aCommands);
mCompositorScheduler->ScheduleComposition();
}
mScrollData.SetFocusTarget(aFocusTarget);
UpdateAPZ(false);
// XXX Call DidComposite at correct timing.
TimeStamp now = TimeStamp::Now();
HoldPendingTransactionId(mWrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
mCompositorBridge->DidComposite(wr::AsUint64(mPipelineId), now, now);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvSetFocusTarget(const FocusTarget& aFocusTarget)
{

View File

@@ -106,6 +106,14 @@ public:
const wr::IdNamespace& aIdNamespace,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime) override;
mozilla::ipc::IPCResult RecvEmptyTransaction(const FocusTarget& aFocusTarget,
InfallibleTArray<WebRenderParentCommand>&& aCommands,
InfallibleTArray<OpDestroy>&& aToDestroy,
const uint64_t& aFwdTransactionId,
const uint64_t& aTransactionId,
const wr::IdNamespace& aIdNamespace,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime) override;
mozilla::ipc::IPCResult RecvSetFocusTarget(const FocusTarget& aFocusTarget) override;
mozilla::ipc::IPCResult RecvParentCommands(nsTArray<WebRenderParentCommand>&& commands) override;
mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;

View File

@@ -31,6 +31,17 @@ void WebRenderCommandBuilder::Destroy()
RemoveUnusedAndResetWebRenderUserData();
}
void
WebRenderCommandBuilder::EmptyTransaction()
{
// We need to update canvases that might have changed.
for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) {
RefPtr<WebRenderCanvasData> canvasData = iter.Get()->GetKey();
WebRenderCanvasRendererAsync* canvas = canvasData->GetCanvasRenderer();
canvas->UpdateCompositableClient();
}
}
void
WebRenderCommandBuilder::BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResourceUpdates,

View File

@@ -40,6 +40,8 @@ public:
void Destroy();
void EmptyTransaction();
void BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResourceUpdates,
nsDisplayList* aDisplayList,

View File

@@ -174,25 +174,35 @@ WebRenderLayerManager::BeginTransaction()
bool
WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
{
LayoutDeviceIntSize size = mWidget->GetClientSize();
WrBridge()->BeginTransaction();
// With the WebRenderLayerManager we reject attempts to set most kind of
// "pending data" for empty transactions. Any place that attempts to update
// transforms or scroll offset, for example, will get failure return values
// back, and will fall back to a full transaction. Therefore the only piece
// of "pending" information we need to send in an empty transaction is the
// APZ focus state.
WrBridge()->SendSetFocusTarget(mFocusTarget);
// of "pending" information we need to send in an empty transaction are the
// APZ focus state and canvases's CompositableOperations.
// We also need to update canvases that might have changed, but this code
// as-is causes crashes so comment it out for now.
//for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) {
// RefPtr<WebRenderCanvasData> canvasData = iter.Get()->GetKey();
// WebRenderCanvasRendererAsync* canvas = canvasData->GetCanvasRenderer();
// canvas->UpdateCompositableClient();
//}
mWebRenderCommandBuilder.EmptyTransaction();
if (!(aFlags & EndTransactionFlags::END_NO_COMPOSITE)) {
ScheduleComposite();
WrBridge()->ClearReadLocks();
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
TimeStamp transactionStart = mTransactionIdAllocator->GetTransactionStart();
// Skip the synchronization for buffer since we also skip the painting during
// device-reset status.
if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
if (WrBridge()->GetSyncObject() &&
WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
WrBridge()->GetSyncObject()->Synchronize();
}
}
WrBridge()->EndEmptyTransaction(mFocusTarget, mLatestTransactionId, transactionStart);
MakeSnapshotIfRequired(size);
return true;
}