Changeset 92639 in webkit


Ignore:
Timestamp:
Aug 8, 2011 3:01:15 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

Scroll animator changes to nail the framerate
https://bugs.webkit.org/show_bug.cgi?id=65645

Patch by Scott Byer <scottbyer@chromium.org> on 2011-08-08
Reviewed by James Robinson.

Source/WebCore:

Partial test in ScrollAnimatorNoneTest::Enabled.

  • platform/ScrollAnimatorNone.cpp:

(WebCore::ScrollAnimatorNone::PerAxisData::PerAxisData):
(WebCore::ScrollAnimatorNone::PerAxisData::updateDataFromParameters):
(WebCore::ScrollAnimatorNone::PerAxisData::animateScroll):
(WebCore::ScrollAnimatorNone::ScrollAnimatorNone):
(WebCore::ScrollAnimatorNone::~ScrollAnimatorNone):
(WebCore::ScrollAnimatorNone::scroll):
(WebCore::ScrollAnimatorNone::scrollToOffsetWithoutAnimation):
(WebCore::ScrollAnimatorNone::animationTimerFired):
(WebCore::ScrollAnimatorNone::stopAnimationTimerIfNeeded):

  • platform/ScrollAnimatorNone.h:

Source/WebKit/chromium:

  • tests/ScrollAnimatorNoneTest.cpp:

(TEST):

Location:
trunk/Source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r92638 r92639  
     12011-08-08  Scott Byer  <scottbyer@chromium.org>
     2
     3        Scroll animator changes to nail the framerate
     4        https://bugs.webkit.org/show_bug.cgi?id=65645
     5
     6        Reviewed by James Robinson.
     7
     8        Partial test in ScrollAnimatorNoneTest::Enabled.
     9
     10        * platform/ScrollAnimatorNone.cpp:
     11        (WebCore::ScrollAnimatorNone::PerAxisData::PerAxisData):
     12        (WebCore::ScrollAnimatorNone::PerAxisData::updateDataFromParameters):
     13        (WebCore::ScrollAnimatorNone::PerAxisData::animateScroll):
     14        (WebCore::ScrollAnimatorNone::ScrollAnimatorNone):
     15        (WebCore::ScrollAnimatorNone::~ScrollAnimatorNone):
     16        (WebCore::ScrollAnimatorNone::scroll):
     17        (WebCore::ScrollAnimatorNone::scrollToOffsetWithoutAnimation):
     18        (WebCore::ScrollAnimatorNone::animationTimerFired):
     19        (WebCore::ScrollAnimatorNone::stopAnimationTimerIfNeeded):
     20        * platform/ScrollAnimatorNone.h:
     21
    1222011-08-08  Emil A Eklund  <eae@chromium.org>
    223
  • trunk/Source/WebCore/platform/ScrollAnimatorNone.cpp

    r92002 r92639  
    4949namespace WebCore {
    5050
    51 static double kTickTime = .0166;
    52 
    53 // This is used to set the timer delay - it needs to be slightly smaller than the tick count to leave some overhead.
    54 static double kAnimationTimerDelay = 0.015;
     51static double kFrameRate = 60;
     52static double kTickTime = 1 / kFrameRate;
     53static double kMinimumTimerInterval = .001;
    5554
    5655PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea)
     
    132131ScrollAnimatorNone::PerAxisData::PerAxisData(ScrollAnimatorNone* parent, float* currentPosition)
    133132    : m_currentPosition(currentPosition)
    134     , m_animationTimer(parent, &ScrollAnimatorNone::animationTimerFired)
    135133{
    136134    reset();
     
    195193        m_startTime = currentTime - kTickTime / 2;
    196194        m_startPosition = *m_currentPosition;
    197         m_lastAnimationTime = currentTime;
     195        m_lastAnimationTime = m_startTime;
    198196    }
    199197    m_startVelocity = m_currentVelocity;
     
    241239bool ScrollAnimatorNone::PerAxisData::animateScroll(double currentTime)
    242240{
    243     // Get the current time; grabbing the current time once helps keep a consistent heartbeat.
    244241    double lastScrollInterval = currentTime - m_lastAnimationTime;
     242    if (lastScrollInterval < kMinimumTimerInterval)
     243        return true;
     244
    245245    m_lastAnimationTime = currentTime;
    246246
     
    275275    , m_horizontalData(this, &m_currentPosX)
    276276    , m_verticalData(this, &m_currentPosY)
     277    , m_animationTimer(this, &ScrollAnimatorNone::animationTimerFired)
    277278{
    278279}
     
    280281ScrollAnimatorNone::~ScrollAnimatorNone()
    281282{
    282     stopAnimationTimerIfNeeded(&m_horizontalData);
    283     stopAnimationTimerIfNeeded(&m_verticalData);
     283    stopAnimationTimerIfNeeded();
    284284}
    285285
     
    312312        return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
    313313
    314     // This is an animatable scroll. Calculate the scroll delta.
    315     PerAxisData* data = (orientation == VerticalScrollbar) ? &m_verticalData : &m_horizontalData;
    316 
     314    // This is an animatable scroll. Set the animation in motion using the appropriate parameters.
    317315    float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orientation));
    318     bool result = data->updateDataFromParameters(orientation, step, multiplier, scrollableSize, WTF::currentTime(), &parameters);
    319     if (!data->m_animationTimer.isActive()) {
    320         result &= data->animateScroll(WTF::currentTime());
    321         if (result)
    322             data->m_animationTimer.startOneShot(kAnimationTimerDelay);
    323     }
    324     notityPositionChanged();
    325     return result;
     316
     317    PerAxisData& data = (orientation == VerticalScrollbar) ? m_verticalData : m_horizontalData;
     318    bool needToScroll = data.updateDataFromParameters(orientation, step, multiplier, scrollableSize, WTF::monotonicallyIncreasingTime(), &parameters);
     319    if (needToScroll && !m_animationTimer.isActive()) {
     320        m_startTime = data.m_startTime;
     321        animationTimerFired(&m_animationTimer);
     322    }
     323    return needToScroll;
    326324}
    327325
    328326void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
    329327{
    330     stopAnimationTimerIfNeeded(&m_horizontalData);
    331     stopAnimationTimerIfNeeded(&m_verticalData);
     328    stopAnimationTimerIfNeeded();
    332329
    333330    m_horizontalData.reset();
     
    344341void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer)
    345342{
    346     double currentTime = WTF::currentTime();
    347     if ((timer == &m_horizontalData.m_animationTimer) ?
    348         m_horizontalData.animateScroll(currentTime) :
    349         m_verticalData.animateScroll(currentTime))
    350     {
    351         double delta = WTF::currentTime() - currentTime;
    352         timer->startOneShot(kAnimationTimerDelay - delta);
     343    double currentTime = WTF::monotonicallyIncreasingTime();
     344    double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / kFrameRate - (currentTime - m_startTime);
     345
     346    bool continueAnimation = false;
     347    if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTime + deltaToNextFrame))
     348        continueAnimation = true;
     349    if (m_verticalData.m_startTime && m_verticalData.animateScroll(currentTime + deltaToNextFrame))
     350        continueAnimation = true;
     351    if (continueAnimation) {
     352        double nextTimerInterval = max(kMinimumTimerInterval, deltaToNextFrame);
     353        timer->startOneShot(nextTimerInterval);
    353354    }
    354355    notityPositionChanged();
    355356}
    356357
    357 void ScrollAnimatorNone::stopAnimationTimerIfNeeded(PerAxisData* data)
    358 {
    359     if (data->m_animationTimer.isActive())
    360         data->m_animationTimer.stop();
     358void ScrollAnimatorNone::stopAnimationTimerIfNeeded()
     359{
     360    if (m_animationTimer.isActive())
     361        m_animationTimer.stop();
    361362}
    362363
  • trunk/Source/WebCore/platform/ScrollAnimatorNone.h

    r92002 r92639  
    113113
    114114        ScrollbarOrientation m_orientation;
    115         Timer<ScrollAnimatorNone> m_animationTimer;
    116115    };
    117116
    118117    void animationTimerFired(Timer<ScrollAnimatorNone>*);
    119     void stopAnimationTimerIfNeeded(PerAxisData*);
     118    void stopAnimationTimerIfNeeded();
    120119
    121120    PerAxisData m_horizontalData;
    122121    PerAxisData m_verticalData;
     122
     123    double m_startTime;
     124    Timer<ScrollAnimatorNone> m_animationTimer;
    123125};
    124126
  • trunk/Source/WebKit/chromium/ChangeLog

    r92619 r92639  
     12011-08-08  Scott Byer  <scottbyer@chromium.org>
     2
     3        Scroll animator changes to nail the framerate
     4        https://bugs.webkit.org/show_bug.cgi?id=65645
     5
     6        Reviewed by James Robinson.
     7
     8        * tests/ScrollAnimatorNoneTest.cpp:
     9        (TEST):
     10
    1112011-08-08  Dmitry Lomov  <dslomov@google.com>
    212
  • trunk/Source/WebKit/chromium/tests/ScrollAnimatorNoneTest.cpp

    r92002 r92639  
    8080    void reset()
    8181    {
    82         stopAnimationTimerIfNeeded(&m_horizontalData);
    83         stopAnimationTimerIfNeeded(&m_verticalData);
     82        stopAnimationTimerIfNeeded();
    8483        m_currentPosX = 0;
    8584        m_currentPosY = 0;
     
    9493{
    9594    MockScrollableArea scrollableArea(true);
    96     MockScrollAnimatorNone scrollAnimatorChromium(&scrollableArea);
     95    MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea);
    9796
    9897    EXPECT_CALL(scrollableArea, scrollSize(_)).Times(AtLeast(1)).WillRepeatedly(Return(1000));
    99     EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(AtLeast(1));
    100 
    101     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
    102     EXPECT_NE(100, scrollAnimatorChromium.currentX());
    103     EXPECT_NE(0, scrollAnimatorChromium.currentX());
    104     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    105     scrollAnimatorChromium.reset();
    106 
    107     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
    108     EXPECT_NE(100, scrollAnimatorChromium.currentX());
    109     EXPECT_NE(0, scrollAnimatorChromium.currentX());
    110     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    111     scrollAnimatorChromium.reset();
    112 
    113     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPixel, 4, 25);
    114     EXPECT_NE(100, scrollAnimatorChromium.currentX());
    115     EXPECT_NE(0, scrollAnimatorChromium.currentX());
    116     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    117     scrollAnimatorChromium.reset();
     98    EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(3);
     99
     100    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
     101    EXPECT_NE(100, scrollAnimatorNone.currentX());
     102    EXPECT_NE(0, scrollAnimatorNone.currentX());
     103    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     104    scrollAnimatorNone.reset();
     105
     106    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
     107    EXPECT_NE(100, scrollAnimatorNone.currentX());
     108    EXPECT_NE(0, scrollAnimatorNone.currentX());
     109    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     110    scrollAnimatorNone.reset();
     111
     112    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 4, 25);
     113    EXPECT_NE(100, scrollAnimatorNone.currentX());
     114    EXPECT_NE(0, scrollAnimatorNone.currentX());
     115    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     116    scrollAnimatorNone.reset();
    118117}
    119118
     
    121120{
    122121    MockScrollableArea scrollableArea(false);
    123     MockScrollAnimatorNone scrollAnimatorChromium(&scrollableArea);
     122    MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea);
    124123
    125124    EXPECT_CALL(scrollableArea, scrollSize(_)).Times(AtLeast(1)).WillRepeatedly(Return(1000));
    126     EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(AtLeast(1));
    127 
    128     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
    129     EXPECT_EQ(100, scrollAnimatorChromium.currentX());
    130     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    131     scrollAnimatorChromium.reset();
    132 
    133     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
    134     EXPECT_EQ(100, scrollAnimatorChromium.currentX());
    135     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    136     scrollAnimatorChromium.reset();
    137 
    138     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByDocument, 100, 1);
    139     EXPECT_EQ(100, scrollAnimatorChromium.currentX());
    140     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    141     scrollAnimatorChromium.reset();
    142 
    143     scrollAnimatorChromium.scroll(HorizontalScrollbar, ScrollByPixel, 100, 1);
    144     EXPECT_EQ(100, scrollAnimatorChromium.currentX());
    145     EXPECT_EQ(0, scrollAnimatorChromium.currentY());
    146     scrollAnimatorChromium.reset();
     125    EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(4);
     126
     127    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
     128    EXPECT_EQ(100, scrollAnimatorNone.currentX());
     129    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     130    scrollAnimatorNone.reset();
     131
     132    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
     133    EXPECT_EQ(100, scrollAnimatorNone.currentX());
     134    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     135    scrollAnimatorNone.reset();
     136
     137    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByDocument, 100, 1);
     138    EXPECT_EQ(100, scrollAnimatorNone.currentX());
     139    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     140    scrollAnimatorNone.reset();
     141
     142    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 100, 1);
     143    EXPECT_EQ(100, scrollAnimatorNone.currentX());
     144    EXPECT_EQ(0, scrollAnimatorNone.currentY());
     145    scrollAnimatorNone.reset();
    147146}
    148147
Note: See TracChangeset for help on using the changeset viewer.