Bug 1405824 - Use WebRenderBridgeChild instead of IShmemAllocator in IpcResourceUpdateQueue. r=jrmuizel
authorNicolas Silva <nsilva@mozilla.com>
Fri, 12 Jan 2018 15:11:28 +0100
changeset 453328 62401d22f92a45c4a50040424b77915fdea687bc
parent 453327 35b2ebc973dce92142f03c78bbae268a71ec3989
child 453329 8c8d66d7b4640ad3d1031221e60b1eb43666e68a
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1405824
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1405824 - Use WebRenderBridgeChild instead of IShmemAllocator in IpcResourceUpdateQueue. r=jrmuizel
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/wr/IpcResourceUpdateQueue.cpp
gfx/layers/wr/IpcResourceUpdateQueue.h
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderLayerManager.cpp
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -47,23 +47,23 @@ parent:
   // next Update call.
   async InitReadLocks(ReadLockInit[] locks);
 
   sync Create(IntSize aSize);
   async DeleteCompositorAnimations(uint64_t[] aIds);
   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);
   async RemovePipelineIdForCompositable(PipelineId aPipelineId);
   async AddExternalImageIdForCompositable(ExternalImageId aImageId, CompositableHandle aHandle);
   async RemoveExternalImageId(ExternalImageId aImageId);
   async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
   async ClearCachedResources();
--- a/gfx/layers/wr/IpcResourceUpdateQueue.cpp
+++ b/gfx/layers/wr/IpcResourceUpdateQueue.cpp
@@ -4,21 +4,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "IpcResourceUpdateQueue.h"
 #include <string.h>
 #include <algorithm>
 #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)
 {
   MOZ_ASSERT(mShmAllocator);
 }
 
 ShmSegmentsWriter::~ShmSegmentsWriter()
@@ -44,18 +47,18 @@ ShmSegmentsWriter::Write(Range<uint8_t> 
   size_t srcCursor = 0;
   size_t dstCursor = mCursor;
   size_t currAllocLen = mSmallAllocs.Length();
 
   while (remainingBytesToCopy > 0) {
     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);
       }
       continue;
     }
 
     const size_t dstMaxOffset = mChunkSize * mSmallAllocs.Length();
@@ -63,17 +66,17 @@ ShmSegmentsWriter::Write(Range<uint8_t> 
 
     MOZ_ASSERT(dstCursor >= dstBaseOffset);
     MOZ_ASSERT(dstCursor <= dstMaxOffset);
 
     size_t availableRange = dstMaxOffset - dstCursor;
     size_t copyRange = std::min<int>(availableRange, remainingBytesToCopy);
 
     uint8_t* srcPtr = &aBytes[srcCursor];
-    uint8_t* dstPtr = mSmallAllocs.LastElement().get<uint8_t>() + (dstCursor - dstBaseOffset);
+    uint8_t* dstPtr = RefCountedShm::GetBytes(mSmallAllocs.LastElement()) + (dstCursor - dstBaseOffset);
 
     memcpy(dstPtr, srcPtr, copyRange);
 
     srcCursor += copyRange;
     dstCursor += copyRange;
     remainingBytesToCopy -= copyRange;
 
     // sanity check
@@ -83,19 +86,18 @@ ShmSegmentsWriter::Write(Range<uint8_t> 
   mCursor += length;
 
   return layers::OffsetRange(0, start, length);
 }
 
 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;
   }
   mSmallAllocs.AppendElement(shm);
   return true;
 }
 
@@ -110,59 +112,59 @@ ShmSegmentsWriter::AllocLargeChunk(size_
     return layers::OffsetRange(0, 0, 0);
   }
   mLargeAllocs.AppendElement(shm);
 
   return layers::OffsetRange(mLargeAllocs.Length(), 0, aSize);
 }
 
 void
-ShmSegmentsWriter::Flush(nsTArray<ipc::Shmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs)
+ShmSegmentsWriter::Flush(nsTArray<RefCountedShmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs)
 {
   aSmallAllocs.Clear();
   aLargeAllocs.Clear();
   mSmallAllocs.SwapElements(aSmallAllocs);
   mLargeAllocs.SwapElements(aLargeAllocs);
 }
 
 void
 ShmSegmentsWriter::Clear()
 {
   if (mShmAllocator) {
     for (auto& shm : mSmallAllocs) {
-      mShmAllocator->DeallocShmem(shm);
+      RefCountedShm::Dealloc(mShmAllocator, shm);
     }
     for (auto& shm : mLargeAllocs) {
       mShmAllocator->DeallocShmem(shm);
     }
   }
   mSmallAllocs.Clear();
   mLargeAllocs.Clear();
   mCursor = 0;
 }
 
-ShmSegmentsReader::ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
+ShmSegmentsReader::ShmSegmentsReader(const nsTArray<RefCountedShmem>& aSmallShmems,
                                      const nsTArray<ipc::Shmem>& aLargeShmems)
 : mSmallAllocs(aSmallShmems)
 , mLargeAllocs(aLargeShmems)
 , mChunkSize(0)
 {
   if (mSmallAllocs.IsEmpty()) {
     return;
   }
 
-  mChunkSize = mSmallAllocs[0].Size<uint8_t>();
+  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<uint8_t>() != mChunkSize
-        || shm.get<uint8_t>() == nullptr) {
+    if (!RefCountedShm::IsValid(shm)
+        || RefCountedShm::GetSize(shm) != mChunkSize
+        || RefCountedShm::GetBytes(shm) == nullptr) {
       mChunkSize = 0;
       return;
     }
   }
 
   for (const auto& shm : mLargeAllocs) {
     if (!shm.IsReadable()
         || shm.get<uint8_t>() == nullptr) {
@@ -214,28 +216,28 @@ ShmSegmentsReader::Read(const layers::Of
   size_t initialLength = aInto.Length();
 
   size_t srcCursor = aRange.start();
   int remainingBytesToCopy = aRange.length();
   while (remainingBytesToCopy > 0) {
     const size_t shm_idx = srcCursor / mChunkSize;
     const size_t ptrOffset = srcCursor % mChunkSize;
     const size_t copyRange = std::min<int>(remainingBytesToCopy, mChunkSize - ptrOffset);
-    uint8_t* srcPtr = mSmallAllocs[shm_idx].get<uint8_t>() + ptrOffset;
+    uint8_t* srcPtr = RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset;
 
     aInto.PushBytes(Range<uint8_t>(srcPtr, copyRange));
 
     srcCursor += copyRange;
     remainingBytesToCopy -= copyRange;
   }
 
   return aInto.Length() - initialLength == aRange.length();
 }
 
-IpcResourceUpdateQueue::IpcResourceUpdateQueue(ipc::IShmemAllocator* aAllocator,
+IpcResourceUpdateQueue::IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
                                                size_t aChunkSize)
 : mWriter(Move(aAllocator), aChunkSize)
 {}
 
 bool
 IpcResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
                                  Range<uint8_t> aBytes)
 {
@@ -347,17 +349,17 @@ IpcResourceUpdateQueue::AddFontInstance(
 void
 IpcResourceUpdateQueue::DeleteFontInstance(wr::FontInstanceKey aKey)
 {
   mUpdates.AppendElement(layers::OpDeleteFontInstance(aKey));
 }
 
 void
 IpcResourceUpdateQueue::Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
-                              nsTArray<ipc::Shmem>& aSmallAllocs,
+                              nsTArray<RefCountedShmem>& aSmallAllocs,
                               nsTArray<ipc::Shmem>& aLargeAllocs)
 {
   aUpdates.Clear();
   mUpdates.SwapElements(aUpdates);
   mWriter.Flush(aSmallAllocs, aLargeAllocs);
 }
 
 void
--- a/gfx/layers/wr/IpcResourceUpdateQueue.h
+++ b/gfx/layers/wr/IpcResourceUpdateQueue.h
@@ -3,76 +3,77 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_WR_IPCRESOURCEUPDATEQUEUE_H
 #define GFX_WR_IPCRESOURCEUPDATEQUEUE_H
 
 #include "mozilla/layers/WebRenderMessages.h"
+#include "mozilla/layers/RefCountedShmem.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 
 namespace mozilla {
 namespace ipc {
 class IShmemAllocator;
 }
 namespace wr {
 
 /// ShmSegmentsWriter pushes bytes in a sequence of fixed size shmems for small
 /// 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<uint8_t> aBytes);
 
   template<typename T>
   layers::OffsetRange WriteAsBytes(Range<T> aValues)
   {
     return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(), aValues.length() * sizeof(T)));
   }
 
-  void Flush(nsTArray<ipc::Shmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs);
+  void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs);
 
   void Clear();
 
 protected:
   bool AllocChunk();
   layers::OffsetRange AllocLargeChunk(size_t aSize);
 
-  nsTArray<ipc::Shmem> mSmallAllocs;
+  nsTArray<layers::RefCountedShmem> mSmallAllocs;
   nsTArray<ipc::Shmem> mLargeAllocs;
-  ipc::IShmemAllocator* mShmAllocator;
+  layers::WebRenderBridgeChild* mShmAllocator;
   size_t mCursor;
   size_t mChunkSize;
 };
 
 class ShmSegmentsReader {
 public:
-  ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
+  ShmSegmentsReader(const nsTArray<layers::RefCountedShmem>& aSmallShmems,
                     const nsTArray<ipc::Shmem>& aLargeShmems);
 
   bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
 
 protected:
   bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
 
-  const nsTArray<ipc::Shmem>& mSmallAllocs;
+  const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
   const nsTArray<ipc::Shmem>& mLargeAllocs;
   size_t mChunkSize;
 };
 
 class IpcResourceUpdateQueue {
 public:
   // Because we are using shmems, the size should be a multiple of the page size.
   // 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,
                 Range<uint8_t> aBytes);
 
   bool AddBlobImage(wr::ImageKey aKey,
                     const ImageDescriptor& aDescriptor,
                     Range<uint8_t> aBytes);
@@ -109,17 +110,17 @@ public:
                        const wr::FontInstancePlatformOptions* aPlatformOptions,
                        Range<const gfx::FontVariation> aVariations);
 
   void DeleteFontInstance(wr::FontInstanceKey aKey);
 
   void Clear();
 
   void Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
-             nsTArray<ipc::Shmem>& aSmallAllocs,
+             nsTArray<layers::RefCountedShmem>& aSmallAllocs,
              nsTArray<ipc::Shmem>& aLargeAllocs);
 
 protected:
   ShmSegmentsWriter mWriter;
   nsTArray<layers::OpUpdateResource> mUpdates;
 };
 
 } // namespace
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -120,17 +120,17 @@ void
 WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources)
 {
   if (!IPCOpen()) {
     aResources.Clear();
     return;
   }
 
   nsTArray<OpUpdateResource> resourceUpdates;
-  nsTArray<ipc::Shmem> smallShmems;
+  nsTArray<RefCountedShmem> smallShmems;
   nsTArray<ipc::Shmem> largeShmems;
   aResources.Flush(resourceUpdates, smallShmems, largeShmems);
 
   this->SendUpdateResources(resourceUpdates, Move(smallShmems), Move(largeShmems));
 }
 
 void
 WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
@@ -149,17 +149,17 @@ WebRenderBridgeChild::EndTransaction(con
   aDL.dl.inner.data = nullptr;
 
   TimeStamp fwdTime;
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   fwdTime = TimeStamp::Now();
 #endif
 
   nsTArray<OpUpdateResource> resourceUpdates;
-  nsTArray<ipc::Shmem> smallShmems;
+  nsTArray<RefCountedShmem> smallShmems;
   nsTArray<ipc::Shmem> largeShmems;
   aResources.Flush(resourceUpdates, smallShmems, largeShmems);
 
   this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
                            GetFwdTransactionId(), aTransactionId,
                            aContentSize, dlData, aDL.dl_desc, aScrollData,
                            Move(resourceUpdates), Move(smallShmems), Move(largeShmems),
                            mIdNamespace, aTxnStartTime, fwdTime);
@@ -316,17 +316,17 @@ WebRenderBridgeChild::GetFontKeyForScale
              (aScaledFont->GetType() == gfx::FontType::MAC) ||
              (aScaledFont->GetType() == gfx::FontType::FONTCONFIG));
 
   wr::FontInstanceKey instanceKey = { wr::IdNamespace { 0 }, 0 };
   if (mFontInstanceKeys.Get(aScaledFont, &instanceKey)) {
     return instanceKey;
   }
 
-  wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
+  wr::IpcResourceUpdateQueue resources(this);
 
   wr::FontKey fontKey = GetFontKeyForUnscaledFont(aScaledFont->GetUnscaledFont());
   wr::FontKey nullKey = { wr::IdNamespace { 0 }, 0};
   if (fontKey == nullKey) {
     return instanceKey;
   }
 
   instanceKey = GetNextFontInstanceKey();
@@ -349,17 +349,17 @@ WebRenderBridgeChild::GetFontKeyForScale
 
 wr::FontKey
 WebRenderBridgeChild::GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaled)
 {
   MOZ_ASSERT(!mDestroyed);
 
   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
     // and only then fall back to getting the raw font file data. If that fails,
     // then the only thing left to do is signal failure by returning a null font key.
     if (!aUnscaled->GetWRFontDescriptor(WriteFontDescriptor, &sink) &&
         !aUnscaled->GetFontFileData(WriteFontFileData, &sink)) {
       return fontKey;
@@ -371,17 +371,17 @@ WebRenderBridgeChild::GetFontKeyForUnsca
 
   return fontKey;
 }
 
 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()) {
       if (!iter.Key()) {
         resources.DeleteFontInstance(iter.Data());
         iter.Remove();
       }
     }
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -272,19 +272,30 @@ WebRenderBridgeParent::DeallocShmems(nsT
   if (IPCOpen()) {
     for (auto& shm : aShmems) {
       DeallocShmem(shm);
     }
   }
   aShmems.Clear();
 }
 
+void
+WebRenderBridgeParent::DeallocShmems(nsTArray<RefCountedShmem>& aShmems)
+{
+  if (IPCOpen()) {
+    for (auto& shm : aShmems) {
+       RefCountedShm::Dealloc(this, shm);
+    }
+  }
+  aShmems.Clear();
+}
+
 bool
 WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResourceUpdates,
-                                       const nsTArray<ipc::Shmem>& aSmallShmems,
+                                       const nsTArray<RefCountedShmem>& aSmallShmems,
                                        const nsTArray<ipc::Shmem>& aLargeShmems,
                                        wr::ResourceUpdateQueue& aUpdates)
 {
   wr::ShmSegmentsReader reader(aSmallShmems, aLargeShmems);
 
   for (const auto& cmd : aResourceUpdates) {
     switch (cmd.type()) {
       case OpUpdateResource::TOpAddImage: {
@@ -445,17 +456,17 @@ WebRenderBridgeParent::AddExternalImage(
   aResources.AddImage(keys[0], descriptor, data);
   dSurf->Unmap();
 
   return true;
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvUpdateResources(nsTArray<OpUpdateResource>&& aResourceUpdates,
-                                           nsTArray<ipc::Shmem>&& aSmallShmems,
+                                           nsTArray<RefCountedShmem>&& aSmallShmems,
                                            nsTArray<ipc::Shmem>&& aLargeShmems)
 {
   if (mDestroyed) {
     DeallocShmems(aSmallShmems);
     DeallocShmems(aLargeShmems);
     return IPC_OK();
   }
 
@@ -575,17 +586,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
                                           InfallibleTArray<OpDestroy>&& aToDestroy,
                                           const uint64_t& aFwdTransactionId,
                                           const uint64_t& aTransactionId,
                                           const wr::LayoutSize& aContentSize,
                                           ipc::ByteBuf&& dl,
                                           const wr::BuiltDisplayListDescriptor& dlDesc,
                                           const WebRenderScrollData& aScrollData,
                                           nsTArray<OpUpdateResource>&& aResourceUpdates,
-                                          nsTArray<ipc::Shmem>&& aSmallShmems,
+                                          nsTArray<RefCountedShmem>&& aSmallShmems,
                                           nsTArray<ipc::Shmem>&& aLargeShmems,
                                           const wr::IdNamespace& aIdNamespace,
                                           const TimeStamp& aTxnStartTime,
                                           const TimeStamp& aFwdTime)
 {
   if (mDestroyed) {
     for (const auto& op : aToDestroy) {
       DestroyActor(op);
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -69,29 +69,29 @@ public:
 
   mozilla::ipc::IPCResult RecvInitReadLocks(ReadLockArray&& aReadLocks) override;
 
   mozilla::ipc::IPCResult RecvCreate(const gfx::IntSize& aSize) override;
   mozilla::ipc::IPCResult RecvShutdown() override;
   mozilla::ipc::IPCResult RecvShutdownSync() override;
   mozilla::ipc::IPCResult RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds) override;
   mozilla::ipc::IPCResult RecvUpdateResources(nsTArray<OpUpdateResource>&& aUpdates,
-                                              nsTArray<ipc::Shmem>&& aSmallShmems,
+                                              nsTArray<RefCountedShmem>&& aSmallShmems,
                                               nsTArray<ipc::Shmem>&& aLargeShmems) override;
   mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize,
                                              InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                              InfallibleTArray<OpDestroy>&& aToDestroy,
                                              const uint64_t& aFwdTransactionId,
                                              const uint64_t& aTransactionId,
                                              const wr::LayoutSize& aContentSize,
                                              ipc::ByteBuf&& dl,
                                              const wr::BuiltDisplayListDescriptor& dlDesc,
                                              const WebRenderScrollData& aScrollData,
                                              nsTArray<OpUpdateResource>&& aResourceUpdates,
-                                             nsTArray<ipc::Shmem>&& aSmallShmems,
+                                             nsTArray<RefCountedShmem>&& aSmallShmems,
                                              nsTArray<ipc::Shmem>&& aLargeShmems,
                                              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,
@@ -188,22 +188,23 @@ public:
 
   void UpdateWebRender(CompositorVsyncScheduler* aScheduler,
                        wr::WebRenderAPI* aApi,
                        AsyncImagePipelineManager* aImageMgr,
                        CompositorAnimationStorage* aAnimStorage);
 
 private:
   void DeallocShmems(nsTArray<ipc::Shmem>& aShmems);
+  void DeallocShmems(nsTArray<RefCountedShmem>& aShmems);
 
   explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId);
   virtual ~WebRenderBridgeParent();
 
   bool UpdateResources(const nsTArray<OpUpdateResource>& aResourceUpdates,
-                       const nsTArray<ipc::Shmem>& aSmallShmems,
+                       const nsTArray<RefCountedShmem>& aSmallShmems,
                        const nsTArray<ipc::Shmem>& aLargeShmems,
                        wr::ResourceUpdateQueue& aUpdates);
   bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
                         wr::ResourceUpdateQueue& aResources);
 
   uint64_t GetLayersId() const;
   void ProcessWebRenderParentCommands(const InfallibleTArray<WebRenderParentCommand>& aCommands);
 
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -262,17 +262,17 @@ WebRenderLayerManager::EndTransactionWit
   mAnimationReadyTime = TimeStamp::Now();
 
   WrBridge()->BeginTransaction();
   DiscardCompositorAnimations();
 
   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,
                                                   aDisplayList,
                                                   aDisplayListBuilder,
                                                   mScrollData,
                                                   contentSize);
 
@@ -408,17 +408,17 @@ void
 WebRenderLayerManager::AddImageKeyForDiscard(wr::ImageKey key)
 {
   mImageKeysToDeleteLater.AppendElement(key);
 }
 
 void
 WebRenderLayerManager::DiscardImages()
 {
-  wr::IpcResourceUpdateQueue resources(WrBridge()->GetShmemAllocator());
+  wr::IpcResourceUpdateQueue resources(WrBridge());
   for (const auto& key : mImageKeysToDeleteLater) {
     resources.DeleteImage(key);
   }
   for (const auto& key : mImageKeysToDelete) {
     resources.DeleteImage(key);
   }
   mImageKeysToDeleteLater.Clear();
   mImageKeysToDelete.Clear();