Bug 1495055 - Adjust the composited layout viewport in AdjustScrollForSurfaceShift(). r=kats

Depends on D7368

Differential Revision: https://phabricator.services.mozilla.com/D7369
This commit is contained in:
Botond Ballo
2018-10-11 05:58:13 +00:00
parent e324160896
commit 6746d2e315
3 changed files with 49 additions and 23 deletions

View File

@@ -19,16 +19,23 @@ FrameMetrics::RecalculateViewportOffset()
if (!mIsRootContent) {
return;
}
CSSRect visualViewport = GetVisualViewport();
KeepLayoutViewportEnclosingVisualViewport(GetVisualViewport(), mViewport);
}
/* static */ void
FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(
const CSSRect& aVisualViewport,
CSSRect& aLayoutViewport)
{
// If the visual viewport is contained within the layout viewport, we don't
// need to make any adjustments, so we can exit early.
//
// Additionally, if the composition bounds changes (due to an orientation
// change, window resize, etc.), it may take a few frames for mViewport to
// change, window resize, etc.), it may take a few frames for aLayoutViewport to
// update and during that time, the visual viewport may be larger than the
// layout viewport. In such situations, we take an early exit if the visual
// viewport contains the layout viewport.
if (mViewport.Contains(visualViewport) || visualViewport.Contains(mViewport)) {
if (aLayoutViewport.Contains(aVisualViewport) || aVisualViewport.Contains(aLayoutViewport)) {
return;
}
@@ -36,40 +43,41 @@ FrameMetrics::RecalculateViewportOffset()
// viewport such that it remains inside the visual viewport. Otherwise,
// move the layout viewport such that the visual viewport is contained
// inside the layout viewport.
if ((mViewport.Width() < visualViewport.Width() &&
!FuzzyEqualsMultiplicative(mViewport.Width(), visualViewport.Width())) ||
(mViewport.Height() < visualViewport.Height() &&
!FuzzyEqualsMultiplicative(mViewport.Height(), visualViewport.Height()))) {
if ((aLayoutViewport.Width() < aVisualViewport.Width() &&
!FuzzyEqualsMultiplicative(aLayoutViewport.Width(), aVisualViewport.Width())) ||
(aLayoutViewport.Height() < aVisualViewport.Height() &&
!FuzzyEqualsMultiplicative(aLayoutViewport.Height(), aVisualViewport.Height()))) {
if (mViewport.X() < visualViewport.X()) {
if (aLayoutViewport.X() < aVisualViewport.X()) {
// layout viewport moves right
mViewport.MoveToX(visualViewport.X());
} else if (visualViewport.XMost() < mViewport.XMost()) {
aLayoutViewport.MoveToX(aVisualViewport.X());
} else if (aVisualViewport.XMost() < aLayoutViewport.XMost()) {
// layout viewport moves left
mViewport.MoveByX(visualViewport.XMost() - mViewport.XMost());
aLayoutViewport.MoveByX(aVisualViewport.XMost() - aLayoutViewport.XMost());
}
if (mViewport.Y() < visualViewport.Y()) {
if (aLayoutViewport.Y() < aVisualViewport.Y()) {
// layout viewport moves down
mViewport.MoveToY(visualViewport.Y());
} else if (visualViewport.YMost() < mViewport.YMost()) {
aLayoutViewport.MoveToY(aVisualViewport.Y());
} else if (aVisualViewport.YMost() < aLayoutViewport.YMost()) {
// layout viewport moves up
mViewport.MoveByY(visualViewport.YMost() - mViewport.YMost());
aLayoutViewport.MoveByY(aVisualViewport.YMost() - aLayoutViewport.YMost());
}
} else {
if (visualViewport.X() < mViewport.X()) {
mViewport.MoveToX(visualViewport.X());
} else if (mViewport.XMost() < visualViewport.XMost()) {
mViewport.MoveByX(visualViewport.XMost() - mViewport.XMost());
if (aVisualViewport.X() < aLayoutViewport.X()) {
aLayoutViewport.MoveToX(aVisualViewport.X());
} else if (aLayoutViewport.XMost() < aVisualViewport.XMost()) {
aLayoutViewport.MoveByX(aVisualViewport.XMost() - aLayoutViewport.XMost());
}
if (visualViewport.Y() < mViewport.Y()) {
mViewport.MoveToY(visualViewport.Y());
} else if (mViewport.YMost() < visualViewport.YMost()) {
mViewport.MoveByY(visualViewport.YMost() - mViewport.YMost());
if (aVisualViewport.Y() < aLayoutViewport.Y()) {
aLayoutViewport.MoveToY(aVisualViewport.Y());
} else if (aLayoutViewport.YMost() < aVisualViewport.YMost()) {
aLayoutViewport.MoveByY(aVisualViewport.YMost() - aLayoutViewport.YMost());
}
}
}
void
ScrollMetadata::SetUsesContainerScrolling(bool aValue) {
mUsesContainerScrolling = aValue;

View File

@@ -538,6 +538,16 @@ public:
// This is a no-op if mIsRootContent is false.
void RecalculateViewportOffset();
// Helper function for RecalculateViewportOffset(). Exposed so that
// APZC can perform the operation on other copies of the layout
// and visual viewport rects (e.g. the "effective" ones used to implement
// the frame delay).
// Modifies |aLayoutViewport| to continue enclosing |aVisualViewport|
// if possible.
static void KeepLayoutViewportEnclosingVisualViewport(
const CSSRect& aVisualViewport,
CSSRect& aLayoutViewport);
private:
// A unique ID assigned to each scrollable frame.
ViewID mScrollId;

View File

@@ -3348,6 +3348,14 @@ void AsyncPanZoomController::AdjustScrollForSurfaceShift(const ScreenPoint& aShi
// the shift to take effect right away, without the usual frame delay.
mCompositedScrollOffset = scrollRange.ClampPoint(
mCompositedScrollOffset + adjustment);
// For a similar reason, apply the shift to mCompositedLayoutViewport.
// mCompositedLayoutViewport also needs to immediately pick up any new
// size from Metrics().GetViewport() to make sure it reflects any height
// change due to dynamic toolbar movement.
mCompositedLayoutViewport.SizeTo(Metrics().GetViewport().Size());
FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(
CSSRect(mCompositedScrollOffset, Metrics().CalculateCompositedSizeInCssPixels()),
mCompositedLayoutViewport);
RequestContentRepaint();
UpdateSharedCompositorFrameMetrics();
}