From aa78fbc550d8433618ed678911e02672bb43f316 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Fri, 12 Jan 2018 15:11:28 +0100 Subject: [PATCH] Bug 1405824 - Use WebRenderBridgeChild instead of IShmemAllocator in IpcResourceUpdateQueue. r=jrmuizel --- gfx/layers/ipc/PWebRenderBridge.ipdl | 4 +-- gfx/layers/wr/IpcResourceUpdateQueue.cpp | 36 +++++++++++++----------- gfx/layers/wr/IpcResourceUpdateQueue.h | 17 +++++------ gfx/layers/wr/WebRenderBridgeChild.cpp | 10 +++---- gfx/layers/wr/WebRenderBridgeParent.cpp | 17 +++++++++-- gfx/layers/wr/WebRenderBridgeParent.h | 7 +++-- gfx/layers/wr/WebRenderLayerManager.cpp | 4 +-- 7 files changed, 55 insertions(+), 40 deletions(-) diff --git a/gfx/layers/ipc/PWebRenderBridge.ipdl b/gfx/layers/ipc/PWebRenderBridge.ipdl index 3e1b8eb17775..a2cc37197640 100644 --- a/gfx/layers/ipc/PWebRenderBridge.ipdl +++ b/gfx/layers/ipc/PWebRenderBridge.ipdl @@ -52,13 +52,13 @@ parent: async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId, LayoutSize aContentSize, ByteBuf aDL, BuiltDisplayListDescriptor aDLDesc, WebRenderScrollData aScrollData, - OpUpdateResource[] aResourceUpdates, Shmem[] aSmallShmems, Shmem[] aLargeShmems, + OpUpdateResource[] aResourceUpdates, RefCountedShmem[] 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 UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems); async ParentCommands(WebRenderParentCommand[] commands); sync GetSnapshot(PTexture texture); async AddPipelineIdForCompositable(PipelineId aImageId, CompositableHandle aHandle, bool aAsync); diff --git a/gfx/layers/wr/IpcResourceUpdateQueue.cpp b/gfx/layers/wr/IpcResourceUpdateQueue.cpp index 375b530b3f6e..e856437828ce 100644 --- a/gfx/layers/wr/IpcResourceUpdateQueue.cpp +++ b/gfx/layers/wr/IpcResourceUpdateQueue.cpp @@ -9,11 +9,14 @@ #include #include "mozilla/Maybe.h" #include "mozilla/ipc/SharedMemory.h" +#include "mozilla/layers/WebRenderBridgeChild.h" namespace mozilla { namespace wr { -ShmSegmentsWriter::ShmSegmentsWriter(ipc::IShmemAllocator* aAllocator, size_t aChunkSize) +using namespace mozilla::layers; + +ShmSegmentsWriter::ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize) : mShmAllocator(aAllocator) , mCursor(0) , mChunkSize(aChunkSize) @@ -49,8 +52,8 @@ ShmSegmentsWriter::Write(Range aBytes) if (dstCursor >= mSmallAllocs.Length() * mChunkSize) { if (!AllocChunk()) { for (size_t i = mSmallAllocs.Length() ; currAllocLen < i ; i--) { - ipc::Shmem shm = mSmallAllocs.ElementAt(i); - mShmAllocator->DeallocShmem(shm); + RefCountedShmem& shm = mSmallAllocs.ElementAt(i); + RefCountedShm::Dealloc(mShmAllocator, shm); mSmallAllocs.RemoveElementAt(i); } return layers::OffsetRange(0, start, 0); @@ -68,7 +71,7 @@ ShmSegmentsWriter::Write(Range aBytes) size_t copyRange = std::min(availableRange, remainingBytesToCopy); uint8_t* srcPtr = &aBytes[srcCursor]; - uint8_t* dstPtr = mSmallAllocs.LastElement().get() + (dstCursor - dstBaseOffset); + uint8_t* dstPtr = RefCountedShm::GetBytes(mSmallAllocs.LastElement()) + (dstCursor - dstBaseOffset); memcpy(dstPtr, srcPtr, copyRange); @@ -88,9 +91,8 @@ ShmSegmentsWriter::Write(Range aBytes) bool ShmSegmentsWriter::AllocChunk() { - ipc::Shmem shm; - auto shmType = ipc::SharedMemory::SharedMemoryType::TYPE_BASIC; - if (!mShmAllocator->AllocShmem(mChunkSize, shmType, &shm)) { + RefCountedShmem shm; + if (!RefCountedShm::Alloc(mShmAllocator, mChunkSize, shm)) { gfxCriticalNote << "ShmSegmentsWriter failed to allocate chunk #" << mSmallAllocs.Length(); MOZ_ASSERT(false, "ShmSegmentsWriter fails to allocate chunk"); return false; @@ -115,7 +117,7 @@ ShmSegmentsWriter::AllocLargeChunk(size_t aSize) } void -ShmSegmentsWriter::Flush(nsTArray& aSmallAllocs, nsTArray& aLargeAllocs) +ShmSegmentsWriter::Flush(nsTArray& aSmallAllocs, nsTArray& aLargeAllocs) { aSmallAllocs.Clear(); aLargeAllocs.Clear(); @@ -128,7 +130,7 @@ ShmSegmentsWriter::Clear() { if (mShmAllocator) { for (auto& shm : mSmallAllocs) { - mShmAllocator->DeallocShmem(shm); + RefCountedShm::Dealloc(mShmAllocator, shm); } for (auto& shm : mLargeAllocs) { mShmAllocator->DeallocShmem(shm); @@ -139,7 +141,7 @@ ShmSegmentsWriter::Clear() mCursor = 0; } -ShmSegmentsReader::ShmSegmentsReader(const nsTArray& aSmallShmems, +ShmSegmentsReader::ShmSegmentsReader(const nsTArray& aSmallShmems, const nsTArray& aLargeShmems) : mSmallAllocs(aSmallShmems) , mLargeAllocs(aLargeShmems) @@ -149,15 +151,15 @@ ShmSegmentsReader::ShmSegmentsReader(const nsTArray& aSmallShmems, return; } - mChunkSize = mSmallAllocs[0].Size(); + mChunkSize = RefCountedShm::GetSize(mSmallAllocs[0]); // Check that all shmems are readable and have the same size. If anything // isn't right, set mChunkSize to zero which signifies that the reader is // in an invalid state and Read calls will return false; for (const auto& shm : mSmallAllocs) { - if (!shm.IsReadable() - || shm.Size() != mChunkSize - || shm.get() == nullptr) { + if (!RefCountedShm::IsValid(shm) + || RefCountedShm::GetSize(shm) != mChunkSize + || RefCountedShm::GetBytes(shm) == nullptr) { mChunkSize = 0; return; } @@ -219,7 +221,7 @@ ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec& aIn const size_t shm_idx = srcCursor / mChunkSize; const size_t ptrOffset = srcCursor % mChunkSize; const size_t copyRange = std::min(remainingBytesToCopy, mChunkSize - ptrOffset); - uint8_t* srcPtr = mSmallAllocs[shm_idx].get() + ptrOffset; + uint8_t* srcPtr = RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset; aInto.PushBytes(Range(srcPtr, copyRange)); @@ -230,7 +232,7 @@ ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec& aIn return aInto.Length() - initialLength == aRange.length(); } -IpcResourceUpdateQueue::IpcResourceUpdateQueue(ipc::IShmemAllocator* aAllocator, +IpcResourceUpdateQueue::IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize) : mWriter(Move(aAllocator), aChunkSize) {} @@ -352,7 +354,7 @@ IpcResourceUpdateQueue::DeleteFontInstance(wr::FontInstanceKey aKey) void IpcResourceUpdateQueue::Flush(nsTArray& aUpdates, - nsTArray& aSmallAllocs, + nsTArray& aSmallAllocs, nsTArray& aLargeAllocs) { aUpdates.Clear(); diff --git a/gfx/layers/wr/IpcResourceUpdateQueue.h b/gfx/layers/wr/IpcResourceUpdateQueue.h index 3042ac09f63c..9e2ec4591977 100644 --- a/gfx/layers/wr/IpcResourceUpdateQueue.h +++ b/gfx/layers/wr/IpcResourceUpdateQueue.h @@ -8,6 +8,7 @@ #define GFX_WR_IPCRESOURCEUPDATEQUEUE_H #include "mozilla/layers/WebRenderMessages.h" +#include "mozilla/layers/RefCountedShmem.h" #include "mozilla/webrender/WebRenderTypes.h" namespace mozilla { @@ -20,7 +21,7 @@ namespace wr { /// allocations and creates dedicated shmems for large allocations. class ShmSegmentsWriter { public: - ShmSegmentsWriter(ipc::IShmemAllocator* aAllocator, size_t aChunkSize); + ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize); ~ShmSegmentsWriter(); layers::OffsetRange Write(Range aBytes); @@ -31,7 +32,7 @@ public: return Write(Range((uint8_t*)aValues.begin().get(), aValues.length() * sizeof(T))); } - void Flush(nsTArray& aSmallAllocs, nsTArray& aLargeAllocs); + void Flush(nsTArray& aSmallAllocs, nsTArray& aLargeAllocs); void Clear(); @@ -39,16 +40,16 @@ protected: bool AllocChunk(); layers::OffsetRange AllocLargeChunk(size_t aSize); - nsTArray mSmallAllocs; + nsTArray mSmallAllocs; nsTArray mLargeAllocs; - ipc::IShmemAllocator* mShmAllocator; + layers::WebRenderBridgeChild* mShmAllocator; size_t mCursor; size_t mChunkSize; }; class ShmSegmentsReader { public: - ShmSegmentsReader(const nsTArray& aSmallShmems, + ShmSegmentsReader(const nsTArray& aSmallShmems, const nsTArray& aLargeShmems); bool Read(const layers::OffsetRange& aRange, wr::Vec& aInto); @@ -56,7 +57,7 @@ public: protected: bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec& aInto); - const nsTArray& mSmallAllocs; + const nsTArray& mSmallAllocs; const nsTArray& mLargeAllocs; size_t mChunkSize; }; @@ -67,7 +68,7 @@ public: // Each shmem has two guard pages, and the minimum shmem size (at least one Windows) // is 64k which is already quite large for a lot of the resources we use here. // So we pick 64k - 2 * 4k = 57344 bytes as the defautl alloc - explicit IpcResourceUpdateQueue(ipc::IShmemAllocator* aAllocator, size_t aChunkSize = 57344); + explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize = 57344); bool AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, @@ -114,7 +115,7 @@ public: void Clear(); void Flush(nsTArray& aUpdates, - nsTArray& aSmallAllocs, + nsTArray& aSmallAllocs, nsTArray& aLargeAllocs); protected: diff --git a/gfx/layers/wr/WebRenderBridgeChild.cpp b/gfx/layers/wr/WebRenderBridgeChild.cpp index 9e31259edb09..ca61fa7a5310 100644 --- a/gfx/layers/wr/WebRenderBridgeChild.cpp +++ b/gfx/layers/wr/WebRenderBridgeChild.cpp @@ -125,7 +125,7 @@ WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources) } nsTArray resourceUpdates; - nsTArray smallShmems; + nsTArray smallShmems; nsTArray largeShmems; aResources.Flush(resourceUpdates, smallShmems, largeShmems); @@ -154,7 +154,7 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize, #endif nsTArray resourceUpdates; - nsTArray smallShmems; + nsTArray smallShmems; nsTArray largeShmems; aResources.Flush(resourceUpdates, smallShmems, largeShmems); @@ -321,7 +321,7 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont) return instanceKey; } - wr::IpcResourceUpdateQueue resources(GetShmemAllocator()); + wr::IpcResourceUpdateQueue resources(this); wr::FontKey fontKey = GetFontKeyForUnscaledFont(aScaledFont->GetUnscaledFont()); wr::FontKey nullKey = { wr::IdNamespace { 0 }, 0}; @@ -354,7 +354,7 @@ WebRenderBridgeChild::GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaled) wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0}; if (!mFontKeys.Get(aUnscaled, &fontKey)) { - wr::IpcResourceUpdateQueue resources(GetShmemAllocator()); + wr::IpcResourceUpdateQueue resources(this); FontFileDataSink sink = { &fontKey, this, &resources }; // First try to retrieve a descriptor for the font, as this is much cheaper // to send over IPC than the full raw font data. If this is not possible, then @@ -376,7 +376,7 @@ void WebRenderBridgeChild::RemoveExpiredFontKeys() { uint32_t counter = gfx::ScaledFont::DeletionCounter(); - wr::IpcResourceUpdateQueue resources(GetShmemAllocator()); + wr::IpcResourceUpdateQueue resources(this); if (mFontInstanceKeysDeleted != counter) { mFontInstanceKeysDeleted = counter; for (auto iter = mFontInstanceKeys.Iter(); !iter.Done(); iter.Next()) { diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 1caee6b84f96..889384bc2e28 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -277,9 +277,20 @@ WebRenderBridgeParent::DeallocShmems(nsTArray& aShmems) aShmems.Clear(); } +void +WebRenderBridgeParent::DeallocShmems(nsTArray& aShmems) +{ + if (IPCOpen()) { + for (auto& shm : aShmems) { + RefCountedShm::Dealloc(this, shm); + } + } + aShmems.Clear(); +} + bool WebRenderBridgeParent::UpdateResources(const nsTArray& aResourceUpdates, - const nsTArray& aSmallShmems, + const nsTArray& aSmallShmems, const nsTArray& aLargeShmems, wr::ResourceUpdateQueue& aUpdates) { @@ -450,7 +461,7 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey mozilla::ipc::IPCResult WebRenderBridgeParent::RecvUpdateResources(nsTArray&& aResourceUpdates, - nsTArray&& aSmallShmems, + nsTArray&& aSmallShmems, nsTArray&& aLargeShmems) { if (mDestroyed) { @@ -580,7 +591,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize, const wr::BuiltDisplayListDescriptor& dlDesc, const WebRenderScrollData& aScrollData, nsTArray&& aResourceUpdates, - nsTArray&& aSmallShmems, + nsTArray&& aSmallShmems, nsTArray&& aLargeShmems, const wr::IdNamespace& aIdNamespace, const TimeStamp& aTxnStartTime, diff --git a/gfx/layers/wr/WebRenderBridgeParent.h b/gfx/layers/wr/WebRenderBridgeParent.h index fd845e00dc15..9b15878f8f5f 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.h +++ b/gfx/layers/wr/WebRenderBridgeParent.h @@ -74,7 +74,7 @@ public: mozilla::ipc::IPCResult RecvShutdownSync() override; mozilla::ipc::IPCResult RecvDeleteCompositorAnimations(InfallibleTArray&& aIds) override; mozilla::ipc::IPCResult RecvUpdateResources(nsTArray&& aUpdates, - nsTArray&& aSmallShmems, + nsTArray&& aSmallShmems, nsTArray&& aLargeShmems) override; mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize, InfallibleTArray&& aCommands, @@ -86,7 +86,7 @@ public: const wr::BuiltDisplayListDescriptor& dlDesc, const WebRenderScrollData& aScrollData, nsTArray&& aResourceUpdates, - nsTArray&& aSmallShmems, + nsTArray&& aSmallShmems, nsTArray&& aLargeShmems, const wr::IdNamespace& aIdNamespace, const TimeStamp& aTxnStartTime, @@ -193,12 +193,13 @@ public: private: void DeallocShmems(nsTArray& aShmems); + void DeallocShmems(nsTArray& aShmems); explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId); virtual ~WebRenderBridgeParent(); bool UpdateResources(const nsTArray& aResourceUpdates, - const nsTArray& aSmallShmems, + const nsTArray& aSmallShmems, const nsTArray& aLargeShmems, wr::ResourceUpdateQueue& aUpdates); bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey, diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 92cf9a372eb0..1f3fea2f1c0c 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -267,7 +267,7 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList, LayoutDeviceIntSize size = mWidget->GetClientSize(); wr::LayoutSize contentSize { (float)size.width, (float)size.height }; wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize, mLastDisplayListSize); - wr::IpcResourceUpdateQueue resourceUpdates(WrBridge()->GetShmemAllocator()); + wr::IpcResourceUpdateQueue resourceUpdates(WrBridge()); mWebRenderCommandBuilder.BuildWebRenderCommands(builder, resourceUpdates, @@ -413,7 +413,7 @@ WebRenderLayerManager::AddImageKeyForDiscard(wr::ImageKey key) void WebRenderLayerManager::DiscardImages() { - wr::IpcResourceUpdateQueue resources(WrBridge()->GetShmemAllocator()); + wr::IpcResourceUpdateQueue resources(WrBridge()); for (const auto& key : mImageKeysToDeleteLater) { resources.DeleteImage(key); }