Bug 1502059 - Don't always cancel a scroll animation when we have a relative scroll offset update. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D9871

--HG--
extra : source : 2a457617fbf2ca133af18e9972e505f86dd90dd2
extra : amend_source : 119ab67b6c2c9a09a98cfb2f4c4ca20f82c64b9f
This commit is contained in:
Ryan Hunt 2018-10-25 17:21:29 -05:00
Родитель 76554e50cb
Коммит 358ef761e3
11 изменённых файлов: 79 добавлений и 6 удалений

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

@ -276,14 +276,28 @@ public:
mDoSmoothScroll = aOther.mDoSmoothScroll;
}
void ApplyRelativeScrollUpdateFrom(const FrameMetrics& aOther)
/**
* Applies the relative scroll offset update contained in aOther to the
* scroll offset contained in this. The scroll delta is clamped to the
* scrollable region.
*
* @returns The clamped scroll offset delta that was applied
*/
CSSPoint ApplyRelativeScrollUpdateFrom(const FrameMetrics& aOther)
{
MOZ_ASSERT(aOther.IsRelative());
CSSPoint origin = mScrollOffset;
CSSPoint delta = (aOther.mScrollOffset - aOther.mBaseScrollOffset);
ClampAndSetScrollOffset(mScrollOffset + delta);
mScrollGeneration = aOther.mScrollGeneration;
return mScrollOffset - origin;
}
/**
* Applies the relative scroll offset update contained in aOther to the
* smooth scroll destination offset contained in this. The scroll delta is
* clamped to the scrollable region.
*/
void ApplyRelativeSmoothScrollUpdateFrom(const FrameMetrics& aOther)
{
MOZ_ASSERT(aOther.IsRelative());

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

@ -31,6 +31,19 @@ public:
virtual bool DoSample(FrameMetrics& aFrameMetrics,
const TimeDuration& aDelta) = 0;
/**
* Attempt to apply a translation to the animation in response to content
* providing a relative scroll offset update.
*
* @param aShiftDelta the amount to translate the animation in app units
* @returns Whether the animation was able to translate. If false, the
* animation must be canceled.
*/
virtual bool ApplyContentShift(const CSSPoint& aShiftDelta)
{
return false;
}
bool Sample(FrameMetrics& aFrameMetrics,
const TimeDuration& aDelta) {
// In some situations, particularly when handoff is involved, it's possible

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

@ -4380,6 +4380,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// becomes incorrect for the purposes of calculating the LD transform. To
// correct this we need to update mExpectedGeckoMetrics to be the
// last thing we know was painted by Gecko.
Maybe<CSSPoint> relativeDelta;
if (gfxPrefs::APZRelativeUpdate() && aLayerMetrics.IsRelative()) {
APZC_LOG("%p relative updating scroll offset from %s by %s\n", this,
ToString(Metrics().GetScrollOffset()).c_str(),
@ -4395,7 +4396,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
userAction = true;
}
Metrics().ApplyRelativeScrollUpdateFrom(aLayerMetrics);
relativeDelta = Some(Metrics().ApplyRelativeScrollUpdateFrom(aLayerMetrics));
} else {
APZC_LOG("%p updating scroll offset from %s to %s\n", this,
ToString(Metrics().GetScrollOffset()).c_str(),
@ -4408,10 +4409,17 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
mCompositedScrollOffset = Metrics().GetScrollOffset();
mExpectedGeckoMetrics = aLayerMetrics;
// Cancel the animation (which might also trigger a repaint request)
// after we update the scroll offset above. Otherwise we can be left
// in a state where things are out of sync.
CancelAnimation();
// If we have applied a relative scroll update and a scroll animation is
// happening, attempt to apply a content shift and preserve the
// animation.
if (!mAnimation ||
relativeDelta.isNothing() ||
!mAnimation->ApplyContentShift(relativeDelta.value())) {
// Cancel the animation (which might also trigger a repaint request)
// after we update the scroll offset above. Otherwise we can be left
// in a state where things are out of sync.
CancelAnimation();
}
// Since the scroll offset has changed, we need to recompute the
// displayport margins and send them to layout. Otherwise there might be

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

@ -22,6 +22,13 @@ public:
bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) override;
bool ApplyContentShift(const CSSPoint& aShiftDelta) override
{
// Autoscroll works using screen space coordinates, so there's no work we
// need to do to handle a content shift
return true;
}
void Cancel(CancelAnimationFlags aFlags) override;
private:
AsyncPanZoomController& mApzc;

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

@ -109,5 +109,12 @@ GenericScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, const TimeDuration
return !finished;
}
bool
GenericScrollAnimation::ApplyContentShift(const CSSPoint& aShiftDelta)
{
mAnimationPhysics->ApplyContentShift(aShiftDelta);
return true;
}
} // namespace layers
} // namespace mozilla

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

@ -28,6 +28,8 @@ public:
bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) override;
bool ApplyContentShift(const CSSPoint& aShiftDelta) override;
void UpdateDelta(TimeStamp aTime,
const nsPoint& aDelta,
const nsSize& aCurrentVelocity);

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

@ -53,6 +53,14 @@ ScrollAnimationBezierPhysics::Update(const TimeStamp& aTime,
mIsFirstIteration = false;
}
void
ScrollAnimationBezierPhysics::ApplyContentShift(const CSSPoint& aShiftDelta)
{
nsPoint shiftDelta = CSSPoint::ToAppUnits(aShiftDelta);
mStartPos += shiftDelta;
mDestination += shiftDelta;
}
TimeDuration
ScrollAnimationBezierPhysics::ComputeDuration(const TimeStamp& aTime)
{

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

@ -35,6 +35,8 @@ public:
const nsPoint& aDestination,
const nsSize& aCurrentVelocity) override;
void ApplyContentShift(const CSSPoint& aShiftDelta) override;
// Get the velocity at a point in time in nscoords/sec.
nsSize VelocityAt(const TimeStamp& aTime) override;

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

@ -48,6 +48,14 @@ ScrollAnimationMSDPhysics::Update(const TimeStamp& aTime,
mIsFirstIteration = false;
}
void
ScrollAnimationMSDPhysics::ApplyContentShift(const CSSPoint& aShiftDelta)
{
nsPoint shiftDelta = CSSPoint::ToAppUnits(aShiftDelta);
mStartPos += shiftDelta;
mDestination += shiftDelta;
}
double
ScrollAnimationMSDPhysics::ComputeSpringConstant(const TimeStamp& aTime)
{

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

@ -25,6 +25,8 @@ public:
const nsPoint& aDestination,
const nsSize& aCurrentVelocity) override;
void ApplyContentShift(const CSSPoint& aShiftDelta) override;
// Get the velocity at a point in time in nscoords/sec.
nsSize VelocityAt(const TimeStamp& aTime) override;

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

@ -19,6 +19,8 @@ public:
const nsPoint& aDestination,
const nsSize& aCurrentVelocity) = 0;
virtual void ApplyContentShift(const CSSPoint& aShiftDelta) = 0;
// Get the velocity at a point in time in nscoords/sec.
virtual nsSize VelocityAt(const TimeStamp& aTime) = 0;