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

@@ -50,9 +50,10 @@ parent:
IdNamespace aIdNamespace, bool containsSVGGroup, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime); IdNamespace aIdNamespace, bool containsSVGGroup, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime);
async EmptyTransaction(FocusTarget focusTarget, ScrollUpdatesMap scrollUpdates, uint32_t aPaintSequenceNumber, async EmptyTransaction(FocusTarget focusTarget, ScrollUpdatesMap scrollUpdates, uint32_t aPaintSequenceNumber,
WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems,
IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime); IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime);
async SetFocusTarget(FocusTarget focusTarget); async SetFocusTarget(FocusTarget focusTarget);
async UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems); async UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems, bool scheduleComposite);
async ParentCommands(WebRenderParentCommand[] commands); async ParentCommands(WebRenderParentCommand[] commands);
sync GetSnapshot(PTexture texture); sync GetSnapshot(PTexture texture);
async SetLayersObserverEpoch(LayersObserverEpoch childEpoch); async SetLayersObserverEpoch(LayersObserverEpoch childEpoch);

View File

@@ -30,6 +30,30 @@ ShmSegmentsWriter::~ShmSegmentsWriter()
Clear(); Clear();
} }
ShmSegmentsWriter::ShmSegmentsWriter(ShmSegmentsWriter&& aOther) noexcept
: mSmallAllocs(std::move(aOther.mSmallAllocs))
, mLargeAllocs(std::move(aOther.mLargeAllocs))
, mShmAllocator(aOther.mShmAllocator)
, mCursor(aOther.mCursor)
, mChunkSize(aOther.mChunkSize)
{
aOther.mCursor = 0;
}
ShmSegmentsWriter&
ShmSegmentsWriter::operator=(ShmSegmentsWriter&& aOther) noexcept
{
MOZ_ASSERT(IsEmpty(), "Will forget existing updates!");
Clear();
mSmallAllocs = std::move(aOther.mSmallAllocs);
mLargeAllocs = std::move(aOther.mLargeAllocs);
mShmAllocator = aOther.mShmAllocator;
mCursor = aOther.mCursor;
mChunkSize = aOther.mChunkSize;
aOther.mCursor = 0;
return *this;
}
layers::OffsetRange layers::OffsetRange
ShmSegmentsWriter::Write(Range<uint8_t> aBytes) ShmSegmentsWriter::Write(Range<uint8_t> aBytes)
{ {
@@ -246,9 +270,23 @@ ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aIn
IpcResourceUpdateQueue::IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, IpcResourceUpdateQueue::IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
size_t aChunkSize) size_t aChunkSize)
: mWriter(std::move(aAllocator), aChunkSize) : mWriter(aAllocator, aChunkSize)
{} {}
IpcResourceUpdateQueue::IpcResourceUpdateQueue(IpcResourceUpdateQueue&& aOther) noexcept
: mWriter(std::move(aOther.mWriter))
, mUpdates(std::move(aOther.mUpdates))
{ }
IpcResourceUpdateQueue&
IpcResourceUpdateQueue::operator=(IpcResourceUpdateQueue&& aOther) noexcept
{
MOZ_ASSERT(IsEmpty(), "Will forget existing updates!");
mWriter = std::move(aOther.mWriter);
mUpdates = std::move(aOther.mUpdates);
return *this;
}
bool bool
IpcResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor, IpcResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes) Range<uint8_t> aBytes)

View File

@@ -24,6 +24,12 @@ public:
ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize); ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize);
~ShmSegmentsWriter(); ~ShmSegmentsWriter();
ShmSegmentsWriter(ShmSegmentsWriter&& aOther) noexcept;
ShmSegmentsWriter& operator=(ShmSegmentsWriter&& aOther) noexcept;
ShmSegmentsWriter(const ShmSegmentsWriter& aOther) = delete;
ShmSegmentsWriter& operator=(const ShmSegmentsWriter& aOther) = delete;
layers::OffsetRange Write(Range<uint8_t> aBytes); layers::OffsetRange Write(Range<uint8_t> aBytes);
template<typename T> template<typename T>
@@ -32,7 +38,7 @@ public:
return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(), aValues.length() * sizeof(T))); return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(), aValues.length() * sizeof(T)));
} }
void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs); void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs, nsTArray<mozilla::ipc::Shmem>& aLargeAllocs);
void Clear(); void Clear();
bool IsEmpty() const; bool IsEmpty() const;
@@ -44,7 +50,7 @@ protected:
layers::OffsetRange AllocLargeChunk(size_t aSize); layers::OffsetRange AllocLargeChunk(size_t aSize);
nsTArray<layers::RefCountedShmem> mSmallAllocs; nsTArray<layers::RefCountedShmem> mSmallAllocs;
nsTArray<ipc::Shmem> mLargeAllocs; nsTArray<mozilla::ipc::Shmem> mLargeAllocs;
layers::WebRenderBridgeChild* mShmAllocator; layers::WebRenderBridgeChild* mShmAllocator;
size_t mCursor; size_t mCursor;
size_t mChunkSize; size_t mChunkSize;
@@ -53,7 +59,7 @@ protected:
class ShmSegmentsReader { class ShmSegmentsReader {
public: public:
ShmSegmentsReader(const nsTArray<layers::RefCountedShmem>& aSmallShmems, ShmSegmentsReader(const nsTArray<layers::RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems); const nsTArray<mozilla::ipc::Shmem>& aLargeShmems);
bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto); bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
@@ -61,7 +67,7 @@ protected:
bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto); bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
const nsTArray<layers::RefCountedShmem>& mSmallAllocs; const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
const nsTArray<ipc::Shmem>& mLargeAllocs; const nsTArray<mozilla::ipc::Shmem>& mLargeAllocs;
size_t mChunkSize; size_t mChunkSize;
}; };
@@ -75,6 +81,12 @@ public:
// So we pick 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size. // So we pick 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size.
explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize = 57328); explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize = 57328);
IpcResourceUpdateQueue(IpcResourceUpdateQueue&& aOther) noexcept;
IpcResourceUpdateQueue& operator=(IpcResourceUpdateQueue&& aOther) noexcept;
IpcResourceUpdateQueue(const IpcResourceUpdateQueue& aOther) = delete;
IpcResourceUpdateQueue& operator=(const IpcResourceUpdateQueue& aOther) = delete;
bool AddImage(wr::ImageKey aKey, bool AddImage(wr::ImageKey aKey,
const ImageDescriptor& aDescriptor, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes); Range<uint8_t> aBytes);
@@ -126,12 +138,12 @@ public:
void Flush(nsTArray<layers::OpUpdateResource>& aUpdates, void Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
nsTArray<layers::RefCountedShmem>& aSmallAllocs, nsTArray<layers::RefCountedShmem>& aSmallAllocs,
nsTArray<ipc::Shmem>& aLargeAllocs); nsTArray<mozilla::ipc::Shmem>& aLargeAllocs);
bool IsEmpty() const; bool IsEmpty() const;
static void ReleaseShmems(ipc::IProtocol*, nsTArray<layers::RefCountedShmem>& aShmems); static void ReleaseShmems(mozilla::ipc::IProtocol*, nsTArray<layers::RefCountedShmem>& aShms);
static void ReleaseShmems(ipc::IProtocol*, nsTArray<ipc::Shmem>& aShmems); static void ReleaseShmems(mozilla::ipc::IProtocol*, nsTArray<mozilla::ipc::Shmem>& aShms);
protected: protected:
ShmSegmentsWriter mWriter; ShmSegmentsWriter mWriter;
nsTArray<layers::OpUpdateResource> mUpdates; nsTArray<layers::OpUpdateResource> mUpdates;

View File

@@ -96,7 +96,8 @@ WebRenderBridgeChild::BeginTransaction()
} }
void void
WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources) WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources,
bool aScheduleComposite /* = false */)
{ {
if (!IPCOpen()) { if (!IPCOpen()) {
aResources.Clear(); aResources.Clear();
@@ -112,7 +113,8 @@ WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources)
nsTArray<ipc::Shmem> largeShmems; nsTArray<ipc::Shmem> largeShmems;
aResources.Flush(resourceUpdates, smallShmems, largeShmems); aResources.Flush(resourceUpdates, smallShmems, largeShmems);
this->SendUpdateResources(resourceUpdates, std::move(smallShmems), largeShmems); this->SendUpdateResources(resourceUpdates, smallShmems,
largeShmems, aScheduleComposite);
} }
void void
@@ -146,7 +148,7 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors, this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId, GetFwdTransactionId(), aTransactionId,
aContentSize, dlData, aDL.dl_desc, aScrollData, aContentSize, dlData, aDL.dl_desc, aScrollData,
std::move(resourceUpdates), std::move(smallShmems), largeShmems, resourceUpdates, smallShmems, largeShmems,
mIdNamespace, aContainsSVGGroup, aRefreshStartTime, aTxnStartTime, fwdTime); mIdNamespace, aContainsSVGGroup, aRefreshStartTime, aTxnStartTime, fwdTime);
mParentCommands.Clear(); mParentCommands.Clear();
@@ -157,6 +159,7 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
void void
WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget, WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
const ScrollUpdatesMap& aUpdates, const ScrollUpdatesMap& aUpdates,
Maybe<wr::IpcResourceUpdateQueue>& aResources,
uint32_t aPaintSequenceNumber, uint32_t aPaintSequenceNumber,
TransactionId aTransactionId, TransactionId aTransactionId,
const mozilla::TimeStamp& aRefreshStartTime, const mozilla::TimeStamp& aRefreshStartTime,
@@ -170,9 +173,18 @@ WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
fwdTime = TimeStamp::Now(); fwdTime = TimeStamp::Now();
#endif #endif
nsTArray<OpUpdateResource> resourceUpdates;
nsTArray<RefCountedShmem> smallShmems;
nsTArray<ipc::Shmem> largeShmems;
if (aResources) {
aResources->Flush(resourceUpdates, smallShmems, largeShmems);
aResources.reset();
}
this->SendEmptyTransaction(aFocusTarget, aUpdates, aPaintSequenceNumber, this->SendEmptyTransaction(aFocusTarget, aUpdates, aPaintSequenceNumber,
mParentCommands, mDestroyedActors, mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId, GetFwdTransactionId(), aTransactionId,
resourceUpdates, smallShmems, largeShmems,
mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime); mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime);
mParentCommands.Clear(); mParentCommands.Clear();
mDestroyedActors.Clear(); mDestroyedActors.Clear();

View File

@@ -66,7 +66,8 @@ public:
void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd); void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
void UpdateResources(wr::IpcResourceUpdateQueue& aResources); void UpdateResources(wr::IpcResourceUpdateQueue& aResources,
bool aScheduleComposite = false);
void BeginTransaction(); void BeginTransaction();
void EndTransaction(const wr::LayoutSize& aContentSize, void EndTransaction(const wr::LayoutSize& aContentSize,
wr::BuiltDisplayList& dl, wr::BuiltDisplayList& dl,
@@ -79,6 +80,7 @@ public:
const mozilla::TimeStamp& aTxnStartTime); const mozilla::TimeStamp& aTxnStartTime);
void EndEmptyTransaction(const FocusTarget& aFocusTarget, void EndEmptyTransaction(const FocusTarget& aFocusTarget,
const ScrollUpdatesMap& aUpdates, const ScrollUpdatesMap& aUpdates,
Maybe<wr::IpcResourceUpdateQueue>& aResources,
uint32_t aPaintSequenceNumber, uint32_t aPaintSequenceNumber,
TransactionId aTransactionId, TransactionId aTransactionId,
const mozilla::TimeStamp& aRefreshStartTime, const mozilla::TimeStamp& aRefreshStartTime,

View File

@@ -624,25 +624,34 @@ WebRenderBridgeParent::UpdateExternalImage(wr::ExternalImageId aExtId,
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvUpdateResources(nsTArray<OpUpdateResource>&& aResourceUpdates, WebRenderBridgeParent::RecvUpdateResources(nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<RefCountedShmem>&& aSmallShmems, nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems) nsTArray<ipc::Shmem>&& aLargeShmems,
const bool& aScheduleComposite)
{ {
if (mDestroyed) { if (mDestroyed) {
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
return IPC_OK(); return IPC_OK();
} }
wr::TransactionBuilder txn; wr::TransactionBuilder txn;
txn.SetLowPriority(!IsRootWebRenderBridgeParent()); txn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (!UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems, txn)) { bool success =
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems); UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems, txn);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems); wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
IPC_FAIL(this, "Invalid WebRender resource data shmem or address."); wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
if (!success) {
return IPC_FAIL(this, "Invalid WebRender resource data shmem or address.");
}
if (aScheduleComposite) {
txn.InvalidateRenderedFrame();
ScheduleGenerateFrame();
} }
mApi->SendTransaction(txn); mApi->SendTransaction(txn);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
return IPC_OK(); return IPC_OK();
} }
@@ -910,6 +919,9 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
InfallibleTArray<OpDestroy>&& aToDestroy, InfallibleTArray<OpDestroy>&& aToDestroy,
const uint64_t& aFwdTransactionId, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const TransactionId& aTransactionId,
nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems,
const wr::IdNamespace& aIdNamespace, const wr::IdNamespace& aIdNamespace,
const TimeStamp& aRefreshStartTime, const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime, const TimeStamp& aTxnStartTime,
@@ -941,10 +953,18 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
scheduleComposite = true; scheduleComposite = true;
} }
wr::TransactionBuilder txn;
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (!aResourceUpdates.IsEmpty()) {
scheduleComposite = true;
}
if (!UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems, txn)) {
return IPC_FAIL(this, "Failed to deserialize resource updates");
}
if (!aCommands.IsEmpty()) { if (!aCommands.IsEmpty()) {
mAsyncImageManager->SetCompositionTime(TimeStamp::Now()); mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
wr::TransactionBuilder txn;
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
wr::Epoch wrEpoch = GetNextWrEpoch(); wr::Epoch wrEpoch = GetNextWrEpoch();
txn.UpdateEpoch(mPipelineId, wrEpoch); txn.UpdateEpoch(mPipelineId, wrEpoch);
if (!ProcessWebRenderParentCommands(aCommands, txn)) { if (!ProcessWebRenderParentCommands(aCommands, txn)) {
@@ -962,10 +982,13 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
); );
} }
mApi->SendTransaction(txn);
scheduleComposite = true; scheduleComposite = true;
} }
if (!txn.IsEmpty()) {
mApi->SendTransaction(txn);
}
bool sendDidComposite = true; bool sendDidComposite = true;
if (scheduleComposite || !mPendingTransactionIds.empty()) { if (scheduleComposite || !mPendingTransactionIds.empty()) {
// If we are going to kick off a new composite as a result of this // If we are going to kick off a new composite as a result of this
@@ -1001,6 +1024,8 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
} }
} }
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
return IPC_OK(); return IPC_OK();
} }

View File

@@ -78,7 +78,8 @@ public:
mozilla::ipc::IPCResult RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds) override; mozilla::ipc::IPCResult RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds) override;
mozilla::ipc::IPCResult RecvUpdateResources(nsTArray<OpUpdateResource>&& aUpdates, mozilla::ipc::IPCResult RecvUpdateResources(nsTArray<OpUpdateResource>&& aUpdates,
nsTArray<RefCountedShmem>&& aSmallShmems, nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems) override; nsTArray<ipc::Shmem>&& aLargeShmems,
const bool& aScheduleComposite) override;
mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize, mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize,
InfallibleTArray<WebRenderParentCommand>&& aCommands, InfallibleTArray<WebRenderParentCommand>&& aCommands,
InfallibleTArray<OpDestroy>&& aToDestroy, InfallibleTArray<OpDestroy>&& aToDestroy,
@@ -103,6 +104,9 @@ public:
InfallibleTArray<OpDestroy>&& aToDestroy, InfallibleTArray<OpDestroy>&& aToDestroy,
const uint64_t& aFwdTransactionId, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const TransactionId& aTransactionId,
nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems,
const wr::IdNamespace& aIdNamespace, const wr::IdNamespace& aIdNamespace,
const TimeStamp& aRefreshStartTime, const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime, const TimeStamp& aTxnStartTime,

View File

@@ -14,7 +14,6 @@
#include "mozilla/dom/TabGroup.h" #include "mozilla/dom/TabGroup.h"
#include "mozilla/gfx/DrawEventRecorder.h" #include "mozilla/gfx/DrawEventRecorder.h"
#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClient.h" #include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/WebRenderBridgeChild.h" #include "mozilla/layers/WebRenderBridgeChild.h"
@@ -248,7 +247,8 @@ WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
} }
WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates, WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates,
mPaintSequenceNumber, mLatestTransactionId, refreshStart, mTransactionStart); mAsyncResourceUpdates, mPaintSequenceNumber, mLatestTransactionId,
refreshStart, mTransactionStart);
ClearPendingScrollInfoUpdate(); ClearPendingScrollInfoUpdate();
mTransactionStart = TimeStamp(); mTransactionStart = TimeStamp();
@@ -343,6 +343,19 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true); mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart(); 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) { for (const auto& key : mImageKeysToDelete) {
resourceUpdates.DeleteImage(key); resourceUpdates.DeleteImage(key);
} }
@@ -706,5 +719,39 @@ WebRenderLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
return LayerManager::CreatePersistentBufferProvider(aSize, aFormat); 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 layers
} // namespace mozilla } // namespace mozilla

View File

@@ -12,9 +12,11 @@
#include "gfxPrefs.h" #include "gfxPrefs.h"
#include "Layers.h" #include "Layers.h"
#include "mozilla/Maybe.h"
#include "mozilla/MozPromise.h" #include "mozilla/MozPromise.h"
#include "mozilla/layers/APZTestData.h" #include "mozilla/layers/APZTestData.h"
#include "mozilla/layers/FocusTarget.h" #include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TransactionIdAllocator.h" #include "mozilla/layers/TransactionIdAllocator.h"
#include "mozilla/layers/WebRenderCommandBuilder.h" #include "mozilla/layers/WebRenderCommandBuilder.h"
@@ -133,6 +135,9 @@ public:
void DiscardImages(); void DiscardImages();
void DiscardLocalImages(); void DiscardLocalImages();
wr::IpcResourceUpdateQueue& AsyncResourceUpdates();
void FlushAsyncResourceUpdates();
// Methods to manage the compositor animation ids. Active animations are still // Methods to manage the compositor animation ids. Active animations are still
// going, and when they end we discard them and remove them from the active // going, and when they end we discard them and remove them from the active
// list. // list.
@@ -219,6 +224,8 @@ private:
WebRenderCommandBuilder mWebRenderCommandBuilder; WebRenderCommandBuilder mWebRenderCommandBuilder;
size_t mLastDisplayListSize; size_t mLastDisplayListSize;
Maybe<wr::IpcResourceUpdateQueue> mAsyncResourceUpdates;
}; };
} // namespace layers } // namespace layers