Bug 1709334 - Ensure calling SampleOverscrollAnimation for overscroll animations which are about to finish. r=botond

In cases where the overscroll amount is pretty small, the animation's
physics model considers it's finished, which exacly means it's about
to finish, so if we don't call SampleOverscrollAnimation in such cases,
the small amount of overscrolling value remains there, then we try to
create overscroll animations repeatedly even if the overscroll amount
is visually noticeablt.

Differential Revision: https://phabricator.services.mozilla.com/D114445
This commit is contained in:
Hiroyuki Ikezoe 2021-05-06 21:02:10 +00:00
Родитель 73dae4e665
Коммит e98f6aecf9
2 изменённых файлов: 62 добавлений и 4 удалений

Просмотреть файл

@ -37,10 +37,10 @@ class OverscrollAnimation : public AsyncPanZoomAnimation {
virtual bool DoSample(FrameMetrics& aFrameMetrics,
const TimeDuration& aDelta) override {
// Can't inline these variables due to short-circuit evaluation.
bool continueX = mApzc.mX.IsOverscrollAnimationRunning() &&
mApzc.mX.SampleOverscrollAnimation(aDelta);
bool continueY = mApzc.mY.IsOverscrollAnimationRunning() &&
mApzc.mY.SampleOverscrollAnimation(aDelta);
bool continueX =
mApzc.mX.IsOverscrolled() && mApzc.mX.SampleOverscrollAnimation(aDelta);
bool continueY =
mApzc.mY.IsOverscrolled() && mApzc.mY.SampleOverscrollAnimation(aDelta);
if (!continueX && !continueY) {
// If we got into overscroll from a fling, that fling did not request a
// fling snap to avoid a resulting scrollTo from cancelling the overscroll

Просмотреть файл

@ -1437,6 +1437,64 @@ TEST_F(APZCOverscrollTester, DynamicallyLoadingContent) {
}
#endif
#ifndef MOZ_WIDGET_ANDROID // Only applies to GenericOverscrollEffect
TEST_F(APZCOverscrollTester, SmallAmountOfOverscroll) {
SCOPED_GFX_PREF_BOOL("apz.overscroll.enabled", true);
ScrollMetadata metadata;
FrameMetrics& metrics = metadata.GetMetrics();
metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
metrics.SetScrollableRect(CSSRect(0, 0, 100, 1000));
// Do vertical overscroll first.
ScreenIntPoint panPoint(50, 50);
PanGesture(PanGestureInput::PANGESTURE_START, apzc, panPoint,
ScreenPoint(0, -10), mcc->Time());
mcc->AdvanceByMillis(10);
PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, panPoint,
ScreenPoint(0, -10), mcc->Time());
mcc->AdvanceByMillis(10);
PanGesture(PanGestureInput::PANGESTURE_END, apzc, panPoint, ScreenPoint(0, 0),
mcc->Time());
mcc->AdvanceByMillis(10);
// Then do small horizontal overscroll which will be considered as "finished"
// by our overscroll animation physics model.
PanGesture(PanGestureInput::PANGESTURE_START, apzc, panPoint,
ScreenPoint(-0.1, 0), mcc->Time());
mcc->AdvanceByMillis(10);
PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, panPoint,
ScreenPoint(-0.2, 0), mcc->Time());
mcc->AdvanceByMillis(10);
PanGesture(PanGestureInput::PANGESTURE_END, apzc, panPoint, ScreenPoint(0, 0),
mcc->Time());
mcc->AdvanceByMillis(10);
EXPECT_TRUE(apzc->IsOverscrolled());
EXPECT_TRUE(apzc->GetOverscrollAmount().y < 0); // overscrolled at top
EXPECT_TRUE(apzc->GetOverscrollAmount().x < 0); // and overscrolled at left
// Then do vertical scroll.
PanGesture(PanGestureInput::PANGESTURE_START, apzc, panPoint,
ScreenPoint(0, 10), mcc->Time());
mcc->AdvanceByMillis(10);
PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, panPoint,
ScreenPoint(0, 100), mcc->Time());
mcc->AdvanceByMillis(10);
PanGesture(PanGestureInput::PANGESTURE_END, apzc, panPoint, ScreenPoint(0, 0),
mcc->Time());
ParentLayerPoint scrollOffset =
apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForHitTesting);
EXPECT_GT(scrollOffset.y, 0); // Make sure the vertical scroll offset is
// greater than zero.
// The small horizontal overscroll amount should be restored to zero.
ParentLayerPoint expectedScrollOffset(0, scrollOffset.y);
SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
}
#endif
class APZCOverscrollTesterForLayersOnly : public APZCTreeManagerTester {
public:
APZCOverscrollTesterForLayersOnly() { mLayersOnly = true; }