Bug 1520319 - Store an array of pending transactions in LayerTransactionParent to avoid overwriting data when we get multiple. r=jrmuizel
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 15 Jan 2019 23:55:37 +0000
changeset 511143 7da55789063f261d79bc947ac6338f6b2658e10e
parent 511106 b46d5d689c8dcf861537da5f9d6bec81e073c910
child 511144 557a23aec3afb838fbcf1b80e1228fa3a3182380
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1520319
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1520319 - Store an array of pending transactions in LayerTransactionParent to avoid overwriting data when we get multiple. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D16603
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -52,17 +52,16 @@ LayerTransactionParent::LayerTransaction
     TimeDuration aVsyncRate)
     : mLayerManager(aManager),
       mCompositorBridge(aBridge),
       mAnimStorage(aAnimStorage),
       mId(aId),
       mChildEpoch{0},
       mParentEpoch{0},
       mVsyncRate(aVsyncRate),
-      mPendingTransaction{0},
       mDestroyed(false),
       mIPCOpen(false),
       mUpdateHitTestingTree(false) {
   MOZ_ASSERT(mId.IsValid());
 }
 
 LayerTransactionParent::~LayerTransactionParent() {}
 
@@ -879,49 +878,62 @@ void LayerTransactionParent::DeallocShme
   }
   PLayerTransactionParent::DeallocShmem(aShmem);
 }
 
 bool LayerTransactionParent::IsSameProcess() const {
   return OtherPid() == base::GetCurrentProcId();
 }
 
+void LayerTransactionParent::SetPendingTransactionId(
+    TransactionId aId, const VsyncId& aVsyncId,
+    const TimeStamp& aVsyncStartTime, const TimeStamp& aRefreshStartTime,
+    const TimeStamp& aTxnStartTime, const TimeStamp& aTxnEndTime, bool aContainsSVG,
+    const nsCString& aURL, const TimeStamp& aFwdTime) {
+  mPendingTransactions.AppendElement(
+      PendingTransaction{aId, aVsyncId, aVsyncStartTime, aRefreshStartTime,
+                         aTxnStartTime, aTxnEndTime, aFwdTime, aURL, aContainsSVG});
+}
+
 TransactionId LayerTransactionParent::FlushTransactionId(
-    const VsyncId& aId, TimeStamp& aCompositeEnd) {
-  if (mId.IsValid() && mPendingTransaction.IsValid() && !mVsyncRate.IsZero()) {
-    RecordContentFrameTime(mTxnVsyncId, mVsyncStartTime, mTxnStartTime, aId,
-                           aCompositeEnd, mTxnEndTime - mTxnStartTime,
-                           mVsyncRate, mContainsSVG, false);
-  }
+    const VsyncId& aCompositeId, TimeStamp& aCompositeEnd) {
+  TransactionId id;
+  for (auto& transaction : mPendingTransactions) {
+    id = transaction.mId;
+    if (mId.IsValid() && transaction.mId.IsValid() && !mVsyncRate.IsZero()) {
+      RecordContentFrameTime(
+          transaction.mTxnVsyncId, transaction.mVsyncStartTime,
+          transaction.mTxnStartTime, aCompositeId, aCompositeEnd,
+          transaction.mTxnEndTime - transaction.mTxnStartTime, mVsyncRate,
+          transaction.mContainsSVG, false);
+    }
 
 #if defined(ENABLE_FRAME_LATENCY_LOG)
-  if (mPendingTransaction.IsValid()) {
-    if (mRefreshStartTime) {
-      int32_t latencyMs =
-          lround((aCompositeEnd - mRefreshStartTime).ToMilliseconds());
-      printf_stderr(
-          "From transaction start to end of generate frame latencyMs %d this "
-          "%p\n",
-          latencyMs, this);
+    if (transaction.mId.IsValid()) {
+      if (transaction.mRefreshStartTime) {
+        int32_t latencyMs = lround(
+            (aCompositeEnd - transaction.mRefreshStartTime).ToMilliseconds());
+        printf_stderr(
+            "From transaction start to end of generate frame latencyMs %d this "
+            "%p\n",
+            latencyMs, this);
+      }
+      if (transaction.mFwdTime) {
+        int32_t latencyMs =
+            lround((aCompositeEnd - transaction.mFwdTime).ToMilliseconds());
+        printf_stderr(
+            "From forwarding transaction to end of generate frame latencyMs %d "
+            "this %p\n",
+            latencyMs, this);
+      }
     }
-    if (mFwdTime) {
-      int32_t latencyMs = lround((aCompositeEnd - mFwdTime).ToMilliseconds());
-      printf_stderr(
-          "From forwarding transaction to end of generate frame latencyMs %d "
-          "this %p\n",
-          latencyMs, this);
-    }
+#endif
   }
-#endif
 
-  mRefreshStartTime = TimeStamp();
-  mTxnStartTime = TimeStamp();
-  mFwdTime = TimeStamp();
-  TransactionId id = mPendingTransaction;
-  mPendingTransaction = TransactionId{0};
+  mPendingTransactions.Clear();
   return id;
 }
 
 void LayerTransactionParent::SendAsyncMessage(
     const InfallibleTArray<AsyncParentMessageData>& aMessage) {
   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
 }
 
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -66,34 +66,23 @@ class LayerTransactionParent final : pub
 
   bool AllocUnsafeShmem(size_t aSize, ipc::SharedMemory::SharedMemoryType aType,
                         ipc::Shmem* aShmem) override;
 
   void DeallocShmem(ipc::Shmem& aShmem) override;
 
   bool IsSameProcess() const override;
 
-  const TransactionId& GetPendingTransactionId() { return mPendingTransaction; }
   void SetPendingTransactionId(TransactionId aId, const VsyncId& aVsyncId,
                                const TimeStamp& aVsyncStartTime,
                                const TimeStamp& aRefreshStartTime,
                                const TimeStamp& aTxnStartTime,
                                const TimeStamp& aTxnEndTime, bool aContainsSVG,
                                const nsCString& aURL,
-                               const TimeStamp& aFwdTime) {
-    mPendingTransaction = aId;
-    mTxnVsyncId = aVsyncId;
-    mVsyncStartTime = aVsyncStartTime;
-    mRefreshStartTime = aRefreshStartTime;
-    mTxnStartTime = aTxnStartTime;
-    mTxnEndTime = aTxnEndTime;
-    mContainsSVG = aContainsSVG;
-    mTxnURL = aURL;
-    mFwdTime = aFwdTime;
-  }
+                               const TimeStamp& aFwdTime);
   TransactionId FlushTransactionId(const VsyncId& aId,
                                    TimeStamp& aCompositeEnd);
 
   // CompositableParentManager
   void SendAsyncMessage(
       const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   void SendPendingAsyncMessages() override;
@@ -203,25 +192,28 @@ class LayerTransactionParent final : pub
   // parent. mChildEpoch is the latest epoch value received from the child.
   // mParentEpoch is the latest epoch value that we have told TabParent about
   // (via ObserveLayerUpdate).
   LayersObserverEpoch mChildEpoch;
   LayersObserverEpoch mParentEpoch;
 
   TimeDuration mVsyncRate;
 
-  TransactionId mPendingTransaction;
-  VsyncId mTxnVsyncId;
-  TimeStamp mVsyncStartTime;
-  TimeStamp mRefreshStartTime;
-  TimeStamp mTxnStartTime;
-  TimeStamp mTxnEndTime;
-  TimeStamp mFwdTime;
-  nsCString mTxnURL;
-  bool mContainsSVG;
+  struct PendingTransaction {
+    TransactionId mId;
+    VsyncId mTxnVsyncId;
+    TimeStamp mVsyncStartTime;
+    TimeStamp mRefreshStartTime;
+    TimeStamp mTxnStartTime;
+    TimeStamp mTxnEndTime;
+    TimeStamp mFwdTime;
+    nsCString mTxnURL;
+    bool mContainsSVG;
+  };
+  AutoTArray<PendingTransaction, 2> mPendingTransactions;
 
   // When the widget/frame/browser stuff in this process begins its
   // destruction process, we need to Disconnect() all the currently
   // live shadow layers, because some of them might be orphaned from
   // the layer tree.  This happens in Destroy() above.  After we
   // Destroy() ourself, there's a window in which that information
   // hasn't yet propagated back to the child side and it might still
   // send us layer transactions.  We want to ignore those transactions