Simplify calling SendUpdate/SendUpdateNoSwap. (bug 1325993, r=nical)
authorDavid Anderson <dvander@alliedmods.net>
Wed, 04 Jan 2017 12:58:58 -0500
changeset 327971 49bdb10395bd40c4ef0b72c059fdd3a67d4dcaf8
parent 327970 061f9628b1728d91a4475d255731c5c2f5a7b50c
child 327972 3e3b75439ccaf3c0b661e2ce5d3af797a2734501
push id31160
push userphilringnalda@gmail.com
push dateThu, 05 Jan 2017 02:33:44 +0000
treeherdermozilla-central@f13abb8ba9f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1325993
milestone53.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
Simplify calling SendUpdate/SendUpdateNoSwap. (bug 1325993, r=nical)
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/PLayerTransaction.ipdl
gfx/layers/ipc/ShadowLayers.cpp
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1137,58 +1137,54 @@ CompositorBridgeParent::ScheduleRotation
       NewCancelableRunnableMethod(this, &CompositorBridgeParent::ForceComposition);
     mForceCompositionTask = task;
     ScheduleTask(task.forget(), gfxPrefs::OrientationSyncMillis());
   }
 }
 
 void
 CompositorBridgeParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
-                                            const uint64_t& aTransactionId,
-                                            const TargetConfig& aTargetConfig,
-                                            const InfallibleTArray<PluginWindowData>& aUnused,
-                                            bool aIsFirstPaint,
-                                            bool aScheduleComposite,
-                                            uint32_t aPaintSequenceNumber,
-                                            bool aIsRepeatTransaction,
-                                            int32_t aPaintSyncId,
+                                            const TransactionInfo& aInfo,
                                             bool aHitTestUpdate)
 {
-  ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
+  const TargetConfig& targetConfig = aInfo.targetConfig();
+
+  ScheduleRotationOnCompositorThread(targetConfig, aInfo.isFirstPaint());
 
   // Instruct the LayerManager to update its render bounds now. Since all the orientation
   // change, dimension change would be done at the stage, update the size here is free of
   // race condition.
-  mLayerManager->UpdateRenderBounds(aTargetConfig.naturalBounds());
-  mLayerManager->SetRegionToClear(aTargetConfig.clearRegion());
+  mLayerManager->UpdateRenderBounds(targetConfig.naturalBounds());
+  mLayerManager->SetRegionToClear(targetConfig.clearRegion());
   if (mLayerManager->GetCompositor()) {
-    mLayerManager->GetCompositor()->SetScreenRotation(aTargetConfig.rotation());
+    mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
   }
 
-  mCompositionManager->Updated(aIsFirstPaint, aTargetConfig, aPaintSyncId);
+  mCompositionManager->Updated(aInfo.isFirstPaint(), targetConfig, aInfo.paintSyncId());
   Layer* root = aLayerTree->GetRoot();
   mLayerManager->SetRoot(root);
 
-  if (mApzcTreeManager && !aIsRepeatTransaction && aHitTestUpdate) {
+  if (mApzcTreeManager && !aInfo.isRepeatTransaction() && aHitTestUpdate) {
     AutoResolveRefLayers resolve(mCompositionManager);
 
-    mApzcTreeManager->UpdateHitTestingTree(mRootLayerTreeID, root, aIsFirstPaint,
-        mRootLayerTreeID, aPaintSequenceNumber);
+    mApzcTreeManager->UpdateHitTestingTree(
+      mRootLayerTreeID, root, aInfo.isFirstPaint(),
+      mRootLayerTreeID, aInfo.paintSequenceNumber());
   }
 
   // The transaction ID might get reset to 1 if the page gets reloaded, see
   // https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
   // Otherwise, it should be continually increasing.
-  MOZ_ASSERT(aTransactionId == 1 || aTransactionId > mPendingTransaction);
-  mPendingTransaction = aTransactionId;
+  MOZ_ASSERT(aInfo.id() == 1 || aInfo.id() > mPendingTransaction);
+  mPendingTransaction = aInfo.id();
 
   if (root) {
     SetShadowProperties(root);
   }
-  if (aScheduleComposite) {
+  if (aInfo.scheduleComposite()) {
     ScheduleComposition();
     if (mPaused) {
       TimeStamp now = TimeStamp::Now();
       DidComposite(now, now);
     }
   }
   mLayerManager->NotifyShadowTreeTransaction();
 }
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -85,24 +85,17 @@ private:
 
 class CompositorBridgeParentBase : public PCompositorBridgeParent,
                                    public HostIPCAllocator,
                                    public ShmemAllocator,
                                    public MetricsSharingController
 {
 public:
   virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
-                                   const uint64_t& aTransactionId,
-                                   const TargetConfig& aTargetConfig,
-                                   const InfallibleTArray<PluginWindowData>& aPlugins,
-                                   bool aIsFirstPaint,
-                                   bool aScheduleComposite,
-                                   uint32_t aPaintSequenceNumber,
-                                   bool aIsRepeatTransaction,
-                                   int32_t aPaintSyncId,
+                                   const TransactionInfo& aInfo,
                                    bool aHitTestUpdate) = 0;
 
   virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) { return nullptr; }
 
   virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) { }
 
   virtual void ForceComposite(LayerTransactionParent* aLayerTree) { }
   virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
@@ -215,24 +208,17 @@ public:
   virtual mozilla::ipc::IPCResult RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
                                                                        const CSSIntRegion& aRegion) override;
 
   virtual mozilla::ipc::IPCResult RecvAllPluginsCaptured() override;
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
-                                   const uint64_t& aTransactionId,
-                                   const TargetConfig& aTargetConfig,
-                                   const InfallibleTArray<PluginWindowData>& aPlugins,
-                                   bool aIsFirstPaint,
-                                   bool aScheduleComposite,
-                                   uint32_t aPaintSequenceNumber,
-                                   bool aIsRepeatTransaction,
-                                   int32_t aPaintSyncId,
+                                   const TransactionInfo& aInfo,
                                    bool aHitTestUpdate) override;
   virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
   virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
                                  const TimeStamp& aTime) override;
   virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
   virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
                override;
   virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -203,64 +203,64 @@ CrossProcessCompositorBridgeParent::Recv
     }
   }
   return IPC_FAIL_NO_REASON(this);
 }
 
 void
 CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
   LayerTransactionParent* aLayerTree,
-  const uint64_t& aTransactionId,
-  const TargetConfig& aTargetConfig,
-  const InfallibleTArray<PluginWindowData>& aPlugins,
-  bool aIsFirstPaint,
-  bool aScheduleComposite,
-  uint32_t aPaintSequenceNumber,
-  bool aIsRepeatTransaction,
-  int32_t /*aPaintSyncId: unused*/,
+  const TransactionInfo& aInfo,
   bool aHitTestUpdate)
 {
   uint64_t id = aLayerTree->GetId();
 
   MOZ_ASSERT(id != 0);
 
   CompositorBridgeParent::LayerTreeState* state =
     CompositorBridgeParent::GetIndirectShadowTree(id);
   if (!state) {
     return;
   }
   MOZ_ASSERT(state->mParent);
-  state->mParent->ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
+  state->mParent->ScheduleRotationOnCompositorThread(
+    aInfo.targetConfig(),
+    aInfo.isFirstPaint());
 
   Layer* shadowRoot = aLayerTree->GetRoot();
   if (shadowRoot) {
     CompositorBridgeParent::SetShadowProperties(shadowRoot);
   }
-  UpdateIndirectTree(id, shadowRoot, aTargetConfig);
+  UpdateIndirectTree(id, shadowRoot, aInfo.targetConfig());
 
   // Cache the plugin data for this remote layer tree
-  state->mPluginData = aPlugins;
+  state->mPluginData = aInfo.plugins();
   state->mUpdatedPluginDataAvailable = true;
 
-  state->mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite,
-      aPaintSequenceNumber, aIsRepeatTransaction, aHitTestUpdate);
+  state->mParent->NotifyShadowTreeTransaction(
+    id,
+    aInfo.isFirstPaint(),
+    aInfo.scheduleComposite(),
+    aInfo.paintSequenceNumber(),
+    aInfo.isRepeatTransaction(),
+    aHitTestUpdate);
 
   // Send the 'remote paint ready' message to the content thread if it has already asked.
   if(mNotifyAfterRemotePaint)  {
     Unused << SendRemotePaintIsReady();
     mNotifyAfterRemotePaint = false;
   }
 
   if (aLayerTree->ShouldParentObserveEpoch()) {
     // Note that we send this through the window compositor, since this needs
     // to reach the widget owning the tab.
     Unused << state->mParent->SendObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), true);
   }
 
-  aLayerTree->SetPendingTransactionId(aTransactionId);
+  aLayerTree->SetPendingTransactionId(aInfo.id());
 }
 
 void
 CrossProcessCompositorBridgeParent::DidComposite(
   uint64_t aId,
   TimeStamp& aCompositeStart,
   TimeStamp& aCompositeEnd)
 {
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
@@ -89,24 +89,17 @@ public:
     AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
                                  const uint64_t& aId,
                                  TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                  bool *aSuccess) override;
 
   virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override;
 
   virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
-                                   const uint64_t& aTransactionId,
-                                   const TargetConfig& aTargetConfig,
-                                   const InfallibleTArray<PluginWindowData>& aPlugins,
-                                   bool aIsFirstPaint,
-                                   bool aScheduleComposite,
-                                   uint32_t aPaintSequenceNumber,
-                                   bool aIsRepeatTransaction,
-                                   int32_t /*aPaintSyncId: unused*/,
+                                   const TransactionInfo& aInfo,
                                    bool aHitTestUpdate) override;
   virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
   virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) override;
   virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
                                  const TimeStamp& aTime) override;
   virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
   virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
                override;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -83,40 +83,26 @@ LayerTransactionParent::RecvShutdown()
 
 void
 LayerTransactionParent::Destroy()
 {
   mDestroyed = true;
 }
 
 mozilla::ipc::IPCResult
-LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset,
-                                         InfallibleTArray<OpDestroy>&& aToDestroy,
-                                         const uint64_t& aFwdTransactionId,
-                                         const uint64_t& aTransactionId,
-                                         const TargetConfig& targetConfig,
-                                         PluginsArray&& aPlugins,
-                                         const bool& isFirstPaint,
-                                         const bool& scheduleComposite,
-                                         const uint32_t& paintSequenceNumber,
-                                         const bool& isRepeatTransaction,
-                                         const mozilla::TimeStamp& aTransactionStart,
-                                         const int32_t& aPaintSyncId)
+LayerTransactionParent::RecvUpdateNoSwap(const TransactionInfo& txn)
 {
-  return RecvUpdate(Move(cset), Move(aToDestroy), aFwdTransactionId,
-      aTransactionId, targetConfig, Move(aPlugins), isFirstPaint,
-      scheduleComposite, paintSequenceNumber, isRepeatTransaction,
-      aTransactionStart, aPaintSyncId, nullptr);
+  return RecvUpdate(txn, nullptr);
 }
 
 class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender
 {
 public:
   explicit AutoLayerTransactionParentAsyncMessageSender(LayerTransactionParent* aLayerTransaction,
-                                                        InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
+                                                        const InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
     : mLayerTransaction(aLayerTransaction)
     , mActorsToDestroy(aDestroyActors)
   {
     mLayerTransaction->SetAboutToSendAsyncMessages();
     ImageBridgeParent::SetAboutToSendAsyncMessages(mLayerTransaction->GetChildProcessId());
   }
 
   ~AutoLayerTransactionParentAsyncMessageSender()
@@ -128,76 +114,65 @@ public:
       // references to some actors.
       for (const auto& op : *mActorsToDestroy) {
         mLayerTransaction->DestroyActor(op);
       }
     }
   }
 private:
   LayerTransactionParent* mLayerTransaction;
-  InfallibleTArray<OpDestroy>* mActorsToDestroy;
+  const InfallibleTArray<OpDestroy>* mActorsToDestroy;
 };
 
 mozilla::ipc::IPCResult
 LayerTransactionParent::RecvPaintTime(const uint64_t& aTransactionId,
                                       const TimeDuration& aPaintTime)
 {
   mCompositorBridge->UpdatePaintTime(this, aPaintTime);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
-                                   InfallibleTArray<OpDestroy>&& aToDestroy,
-                                   const uint64_t& aFwdTransactionId,
-                                   const uint64_t& aTransactionId,
-                                   const TargetConfig& targetConfig,
-                                   PluginsArray&& aPlugins,
-                                   const bool& isFirstPaint,
-                                   const bool& scheduleComposite,
-                                   const uint32_t& paintSequenceNumber,
-                                   const bool& isRepeatTransaction,
-                                   const mozilla::TimeStamp& aTransactionStart,
-                                   const int32_t& aPaintSyncId,
+LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo,
                                    InfallibleTArray<EditReply>* reply)
 {
   profiler_tracing("Paint", "LayerTransaction", TRACING_INTERVAL_START);
   PROFILER_LABEL("LayerTransactionParent", "RecvUpdate",
     js::ProfileEntry::Category::GRAPHICS);
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   TimeStamp updateStart = TimeStamp::Now();
 #endif
 
-  MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
+  MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", aInfo.cset().Length()));
 
-  UpdateFwdTransactionId(aFwdTransactionId);
+  UpdateFwdTransactionId(aInfo.fwdTransactionId());
 
   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
-    for (const auto& op : aToDestroy) {
+    for (const auto& op : aInfo.toDestroy()) {
       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, &aToDestroy);
+  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;
 
-  for (EditArray::index_type i = 0; i < cset.Length(); ++i) {
-    Edit& edit = cset[i];
+  for (EditArray::index_type i = 0; i < aInfo.cset().Length(); ++i) {
+    const Edit& edit = const_cast<Edit&>(aInfo.cset()[i]);
 
     switch (edit.type()) {
     // Create* ops
     case Edit::TOpCreatePaintedLayer: {
       MOZ_LAYERS_LOG(("[ParentSide] CreatePaintedLayer"));
 
       RefPtr<PaintedLayer> layer = layer_manager()->CreatePaintedLayer();
       if (!BindLayer(layer, edit.get_OpCreatePaintedLayer())) {
@@ -284,22 +259,22 @@ LayerTransactionParent::RecvUpdate(Infal
       updateHitTestingTree = true;
       break;
     }
 
     // Attributes
     case Edit::TOpSetLayerAttributes: {
       MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes"));
 
-      OpSetLayerAttributes& osla = edit.get_OpSetLayerAttributes();
+      const OpSetLayerAttributes& osla = edit.get_OpSetLayerAttributes();
       Layer* layer = AsLayer(osla.layer());
       if (!layer) {
         return IPC_FAIL_NO_REASON(this);
       }
-      LayerAttributes& attrs = osla.attrs();
+      const LayerAttributes& attrs = osla.attrs();
 
       const CommonLayerAttributes& common = attrs.common();
       layer->SetLayerBounds(common.layerBounds());
       layer->SetVisibleRegion(common.visibleRegion());
       layer->SetEventRegions(common.eventRegions());
       layer->SetContentFlags(common.contentFlags());
       layer->SetOpacity(common.opacity());
       layer->SetClipRect(common.useClipRect() ? Some(common.clipRect()) : Nothing());
@@ -345,17 +320,17 @@ LayerTransactionParent::RecvUpdate(Infal
         if (!maskLayer) {
           return IPC_FAIL_NO_REASON(this);
         }
         maskLayers.AppendElement(maskLayer);
       }
       layer->SetAncestorMaskLayers(maskLayers);
 
       typedef SpecificLayerAttributes Specific;
-      SpecificLayerAttributes& specific = attrs.specific();
+      const SpecificLayerAttributes& specific = attrs.specific();
       switch (specific.type()) {
       case Specific::Tnull_t:
         break;
 
       case Specific::TPaintedLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   painted layer"));
 
         PaintedLayer* paintedLayer = layer->AsPaintedLayer();
@@ -399,19 +374,20 @@ LayerTransactionParent::RecvUpdate(Infal
       }
       case Specific::TTextLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   text layer"));
 
         TextLayer* textLayer = layer->AsTextLayer();
         if (!textLayer) {
           return IPC_FAIL_NO_REASON(this);
         }
-        textLayer->SetBounds(specific.get_TextLayerAttributes().bounds());
-        textLayer->SetGlyphs(Move(specific.get_TextLayerAttributes().glyphs()));
-        textLayer->SetScaledFont(reinterpret_cast<gfx::ScaledFont*>(specific.get_TextLayerAttributes().scaledFont()));
+        const auto& tla = specific.get_TextLayerAttributes();
+        textLayer->SetBounds(tla.bounds());
+        textLayer->SetGlyphs(Move(const_cast<nsTArray<GlyphArray>&>(tla.glyphs())));
+        textLayer->SetScaledFont(reinterpret_cast<gfx::ScaledFont*>(tla.scaledFont()));
         break;
       }
       case Specific::TBorderLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   border layer"));
 
         BorderLayer* borderLayer = layer->AsBorderLayer();
         if (!borderLayer) {
           return IPC_FAIL_NO_REASON(this);
@@ -626,20 +602,17 @@ LayerTransactionParent::RecvUpdate(Infal
       }
       break;
     }
     default:
       MOZ_CRASH("not reached");
     }
   }
 
-  mCompositorBridge->ShadowLayersUpdated(this, aTransactionId, targetConfig,
-                                         aPlugins, isFirstPaint, scheduleComposite,
-                                         paintSequenceNumber, isRepeatTransaction,
-                                         aPaintSyncId, updateHitTestingTree);
+  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());
@@ -662,17 +635,17 @@ LayerTransactionParent::RecvUpdate(Infal
   }
 #endif
 
   // Enable visual warning for long transaction when draw FPS option is enabled
   bool drawFps = gfxPrefs::LayersDrawFPS();
   if (drawFps) {
     uint32_t visualWarningTrigger = gfxPrefs::LayerTransactionWarning();
     // The default theshold is 200ms to trigger, hit red when it take 4 times longer
-    TimeDuration latency = TimeStamp::Now() - aTransactionStart;
+    TimeDuration latency = TimeStamp::Now() - aInfo.transactionStart();
     if (latency > TimeDuration::FromMilliseconds(visualWarningTrigger)) {
       float severity = (latency - TimeDuration::FromMilliseconds(visualWarningTrigger)).ToMilliseconds() /
                          (4 * visualWarningTrigger);
       if (severity > 1.f) {
         severity = 1.f;
       }
       mLayerManager->VisualFrameWarning(severity);
       PR_LogPrint("LayerTransactionParent::RecvUpdate transaction from process %d took %f ms",
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -109,42 +109,20 @@ 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(EditArray&& cset,
-                                             OpDestroyArray&& aToDestroy,
-                                             const uint64_t& aFwdTransactionId,
-                                             const uint64_t& aTransactionId,
-                                             const TargetConfig& targetConfig,
-                                             PluginsArray&& aPlugins,
-                                             const bool& isFirstPaint,
-                                             const bool& scheduleComposite,
-                                             const uint32_t& paintSequenceNumber,
-                                             const bool& isRepeatTransaction,
-                                             const mozilla::TimeStamp& aTransactionStart,
-                                             const int32_t& aPaintSyncId,
+  virtual mozilla::ipc::IPCResult RecvUpdate(const TransactionInfo& aInfo,
                                              EditReplyArray* reply) override;
 
-  virtual mozilla::ipc::IPCResult RecvUpdateNoSwap(EditArray&& cset,
-                                                   OpDestroyArray&& aToDestroy,
-                                                   const uint64_t& aFwdTransactionId,
-                                                   const uint64_t& aTransactionId,
-                                                   const TargetConfig& targetConfig,
-                                                   PluginsArray&& aPlugins,
-                                                   const bool& isFirstPaint,
-                                                   const bool& scheduleComposite,
-                                                   const uint32_t& paintSequenceNumber,
-                                                   const bool& isRepeatTransaction,
-                                                   const mozilla::TimeStamp& aTransactionStart,
-                                                   const int32_t& aPaintSyncId) override;
+  virtual mozilla::ipc::IPCResult RecvUpdateNoSwap(const TransactionInfo& aInfo) override;
 
   virtual mozilla::ipc::IPCResult RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch) override;
   virtual mozilla::ipc::IPCResult RecvReleaseLayer(const LayerHandle& aHandle) override;
 
   virtual mozilla::ipc::IPCResult RecvClearCachedResources() override;
   virtual mozilla::ipc::IPCResult RecvForceComposite() override;
   virtual mozilla::ipc::IPCResult RecvSetTestSampleTime(const TimeStamp& aTime) override;
   virtual mozilla::ipc::IPCResult RecvLeaveTestMode() override;
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -534,10 +534,26 @@ struct ImageCompositeNotification {
 union EditReply {
   OpContentBufferSwap;
 };
 
 union AsyncParentMessageData {
   OpNotifyNotUsed;
 };
 
+struct TransactionInfo
+{
+  Edit[] cset;
+  OpDestroy[] toDestroy;
+  uint64_t fwdTransactionId;
+  uint64_t id;
+  TargetConfig targetConfig;
+  PluginWindowData[] plugins;
+  bool isFirstPaint;
+  bool scheduleComposite;
+  uint32_t paintSequenceNumber;
+  bool isRepeatTransaction;
+  TimeStamp transactionStart;
+  int32_t paintSyncId;
+};
+
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -42,36 +42,23 @@ sync protocol PLayerTransaction {
   manager PCompositorBridge;
   manages PCompositable;
 
 parent:
   async PCompositable(TextureInfo aTextureInfo);
 
   // The isFirstPaint flag can be used to indicate that this is the first update
   // for a particular document.
-  sync Update(Edit[] cset, OpDestroy[] toDestroy,
-              uint64_t fwdTransactionId,
-              uint64_t id, TargetConfig targetConfig,
-              PluginWindowData[] plugins, bool isFirstPaint,
-              bool scheduleComposite, uint32_t paintSequenceNumber,
-              bool isRepeatTransaction, TimeStamp transactionStart,
-              int32_t paintSyncId)
-    returns (EditReply[] reply);
+  sync Update(TransactionInfo txn) returns (EditReply[] reply);
 
   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(Edit[] cset, OpDestroy[] toDestroy,
-                     uint64_t fwdTransactionId,
-                     uint64_t id, TargetConfig targetConfig,
-                     PluginWindowData[] plugins, bool isFirstPaint,
-                     bool scheduleComposite, uint32_t paintSequenceNumber,
-                     bool isRepeatTransaction, TimeStamp transactionStart,
-                     int32_t paintSyncId);
+  async UpdateNoSwap(TransactionInfo txn);
 
   async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
 
   // Release a layer that is no longer in use.
   async ReleaseLayer(LayerHandle layer);
 
   // Testing APIs
 
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -565,16 +565,18 @@ ShadowLayerForwarder::EndTransaction(Inf
                                      bool aScheduleComposite,
                                      uint32_t aPaintSequenceNumber,
                                      bool aIsRepeatTransaction,
                                      const mozilla::TimeStamp& aTransactionStart,
                                      bool* aSent)
 {
   *aSent = false;
 
+  TransactionInfo info;
+
   MOZ_ASSERT(IPCOpen(), "no manager to forward to");
   if (!IPCOpen()) {
     return false;
   }
 
   GetCompositorBridgeChild()->WillEndTransaction();
 
   MOZ_ASSERT(aId);
@@ -687,68 +689,70 @@ ShadowLayerForwarder::EndTransaction(Inf
     attrs.specific() = null_t();
     mutant->FillSpecificAttributes(attrs.specific());
 
     MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant));
 
     mTxn->AddEdit(OpSetLayerAttributes(Shadow(shadow), attrs));
   }
 
-  AutoTArray<Edit, 10> cset;
   size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size();
   if (nCsets == 0 && !mTxn->RotationChanged()) {
     return true;
   }
 
+  auto& cset = info.cset();
   cset.SetCapacity(nCsets);
   if (!mTxn->mCset.empty()) {
     cset.AppendElements(&mTxn->mCset.front(), mTxn->mCset.size());
   }
   // Paints after non-paint ops, including attribute changes.  See
   // above.
   if (!mTxn->mPaints.empty()) {
     cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size());
   }
 
   mWindowOverlayChanged = false;
 
+  info.toDestroy() = mTxn->mDestroyedActors;
+  info.fwdTransactionId() = GetFwdTransactionId();
+  info.id() = aId;
+  info.plugins() = mPluginWindowData;
+  info.isFirstPaint() = mIsFirstPaint;
+  info.scheduleComposite() = aScheduleComposite;
+  info.paintSequenceNumber() = aPaintSequenceNumber;
+  info.isRepeatTransaction() = aIsRepeatTransaction;
+  info.transactionStart() = aTransactionStart;
+  info.paintSyncId() = mPaintSyncId;
+
   TargetConfig targetConfig(mTxn->mTargetBounds,
                             mTxn->mTargetRotation,
                             mTxn->mTargetOrientation,
                             aRegionToClear);
+  info.targetConfig() = targetConfig;
 
   if (!GetTextureForwarder()->IsSameProcess()) {
     MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
     PlatformSyncBeforeUpdate();
   }
 
   profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END);
   if (mTxn->mSwapRequired) {
     MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
     RenderTraceScope rendertrace3("Forward Transaction", "000093");
-    if (!mShadowManager->SendUpdate(cset, mTxn->mDestroyedActors,
-                                    GetFwdTransactionId(),
-                                    aId, targetConfig, mPluginWindowData,
-                                    mIsFirstPaint, aScheduleComposite,
-                                    aPaintSequenceNumber, aIsRepeatTransaction,
-                                    aTransactionStart, mPaintSyncId, aReplies)) {
+    if (!mShadowManager->SendUpdate(info, aReplies)) {
       MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
       return false;
     }
   } 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(cset, mTxn->mDestroyedActors,
-                                          GetFwdTransactionId(),
-                                          aId, targetConfig, mPluginWindowData,
-                                          mIsFirstPaint, aScheduleComposite,
-                                          aPaintSequenceNumber, aIsRepeatTransaction,
-                                          aTransactionStart, mPaintSyncId)) {
+    if (!mShadowManager->SendUpdateNoSwap(info)) {
       MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
       return false;
     }
   }
 
   *aSent = true;
   mIsFirstPaint = false;
   mPaintSyncId = 0;