Pass transaction IDs all over the place for no particular reason. draft
authorMarkus Stange <mstange@themasta.com>
Thu, 17 Mar 2016 16:54:09 -0400
changeset 343059 211e277d1000d2ebf26bac957e03a8a39e6e05c5
parent 343058 7e9fffa6c0d86bb5f8ed01b25016935a9c207186
child 343060 8c773f7ec364de81a3892cf42f5ea67e5e776239
push id13517
push usermstange@themasta.com
push dateMon, 21 Mar 2016 20:51:56 +0000
milestone48.0a1
Pass transaction IDs all over the place for no particular reason.
gfx/layers/TransactionIdAllocator.h
gfx/layers/client/ClientLayerManager.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsRefreshDriver.cpp
layout/base/nsRefreshDriver.h
view/nsView.cpp
view/nsView.h
widget/nsIWidgetListener.cpp
widget/nsIWidgetListener.h
--- a/gfx/layers/TransactionIdAllocator.h
+++ b/gfx/layers/TransactionIdAllocator.h
@@ -24,16 +24,23 @@ public:
    * only be called while IsInRefresh().
    *
    * If too many id's are allocated without being returned then
    * the refresh driver will suspend until they catch up.
    */
   virtual uint64_t GetTransactionId() = 0;
 
   /**
+   * Return the transaction id that for the last non-revoked transaction.
+   * This allows the caller to tell whether a composite was triggered by
+   * a paint that occurred after a call to TransactionId().
+   */
+  virtual uint64_t LastTransactionId() const = 0;
+
+  /**
    * Notify that all work (including asynchronous composites)
    * for a given transaction id has been completed.
    *
    * If the refresh driver has been suspended because
    * of having too many outstanding id's, then this may
    * resume it.
    */
   virtual void NotifyTransactionCompleted(uint64_t aTransactionId) = 0;
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -403,21 +403,21 @@ ClientLayerManager::DidComposite(uint64_
 {
   MOZ_ASSERT(mWidget);
 
   // |aTransactionId| will be > 0 if the compositor is acknowledging a shadow
   // layers transaction.
   if (aTransactionId) {
     nsIWidgetListener *listener = mWidget->GetWidgetListener();
     if (listener) {
-      listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
+      listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
     }
     listener = mWidget->GetAttachedWidgetListener();
     if (listener) {
-      listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
+      listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
     }
     mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
   }
 
   // These observers fire whether or not we were in a transaction.
   for (size_t i = 0; i < mDidCompositeObservers.Length(); i++) {
     mDidCompositeObservers[i]->DidComposite();
   }
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2660,17 +2660,18 @@ public:
     return NS_OK;
   }
 
   RefPtr<nsPresContext> mPresContext;
   nsInvalidateRequestList mList;
 };
 
 void
-nsPresContext::NotifyDidPaintForSubtree(uint32_t aFlags)
+nsPresContext::NotifyDidPaintForSubtree(uint32_t aFlags, uint64_t aTransactionId,
+                                        const mozilla::TimeStamp& aTimeStamp)
 {
   if (IsRoot()) {
     static_cast<nsRootPresContext*>(this)->CancelDidPaintTimer();
 
     if (!mFireAfterPaintEvents) {
       return;
     }
   }
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -922,17 +922,18 @@ public:
   // and, if necessary, synchronously rebuilding all style data.
   void EnsureSafeToHandOutCSSRules();
 
   void NotifyInvalidation(uint32_t aFlags);
   void NotifyInvalidation(const nsRect& aRect, uint32_t aFlags);
   // aRect is in device pixels
   void NotifyInvalidation(const nsIntRect& aRect, uint32_t aFlags);
   // aFlags are nsIPresShell::PAINT_ flags
-  void NotifyDidPaintForSubtree(uint32_t aFlags);
+  void NotifyDidPaintForSubtree(uint32_t aFlags, uint64_t aTransactionId = 0,
+                                const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
   void FireDOMPaintEvent(nsInvalidateRequestList* aList);
 
   // Callback for catching invalidations in ContainerLayers
   // Passed to LayerProperties::ComputeDifference
   static void NotifySubDocInvalidation(mozilla::layers::ContainerLayer* aContainer,
                                        const nsIntRegion& aRegion);
   void SetNotifySubDocInvalidationData(mozilla::layers::ContainerLayer* aContainer);
   static void ClearNotifySubDocInvalidationData(mozilla::layers::ContainerLayer* aContainer);
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1995,16 +1995,22 @@ nsRefreshDriver::GetTransactionId()
       !mTestControllingRefreshes) {
     mWaitingForTransaction = true;
     mSkippedPaints = false;
   }
 
   return mPendingTransaction;
 }
 
+uint64_t
+nsRefreshDriver::LastTransactionId() const
+{
+  return mPendingTransaction;
+}
+
 void
 nsRefreshDriver::RevokeTransactionId(uint64_t aTransactionId)
 {
   MOZ_ASSERT(aTransactionId == mPendingTransaction);
   if (mPendingTransaction == mCompletedTransaction + 2 &&
       mWaitingForTransaction) {
     MOZ_ASSERT(!mSkippedPaints, "How did we skip a paint when we're in the middle of one?");
     FinishedWaitingForTransaction();
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -308,17 +308,18 @@ public:
    * time.
    *
    * Return `false` if `aJank` needs to be grown to accomodate the
    * data but we didn't have enough memory.
    */
   static bool GetJankLevels(mozilla::Vector<uint64_t>& aJank);
 
   // mozilla::layers::TransactionIdAllocator
-  virtual uint64_t GetTransactionId() override;
+  uint64_t GetTransactionId() override;
+  uint64_t LastTransactionId() const override;
   void NotifyTransactionCompleted(uint64_t aTransactionId) override;
   void RevokeTransactionId(uint64_t aTransactionId) override;
   mozilla::TimeStamp GetTransactionStart() override;
 
   bool IsWaitingForPaint(mozilla::TimeStamp aTime);
 
   // nsARefreshObserver
   NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override { return TransactionIdAllocator::AddRef(); }
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -1081,28 +1081,29 @@ nsView::DidPaintWindow()
 
 static int64_t Date_Now() {
   struct timeval tv;
   gettimeofday(&tv, 0);
   return (int64_t(tv.tv_sec) * 1000000L + int64_t(tv.tv_usec)) / 1000L;
 }
 
 void
-nsView::DidCompositeWindow(const TimeStamp& aCompositeStart,
+nsView::DidCompositeWindow(uint64_t aTransactionId,
+                           const TimeStamp& aCompositeStart,
                            const TimeStamp& aCompositeEnd)
 { 
   printf("[%lld] [%s] nsView::DidCompositeWindow\n", Date_Now(), XRE_IsContentProcess() ? "content" : "parent");
   nsIPresShell* presShell = mViewManager->GetPresShell();
   if (presShell) {
     nsAutoScriptBlocker scriptBlocker;
 
     nsPresContext* context = presShell->GetPresContext();
     nsRootPresContext* rootContext = context->GetRootPresContext();
     MOZ_ASSERT(rootContext, "rootContext must be valid.");
-    rootContext->NotifyDidPaintForSubtree(nsIPresShell::PAINT_COMPOSITE);
+    rootContext->NotifyDidPaintForSubtree(nsIPresShell::PAINT_COMPOSITE, aTransactionId, aCompositeEnd);
 
     // If the two timestamps are identical, this was likely a fake composite
     // event which wouldn't be terribly useful to display.
     if (aCompositeStart == aCompositeEnd) {
       return;
     }
 
     nsIDocShell* docShell = context->GetDocShell();
--- a/view/nsView.h
+++ b/view/nsView.h
@@ -381,17 +381,18 @@ public:
   virtual nsView* GetView() override { return this; }
   virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) override;
   virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) override;
   virtual bool RequestWindowClose(nsIWidget* aWidget) override;
   virtual void WillPaintWindow(nsIWidget* aWidget) override;
   virtual bool PaintWindow(nsIWidget* aWidget,
                            LayoutDeviceIntRegion aRegion) override;
   virtual void DidPaintWindow() override;
-  virtual void DidCompositeWindow(const mozilla::TimeStamp& aCompositeStart,
+  virtual void DidCompositeWindow(uint64_t aTransactionId,
+                                  const mozilla::TimeStamp& aCompositeStart,
                                   const mozilla::TimeStamp& aCompositeEnd) override;
   virtual void RequestRepaint() override;
   virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
                                     bool aUseAttachedEvents) override;
 
   virtual ~nsView();
 
   nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const;
--- a/widget/nsIWidgetListener.cpp
+++ b/widget/nsIWidgetListener.cpp
@@ -102,17 +102,18 @@ nsIWidgetListener::PaintWindow(nsIWidget
 }
 
 void
 nsIWidgetListener::DidPaintWindow()
 {
 }
 
 void
-nsIWidgetListener::DidCompositeWindow(const TimeStamp& aCompositeStart,
+nsIWidgetListener::DidCompositeWindow(uint64_t aTransactionId,
+                                      const TimeStamp& aCompositeStart,
                                       const TimeStamp& aCompositeEnd)
 {
 }
 
 void
 nsIWidgetListener::RequestRepaint()
 {
 }
--- a/widget/nsIWidgetListener.h
+++ b/widget/nsIWidgetListener.h
@@ -135,17 +135,18 @@ public:
   /**
    * Indicates that a paint occurred.
    * This is called at a time when it is OK to change the geometry of
    * this widget or of other widgets.
    * Must be called after every call to PaintWindow.
    */
   virtual void DidPaintWindow();
 
-  virtual void DidCompositeWindow(const mozilla::TimeStamp& aCompositeStart,
+  virtual void DidCompositeWindow(uint64_t aTransactionId,
+                                  const mozilla::TimeStamp& aCompositeStart,
                                   const mozilla::TimeStamp& aCompositeEnd);
 
   /**
    * Request that layout schedules a repaint on the next refresh driver tick.
    */
   virtual void RequestRepaint();
 
   /**