Index: Source/WebCore/platform/ScrollAnimatorNone.cpp |
=================================================================== |
--- Source/WebCore/platform/ScrollAnimatorNone.cpp (revision 92726) |
+++ Source/WebCore/platform/ScrollAnimatorNone.cpp (working copy) |
@@ -48,11 +48,10 @@ |
namespace WebCore { |
-static double kTickTime = .0166; |
+static double kFrameRate = 60; |
+static double kTickTime = 1 / kFrameRate; |
+static double kMinimumTimerInterval = .001; |
-// This is used to set the timer delay - it needs to be slightly smaller than the tick count to leave some overhead. |
-static double kAnimationTimerDelay = 0.015; |
- |
PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea) |
{ |
if (scrollableArea && scrollableArea->scrollAnimatorEnabled()) |
@@ -131,7 +130,6 @@ |
ScrollAnimatorNone::PerAxisData::PerAxisData(ScrollAnimatorNone* parent, float* currentPosition) |
: m_currentPosition(currentPosition) |
- , m_animationTimer(parent, &ScrollAnimatorNone::animationTimerFired) |
{ |
reset(); |
} |
@@ -194,7 +192,7 @@ |
// FIXME: This should be the time from the event that got us here. |
m_startTime = currentTime - kTickTime / 2; |
m_startPosition = *m_currentPosition; |
- m_lastAnimationTime = currentTime; |
+ m_lastAnimationTime = m_startTime; |
} |
m_startVelocity = m_currentVelocity; |
@@ -240,8 +238,10 @@ |
// FIXME: Add in jank detection trace events into this function. |
bool ScrollAnimatorNone::PerAxisData::animateScroll(double currentTime) |
{ |
- // Get the current time; grabbing the current time once helps keep a consistent heartbeat. |
double lastScrollInterval = currentTime - m_lastAnimationTime; |
+ if (lastScrollInterval < kMinimumTimerInterval) |
+ return true; |
+ |
m_lastAnimationTime = currentTime; |
double deltaTime = currentTime - m_startTime; |
@@ -274,13 +274,13 @@ |
: ScrollAnimator(scrollableArea) |
, m_horizontalData(this, &m_currentPosX) |
, m_verticalData(this, &m_currentPosY) |
+ , m_animationTimer(this, &ScrollAnimatorNone::animationTimerFired) |
{ |
} |
ScrollAnimatorNone::~ScrollAnimatorNone() |
{ |
- stopAnimationTimerIfNeeded(&m_horizontalData); |
- stopAnimationTimerIfNeeded(&m_verticalData); |
+ stopAnimationTimerIfNeeded(); |
} |
bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier) |
@@ -311,24 +311,21 @@ |
if (!parameters.m_isEnabled) |
return ScrollAnimator::scroll(orientation, granularity, step, multiplier); |
- // This is an animatable scroll. Calculate the scroll delta. |
- PerAxisData* data = (orientation == VerticalScrollbar) ? &m_verticalData : &m_horizontalData; |
+ // This is an animatable scroll. Set the animation in motion using the appropriate parameters. |
+ float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orientation)); |
- float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orientation)); |
- bool result = data->updateDataFromParameters(orientation, step, multiplier, scrollableSize, WTF::currentTime(), ¶meters); |
- if (!data->m_animationTimer.isActive()) { |
- result &= data->animateScroll(WTF::currentTime()); |
- if (result) |
- data->m_animationTimer.startOneShot(kAnimationTimerDelay); |
+ PerAxisData& data = (orientation == VerticalScrollbar) ? m_verticalData : m_horizontalData; |
+ bool needToScroll = data.updateDataFromParameters(orientation, step, multiplier, scrollableSize, WTF::monotonicallyIncreasingTime(), ¶meters); |
+ if (needToScroll && !m_animationTimer.isActive()) { |
+ m_startTime = data.m_startTime; |
+ animationTimerFired(&m_animationTimer); |
} |
- notityPositionChanged(); |
- return result; |
+ return needToScroll; |
} |
void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset) |
{ |
- stopAnimationTimerIfNeeded(&m_horizontalData); |
- stopAnimationTimerIfNeeded(&m_verticalData); |
+ stopAnimationTimerIfNeeded(); |
m_horizontalData.reset(); |
*m_horizontalData.m_currentPosition = offset.x(); |
@@ -343,21 +340,25 @@ |
void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer) |
{ |
- double currentTime = WTF::currentTime(); |
- if ((timer == &m_horizontalData.m_animationTimer) ? |
- m_horizontalData.animateScroll(currentTime) : |
- m_verticalData.animateScroll(currentTime)) |
- { |
- double delta = WTF::currentTime() - currentTime; |
- timer->startOneShot(kAnimationTimerDelay - delta); |
+ double currentTime = WTF::monotonicallyIncreasingTime(); |
+ double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime); |
+ |
+ bool continueAnimation = false; |
+ if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime + deltaToNextFrame)) |
+ continueAnimation = true; |
+ if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime + deltaToNextFrame)) |
+ continueAnimation = true; |
+ if (continueAnimation) { |
+ double nextTimerInterval = max(kMinimumTimerInterval, deltaToNextFrame); |
+ timer->startOneShot(nextTimerInterval); |
} |
notityPositionChanged(); |
} |
-void ScrollAnimatorNone::stopAnimationTimerIfNeeded(PerAxisData* data) |
+void ScrollAnimatorNone::stopAnimationTimerIfNeeded() |
{ |
- if (data->m_animationTimer.isActive()) |
- data->m_animationTimer.stop(); |
+ if (m_animationTimer.isActive()) |
+ m_animationTimer.stop(); |
} |
} // namespace WebCore |