Bug 1531796 - Call NotifyApzTransaction() for skipped paints, too. r=rhunt,kats
authorBotond Ballo <botond@mozilla.com>
Sat, 27 Apr 2019 05:06:23 +0000
changeset 530440 8ebd99752f720b8f08529159ea1a893d71dba7f4
parent 530439 57b12599afe20163b7abd2b0e9dd23f08e2268c4
child 530441 58093e575a85553bb3b0c2b8d181c83529d4bb33
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt, kats
bugs1531796
milestone68.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 1531796 - Call NotifyApzTransaction() for skipped paints, too. r=rhunt,kats We need to do this separately in the WR and non-WR codepaths for picking up scroll updates for skipped paints. Differential Revision: https://phabricator.services.mozilla.com/D29061
gfx/layers/Layers.cpp
gfx/layers/wr/WebRenderLayerManager.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -611,20 +611,22 @@ void Layer::ApplyPendingUpdatesForThisTr
   if (mAnimationInfo.ApplyPendingUpdatesForThisTransaction()) {
     MOZ_LAYERS_LOG_IF_SHADOWABLE(
         this, ("Layer::Mutated(%p) PendingUpdatesForThisTransaction", this));
     Mutated();
   }
 
   for (size_t i = 0; i < mScrollMetadata.Length(); i++) {
     FrameMetrics& fm = mScrollMetadata[i].GetMetrics();
+    ScrollableLayerGuid::ViewID scrollId = fm.GetScrollId();
     Maybe<ScrollUpdateInfo> update =
-        Manager()->GetPendingScrollInfoUpdate(fm.GetScrollId());
+        Manager()->GetPendingScrollInfoUpdate(scrollId);
     if (update) {
       fm.UpdatePendingScrollInfo(update.value());
+      nsLayoutUtils::NotifyPaintSkipTransaction(scrollId);
       Mutated();
     }
   }
 }
 
 float Layer::GetLocalOpacity() {
   float opacity = mSimpleAttrs.GetOpacity();
   if (HostLayer* shadow = AsHostLayer()) opacity = shadow->GetShadowOpacity();
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -243,16 +243,19 @@ bool WebRenderLayerManager::EndEmptyTran
       auto updates = renderRootUpdates.AppendElement();
       updates->mRenderRoot = renderRoot;
       if (stateManager.mAsyncResourceUpdates) {
         stateManager.mAsyncResourceUpdates->Flush(updates->mResourceUpdates,
                                                   updates->mSmallShmems,
                                                   updates->mLargeShmems);
       }
       updates->mScrollUpdates = std::move(mPendingScrollUpdates[renderRoot]);
+      for (const auto& entry : updates->mScrollUpdates) {
+        nsLayoutUtils::NotifyPaintSkipTransaction(/*scroll id=*/entry.first);
+      }
     }
   }
 
   Maybe<wr::IpcResourceUpdateQueue> nothing;
   WrBridge()->EndEmptyTransaction(mFocusTarget, renderRootUpdates,
                                   mPaintSequenceNumber, mLatestTransactionId,
                                   mTransactionIdAllocator->GetVsyncId(),
                                   mTransactionIdAllocator->GetVsyncStart(),
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1383,16 +1383,23 @@ bool nsLayoutUtils::GetHighResolutionDis
   return GetDisplayPort(aContent, aResult);
 }
 
 void nsLayoutUtils::RemoveDisplayPort(nsIContent* aContent) {
   aContent->DeleteProperty(nsGkAtoms::DisplayPort);
   aContent->DeleteProperty(nsGkAtoms::DisplayPortMargins);
 }
 
+void nsLayoutUtils::NotifyPaintSkipTransaction(ViewID aScrollId) {
+  if (nsIScrollableFrame* scrollFrame =
+          nsLayoutUtils::FindScrollableFrameFor(aScrollId)) {
+    scrollFrame->NotifyApzTransaction();
+  }
+}
+
 nsContainerFrame* nsLayoutUtils::LastContinuationWithChild(
     nsContainerFrame* aFrame) {
   MOZ_ASSERT(aFrame, "NULL frame pointer");
   for (auto f = aFrame->LastContinuation(); f; f = f->GetPrevContinuation()) {
     for (nsIFrame::ChildListIterator lists(f); !lists.IsDone(); lists.Next()) {
       if (MOZ_LIKELY(!lists.CurrentList().IsEmpty())) {
         return static_cast<nsContainerFrame*>(f);
       }
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -317,16 +317,28 @@ class nsLayoutUtils {
                                            nsRect* aResult);
 
   /**
    * Remove the displayport for the given element.
    */
   static void RemoveDisplayPort(nsIContent* aContent);
 
   /**
+   * Notify the scroll frame with the given scroll id that its scroll offset
+   * is being sent to APZ as part of a paint-skip transaction.
+   *
+   * Normally, this notification happens during painting, after calls to
+   * ComputeScrollMetadata(). During paint-skipping that code is skipped,
+   * but it's still important for the scroll frame to be notified for
+   * correctness of relative scroll updates, so the code that sends the
+   * empty paint-skip transaction needs to call this.
+   */
+  static void NotifyPaintSkipTransaction(ViewID aScrollId);
+
+  /**
    * Use heuristics to figure out the child list that
    * aChildFrame is currently in.
    */
   static mozilla::layout::FrameChildListID GetChildListNameFor(
       nsIFrame* aChildFrame);
 
   /**
    * Returns the ::before pseudo-element for aContent, if any.