Bug 1302071 - Part 4: Pass the current transaction ID to NotifyInvalidation. r?tnikkel draft
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 17 Feb 2017 15:15:45 +1300
changeset 485815 0b194b8ab70913183e61104854ad4a64b534cff6
parent 485814 2b25ffbf3bc1ea592da941dbc25406e633d1b19f
child 485816 62405a04a71b50db87ddb1b474f24ceac4a07879
push id45861
push usermwoodrow@mozilla.com
push dateFri, 17 Feb 2017 08:19:13 +0000
reviewerstnikkel
bugs1302071
milestone54.0a1
Bug 1302071 - Part 4: Pass the current transaction ID to NotifyInvalidation. r?tnikkel MozReview-Commit-ID: AMLjzElRp1l
gfx/layers/Layers.h
gfx/layers/client/ClientLayerManager.h
layout/base/PresShell.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/painting/nsDisplayList.cpp
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -699,16 +699,18 @@ public:
 
   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier()
   {
     return TextureFactoryIdentifier();
   }
 
   virtual void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) {}
 
+  virtual uint64_t GetLastTransactionId() { return 0; }
+
   virtual CompositorBridgeChild* GetCompositorBridgeChild() { return nullptr; }
 
 protected:
   RefPtr<Layer> mRoot;
   gfx::UserData mUserData;
   bool mDestroyed;
   bool mSnapEffectiveTransforms;
 
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -220,16 +220,18 @@ public:
   // Get a copy of the compositor-side APZ test data for our layers ID.
   void GetCompositorSideAPZTestData(APZTestData* aData) const;
 
   virtual void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) override
   {
      mTransactionIdAllocator = aAllocator;
   }
 
+  virtual uint64_t GetLastTransactionId() override { return mLatestTransactionId; }
+
   float RequestProperty(const nsAString& aProperty) override;
 
   bool AsyncPanZoomEnabled() const override;
 
   void SetNextPaintSyncId(int32_t aSyncId);
 
   virtual void SetLayerObserverEpoch(uint64_t aLayerObserverEpoch) override;
 
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -6409,17 +6409,17 @@ PresShell::Paint(nsView*        aViewToP
             nsIntRect bounds = invalid.GetBounds();
             nsRect rect(presContext->DevPixelsToAppUnits(bounds.x),
                         presContext->DevPixelsToAppUnits(bounds.y),
                         presContext->DevPixelsToAppUnits(bounds.width),
                         presContext->DevPixelsToAppUnits(bounds.height));
             if (shouldInvalidate) {
               aViewToPaint->GetViewManager()->InvalidateViewNoSuppression(aViewToPaint, rect);
             }
-            presContext->NotifyInvalidation(bounds);
+            presContext->NotifyInvalidation(layerManager->GetLastTransactionId(), bounds);
           }
         } else if (shouldInvalidate) {
           aViewToPaint->GetViewManager()->InvalidateView(aViewToPaint);
         }
 
         frame->UpdatePaintCountForPaintedPresShells();
         return;
       }
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -160,17 +160,17 @@ nsPresContext::IsDOMPaintEventPending()
   if (mFireAfterPaintEvents) {
     return true;
   }
   nsRootPresContext* drpc = GetRootPresContext();
   if (drpc && drpc->mRefreshDriver->ViewManagerFlushIsPending()) {
     // Since we're promising that there will be a MozAfterPaint event
     // fired, we record an empty invalidation in case display list
     // invalidation doesn't invalidate anything further.
-    NotifyInvalidation(nsRect(0, 0, 0, 0));
+    NotifyInvalidation(drpc->mRefreshDriver->LastTransactionId() + 1, nsRect(0, 0, 0, 0));
     NS_ASSERTION(mFireAfterPaintEvents, "Why aren't we planning to fire the event?");
     return true;
   }
   return false;
 }
 
 void
 nsPresContext::PrefChangedCallback(const char* aPrefName, void* instance_data)
@@ -2440,38 +2440,38 @@ nsPresContext::MayHavePaintEventListener
   }
 
   bool result = false;
   mDocument->EnumerateSubDocuments(MayHavePaintEventListenerSubdocumentCallback, &result);
   return result;
 }
 
 void
-nsPresContext::NotifyInvalidation(const nsIntRect& aRect)
+nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRect)
 {
   // Prevent values from overflow after DevPixelsToAppUnits().
   //
   // DevPixelsTopAppUnits() will multiple a factor (60) to the value,
   // it may make the result value over the edge (overflow) of max or
   // min value of int32_t. Compute the max sized dev pixel rect that
   // we can support and intersect with it.
   nsIntRect clampedRect = nsIntRect::MaxIntRect();
   clampedRect.ScaleInverseRoundIn(AppUnitsPerDevPixel());
 
   clampedRect = clampedRect.Intersect(aRect);
 
   nsRect rect(DevPixelsToAppUnits(clampedRect.x),
               DevPixelsToAppUnits(clampedRect.y),
               DevPixelsToAppUnits(clampedRect.width),
               DevPixelsToAppUnits(clampedRect.height));
-  NotifyInvalidation(rect);
+  NotifyInvalidation(aTransactionId, rect);
 }
 
 void
-nsPresContext::NotifyInvalidation(const nsRect& aRect)
+nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
 {
   MOZ_ASSERT(GetContainerWeak(), "Invalidation in detached pres context");
 
   // If there is no paint event listener, then we don't need to fire
   // the asynchronous event. We don't even need to record invalidation.
   // MayHavePaintEventListener is pretty cheap and we could make it
   // even cheaper by providing a more efficient
   // nsPIDOMWindow::GetListenerManager.
@@ -2506,17 +2506,17 @@ nsPresContext::NotifySubDocInvalidation(
   nsIntPoint topLeft = aContainer->GetVisibleRegion().ToUnknownRegion().GetBounds().TopLeft();
 
   for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
     nsIntRect rect(iter.Get());
     //PresContext coordinate space is relative to the start of our visible
     // region. Is this really true? This feels like the wrong way to get the right
     // answer.
     rect.MoveBy(-topLeft);
-    data->mPresContext->NotifyInvalidation(rect);
+    data->mPresContext->NotifyInvalidation(aContainer->Manager()->GetLastTransactionId(), rect);
   }
 }
 
 void
 nsPresContext::SetNotifySubDocInvalidationData(ContainerLayer* aContainer)
 {
   ContainerLayerPresContext* pres = new ContainerLayerPresContext;
   pres->mPresContext = this;
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -950,19 +950,23 @@ public:
   void FlushCounterStyles();
   void RebuildCounterStyles(); // asynchronously
 
   // Ensure that it is safe to hand out CSS rules outside the layout
   // engine by ensuring that all CSS style sheets have unique inners
   // and, if necessary, synchronously rebuilding all style data.
   void EnsureSafeToHandOutCSSRules();
 
-  void NotifyInvalidation(const nsRect& aRect);
+  // Mark an area as invalidated, associated with a given transaction id (allocated
+  // by nsRefreshDriver::GetTransactionId).
+  // Invalidated regions will be dispatched to MozAfterPaint events when
+  // NotifyDidPaintForSubtree is called for the transaction id (or any higher id).
+  void NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect);
   // aRect is in device pixels
-  void NotifyInvalidation(const nsIntRect& aRect);
+  void NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRect);
   // aFlags are nsIPresShell::PAINT_ flags
   void NotifyDidPaintForSubtree(uint32_t aFlags, uint64_t aTransactionId = 0,
                                 const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
   void FireDOMPaintEvent(nsTArray<nsRect>* aList, uint64_t aTransactionId,
                          mozilla::TimeStamp aTimeStamp = mozilla::TimeStamp());
 
   // Callback for catching invalidations in ContainerLayers
   // Passed to LayerProperties::ComputeDifference
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2252,17 +2252,17 @@ already_AddRefed<LayerManager> nsDisplay
         nsIntRect bounds = invalid.GetBounds();
         nsRect rect(presContext->DevPixelsToAppUnits(bounds.x),
                     presContext->DevPixelsToAppUnits(bounds.y),
                     presContext->DevPixelsToAppUnits(bounds.width),
                     presContext->DevPixelsToAppUnits(bounds.height));
         if (shouldInvalidate) {
           view->GetViewManager()->InvalidateViewNoSuppression(view, rect);
         }
-        presContext->NotifyInvalidation(bounds);
+        presContext->NotifyInvalidation(layerManager->GetLastTransactionId(), bounds);
       }
     } else if (shouldInvalidate) {
       view->GetViewManager()->InvalidateView(view);
     }
   }
 
   layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
   return layerManager.forget();