Bug 1428558 - Part 2. Improve plumbing to sending resource updates to WebRender. r=nical

Animated images will require scheduling a composite of the frame in
addition to updating the ImageKey/external image ID bindings. It would
be good if this could be done as part of the same IPDL message.
Additionally a page may have many animated images that we update the
frame for at the same time, so these updates should be batched together.
In the event that we needed to regenerate the display list, or produce
an empty transaction, ideally we would just throw these resource updates
in with the rest of the changes. This patch allows us to do all of that
without unnecessarily burdening the caller with tracking extra state.

Differential Revision: https://phabricator.services.mozilla.com/D7499
This commit is contained in:
Andrew Osmond
2018-10-11 10:41:46 -04:00
parent caf314a51b
commit 013921e5f8
9 changed files with 174 additions and 26 deletions

View File

@@ -14,7 +14,6 @@
#include "mozilla/dom/TabGroup.h"
#include "mozilla/gfx/DrawEventRecorder.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
@@ -248,7 +247,8 @@ WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
}
WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates,
mPaintSequenceNumber, mLatestTransactionId, refreshStart, mTransactionStart);
mAsyncResourceUpdates, mPaintSequenceNumber, mLatestTransactionId,
refreshStart, mTransactionStart);
ClearPendingScrollInfoUpdate();
mTransactionStart = TimeStamp();
@@ -343,6 +343,19 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
if (mAsyncResourceUpdates) {
if (resourceUpdates.IsEmpty()) {
resourceUpdates = std::move(mAsyncResourceUpdates.ref());
} else {
// If we can't just swap the queue, we need to take the slow path and
// send the update as a separate message. We don't need to schedule a
// composite however because that will happen with EndTransaction.
WrBridge()->UpdateResources(mAsyncResourceUpdates.ref(),
/* aScheduleComposite */ false);
}
mAsyncResourceUpdates.reset();
}
for (const auto& key : mImageKeysToDelete) {
resourceUpdates.DeleteImage(key);
}
@@ -706,5 +719,39 @@ WebRenderLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
return LayerManager::CreatePersistentBufferProvider(aSize, aFormat);
}
wr::IpcResourceUpdateQueue&
WebRenderLayerManager::AsyncResourceUpdates()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mAsyncResourceUpdates) {
mAsyncResourceUpdates.emplace(WrBridge());
RefPtr<Runnable> task = NewRunnableMethod(
"WebRenderLayerManager::FlushAsyncResourceUpdates",
this, &WebRenderLayerManager::FlushAsyncResourceUpdates);
NS_DispatchToMainThread(task.forget());
}
return mAsyncResourceUpdates.ref();
}
void
WebRenderLayerManager::FlushAsyncResourceUpdates()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mAsyncResourceUpdates) {
return;
}
if (!IsDestroyed() && WrBridge()) {
WrBridge()->UpdateResources(mAsyncResourceUpdates.ref(),
/* aScheduleComposite */ true);
}
mAsyncResourceUpdates.reset();
}
} // namespace layers
} // namespace mozilla