Modified: trunk/Source/WebCore/platform/ScrollAnimatorNone.cpp (92638 => 92639)
--- trunk/Source/WebCore/platform/ScrollAnimatorNone.cpp 2011-08-08 21:53:39 UTC (rev 92638)
+++ trunk/Source/WebCore/platform/ScrollAnimatorNone.cpp 2011-08-08 22:01:15 UTC (rev 92639)
@@ -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 = "" == 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 = "" == 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
Modified: trunk/Source/WebKit/chromium/tests/ScrollAnimatorNoneTest.cpp (92638 => 92639)
--- trunk/Source/WebKit/chromium/tests/ScrollAnimatorNoneTest.cpp 2011-08-08 21:53:39 UTC (rev 92638)
+++ trunk/Source/WebKit/chromium/tests/ScrollAnimatorNoneTest.cpp 2011-08-08 22:01:15 UTC (rev 92639)
@@ -79,8 +79,7 @@
void reset()
{
- stopAnimationTimerIfNeeded(&m_horizontalData);
- stopAnimationTimerIfNeeded(&m_verticalData);
+ stopAnimationTimerIfNeeded();
m_currentPosX = 0;
m_currentPosY = 0;
m_horizontalData.reset();
@@ -93,57 +92,57 @@
TEST(ScrollAnimatorEnabled, Enabled)
{
MockScrollableArea scrollableArea(true);
- MockScrollAnimatorNone scrollAnimatorChromium(&scrollableArea);
+ MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea);
EXPECT_CALL(scrollableArea, scrollSize(_)).Times(AtLeast(1)).WillRepeatedly(Return(1000));
- EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(AtLeast(1));
+ EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(3);
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
- EXPECT_NE(100, scrollAnimatorChromium.currentX());
- EXPECT_NE(0, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
+ EXPECT_NE(100, scrollAnimatorNone.currentX());
+ EXPECT_NE(0, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
- EXPECT_NE(100, scrollAnimatorChromium.currentX());
- EXPECT_NE(0, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
+ EXPECT_NE(100, scrollAnimatorNone.currentX());
+ EXPECT_NE(0, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPixel, 4, 25);
- EXPECT_NE(100, scrollAnimatorChromium.currentX());
- EXPECT_NE(0, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 4, 25);
+ EXPECT_NE(100, scrollAnimatorNone.currentX());
+ EXPECT_NE(0, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
}
TEST(ScrollAnimatorEnabled, Disabled)
{
MockScrollableArea scrollableArea(false);
- MockScrollAnimatorNone scrollAnimatorChromium(&scrollableArea);
+ MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea);
EXPECT_CALL(scrollableArea, scrollSize(_)).Times(AtLeast(1)).WillRepeatedly(Return(1000));
- EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(AtLeast(1));
+ EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(4);
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
- EXPECT_EQ(100, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
+ EXPECT_EQ(100, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
- EXPECT_EQ(100, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
+ EXPECT_EQ(100, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByDocument, 100, 1);
- EXPECT_EQ(100, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByDocument, 100, 1);
+ EXPECT_EQ(100, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
- scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPixel, 100, 1);
- EXPECT_EQ(100, scrollAnimatorChromium.currentX());
- EXPECT_EQ(0, scrollAnimatorChromium.currentY());
- scrollAnimatorChromium.reset();
+ scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 100, 1);
+ EXPECT_EQ(100, scrollAnimatorNone.currentX());
+ EXPECT_EQ(0, scrollAnimatorNone.currentY());
+ scrollAnimatorNone.reset();
}
class ScrollAnimatorNoneTest : public testing::Test {