Bug 1325227 - Part 1: Remove synchronous transaction replies since they don't return any data we didn't already have. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 06 Dec 2016 13:34:54 -1000
changeset 371791 8255c2bb705ad0812132c4a91d9ac92e3904925d
parent 371790 bcda57aa0c3b291dcd5de5d7fd048af69dbdff4d
child 371792 070b40fcd8d120d0ab10b177d7572bdc2772d64a
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)
reviewersnical
bugs1325227
milestone54.0a1
Bug 1325227 - Part 1: Remove synchronous transaction replies since they don't return any data we didn't already have. r=nical MozReview-Commit-ID: 2HIbk65L7zR
gfx/layers/client/ClientPaintedLayer.cpp
gfx/layers/client/ClientPaintedLayer.h
gfx/layers/client/ContentClient.cpp
gfx/layers/composite/CompositableHost.h
gfx/layers/composite/ContentHost.cpp
gfx/layers/composite/ContentHost.h
gfx/layers/composite/TiledContentHost.h
gfx/layers/ipc/CompositableTransactionParent.cpp
gfx/layers/ipc/CompositableTransactionParent.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/PImageBridge.ipdl
gfx/layers/ipc/PLayerTransaction.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/wr/WebRenderBridgeParent.cpp
--- a/gfx/layers/client/ClientPaintedLayer.cpp
+++ b/gfx/layers/client/ClientPaintedLayer.cpp
@@ -25,24 +25,26 @@
 #include "ReadbackProcessor.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
-ClientPaintedLayer::PaintThebes()
+ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates)
 {
   PROFILER_LABEL("ClientPaintedLayer", "PaintThebes",
     js::ProfileEntry::Category::GRAPHICS);
 
   NS_ASSERTION(ClientManager()->InDrawing(),
                "Can only draw in drawing phase");
   
+  mContentClient->BeginPaint();
+
   uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED;
 #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
   if (ClientManager()->CompositorMightResample()) {
     flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
   }
   if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) {
     if (MayResample()) {
       flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
@@ -88,16 +90,18 @@ ClientPaintedLayer::PaintThebes()
                                               state.mRegionToInvalidate,
                                               ClientManager()->GetPaintedLayerCallbackData());
 
     ctx = nullptr;
     mContentClient->ReturnDrawTargetToBuffer(target);
     didUpdate = true;
   }
 
+  mContentClient->EndPaint(aReadbackUpdates);
+
   if (didUpdate) {
     Mutated();
 
     mValidRegion.Or(mValidRegion, state.mRegionToDraw);
 
     ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
     MOZ_ASSERT(contentClientRemote->GetIPCHandle());
 
@@ -127,20 +131,17 @@ ClientPaintedLayer::RenderLayerWithReadb
   }
 
   nsTArray<ReadbackProcessor::Update> readbackUpdates;
   nsIntRegion readbackRegion;
   if (aReadback && UsedForReadback()) {
     aReadback->GetPaintedLayerUpdates(this, &readbackUpdates);
   }
 
-  IntPoint origin(mVisibleRegion.GetBounds().x, mVisibleRegion.GetBounds().y);
-  mContentClient->BeginPaint();
-  PaintThebes();
-  mContentClient->EndPaint(&readbackUpdates);
+  PaintThebes(&readbackUpdates);
 }
 
 already_AddRefed<PaintedLayer>
 ClientLayerManager::CreatePaintedLayer()
 {
   return CreatePaintedLayerWithHint(NONE);
 }
 
--- a/gfx/layers/client/ClientPaintedLayer.h
+++ b/gfx/layers/client/ClientPaintedLayer.h
@@ -103,17 +103,17 @@ public:
   }
 
   virtual void Disconnect() override
   {
     mContentClient = nullptr;
   }
 
 protected:
-  void PaintThebes();
+  void PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates);
 
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
 
   void DestroyBackBuffer()
   {
     mContentClient = nullptr;
   }
 
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -405,20 +405,24 @@ ContentClientRemoteBuffer::Updated(const
   } else {
     AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
     CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
     t->mTextureClient = mTextureClient;
     IntSize size = mTextureClient->GetSize();
     t->mPictureRect = nsIntRect(0, 0, size.width, size.height);
     GetForwarder()->UseTextures(this, textures);
   }
+  // This forces a synchronous transaction, so we can swap buffers now
+  // and know that we'll have sole ownership of the old front buffer
+  // by the time we paint next.
   mForwarder->UpdateTextureRegion(this,
                                   ThebesBufferData(BufferRect(),
                                                    BufferRotation()),
                                   updatedRegion);
+  SwapBuffers(updatedRegion);
 }
 
 void
 ContentClientRemoteBuffer::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion)
 {
   mFrontAndBackBufferDiffer = true;
 }
 
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -100,23 +100,21 @@ public:
                          const gfx::Matrix4x4& aTransform,
                          const gfx::SamplingFilter aSamplingFilter,
                          const gfx::IntRect& aClipRect,
                          const nsIntRegion* aVisibleRegion = nullptr,
                          const Maybe<gfx::Polygon>& aGeometry = Nothing()) = 0;
 
   /**
    * Update the content host.
-   * aUpdated is the region which should be updated
-   * aUpdatedRegionBack is the region in aNewBackResult which has been updated
+   * aUpdated is the region which should be updated.
    */
   virtual bool UpdateThebes(const ThebesBufferData& aData,
                             const nsIntRegion& aUpdated,
-                            const nsIntRegion& aOldValidRegionBack,
-                            nsIntRegion* aUpdatedRegionBack)
+                            const nsIntRegion& aOldValidRegionBack)
   {
     NS_ERROR("should be implemented or not used");
     return false;
   }
 
   /**
    * Returns the front buffer.
    * *aPictureRect (if non-null, and the returned TextureHost is non-null)
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -317,21 +317,18 @@ AddWrappedRegion(const nsIntRegion& aInp
   tempRegion.And(IntRect(aShift, aSize), aInput);
   tempRegion.MoveBy(-aShift);
   aOutput.Or(aOutput, tempRegion);
 }
 
 bool
 ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
                                         const nsIntRegion& aUpdated,
-                                        const nsIntRegion& aOldValidRegionBack,
-                                        nsIntRegion* aUpdatedRegionBack)
+                                        const nsIntRegion& aOldValidRegionBack)
 {
-  aUpdatedRegionBack->SetEmpty();
-
   if (!mTextureHost) {
     mInitialised = false;
     return true; // FIXME should we return false? Returning true for now
   }              // to preserve existing behavior of NOT causing IPC errors.
 
   // updated is in screen coordinates. Convert it to buffer coordinates.
   nsIntRegion destRegion(aUpdated);
 
@@ -380,40 +377,35 @@ ContentHostSingleBuffered::UpdateThebes(
   mBufferRotation = aData.rotation();
 
   return true;
 }
 
 bool
 ContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData,
                                         const nsIntRegion& aUpdated,
-                                        const nsIntRegion& aOldValidRegionBack,
-                                        nsIntRegion* aUpdatedRegionBack)
+                                        const nsIntRegion& aOldValidRegionBack)
 {
   if (!mTextureHost) {
     mInitialised = false;
-
-    *aUpdatedRegionBack = aUpdated;
     return true;
   }
 
   // We don't need to calculate an update region because we assume that if we
   // are using double buffering then we have render-to-texture and thus no
   // upload to do.
   mTextureHost->Updated();
   if (mTextureHostOnWhite) {
     mTextureHostOnWhite->Updated();
   }
   mInitialised = true;
 
   mBufferRect = aData.rect();
   mBufferRotation = aData.rotation();
 
-  *aUpdatedRegionBack = aUpdated;
-
   // Save the current valid region of our front buffer, because if
   // we're double buffering, it's going to be the valid region for the
   // next back buffer sent back to the renderer.
   //
   // NB: we rely here on the fact that mValidRegion is initialized to
   // empty, and that the first time Swap() is called we don't have a
   // valid front buffer that we're going to return to content.
   mValidRegionForNextBackBuffer = aOldValidRegionBack;
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -49,18 +49,17 @@ struct TexturedEffect;
  *
  * ContentHosts support only UpdateThebes(), not Update().
  */
 class ContentHost : public CompositableHost
 {
 public:
   virtual bool UpdateThebes(const ThebesBufferData& aData,
                             const nsIntRegion& aUpdated,
-                            const nsIntRegion& aOldValidRegionBack,
-                            nsIntRegion* aUpdatedRegionBack) = 0;
+                            const nsIntRegion& aOldValidRegionBack) = 0;
 
   virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
   bool PaintWillResample() { return mPaintWillResample; }
 
   // We use this to allow TiledContentHost to invalidate regions where
   // tiles are fading in.
   virtual void AddAnimationInvalidation(nsIntRegion& aRegion) { }
 
@@ -192,18 +191,17 @@ public:
   {}
 
   virtual ~ContentHostDoubleBuffered() {}
 
   virtual CompositableType GetType() { return CompositableType::CONTENT_DOUBLE; }
 
   virtual bool UpdateThebes(const ThebesBufferData& aData,
                             const nsIntRegion& aUpdated,
-                            const nsIntRegion& aOldValidRegionBack,
-                            nsIntRegion* aUpdatedRegionBack);
+                            const nsIntRegion& aOldValidRegionBack);
 
 protected:
   nsIntRegion mValidRegionForNextBackBuffer;
 };
 
 /**
  * Single buffered, therefore we must synchronously upload the image from the
  * TextureHost in the layers transaction (i.e., in UpdateThebes).
@@ -215,16 +213,15 @@ public:
     : ContentHostTexture(aTextureInfo)
   {}
   virtual ~ContentHostSingleBuffered() {}
 
   virtual CompositableType GetType() { return CompositableType::CONTENT_SINGLE; }
 
   virtual bool UpdateThebes(const ThebesBufferData& aData,
                             const nsIntRegion& aUpdated,
-                            const nsIntRegion& aOldValidRegionBack,
-                            nsIntRegion* aUpdatedRegionBack);
+                            const nsIntRegion& aOldValidRegionBack);
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/composite/TiledContentHost.h
+++ b/gfx/layers/composite/TiledContentHost.h
@@ -197,18 +197,17 @@ public:
     return LayerRenderState();
   }
 
   // Generate effect for layerscope when using hwc.
   virtual already_AddRefed<TexturedEffect> GenEffect(const gfx::SamplingFilter aSamplingFilter) override;
 
   virtual bool UpdateThebes(const ThebesBufferData& aData,
                             const nsIntRegion& aUpdated,
-                            const nsIntRegion& aOldValidRegionBack,
-                            nsIntRegion* aUpdatedRegionBack) override
+                            const nsIntRegion& aOldValidRegionBack) override
   {
     NS_ERROR("N/A for tiled layers");
     return false;
   }
 
   const nsIntRegion& GetValidLowPrecisionRegion() const
   {
     return mLowPrecisionTiledBuffer.GetValidRegion();
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -56,18 +56,17 @@ ScheduleComposition(CompositableHost* aC
   if (!cp) {
     return false;
   }
   cp->ScheduleComposition();
   return true;
 }
 
 bool
-CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
-                                                     EditReplyVector& replyv)
+CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit)
 {
   // Ignore all operations on compositables created on stale compositors. We
   // return true because the child is unable to handle errors.
   RefPtr<CompositableHost> compositable = FindCompositable(aEdit.compositable());
   if (!compositable) {
     return false;
   }
   if (compositable->GetCompositor() && !compositable->GetCompositor()->IsValid()) {
@@ -84,26 +83,22 @@ CompositableParentManager::ReceiveCompos
         return false;
       }
       PaintedLayerComposite* thebes = static_cast<PaintedLayerComposite*>(layer);
 
       const ThebesBufferData& bufferData = op.bufferData();
 
       RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());
 
-      nsIntRegion frontUpdatedRegion;
       if (!compositable->UpdateThebes(bufferData,
                                       op.updatedRegion(),
-                                      thebes->GetValidRegion(),
-                                      &frontUpdatedRegion))
+                                      thebes->GetValidRegion()))
       {
         return false;
       }
-      replyv.push_back(
-        OpContentBufferSwap(aEdit.compositable(), frontUpdatedRegion));
 
       RenderTraceInvalidateEnd(thebes, "FF00FF");
       break;
     }
     case CompositableOperationDetail::TOpUseTiledLayerBuffer: {
       MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
       const OpUseTiledLayerBuffer& op = aEdit.detail().get_OpUseTiledLayerBuffer();
       TiledContentHost* tiledHost = compositable->AsTiledContentHost();
--- a/gfx/layers/ipc/CompositableTransactionParent.h
+++ b/gfx/layers/ipc/CompositableTransactionParent.h
@@ -12,18 +12,16 @@
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator
 #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
 #include "CompositableHost.h"
 
 namespace mozilla {
 namespace layers {
 
-typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
-
 // Since PCompositble has two potential manager protocols, we can't just call
 // the Manager() method usually generated when there's one manager protocol,
 // so both manager protocols implement this and we keep a reference to them
 // through this interface.
 class CompositableParentManager : public HostIPCAllocator
 {
 public:
   CompositableParentManager() {}
@@ -42,18 +40,17 @@ public:
     const CompositableHandle& aHandle,
     const TextureInfo& aInfo);
   RefPtr<CompositableHost> FindCompositable(const CompositableHandle& aHandle);
 
 protected:
   /**
    * Handle the IPDL messages that affect PCompositable actors.
    */
-  bool ReceiveCompositableUpdate(const CompositableOperation& aEdit,
-                                 EditReplyVector& replyv);
+  bool ReceiveCompositableUpdate(const CompositableOperation& aEdit);
 
   void ReleaseCompositable(const CompositableHandle& aHandle);
 
   uint64_t mFwdTransactionId = 0;
 
   /**
    * Mapping form IDs to CompositableHosts.
    */
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -550,34 +550,29 @@ ImageBridgeChild::EndTransaction()
   if (!mTxn->mOperations.empty()) {
     cset.AppendElements(&mTxn->mOperations.front(), mTxn->mOperations.size());
   }
 
   if (!IsSameProcess()) {
     ShadowLayerForwarder::PlatformSyncBeforeUpdate();
   }
 
-  AutoTArray<EditReply, 10> replies;
-
   if (mTxn->mSwapRequired) {
-    if (!SendUpdate(cset, mTxn->mDestroyedActors, GetFwdTransactionId(), &replies)) {
+    if (!SendUpdate(cset, mTxn->mDestroyedActors, GetFwdTransactionId())) {
       NS_WARNING("could not send async texture transaction");
       return;
     }
   } else {
     // If we don't require a swap we can call SendUpdateNoSwap which
     // assumes that aReplies is empty (DEBUG assertion)
     if (!SendUpdateNoSwap(cset, mTxn->mDestroyedActors, GetFwdTransactionId())) {
       NS_WARNING("could not send async texture transaction (no swap)");
       return;
     }
   }
-  for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
-    MOZ_CRASH("not reached");
-  }
 }
 
 void
 ImageBridgeChild::SendImageBridgeThreadId()
 {
 }
 
 bool
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -149,53 +149,44 @@ public:
   }
 private:
   ImageBridgeParent* mImageBridge;
   InfallibleTArray<OpDestroy>* mToDestroy;
 };
 
 mozilla::ipc::IPCResult
 ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
-                              const uint64_t& aFwdTransactionId,
-                              EditReplyArray* aReply)
+                              const uint64_t& aFwdTransactionId)
 {
   // This ensures that destroy operations are always processed. It is not safe
   // to early-return from RecvUpdate without doing so.
   AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
   UpdateFwdTransactionId(aFwdTransactionId);
 
-  EditReplyVector replyv;
   for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
-    if (!ReceiveCompositableUpdate(aEdits[i], replyv)) {
+    if (!ReceiveCompositableUpdate(aEdits[i])) {
       return IPC_FAIL_NO_REASON(this);
     }
   }
 
-  aReply->SetCapacity(replyv.size());
-  if (replyv.size() > 0) {
-    aReply->AppendElements(&replyv.front(), replyv.size());
-  }
-
   if (!IsSameProcess()) {
     // Ensure that any pending operations involving back and front
     // buffers have completed, so that neither process stomps on the
     // other's buffer contents.
     LayerManagerComposite::PlatformSyncBeforeReplyUpdate();
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
                                     const uint64_t& aFwdTransactionId)
 {
-  InfallibleTArray<EditReply> noReplies;
-  bool success = RecvUpdate(Move(aEdits), Move(aToDestroy), aFwdTransactionId, &noReplies);
-  MOZ_ASSERT(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
+  bool success = RecvUpdate(Move(aEdits), Move(aToDestroy), aFwdTransactionId);
   if (!success) {
     return IPC_FAIL_NO_REASON(this);
   }
   return IPC_OK();
 }
 
 /* static */ bool
 ImageBridgeParent::CreateForContent(Endpoint<PImageBridgeParent>&& aEndpoint)
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -38,17 +38,16 @@ struct ImageCompositeNotificationInfo;
  */
 class ImageBridgeParent final : public PImageBridgeParent,
                                 public CompositableParentManager,
                                 public ShmemAllocator
 {
 public:
   typedef InfallibleTArray<CompositableOperation> EditArray;
   typedef InfallibleTArray<OpDestroy> OpDestroyArray;
-  typedef InfallibleTArray<EditReply> EditReplyArray;
 
 protected:
   ImageBridgeParent(MessageLoop* aLoop, ProcessId aChildProcessId);
 
 public:
   ~ImageBridgeParent();
 
   static ImageBridgeParent* CreateSameProcess();
@@ -67,18 +66,17 @@ public:
   virtual base::ProcessId GetChildProcessId() override
   {
     return OtherPid();
   }
 
   // PImageBridge
   virtual mozilla::ipc::IPCResult RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override;
   virtual mozilla::ipc::IPCResult RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
-                                          const uint64_t& aFwdTransactionId,
-                                          EditReplyArray* aReply) override;
+                                          const uint64_t& aFwdTransactionId) override;
   virtual mozilla::ipc::IPCResult RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
                                                 const uint64_t& aFwdTransactionId) override;
 
   virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                               const LayersBackend& aLayersBackend,
                                               const TextureFlags& aFlags,
                                               const uint64_t& aSerial) override;
   virtual bool DeallocPTextureParent(PTextureParent* actor) override;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -36,18 +36,16 @@
 #include "nsMathUtils.h"                // for NS_round
 #include "nsPoint.h"                    // for nsPoint
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "TreeTraversal.h"              // for ForEachNode
 #include "GeckoProfiler.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/layers/AsyncCompositionManager.h"
 
-typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
-
 using mozilla::layout::RenderFrameParent;
 
 namespace mozilla {
 namespace layers {
 
 //--------------------------------------------------
 // LayerTransactionParent
 LayerTransactionParent::LayerTransactionParent(HostLayerManager* aManager,
@@ -94,17 +92,17 @@ LayerTransactionParent::Destroy()
 {
   mDestroyed = true;
   mCompositables.clear();
 }
 
 mozilla::ipc::IPCResult
 LayerTransactionParent::RecvUpdateNoSwap(const TransactionInfo& txn)
 {
-  return RecvUpdate(txn, nullptr);
+  return RecvUpdate(txn);
 }
 
 class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender
 {
 public:
   explicit AutoLayerTransactionParentAsyncMessageSender(LayerTransactionParent* aLayerTransaction,
                                                         const InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
     : mLayerTransaction(aLayerTransaction)
@@ -135,18 +133,17 @@ mozilla::ipc::IPCResult
 LayerTransactionParent::RecvPaintTime(const uint64_t& aTransactionId,
                                       const TimeDuration& aPaintTime)
 {
   mCompositorBridge->UpdatePaintTime(this, aPaintTime);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo,
-                                   InfallibleTArray<EditReply>* reply)
+LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
 {
   GeckoProfilerTracingRAII tracer("Paint", "LayerTransaction");
   PROFILER_LABEL("LayerTransactionParent", "RecvUpdate",
     js::ProfileEntry::Category::GRAPHICS);
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   TimeStamp updateStart = TimeStamp::Now();
 #endif
@@ -160,17 +157,16 @@ LayerTransactionParent::RecvUpdate(const
       DestroyActor(op);
     }
     return IPC_OK();
   }
 
   // This ensures that destroy operations are always processed. It is not safe
   // to early-return from RecvUpdate without doing so.
   AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this, &aInfo.toDestroy());
-  EditReplyVector replyv;
 
   {
     AutoResolveRefLayers resolve(mCompositorBridge->GetCompositionManager(this));
     layer_manager()->BeginTransaction();
   }
 
   // not all edits require an update to the hit testing tree
   bool updateHitTestingTree = false;
@@ -380,18 +376,17 @@ LayerTransactionParent::RecvUpdate(const
       if (!container || !container->RepositionChild(child, nullptr)) {
         return IPC_FAIL_NO_REASON(this);
       }
 
       updateHitTestingTree = true;
       break;
     }
     case Edit::TCompositableOperation: {
-      if (!ReceiveCompositableUpdate(edit.get_CompositableOperation(),
-                                replyv)) {
+      if (!ReceiveCompositableUpdate(edit.get_CompositableOperation())) {
         return IPC_FAIL_NO_REASON(this);
       }
       break;
     }
     case Edit::TOpAttachCompositable: {
       const OpAttachCompositable& op = edit.get_OpAttachCompositable();
       RefPtr<CompositableHost> host = FindCompositable(op.compositable());
       if (mPendingCompositorUpdate) {
@@ -457,35 +452,28 @@ LayerTransactionParent::RecvUpdate(const
     if (!SetLayerAttributes(op)) {
       return IPC_FAIL_NO_REASON(this);
     }
     updateHitTestingTree = true;
   }
 
   // Process paints separately, after all normal edits.
   for (const auto& op : aInfo.paints()) {
-    if (!ReceiveCompositableUpdate(op, replyv)) {
+    if (!ReceiveCompositableUpdate(op)) {
       return IPC_FAIL_NO_REASON(this);
     }
   }
 
   mCompositorBridge->ShadowLayersUpdated(this, aInfo, updateHitTestingTree);
 
   {
     AutoResolveRefLayers resolve(mCompositorBridge->GetCompositionManager(this));
     layer_manager()->EndTransaction(TimeStamp(), LayerManager::END_NO_IMMEDIATE_REDRAW);
   }
 
-  if (reply) {
-    reply->SetCapacity(replyv.size());
-    if (replyv.size() > 0) {
-      reply->AppendElements(&replyv.front(), replyv.size());
-    }
-  }
-
   if (!IsSameProcess()) {
     // Ensure that any pending operations involving back and front
     // buffers have completed, so that neither process stomps on the
     // other's buffer contents.
     LayerManagerComposite::PlatformSyncBeforeReplyUpdate();
   }
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -37,17 +37,16 @@ class CompositorBridgeParentBase;
 
 class LayerTransactionParent final : public PLayerTransactionParent,
                                      public CompositableParentManager,
                                      public ShmemAllocator
 {
   typedef mozilla::layout::RenderFrameParent RenderFrameParent;
   typedef InfallibleTArray<Edit> EditArray;
   typedef InfallibleTArray<OpDestroy> OpDestroyArray;
-  typedef InfallibleTArray<EditReply> EditReplyArray;
   typedef InfallibleTArray<PluginWindowData> PluginsArray;
 
 public:
   LayerTransactionParent(HostLayerManager* aManager,
                          CompositorBridgeParentBase* aBridge,
                          uint64_t aId);
 
 protected:
@@ -107,18 +106,17 @@ public:
   }
 
 protected:
   virtual mozilla::ipc::IPCResult RecvShutdown() override;
 
   virtual mozilla::ipc::IPCResult RecvPaintTime(const uint64_t& aTransactionId,
                                                 const TimeDuration& aPaintTime) override;
 
-  virtual mozilla::ipc::IPCResult RecvUpdate(const TransactionInfo& aInfo,
-                                             EditReplyArray* reply) override;
+  virtual mozilla::ipc::IPCResult RecvUpdate(const TransactionInfo& aInfo) override;
 
   virtual mozilla::ipc::IPCResult RecvUpdateNoSwap(const TransactionInfo& aInfo) override;
 
   virtual mozilla::ipc::IPCResult RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch) override;
   virtual mozilla::ipc::IPCResult RecvNewCompositable(const CompositableHandle& aHandle,
                                                       const TextureInfo& aInfo) override;
   virtual mozilla::ipc::IPCResult RecvReleaseLayer(const LayerHandle& aHandle) override;
   virtual mozilla::ipc::IPCResult RecvReleaseCompositable(const CompositableHandle& aHandle) override;
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -501,22 +501,16 @@ struct OpContentBufferSwap {
 struct ImageCompositeNotification {
   CompositableHandle compositable;
   TimeStamp imageTimeStamp;
   TimeStamp firstCompositeTimeStamp;
   uint32_t frameID;
   uint32_t producerID;
 };
 
-// Unit of a "changeset reply".  This is a weird abstraction, probably
-// only to be used for buffer swapping.
-union EditReply {
-  OpContentBufferSwap;
-};
-
 union AsyncParentMessageData {
   OpNotifyNotUsed;
 };
 
 struct TransactionInfo
 {
   Edit[] cset;
   OpSetSimpleLayerAttributes[] setSimpleAttrs;
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -33,18 +33,17 @@ sync protocol PImageBridge
 child:
   async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
 
   async DidComposite(ImageCompositeNotification[] aNotifications);
 
 parent:
   async ImageBridgeThreadId(PlatformThreadId aTreahdId);
 
-  sync Update(CompositableOperation[] ops, OpDestroy[] toDestroy, uint64_t fwdTransactionId)
-    returns (EditReply[] reply);
+  sync Update(CompositableOperation[] ops, OpDestroy[] toDestroy, uint64_t fwdTransactionId);
 
   async UpdateNoSwap(CompositableOperation[] ops, OpDestroy[] toDestroy, uint64_t fwdTransactionId);
 
   // First step of the destruction sequence. This puts ImageBridge
   // in a state in which it can't send asynchronous messages
   // so as to not race with the channel getting closed.
   // In the child side, the Closing the channel does not happen right after WillClose,
   // it is scheduled in the ImageBridgeChild's message queue in order to ensure
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -47,17 +47,17 @@ union MaybeTransform {
  * there is one) or the UI process otherwise.
  */
 sync protocol PLayerTransaction {
   manager PCompositorBridge;
 
 parent:
   // The isFirstPaint flag can be used to indicate that this is the first update
   // for a particular document.
-  sync Update(TransactionInfo txn) returns (EditReply[] reply);
+  sync Update(TransactionInfo txn);
 
   async PaintTime(uint64_t id, TimeDuration paintTime);
 
   // We don't need to send a sync transaction if
   // no transaction operate require a swap.
   async UpdateNoSwap(TransactionInfo txn);
 
   async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -722,25 +722,23 @@ ShadowLayerForwarder::EndTransaction(con
 
   if (!GetTextureForwarder()->IsSameProcess()) {
     MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
     PlatformSyncBeforeUpdate();
   }
 
   profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END);
 
-  AutoTArray<EditReply, 10> replies;
   if (mTxn->mSwapRequired) {
     MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
     RenderTraceScope rendertrace3("Forward Transaction", "000093");
-    if (!mShadowManager->SendUpdate(info, &replies)) {
+    if (!mShadowManager->SendUpdate(info)) {
       MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
       return false;
     }
-    ProcessReplies(replies);
   } else {
     // If we don't require a swap we can call SendUpdateNoSwap which
     // assumes that aReplies is empty (DEBUG assertion)
     MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction..."));
     RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093");
     if (!mShadowManager->SendUpdateNoSwap(info)) {
       MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
       return false;
@@ -749,39 +747,16 @@ ShadowLayerForwarder::EndTransaction(con
 
   *aSent = true;
   mIsFirstPaint = false;
   mPaintSyncId = 0;
   MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
   return true;
 }
 
-void
-ShadowLayerForwarder::ProcessReplies(const nsTArray<EditReply>& aReplies)
-{
-  for (const auto& reply : aReplies) {
-    switch (reply.type()) {
-    case EditReply::TOpContentBufferSwap: {
-      MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
-
-      const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
-
-      RefPtr<CompositableClient> compositable = FindCompositable(obs.compositable());
-      ContentClientRemote* contentClient = compositable->AsContentClientRemote();
-      MOZ_ASSERT(contentClient);
-
-      contentClient->SwapBuffers(obs.frontUpdatedRegion());
-      break;
-    }
-    default:
-      MOZ_CRASH("not reached");
-    }
-  }
-}
-
 RefPtr<CompositableClient>
 ShadowLayerForwarder::FindCompositable(const CompositableHandle& aHandle)
 {
   CompositableClient* client = nullptr;
   if (!mCompositables.Get(aHandle.Value(), &client)) {
     return nullptr;
   }
   return client;
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -28,17 +28,16 @@
 #include <vector>
 #include "nsExpirationTracker.h"
 
 namespace mozilla {
 namespace layers {
 
 class ClientLayerManager;
 class CompositorBridgeChild;
-class EditReply;
 class FixedSizeSmallShmemSectionAllocator;
 class ImageContainer;
 class Layer;
 class PLayerTransactionChild;
 class LayerTransactionChild;
 class ShadowableLayer;
 class SurfaceDescriptor;
 class TextureClient;
@@ -416,18 +415,16 @@ protected:
   explicit ShadowLayerForwarder(ClientLayerManager* aClientLayerManager);
 
 #ifdef DEBUG
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
 #else
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {}
 #endif
 
-  void ProcessReplies(const nsTArray<EditReply>& aReplies);
-
   RefPtr<CompositableClient> FindCompositable(const CompositableHandle& aHandle);
 
   bool InWorkerThread();
 
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   RefPtr<LayerTransactionChild> mShadowManager;
   RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -331,19 +331,17 @@ WebRenderBridgeParent::ProcessWebrenderC
         break;
       }
       case WebRenderCommand::TOpDPPushIframe: {
         const OpDPPushIframe& op = cmd.get_OpDPPushIframe();
         builder.PushIFrame(op.bounds(), op.clip(), op.pipelineId());
         break;
       }
       case WebRenderCommand::TCompositableOperation: {
-        EditReplyVector replyv;
-        if (!ReceiveCompositableUpdate(cmd.get_CompositableOperation(),
-                                       replyv)) {
+        if (!ReceiveCompositableUpdate(cmd.get_CompositableOperation())) {
           NS_ERROR("ReceiveCompositableUpdate failed");
         }
         break;
       }
       case WebRenderCommand::TOpDPPushText: {
         const OpDPPushText& op = cmd.get_OpDPPushText();
         const nsTArray<WrGlyphArray>& glyph_array = op.glyph_array();