Bug 1264409 - Make last transaction ID available via nsIDOMWindowUtils, and pass transaction ID through MozAfterPaint. r?mattwoodrow draft
authorMike Conley <mconley@mozilla.com>
Wed, 13 Apr 2016 16:59:15 -0400
changeset 351067 078a8a1c268ff5e32af6cc622da787a57dc79b0b
parent 349915 1603f92d02073689100cf7b4b65c3f6000d1d597
child 518474 569dbd1703b4b4c1474607ae4be37461d82fae5f
push id15498
push usermconley@mozilla.com
push dateThu, 14 Apr 2016 20:16:13 +0000
reviewersmattwoodrow
bugs1264409
milestone48.0a1
Bug 1264409 - Make last transaction ID available via nsIDOMWindowUtils, and pass transaction ID through MozAfterPaint. r?mattwoodrow MozReview-Commit-ID: 7wCYif8F6ws
dom/base/nsDOMWindowUtils.cpp
dom/events/NotifyPaintEvent.cpp
dom/events/NotifyPaintEvent.h
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
dom/webidl/NotifyPaintEvent.webidl
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/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2301,16 +2301,29 @@ nsDOMWindowUtils::AdvanceTimeAndRefresh(
       transaction->SendSetTestSampleTime(driver->MostRecentRefresh());
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::GetLastTransactionId(uint64_t *aLastTransactionId)
+{
+  nsPresContext* presContext = GetPresContext();
+  if (!presContext) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsRefreshDriver* driver = presContext->GetRootPresContext()->RefreshDriver();
+  *aLastTransactionId = driver->LastTransactionId();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::RestoreNormalRefresh()
 {
   // Kick the compositor out of test mode before the refresh driver, so that
   // the refresh driver doesn't send an update that gets ignored by the
   // compositor.
   RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
   if (transaction && transaction->IPCOpen()) {
     transaction->SendLeaveTestMode();
--- a/dom/events/NotifyPaintEvent.cpp
+++ b/dom/events/NotifyPaintEvent.cpp
@@ -14,25 +14,28 @@
 
 namespace mozilla {
 namespace dom {
 
 NotifyPaintEvent::NotifyPaintEvent(EventTarget* aOwner,
                                    nsPresContext* aPresContext,
                                    WidgetEvent* aEvent,
                                    EventMessage aEventMessage,
-                                   nsInvalidateRequestList* aInvalidateRequests)
+                                   nsInvalidateRequestList* aInvalidateRequests,
+                                   uint64_t aTransactionId)
   : Event(aOwner, aPresContext, aEvent)
 {
   if (mEvent) {
     mEvent->mMessage = aEventMessage;
   }
   if (aInvalidateRequests) {
     mInvalidateRequests.AppendElements(Move(aInvalidateRequests->mRequests));
   }
+
+  mTransactionId = aTransactionId;
 }
 
 NS_INTERFACE_MAP_BEGIN(NotifyPaintEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyPaintEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 NS_IMPL_ADDREF_INHERITED(NotifyPaintEvent, Event)
 NS_IMPL_RELEASE_INHERITED(NotifyPaintEvent, Event)
@@ -149,26 +152,40 @@ NotifyPaintEvent::Deserialize(const IPC:
     NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mRect), false);
     NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mFlags), false);
     mInvalidateRequests.AppendElement(req);
   }
 
   return true;
 }
 
+NS_IMETHODIMP
+NotifyPaintEvent::GetTransactionId(uint64_t* aTransactionId)
+{
+  *aTransactionId = mTransactionId;
+  return NS_OK;
+}
+
+uint64_t
+NotifyPaintEvent::TransactionId()
+{
+  return mTransactionId;
+}
+
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 already_AddRefed<NotifyPaintEvent>
 NS_NewDOMNotifyPaintEvent(EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           WidgetEvent* aEvent,
                           EventMessage aEventMessage,
-                          nsInvalidateRequestList* aInvalidateRequests) 
+                          nsInvalidateRequestList* aInvalidateRequests,
+                          uint64_t aTransactionId)
 {
   RefPtr<NotifyPaintEvent> it =
     new NotifyPaintEvent(aOwner, aPresContext, aEvent, aEventMessage,
-                         aInvalidateRequests);
+                         aInvalidateRequests, aTransactionId);
   return it.forget();
 }
--- a/dom/events/NotifyPaintEvent.h
+++ b/dom/events/NotifyPaintEvent.h
@@ -24,17 +24,18 @@ class NotifyPaintEvent : public Event,
                          public nsIDOMNotifyPaintEvent
 {
 
 public:
   NotifyPaintEvent(EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    WidgetEvent* aEvent,
                    EventMessage aEventMessage,
-                   nsInvalidateRequestList* aInvalidateRequests);
+                   nsInvalidateRequestList* aInvalidateRequests,
+                   uint64_t aTransactionId);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMNOTIFYPAINTEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() override
@@ -50,31 +51,35 @@ public:
   }
 
   already_AddRefed<DOMRectList> ClientRects();
 
   already_AddRefed<DOMRect> BoundingClientRect();
 
   already_AddRefed<PaintRequestList> PaintRequests();
 
+  uint64_t TransactionId();
+
 protected:
   ~NotifyPaintEvent() {}
 
 private:
   nsRegion GetRegion();
 
   nsTArray<nsInvalidateRequestList::Request> mInvalidateRequests;
+  uint64_t mTransactionId;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 // This empties aInvalidateRequests.
 already_AddRefed<mozilla::dom::NotifyPaintEvent>
 NS_NewDOMNotifyPaintEvent(mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           mozilla::WidgetEvent* aEvent,
                           mozilla::EventMessage aEventMessage =
                             mozilla::eVoidEvent,
                           nsInvalidateRequestList* aInvalidateRequests =
-                            nullptr);
+                            nullptr,
+                          uint64_t aTransactionId = 0);
 
 #endif // mozilla_dom_NotifyPaintEvent_h_
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -102,16 +102,21 @@ interface nsIDOMWindowUtils : nsISupport
   unsigned long redraw([optional] in unsigned long aCount);
 
   /**
    * Force a synchronous layer transaction for this window if necessary.
    */
   void updateLayerTree();
 
   /**
+   * Get the last used layer transaction id for this window's refresh driver.
+   */
+  readonly attribute unsigned long long lastTransactionId;
+
+  /**
    * Information retrieved from the <meta name="viewport"> tag.
    * See nsContentUtils::GetViewportInfo for more information.
    */
   void getViewportInfo(in uint32_t aDisplayWidth, in uint32_t aDisplayHeight,
                        out double aDefaultZoom, out boolean aAllowZoom,
                        out double aMinZoom, out double aMaxZoom,
                        out uint32_t aWidth, out uint32_t aHeight,
                        out boolean aAutoSize);
--- a/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
+++ b/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
@@ -30,10 +30,12 @@ interface nsIDOMNotifyPaintEvent : nsISu
    * is in CSS pixels relative to the viewport origin.
    * If the caller is not trusted (e.g., regular Web content) then only painting
    * caused by the current document is reported; in particular, painting in subdocuments
    * is not reported.
    */
   readonly attribute nsIDOMClientRect boundingClientRect;
 
   readonly attribute nsISupports /* PaintRequestList */ paintRequests;
+
+  readonly attribute unsigned long long transactionId;
 };
 
--- a/dom/webidl/NotifyPaintEvent.webidl
+++ b/dom/webidl/NotifyPaintEvent.webidl
@@ -8,9 +8,11 @@
 
 interface NotifyPaintEvent : Event
 {
   readonly attribute DOMRectList clientRects;
 
   readonly attribute DOMRect boundingClientRect;
 
   readonly attribute PaintRequestList paintRequests;
+
+  readonly attribute unsigned long long transactionId;
 };
--- 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
@@ -414,21 +414,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
@@ -2152,17 +2152,17 @@ nsPresContext::EnsureSafeToHandOutCSSRul
     // Nothing to do.
     return;
   }
 
   RebuildAllStyleData(nsChangeHint(0), eRestyle_Subtree);
 }
 
 void
-nsPresContext::FireDOMPaintEvent(nsInvalidateRequestList* aList)
+nsPresContext::FireDOMPaintEvent(nsInvalidateRequestList* aList, uint64_t aTransactionId)
 {
   nsPIDOMWindowInner* ourWindow = mDocument->GetInnerWindow();
   if (!ourWindow)
     return;
 
   nsCOMPtr<EventTarget> dispatchTarget = do_QueryInterface(ourWindow);
   nsCOMPtr<EventTarget> eventTarget = dispatchTarget;
   if (!IsChrome() && !mSendAfterPaintToContent) {
@@ -2177,17 +2177,17 @@ nsPresContext::FireDOMPaintEvent(nsInval
   }
   // Events sent to the window get propagated to the chrome event handler
   // automatically.
   //
   // This will empty our list in case dispatching the event causes more damage
   // (hopefully it won't, or we're likely to get an infinite loop! At least
   // it won't be blocking app execution though).
   RefPtr<NotifyPaintEvent> event =
-    NS_NewDOMNotifyPaintEvent(eventTarget, this, nullptr, eAfterPaint, aList);
+    NS_NewDOMNotifyPaintEvent(eventTarget, this, nullptr, eAfterPaint, aList, aTransactionId);
 
   // Even if we're not telling the window about the event (so eventTarget is
   // the chrome event handler, not the window), the window is still
   // logically the event target.
   event->SetTarget(eventTarget);
   event->SetTrusted(true);
   EventDispatcher::DispatchDOMEvent(dispatchTarget, nullptr,
                                     static_cast<Event*>(event), this, nullptr);
@@ -2374,62 +2374,67 @@ nsPresContext::SetNotifySubDocInvalidati
 /* static */ void
 nsPresContext::ClearNotifySubDocInvalidationData(ContainerLayer* aContainer)
 {
   aContainer->SetUserData(&gNotifySubDocInvalidationData, nullptr);
 }
 
 struct NotifyDidPaintSubdocumentCallbackClosure {
   uint32_t mFlags;
+  uint64_t mTransactionId;
   bool mNeedsAnotherDidPaintNotification;
 };
 static bool
 NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
 {
   NotifyDidPaintSubdocumentCallbackClosure* closure =
     static_cast<NotifyDidPaintSubdocumentCallbackClosure*>(aData);
   nsIPresShell* shell = aDocument->GetShell();
   if (shell) {
     nsPresContext* pc = shell->GetPresContext();
     if (pc) {
-      pc->NotifyDidPaintForSubtree(closure->mFlags);
+      pc->NotifyDidPaintForSubtree(closure->mFlags, closure->mTransactionId);
       if (pc->IsDOMPaintEventPending()) {
         closure->mNeedsAnotherDidPaintNotification = true;
       }
     }
   }
   return true;
 }
 
 class DelayedFireDOMPaintEvent : public nsRunnable {
 public:
   DelayedFireDOMPaintEvent(nsPresContext* aPresContext,
-                           nsInvalidateRequestList* aList)
+                           nsInvalidateRequestList* aList,
+                           uint64_t aTransactionId)
     : mPresContext(aPresContext)
+    , mTransactionId(aTransactionId)
   {
     MOZ_ASSERT(mPresContext->GetContainerWeak(),
                "DOMPaintEvent requested for a detached pres context");
     mList.TakeFrom(aList);
   }
   NS_IMETHOD Run() override
   {
     // The pres context might have been detached during the delay -
     // that's fine, just don't fire the event.
     if (mPresContext->GetContainerWeak()) {
-      mPresContext->FireDOMPaintEvent(&mList);
+      mPresContext->FireDOMPaintEvent(&mList, mTransactionId);
     }
     return NS_OK;
   }
 
   RefPtr<nsPresContext> mPresContext;
+  uint64_t mTransactionId;
   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;
     }
   }
@@ -2446,21 +2451,22 @@ nsPresContext::NotifyDidPaintForSubtree(
 
   if (aFlags & nsIPresShell::PAINT_LAYERS) {
     mUndeliveredInvalidateRequestsBeforeLastPaint.TakeFrom(
         &mInvalidateRequestsSinceLastPaint);
     mAllInvalidated = false;
   }
   if (aFlags & nsIPresShell::PAINT_COMPOSITE) {
     nsCOMPtr<nsIRunnable> ev =
-      new DelayedFireDOMPaintEvent(this, &mUndeliveredInvalidateRequestsBeforeLastPaint);
+      new DelayedFireDOMPaintEvent(this, &mUndeliveredInvalidateRequestsBeforeLastPaint,
+                                   aTransactionId);
     nsContentUtils::AddScriptRunner(ev);
   }
 
-  NotifyDidPaintSubdocumentCallbackClosure closure = { aFlags, false };
+  NotifyDidPaintSubdocumentCallbackClosure closure = { aFlags, aTransactionId, false };
   mDocument->EnumerateSubDocuments(NotifyDidPaintSubdocumentCallback, &closure);
 
   if (!closure.mNeedsAnotherDidPaintNotification &&
       mInvalidateRequestsSinceLastPaint.IsEmpty() &&
       mUndeliveredInvalidateRequestsBeforeLastPaint.IsEmpty()) {
     // Nothing more to do for the moment.
     mFireAfterPaintEvents = false;
   } else {
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -921,18 +921,19 @@ 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 FireDOMPaintEvent(nsInvalidateRequestList* aList);
+  void NotifyDidPaintForSubtree(uint32_t aFlags, uint64_t aTransactionId = 0,
+                                const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
+  void FireDOMPaintEvent(nsInvalidateRequestList* aList, uint64_t aTransactionId);
 
   // 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);
   bool IsDOMPaintEventPending();
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -2002,16 +2002,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
@@ -314,17 +314,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
@@ -1073,27 +1073,29 @@ nsView::PaintWindow(nsIWidget* aWidget, 
 void
 nsView::DidPaintWindow()
 {
   RefPtr<nsViewManager> vm = mViewManager;
   vm->DidPaintWindow();
 }
 
 void
-nsView::DidCompositeWindow(const TimeStamp& aCompositeStart,
+nsView::DidCompositeWindow(uint64_t aTransactionId,
+                           const TimeStamp& aCompositeStart,
                            const TimeStamp& aCompositeEnd)
 {
   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
@@ -107,17 +107,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
@@ -141,17 +141,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();
 
   /**