Bug 1543485 - Preserve the relative scroll offset of the two viewports when accepting a main thread scroll update. r=kats

Differential Revision: https://phabricator.services.mozilla.com/D87686
This commit is contained in:
Botond Ballo 2020-08-21 01:25:37 +00:00
parent eb0f5b96d9
commit 1ec395bfba
3 changed files with 45 additions and 7 deletions

View File

@ -93,6 +93,21 @@ void FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(
aLayoutViewport = aLayoutViewport.MoveInsideAndClamp(aScrollableRect);
}
void FrameMetrics::ApplyScrollUpdateFrom(const FrameMetrics& aContentMetrics) {
// In applying a main-thread scroll update, try to preserve the relative
// offset between the visual and layout viewports.
CSSPoint relativeOffset = GetVisualScrollOffset() - GetLayoutScrollOffset();
MOZ_ASSERT(IsRootContent() || relativeOffset == CSSPoint());
// We need to set the two offsets together, otherwise a subsequent
// RecalculateLayoutViewportOffset() could see divergent layout and
// visual offsets.
SetLayoutScrollOffset(aContentMetrics.GetLayoutScrollOffset());
ClampAndSetVisualScrollOffset(aContentMetrics.GetLayoutScrollOffset() +
relativeOffset);
mScrollGeneration = aContentMetrics.mScrollGeneration;
}
ScrollSnapInfo::ScrollSnapInfo()
: mScrollSnapStrictnessX(StyleScrollSnapStrictness::None),
mScrollSnapStrictnessY(StyleScrollSnapStrictness::None) {}

View File

@ -270,13 +270,7 @@ struct FrameMetrics {
aContentFrameMetrics.GetVisualScrollOffset();
}
void ApplyScrollUpdateFrom(const FrameMetrics& aOther) {
// Note that we set this (APZ) metrics' visual scroll offset to
// the incoming (Gecko) metrics' layout scroll offset.
// This will change in bug 1543485.
SetVisualScrollOffset(aOther.GetLayoutScrollOffset());
mScrollGeneration = aOther.mScrollGeneration;
}
void ApplyScrollUpdateFrom(const FrameMetrics& aContentMetrics);
void ApplySmoothScrollUpdateFrom(const FrameMetrics& aOther) {
mSmoothScrollOffset = aOther.mSmoothScrollOffset;

View File

@ -492,3 +492,32 @@ TEST_F(APZCBasicTester, ResumeInterruptedTouchDrag_Bug1592435) {
TouchUp(apzc, touchPos, mcc->Time());
}
#endif
TEST_F(APZCBasicTester, RelativeScrollOffset) {
// Set up initial conditions: zoomed in, layout offset at (100, 100),
// visual offset at (120, 120); the relative offset is such (20, 20).
ScrollMetadata metadata;
FrameMetrics& metrics = metadata.GetMetrics();
metrics.SetScrollableRect(CSSRect(0, 0, 1000, 1000));
metrics.SetLayoutViewport(CSSRect(100, 100, 100, 100));
metrics.SetZoom(CSSToParentLayerScale2D(2.0, 2.0));
metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
metrics.SetVisualScrollOffset(CSSPoint(120, 120));
metrics.SetIsRootContent(true);
apzc->SetFrameMetrics(metrics);
// Scroll the layout viewport to (200, 200).
ScrollMetadata mainThreadMetadata = metadata;
FrameMetrics& mainThreadMetrics = mainThreadMetadata.GetMetrics();
mainThreadMetrics.SetLayoutScrollOffset(CSSPoint(200, 200));
mainThreadMetrics.SetScrollOffsetUpdateType(FrameMetrics::eMainThread);
mainThreadMetrics.SetScrollGeneration(
mainThreadMetrics.GetScrollGeneration() + 1);
apzc->NotifyLayersUpdated(mainThreadMetadata, /*isFirstPaint=*/false,
/*thisLayerTreeUpdated=*/true);
// Check that the relative offset has been preserved.
metrics = apzc->GetFrameMetrics();
EXPECT_EQ(metrics.GetLayoutScrollOffset(), CSSPoint(200, 200));
EXPECT_EQ(metrics.GetVisualScrollOffset(), CSSPoint(220, 220));
}