Bug 1343770. Separate out Parent commands from Child commands. r=kats
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 02 Mar 2017 16:33:03 -0500
changeset 374827 d6998fb6d473c6e56b169c199752969e8915fa00
parent 374826 c83b1eec0a124f2322d6166f9ac10ca9e1d39952
child 374828 aafcba25dee399d3390ea1fb4c2121e4e62b8b0d
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1343770
milestone54.0a1
Bug 1343770. Separate out Parent commands from Child commands. r=kats This basically just splits the enum in two and does the necessary plumbing. The worst part is that now DisplayItemLayers need to have two arrays of commands. Fortunately, this will be going away in the future. This makes it so we don't send the child side commands to the parent.
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/ipc/WebRenderMessages.ipdlh
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderDisplayItemLayer.cpp
gfx/layers/wr/WebRenderDisplayItemLayer.h
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderPaintedLayer.cpp
layout/generic/nsBulletFrame.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -35,19 +35,19 @@ parent:
   sync Create(IntSize aSize);
   sync AddImage(ImageKey aImageKey, IntSize aSize, uint32_t aStride,
                 SurfaceFormat aFormat, ByteBuffer aBytes);
   sync UpdateImage(ImageKey aImageKey, IntSize aSize,
                    SurfaceFormat aFormat, ByteBuffer aBytes);
   sync DeleteImage(ImageKey aImageKey);
   async AddRawFont(FontKey aFontKey, ByteBuffer aBytes, uint32_t aFontIndex);
   async DPBegin(IntSize aSize);
-  async DPEnd(IntSize aSize, WebRenderCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
+  async DPEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
               ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
-  sync DPSyncEnd(IntSize aSize, WebRenderCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
+  sync DPSyncEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
                  ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
   sync DPGetSnapshot(PTexture texture);
   async AddExternalImageId(uint64_t aImageId, CompositableHandle aHandle);
   async AddExternalImageIdForCompositable(uint64_t aImageId, CompositableHandle aHandle);
   async RemoveExternalImageId(uint64_t aImageId);
   async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
   async ClearCachedResources();
 
--- a/gfx/layers/ipc/WebRenderMessages.ipdlh
+++ b/gfx/layers/ipc/WebRenderMessages.ipdlh
@@ -134,17 +134,20 @@ union WebRenderCommand {
   OpDPPopStackingContext;
   OpDPPushScrollLayer;
   OpDPPopScrollLayer;
   OpDPPushRect;
   OpDPPushBorder;
   OpDPPushLinearGradient;
   OpDPPushRadialGradient;
   OpDPPushImage;
-  OpAddExternalImage;
   OpDPPushIframe;
   OpDPPushText;
   OpDPPushBoxShadow;
+};
+
+union WebRenderParentCommand {
+  OpAddExternalImage;
   CompositableOperation;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -54,16 +54,30 @@ WebRenderBridgeChild::AddWebRenderComman
 
 void
 WebRenderBridgeChild::AddWebRenderCommands(const nsTArray<WebRenderCommand>& aCommands)
 {
   MOZ_ASSERT(mIsInTransaction);
   mCommands.AppendElements(aCommands);
 }
 
+void
+WebRenderBridgeChild::AddWebRenderParentCommand(const WebRenderParentCommand& aCmd)
+{
+  MOZ_ASSERT(mIsInTransaction);
+  mParentCommands.AppendElement(aCmd);
+}
+
+void
+WebRenderBridgeChild::AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands)
+{
+  MOZ_ASSERT(mIsInTransaction);
+  mParentCommands.AppendElements(aCommands);
+}
+
 bool
 WebRenderBridgeChild::DPBegin(const gfx::IntSize& aSize)
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(!mIsInTransaction);
 
   UpdateFwdTransactionId();
   this->SendDPBegin(aSize);
@@ -128,29 +142,21 @@ WebRenderBridgeChild::ProcessWebrenderCo
         break;
       }
       case WebRenderCommand::TOpDPPushImage: {
         const OpDPPushImage& op = cmd.get_OpDPPushImage();
         builder.PushImage(op.bounds(), op.clip(),
                           op.mask().ptrOr(nullptr), op.filter(), wr::ImageKey(op.key()));
         break;
       }
-      case WebRenderCommand::TOpAddExternalImage: {
-        // done on the parent
-        break;
-      }
       case WebRenderCommand::TOpDPPushIframe: {
         const OpDPPushIframe& op = cmd.get_OpDPPushIframe();
         builder.PushIFrame(op.bounds(), op.clip(), op.pipelineId());
         break;
       }
-      case WebRenderCommand::TCompositableOperation: {
-        // done on the parent
-        break;
-      }
       case WebRenderCommand::TOpDPPushText: {
         const OpDPPushText& op = cmd.get_OpDPPushText();
         const nsTArray<WrGlyphArray>& glyph_array = op.glyph_array();
 
         for (size_t i = 0; i < glyph_array.Length(); i++) {
           const nsTArray<WrGlyphInstance>& glyphs = glyph_array[i].glyphs;
           builder.PushText(op.bounds(),
                            op.clip(),
@@ -191,24 +197,25 @@ WebRenderBridgeChild::DPEnd(const gfx::I
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   wr::BuiltDisplayList dl = ProcessWebrenderCommands(aSize, mCommands);
   ByteBuffer dlData(Move(dl.dl));
   ByteBuffer auxData(Move(dl.aux));
 
   if (aIsSync) {
-    this->SendDPSyncEnd(aSize, mCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
+    this->SendDPSyncEnd(aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
                         dlData, dl.dl_desc, auxData, dl.aux_desc);
   } else {
-    this->SendDPEnd(aSize, mCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
+    this->SendDPEnd(aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
                     dlData, dl.dl_desc, auxData, dl.aux_desc);
   }
 
   mCommands.Clear();
+  mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 uint64_t
 WebRenderBridgeChild::GetNextExternalImageId()
 {
   static uint32_t sNextID = 1;
@@ -341,17 +348,17 @@ WebRenderBridgeChild::RemoveTextureFromC
   MOZ_ASSERT(aTexture);
   MOZ_ASSERT(aTexture->GetIPDLActor());
   MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == GetIPCChannel());
   if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
     // We don't have an actor anymore, don't try to use it!
     return;
   }
 
-  AddWebRenderCommand(
+  AddWebRenderParentCommand(
     CompositableOperation(
       aCompositable->GetIPCHandle(),
       OpRemoveTexture(nullptr, aTexture->GetIPDLActor())));
 }
 
 void
 WebRenderBridgeChild::UseTextures(CompositableClient* aCompositable,
                                   const nsTArray<TimedTextureClient>& aTextures)
@@ -371,17 +378,17 @@ WebRenderBridgeChild::UseTextures(Compos
     ReadLockDescriptor readLock;
     t.mTextureClient->SerializeReadLock(readLock);
     textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
                                         readLock,
                                         t.mTimeStamp, t.mPictureRect,
                                         t.mFrameID, t.mProducerID));
     GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
   }
-  AddWebRenderCommand(CompositableOperation(aCompositable->GetIPCHandle(),
+  AddWebRenderParentCommand(CompositableOperation(aCompositable->GetIPCHandle(),
                                             OpUseTexture(textures)));
 }
 
 void
 WebRenderBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositable,
                                                 TextureClient* aClientOnBlack,
                                                 TextureClient* aClientOnWhite)
 {
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -27,16 +27,18 @@ class WebRenderBridgeChild final : publi
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild, override)
 
 public:
   explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
 
   void AddWebRenderCommand(const WebRenderCommand& aCmd);
   void AddWebRenderCommands(const nsTArray<WebRenderCommand>& aCommands);
+  void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
+  void AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands);
 
   bool DPBegin(const  gfx::IntSize& aSize);
   void DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId);
 
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   // KnowsCompositor
   TextureForwarder* GetTextureForwarder() override;
@@ -104,16 +106,17 @@ private:
     MOZ_ASSERT(mIPCOpen == true);
     mIPCOpen = false;
     Release();
   }
 
   bool AddOpDestroy(const OpDestroy& aOp);
 
   nsTArray<WebRenderCommand> mCommands;
+  nsTArray<WebRenderParentCommand> mParentCommands;
   nsTArray<OpDestroy> mDestroyedActors;
   nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
   bool mIsInTransaction;
   uint32_t mIdNamespace;
   uint32_t mResourceId;
   wr::PipelineId mPipelineId;
 
   bool mIPCOpen;
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -211,17 +211,17 @@ WebRenderBridgeParent::RecvDPBegin(const
   if (mDestroyed) {
     return IPC_OK();
   }
   return IPC_OK();
 }
 
 void
 WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
-                                 InfallibleTArray<WebRenderCommand>&& aCommands,
+                                 InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                  InfallibleTArray<OpDestroy>&& aToDestroy,
                                  const uint64_t& aFwdTransactionId,
                                  const uint64_t& aTransactionId,
                                  const ByteBuffer& dl,
                                  const WrBuiltDisplayListDescriptor& dlDesc,
                                  const ByteBuffer& aux,
                                  const WrAuxiliaryListsDescriptor& auxDesc)
 {
@@ -240,62 +240,62 @@ WebRenderBridgeParent::HandleDPEnd(const
   ++mWrEpoch; // Update webrender epoch
   ProcessWebrenderCommands(aSize, aCommands, wr::NewEpoch(mWrEpoch),
                            dl, dlDesc, aux, auxDesc);
   HoldPendingTransactionId(mWrEpoch, aTransactionId);
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvDPEnd(const gfx::IntSize& aSize,
-                                 InfallibleTArray<WebRenderCommand>&& aCommands,
+                                 InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                  InfallibleTArray<OpDestroy>&& aToDestroy,
                                  const uint64_t& aFwdTransactionId,
                                  const uint64_t& aTransactionId,
                                  const ByteBuffer& dl,
                                  const WrBuiltDisplayListDescriptor& dlDesc,
                                  const ByteBuffer& aux,
                                  const WrAuxiliaryListsDescriptor& auxDesc)
 {
   HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
               dl, dlDesc, aux, auxDesc);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvDPSyncEnd(const gfx::IntSize &aSize,
-                                     InfallibleTArray<WebRenderCommand>&& aCommands,
+                                     InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                      InfallibleTArray<OpDestroy>&& aToDestroy,
                                      const uint64_t& aFwdTransactionId,
                                      const uint64_t& aTransactionId,
                                      const ByteBuffer& dl,
                                      const WrBuiltDisplayListDescriptor& dlDesc,
                                      const ByteBuffer& aux,
                                      const WrAuxiliaryListsDescriptor& auxDesc)
 {
   HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
               dl, dlDesc, aux, auxDesc);
   return IPC_OK();
 }
 
 void
 WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
-                                                InfallibleTArray<WebRenderCommand>& aCommands, const wr::Epoch& aEpoch,
+                                                InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch,
                                                 const ByteBuffer& dl,
                                                 const WrBuiltDisplayListDescriptor& dlDesc,
                                                 const ByteBuffer& aux,
                                                 const WrAuxiliaryListsDescriptor& auxDesc)
 {
   // XXX remove it when external image key is used.
   std::vector<wr::ImageKey> keysToDelete;
 
-  for (InfallibleTArray<WebRenderCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
-    const WebRenderCommand& cmd = aCommands[i];
+  for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
+    const WebRenderParentCommand& cmd = aCommands[i];
 
     switch (cmd.type()) {
-      case WebRenderCommand::TOpAddExternalImage: {
+      case WebRenderParentCommand::TOpAddExternalImage: {
         const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
         MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
 
         RefPtr<CompositableHost> host = mExternalImageIds.Get(op.externalImageId());
         if (!host) {
           break;
         }
         RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
@@ -317,17 +317,17 @@ WebRenderBridgeParent::ProcessWebrenderC
         keysToDelete.push_back(key);
         dSurf->Unmap();
         // XXX workaround for releasing Readlock. See Bug 1339625
         if(host->GetType() == CompositableType::CONTENT_SINGLE) {
           host->CleanupResources();
         }
         break;
       }
-      case WebRenderCommand::TCompositableOperation: {
+      case WebRenderParentCommand::TCompositableOperation: {
         if (!ReceiveCompositableUpdate(cmd.get_CompositableOperation())) {
           NS_ERROR("ReceiveCompositableUpdate failed");
         }
         break;
       }
       default: {
         // other commands are handle on the child
         break;
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -71,26 +71,26 @@ public:
                                          const uint32_t& aFontIndex) override;
   mozilla::ipc::IPCResult RecvUpdateImage(const wr::ImageKey& aImageKey,
                                           const gfx::IntSize& aSize,
                                           const gfx::SurfaceFormat& aFormat,
                                           const ByteBuffer& aBuffer) override;
   mozilla::ipc::IPCResult RecvDeleteImage(const wr::ImageKey& a1) override;
   mozilla::ipc::IPCResult RecvDPBegin(const gfx::IntSize& aSize) override;
   mozilla::ipc::IPCResult RecvDPEnd(const gfx::IntSize& aSize,
-                                    InfallibleTArray<WebRenderCommand>&& aCommands,
+                                    InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                     InfallibleTArray<OpDestroy>&& aToDestroy,
                                     const uint64_t& aFwdTransactionId,
                                     const uint64_t& aTransactionId,
                                     const ByteBuffer& dl,
                                     const WrBuiltDisplayListDescriptor& dlDesc,
                                     const ByteBuffer& aux,
                                     const WrAuxiliaryListsDescriptor& auxDesc) override;
   mozilla::ipc::IPCResult RecvDPSyncEnd(const gfx::IntSize& aSize,
-                                        InfallibleTArray<WebRenderCommand>&& aCommands,
+                                        InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                         InfallibleTArray<OpDestroy>&& aToDestroy,
                                         const uint64_t& aFwdTransactionId,
                                         const uint64_t& aTransactionId,
                                         const ByteBuffer& dl,
                                         const WrBuiltDisplayListDescriptor& dlDesc,
                                         const ByteBuffer& aux,
                                         const WrAuxiliaryListsDescriptor& auxDesc) override;
   mozilla::ipc::IPCResult RecvDPGetSnapshot(PTextureParent* aTexture) override;
@@ -145,27 +145,27 @@ public:
   {
     return mIdNameSpace;
   }
 
 private:
   virtual ~WebRenderBridgeParent();
 
   void DeleteOldImages();
-  void ProcessWebrenderCommands(const gfx::IntSize &aSize, InfallibleTArray<WebRenderCommand>& commands, const wr::Epoch& aEpoch,
+  void ProcessWebrenderCommands(const gfx::IntSize &aSize, InfallibleTArray<WebRenderParentCommand>& commands, const wr::Epoch& aEpoch,
                                     const ByteBuffer& dl,
                                     const WrBuiltDisplayListDescriptor& dlDesc,
                                     const ByteBuffer& aux,
                                     const WrAuxiliaryListsDescriptor& auxDesc);
   void ScheduleComposition();
   void ClearResources();
   uint64_t GetChildLayerObserverEpoch() const { return mChildLayerObserverEpoch; }
   bool ShouldParentObserveEpoch();
   void HandleDPEnd(const gfx::IntSize& aSize,
-                   InfallibleTArray<WebRenderCommand>&& aCommands,
+                   InfallibleTArray<WebRenderParentCommand>&& aCommands,
                    InfallibleTArray<OpDestroy>&& aToDestroy,
                    const uint64_t& aFwdTransactionId,
                    const uint64_t& aTransactionId,
                    const ByteBuffer& dl,
                    const WrBuiltDisplayListDescriptor& dlDesc,
                    const ByteBuffer& aux,
                    const WrAuxiliaryListsDescriptor& auxDesc);
 
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -105,17 +105,17 @@ WebRenderCanvasLayer::RenderLayer()
                               1.0f,
                               GetAnimations(),
                               transform,
                               mixBlendMode,
                               FrameMetrics::NULL_SCROLL_ID));
   WrImageKey key;
   key.mNamespace = WrBridge()->GetNamespace();
   key.mHandle = WrBridge()->GetNextResourceId();
-  WrBridge()->AddWebRenderCommand(OpAddExternalImage(mExternalImageId, key));
+  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
   WrBridge()->AddWebRenderCommand(OpDPPushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, key));
   WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 }
 
 void
 WebRenderCanvasLayer::AttachCompositable()
 {
   mCanvasClient->Connect();
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
@@ -16,22 +16,24 @@ namespace mozilla {
 namespace layers {
 
 void
 WebRenderDisplayItemLayer::RenderLayer()
 {
   if (mItem) {
     // We might have recycled this layer. Throw away the old commands.
     mCommands.Clear();
-    mItem->CreateWebRenderCommands(mCommands, this);
+    mParentCommands.Clear();
+    mItem->CreateWebRenderCommands(mCommands, mParentCommands, this);
   }
   // else we have an empty transaction and just use the
   // old commands.
 
   WrBridge()->AddWebRenderCommands(mCommands);
+  WrBridge()->AddWebRenderParentCommands(mParentCommands);
 }
 
 uint64_t
 WebRenderDisplayItemLayer::SendImageContainer(ImageContainer* aContainer)
 {
   if (mImageContainer != aContainer) {
     AutoLockImage autoLock(aContainer);
     Image* image = autoLock.GetImage();
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.h
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.h
@@ -34,18 +34,19 @@ protected:
   }
 
 public:
   Layer* GetLayer() override { return this; }
   void RenderLayer() override;
 
 private:
   nsTArray<WebRenderCommand> mCommands;
+  nsTArray<WebRenderParentCommand> mParentCommands;
   RefPtr<ImageClient> mImageClient;
   RefPtr<ImageContainer> mImageContainer;
   uint64_t mExternalImageId;
 
 };
 
 } // namespace layers
 } // namespace mozilla
 
-#endif // GFX_WEBRENDERDisplayItemLayer_H
\ No newline at end of file
+#endif // GFX_WEBRENDERDisplayItemLayer_H
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -172,17 +172,17 @@ WebRenderImageLayer::RenderLayer()
                             1.0f,
                             GetAnimations(),
                             transform,
                             mixBlendMode,
                             FrameMetrics::NULL_SCROLL_ID));
   WrImageKey key;
   key.mNamespace = WrBridge()->GetNamespace();
   key.mHandle = WrBridge()->GetNextResourceId();
-  WrBridge()->AddWebRenderCommand(OpAddExternalImage(mExternalImageId, key));
+  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
   WrBridge()->AddWebRenderCommand(OpDPPushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, key));
   WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 
   //mContainer->SetImageFactory(originalIF);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -231,15 +231,15 @@ WebRenderPaintedLayer::RenderLayer()
                               1.0f,
                               GetAnimations(),
                               transform,
                               mixBlendMode,
                               FrameMetrics::NULL_SCROLL_ID));
   WrImageKey key;
   key.mNamespace = WrBridge()->GetNamespace();
   key.mHandle = WrBridge()->GetNextResourceId();
-  WrBridge()->AddWebRenderCommand(OpAddExternalImage(mExternalImageId, key));
+  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
   WrBridge()->AddWebRenderCommand(OpDPPushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), wr::ImageRendering::Auto, key));
   WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -224,16 +224,17 @@ public:
     , mListStyleType(listStyleType)
   {
     MOZ_ASSERT(IsTextType());
   }
 
   void
   CreateWebRenderCommands(nsDisplayItem* aItem,
                           nsTArray<layers::WebRenderCommand>& aCommands,
+                          nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                           layers::WebRenderDisplayItemLayer* aLayer);
 
   DrawResult
   Paint(nsRenderingContext& aRenderingContext, nsPoint aPt,
         const nsRect& aDirtyRect, uint32_t aFlags,
         bool aDisableSubpixelAA, nsIFrame* aFrame);
 
   bool
@@ -270,16 +271,17 @@ public:
 
   bool
   IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags);
 
 private:
   void
   CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
                                   nsTArray<layers::WebRenderCommand>& aCommands,
+                                  nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                   layers::WebRenderDisplayItemLayer* aLayer);
 
   void
   CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
                                  nsTArray<layers::WebRenderCommand>& aCommands,
                                  layers::WebRenderDisplayItemLayer* aLayer);
 
   void
@@ -311,20 +313,21 @@ private:
 
   // Store the type of list-style-type.
   int32_t mListStyleType;
 };
 
 void
 BulletRenderer::CreateWebRenderCommands(nsDisplayItem* aItem,
                                         nsTArray<layers::WebRenderCommand>& aCommands,
+                                        nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                         layers::WebRenderDisplayItemLayer* aLayer)
 {
   if (IsImageType()) {
-    CreateWebRenderCommandsForImage(aItem, aCommands, aLayer);
+    CreateWebRenderCommandsForImage(aItem, aCommands, aParentCommands, aLayer);
   } else if (IsPathType()) {
     CreateWebRenderCommandsForPath(aItem, aCommands, aLayer);
   } else {
     MOZ_ASSERT(IsTextType());
     CreateWebRenderCommandsForText(aItem, aCommands, aLayer);
   }
 }
 
@@ -428,16 +431,17 @@ BulletRenderer::IsImageContainerAvailabl
   MOZ_ASSERT(IsImageType());
 
   return mImage->IsImageContainerAvailable(aManager, aFlags);
 }
 
 void
 BulletRenderer::CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
                                                 nsTArray<layers::WebRenderCommand>& aCommands,
+                                                nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                                 layers::WebRenderDisplayItemLayer* aLayer)
 {
   MOZ_ASSERT(IsImageType());
 
   if (!mImage) {
      return;
   }
 
@@ -459,19 +463,19 @@ BulletRenderer::CreateWebRenderCommandsF
   Rect destRect =
     NSRectToRect(mDest, appUnitsPerDevPixel);
   Rect destRectTransformed = aLayer->RelativeToParent(destRect);
   IntRect dest = RoundedToInt(destRectTransformed);
 
   WrImageKey key;
   key.mNamespace = layer->WrBridge()->GetNamespace();
   key.mHandle = layer->WrBridge()->GetNextResourceId();
-  aCommands.AppendElement(layers::OpAddExternalImage(
-                            externalImageId,
-                            key));
+  aParentCommands.AppendElement(layers::OpAddExternalImage(
+                                externalImageId,
+                                key));
   aCommands.AppendElement(layers::OpDPPushImage(
                             wr::ToWrRect(dest),
                             wr::ToWrRect(dest),
                             Nothing(),
                             WrImageRendering::Auto,
                             key));
 
 
@@ -533,16 +537,17 @@ public:
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aParameters) override;
 
   virtual void CreateWebRenderCommands(nsTArray<layers::WebRenderCommand>& aCommands,
+                                       nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                        layers::WebRenderDisplayItemLayer* aLayer) override;
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState,
                        nsTArray<nsIFrame*> *aOutFrames) override {
     aOutFrames->AppendElement(mFrame);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
@@ -646,22 +651,23 @@ nsDisplayBullet::BuildLayer(nsDisplayLis
     return nullptr;
   }
 
   return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
 }
 
 void
 nsDisplayBullet::CreateWebRenderCommands(nsTArray<layers::WebRenderCommand>& aCommands,
+                                         nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                          layers::WebRenderDisplayItemLayer* aLayer)
 {
   if (!mBulletRenderer)
     return;
 
-  mBulletRenderer->CreateWebRenderCommands(this, aCommands, aLayer);
+  mBulletRenderer->CreateWebRenderCommands(this, aCommands, aParentCommands, aLayer);
 }
 
 void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder,
                             nsRenderingContext* aCtx)
 {
   uint32_t flags = imgIContainer::FLAG_NONE;
   if (aBuilder->ShouldSyncDecodeImages()) {
     flags |= imgIContainer::FLAG_SYNC_DECODE;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4143,16 +4143,17 @@ nsDisplayOutline::BuildLayer(nsDisplayLi
                              LayerManager* aManager,
                              const ContainerLayerParameters& aContainerParameters)
 {
   return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
 }
 
 void
 nsDisplayOutline::CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                          nsTArray<WebRenderParentCommand>& aParentCommands,
                                           WebRenderDisplayItemLayer* aLayer)
 {
   MOZ_ASSERT(mBorderRenderer.isSome());
 
   Rect outlineTransformedRect = aLayer->RelativeToParent(mBorderRenderer->mOuterRect);
 
   nsCSSBorderRenderer* br = mBorderRenderer.ptr();
   WrBorderSide side[4];
@@ -4422,16 +4423,17 @@ nsDisplayCaret::Paint(nsDisplayListBuild
                       nsRenderingContext* aCtx) {
   // Note: Because we exist, we know that the caret is visible, so we don't
   // need to check for the caret's visibility.
   mCaret->PaintCaret(*aCtx->GetDrawTarget(), mFrame, ToReferenceFrame());
 }
 
 void
 nsDisplayCaret::CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                        nsTArray<WebRenderParentCommand>& aParentCommands,
                                         WebRenderDisplayItemLayer* aLayer) {
   using namespace mozilla::layers;
   int32_t contentOffset;
   nsIFrame* frame = mCaret->GetFrame(&contentOffset);
   if (!frame) {
     return;
   }
   NS_ASSERTION(frame == mFrame, "We're referring different frame");
@@ -4830,16 +4832,17 @@ nsDisplayBoxShadowOuter::BuildLayer(nsDi
                                     LayerManager* aManager,
                                     const ContainerLayerParameters& aContainerParameters)
 {
   return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
 }
 
 void
 nsDisplayBoxShadowOuter::CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                                 nsTArray<WebRenderParentCommand>& aParentCommands,
                                                  WebRenderDisplayItemLayer* aLayer)
 {
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   nsPoint offset = ToReferenceFrame();
   nsRect borderRect = mFrame->VisualBorderRectRelativeToSelf() + offset;
   //nsPresContext* presContext = mFrame->PresContext();
   AutoTArray<nsRect,10> rects;
   nsRegion visible = aLayer->GetVisibleRegion().ToAppUnits(appUnitsPerDevPixel);
@@ -4983,16 +4986,17 @@ nsDisplayBoxShadowInner::BuildLayer(nsDi
                                     LayerManager* aManager,
                                     const ContainerLayerParameters& aContainerParameters)
 {
   return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
 }
 
 void
 nsDisplayBoxShadowInner::CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                                 nsTArray<WebRenderParentCommand>& aParentCommands,
                                                  WebRenderDisplayItemLayer* aLayer)
 {
   if (!nsCSSRendering::CanPaintBoxShadowInner(mFrame)) {
     return;
   }
 
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   nsPoint offset = ToReferenceFrame();
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -54,16 +54,17 @@ class nsCaret;
 
 namespace mozilla {
 class FrameLayerBuilder;
 namespace layers {
 class Layer;
 class ImageLayer;
 class ImageContainer;
 class WebRenderCommand;
+class WebRenderParentCommand;
 class WebRenderDisplayItemLayer;
 } // namespace layers
 } // namespace mozilla
 
 // A set of blend modes, that never includes OP_OVER (since it's
 // considered the default, rather than a specific blend mode).
 typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
 
@@ -1580,16 +1581,17 @@ public:
   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
   typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollMetadata ScrollMetadata;
   typedef mozilla::layers::FrameMetrics::ViewID ViewID;
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
   typedef mozilla::layers::WebRenderCommand WebRenderCommand;
+  typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
   typedef mozilla::layers::WebRenderDisplayItemLayer WebRenderDisplayItemLayer;
   typedef mozilla::LayerState LayerState;
   typedef class mozilla::gfx::DrawTarget DrawTarget;
 
   // This is never instantiated directly (it has pure virtual methods), so no
   // need to count constructors and destructors.
   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
@@ -1921,16 +1923,17 @@ public:
   { return nullptr; }
 
   /**
     * Create the WebRenderCommands required to paint this display item.
     * The layer this item is in is passed in as rects must be relative
     * to their parent.
     */
    virtual void CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                        nsTArray<WebRenderParentCommand>& aParentCommands,
                                         WebRenderDisplayItemLayer* aLayer) {}
   /**
    * Builds a DisplayItemLayer and sets the display item to this.
    */
    already_AddRefed<Layer>
    BuildDisplayItemLayer(nsDisplayListBuilder* aBuilder,
                          LayerManager* aManager,
                          const ContainerLayerParameters& aContainerParameters);
@@ -2817,16 +2820,17 @@ public:
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
   virtual void CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                       nsTArray<WebRenderParentCommand>& aParentCommands,
                                         WebRenderDisplayItemLayer* aLayer) override;
 
 protected:
   RefPtr<nsCaret> mCaret;
   nsRect mBounds;
 };
 
 /**
@@ -3379,16 +3383,17 @@ public:
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
   virtual void CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                       nsTArray<WebRenderParentCommand>& aParentCommands,
                                        WebRenderDisplayItemLayer* aLayer) override;
 
   nsRect GetBoundsInternal();
 
 private:
   nsRegion mVisibleRegion;
   nsRect mBounds;
   float mOpacity;
@@ -3434,16 +3439,17 @@ public:
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
   virtual void CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                       nsTArray<WebRenderParentCommand>& aParentCommand,
                                        WebRenderDisplayItemLayer* aLayer) override;
 
 private:
   nsRegion mVisibleRegion;
 };
 
 /**
  * The standard display item to paint the CSS outline of a frame.
@@ -3462,16 +3468,17 @@ public:
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
   virtual void CreateWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                       nsTArray<WebRenderParentCommand>& aParentCommands,
                                        mozilla::layers::WebRenderDisplayItemLayer* aLayer) override;
   virtual bool IsInvisibleInRect(const nsRect& aRect) override;
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
   NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
 
   mozilla::Maybe<nsCSSBorderRenderer> mBorderRenderer;
 };