From 50a070b64528a27798f2cb914b9ce9554c6f8fcf Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Sat, 27 Apr 2019 05:06:23 +0000 Subject: [PATCH] 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 --HG-- extra : moz-landing-system : lando --- gfx/layers/Layers.cpp | 4 +++- gfx/layers/wr/WebRenderLayerManager.cpp | 3 +++ layout/base/nsLayoutUtils.cpp | 7 +++++++ layout/base/nsLayoutUtils.h | 12 ++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 1d2986cd6f32..95a8ce3a15aa 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -616,10 +616,12 @@ void Layer::ApplyPendingUpdatesForThisTransaction() { for (size_t i = 0; i < mScrollMetadata.Length(); i++) { FrameMetrics& fm = mScrollMetadata[i].GetMetrics(); + ScrollableLayerGuid::ViewID scrollId = fm.GetScrollId(); Maybe update = - Manager()->GetPendingScrollInfoUpdate(fm.GetScrollId()); + Manager()->GetPendingScrollInfoUpdate(scrollId); if (update) { fm.UpdatePendingScrollInfo(update.value()); + nsLayoutUtils::NotifyPaintSkipTransaction(scrollId); Mutated(); } } diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index a6b983693bb6..cafdf803dc4a 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -248,6 +248,9 @@ bool WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags) { updates->mLargeShmems); } updates->mScrollUpdates = std::move(mPendingScrollUpdates[renderRoot]); + for (const auto& entry : updates->mScrollUpdates) { + nsLayoutUtils::NotifyPaintSkipTransaction(/*scroll id=*/entry.first); + } } } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 47c3c9454de6..55079226ab6f 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1388,6 +1388,13 @@ void nsLayoutUtils::RemoveDisplayPort(nsIContent* aContent) { 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"); diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 502727b96dec..98a5ed9e6ecb 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -321,6 +321,18 @@ class nsLayoutUtils { */ 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.