Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: Source/WebCore/platform/ScrollAnimatorNone.cpp

Issue 7604015: Merge 92639 - Scroll animator changes to nail the framerate (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/835/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011, Google Inc. All rights reserved. 2 * Copyright (c) 2011, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 30 matching lines...) Expand all
41 #include "ScrollbarTheme.h" 41 #include "ScrollbarTheme.h"
42 #include "TraceEvent.h" 42 #include "TraceEvent.h"
43 #include <algorithm> 43 #include <algorithm>
44 #include <wtf/CurrentTime.h> 44 #include <wtf/CurrentTime.h>
45 #include <wtf/PassOwnPtr.h> 45 #include <wtf/PassOwnPtr.h>
46 46
47 using namespace std; 47 using namespace std;
48 48
49 namespace WebCore { 49 namespace WebCore {
50 50
51 static double kTickTime = .0166; 51 static double kFrameRate = 60;
52 52 static double kTickTime = 1 / kFrameRate;
53 // This is used to set the timer delay - it needs to be slightly smaller than th e tick count to leave some overhead. 53 static double kMinimumTimerInterval = .001;
54 static double kAnimationTimerDelay = 0.015;
55 54
56 PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea ) 55 PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea )
57 { 56 {
58 if (scrollableArea && scrollableArea->scrollAnimatorEnabled()) 57 if (scrollableArea && scrollableArea->scrollAnimatorEnabled())
59 return adoptPtr(new ScrollAnimatorNone(scrollableArea)); 58 return adoptPtr(new ScrollAnimatorNone(scrollableArea));
60 return adoptPtr(new ScrollAnimator(scrollableArea)); 59 return adoptPtr(new ScrollAnimator(scrollableArea));
61 } 60 }
62 61
63 ScrollAnimatorNone::Parameters::Parameters() 62 ScrollAnimatorNone::Parameters::Parameters()
64 : m_isEnabled(false) 63 : m_isEnabled(false)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 return t * t * 3; 123 return t * t * 3;
125 case Cubic: 124 case Cubic:
126 return t * t * t * 4; 125 return t * t * t * 4;
127 case Bounce: 126 case Bounce:
128 return t; 127 return t;
129 } 128 }
130 } 129 }
131 130
132 ScrollAnimatorNone::PerAxisData::PerAxisData(ScrollAnimatorNone* parent, float* currentPosition) 131 ScrollAnimatorNone::PerAxisData::PerAxisData(ScrollAnimatorNone* parent, float* currentPosition)
133 : m_currentPosition(currentPosition) 132 : m_currentPosition(currentPosition)
134 , m_animationTimer(parent, &ScrollAnimatorNone::animationTimerFired)
135 { 133 {
136 reset(); 134 reset();
137 } 135 }
138 136
139 void ScrollAnimatorNone::PerAxisData::reset() 137 void ScrollAnimatorNone::PerAxisData::reset()
140 { 138 {
141 m_currentVelocity = 0; 139 m_currentVelocity = 0;
142 140
143 m_desiredPosition = 0; 141 m_desiredPosition = 0;
144 m_desiredVelocity = 0; 142 m_desiredVelocity = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 185
188 if (newPosition == m_desiredPosition) 186 if (newPosition == m_desiredPosition)
189 return false; 187 return false;
190 188
191 m_desiredPosition = newPosition; 189 m_desiredPosition = newPosition;
192 190
193 if (!m_startTime) { 191 if (!m_startTime) {
194 // FIXME: This should be the time from the event that got us here. 192 // FIXME: This should be the time from the event that got us here.
195 m_startTime = currentTime - kTickTime / 2; 193 m_startTime = currentTime - kTickTime / 2;
196 m_startPosition = *m_currentPosition; 194 m_startPosition = *m_currentPosition;
197 m_lastAnimationTime = currentTime; 195 m_lastAnimationTime = m_startTime;
198 } 196 }
199 m_startVelocity = m_currentVelocity; 197 m_startVelocity = m_currentVelocity;
200 198
201 double remainingDelta = m_desiredPosition - *m_currentPosition; 199 double remainingDelta = m_desiredPosition - *m_currentPosition;
202 200
203 double attackAreaLeft = 0; 201 double attackAreaLeft = 0;
204 202
205 double deltaTime = m_lastAnimationTime - m_startTime; 203 double deltaTime = m_lastAnimationTime - m_startTime;
206 double attackTimeLeft = max(0., m_attackTime - deltaTime); 204 double attackTimeLeft = max(0., m_attackTime - deltaTime);
207 double timeLeft = m_animationTime - deltaTime; 205 double timeLeft = m_animationTime - deltaTime;
(...skipping 25 matching lines...) Expand all
233 double roundOff = m_releasePosition - ((attackAreaLeft ? m_attackPositio n : *m_currentPosition) + m_desiredVelocity * sustainTimeLeft); 231 double roundOff = m_releasePosition - ((attackAreaLeft ? m_attackPositio n : *m_currentPosition) + m_desiredVelocity * sustainTimeLeft);
234 m_desiredVelocity += roundOff / sustainTimeLeft; 232 m_desiredVelocity += roundOff / sustainTimeLeft;
235 } 233 }
236 234
237 return true; 235 return true;
238 } 236 }
239 237
240 // FIXME: Add in jank detection trace events into this function. 238 // FIXME: Add in jank detection trace events into this function.
241 bool ScrollAnimatorNone::PerAxisData::animateScroll(double currentTime) 239 bool ScrollAnimatorNone::PerAxisData::animateScroll(double currentTime)
242 { 240 {
243 // Get the current time; grabbing the current time once helps keep a consist ent heartbeat.
244 double lastScrollInterval = currentTime - m_lastAnimationTime; 241 double lastScrollInterval = currentTime - m_lastAnimationTime;
242 if (lastScrollInterval < kMinimumTimerInterval)
243 return true;
244
245 m_lastAnimationTime = currentTime; 245 m_lastAnimationTime = currentTime;
246 246
247 double deltaTime = currentTime - m_startTime; 247 double deltaTime = currentTime - m_startTime;
248 double newPosition = *m_currentPosition; 248 double newPosition = *m_currentPosition;
249 249
250 if (deltaTime > m_animationTime) { 250 if (deltaTime > m_animationTime) {
251 *m_currentPosition = m_desiredPosition; 251 *m_currentPosition = m_desiredPosition;
252 reset(); 252 reset();
253 return false; 253 return false;
254 } 254 }
(...skipping 12 matching lines...) Expand all
267 m_currentVelocity = (newPosition - *m_currentPosition) / lastScrollInter val; 267 m_currentVelocity = (newPosition - *m_currentPosition) / lastScrollInter val;
268 *m_currentPosition = newPosition; 268 *m_currentPosition = newPosition;
269 269
270 return true; 270 return true;
271 } 271 }
272 272
273 ScrollAnimatorNone::ScrollAnimatorNone(ScrollableArea* scrollableArea) 273 ScrollAnimatorNone::ScrollAnimatorNone(ScrollableArea* scrollableArea)
274 : ScrollAnimator(scrollableArea) 274 : ScrollAnimator(scrollableArea)
275 , m_horizontalData(this, &m_currentPosX) 275 , m_horizontalData(this, &m_currentPosX)
276 , m_verticalData(this, &m_currentPosY) 276 , m_verticalData(this, &m_currentPosY)
277 , m_animationTimer(this, &ScrollAnimatorNone::animationTimerFired)
277 { 278 {
278 } 279 }
279 280
280 ScrollAnimatorNone::~ScrollAnimatorNone() 281 ScrollAnimatorNone::~ScrollAnimatorNone()
281 { 282 {
282 stopAnimationTimerIfNeeded(&m_horizontalData); 283 stopAnimationTimerIfNeeded();
283 stopAnimationTimerIfNeeded(&m_verticalData);
284 } 284 }
285 285
286 bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranular ity granularity, float step, float multiplier) 286 bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranular ity granularity, float step, float multiplier)
287 { 287 {
288 if (!m_scrollableArea->scrollAnimatorEnabled()) 288 if (!m_scrollableArea->scrollAnimatorEnabled())
289 return ScrollAnimator::scroll(orientation, granularity, step, multiplier ); 289 return ScrollAnimator::scroll(orientation, granularity, step, multiplier );
290 290
291 // FIXME: get the type passed in. MouseWheel could also be by line, but shou ld still have different 291 // FIXME: get the type passed in. MouseWheel could also be by line, but shou ld still have different
292 // animation parameters than the keyboard. 292 // animation parameters than the keyboard.
293 Parameters parameters; 293 Parameters parameters;
(...skipping 10 matching lines...) Expand all
304 parameters = Parameters(true, 11 * kTickTime, 2 * kTickTime, Quadratic, 3 * kTickTime, Quadratic, 3 * kTickTime); 304 parameters = Parameters(true, 11 * kTickTime, 2 * kTickTime, Quadratic, 3 * kTickTime, Quadratic, 3 * kTickTime);
305 break; 305 break;
306 default: 306 default:
307 break; 307 break;
308 } 308 }
309 309
310 // If the individual input setting is disabled, bail. 310 // If the individual input setting is disabled, bail.
311 if (!parameters.m_isEnabled) 311 if (!parameters.m_isEnabled)
312 return ScrollAnimator::scroll(orientation, granularity, step, multiplier ); 312 return ScrollAnimator::scroll(orientation, granularity, step, multiplier );
313 313
314 // This is an animatable scroll. Calculate the scroll delta. 314 // This is an animatable scroll. Set the animation in motion using the appro priate parameters.
315 PerAxisData* data = (orientation == VerticalScrollbar) ? &m_verticalData : & m_horizontalData; 315 float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orien tation));
316 316
317 float scrollableSize = static_cast<float>(m_scrollableArea->scrollSize(orien tation)); 317 PerAxisData& data = (orientation == VerticalScrollbar) ? m_verticalData : m_ horizontalData;
318 bool result = data->updateDataFromParameters(orientation, step, multiplier, scrollableSize, WTF::currentTime(), &parameters); 318 bool needToScroll = data.updateDataFromParameters(orientation, step, multipl ier, scrollableSize, WTF::monotonicallyIncreasingTime(), &parameters);
319 if (!data->m_animationTimer.isActive()) { 319 if (needToScroll && !m_animationTimer.isActive()) {
320 result &= data->animateScroll(WTF::currentTime()); 320 m_startTime = data.m_startTime;
321 if (result) 321 animationTimerFired(&m_animationTimer);
322 data->m_animationTimer.startOneShot(kAnimationTimerDelay);
323 } 322 }
324 notityPositionChanged(); 323 return needToScroll;
325 return result;
326 } 324 }
327 325
328 void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset ) 326 void ScrollAnimatorNone::scrollToOffsetWithoutAnimation(const FloatPoint& offset )
329 { 327 {
330 stopAnimationTimerIfNeeded(&m_horizontalData); 328 stopAnimationTimerIfNeeded();
331 stopAnimationTimerIfNeeded(&m_verticalData);
332 329
333 m_horizontalData.reset(); 330 m_horizontalData.reset();
334 *m_horizontalData.m_currentPosition = offset.x(); 331 *m_horizontalData.m_currentPosition = offset.x();
335 m_horizontalData.m_desiredPosition = offset.x(); 332 m_horizontalData.m_desiredPosition = offset.x();
336 333
337 m_verticalData.reset(); 334 m_verticalData.reset();
338 *m_verticalData.m_currentPosition = offset.y(); 335 *m_verticalData.m_currentPosition = offset.y();
339 m_verticalData.m_desiredPosition = offset.y(); 336 m_verticalData.m_desiredPosition = offset.y();
340 337
341 notityPositionChanged(); 338 notityPositionChanged();
342 } 339 }
343 340
344 void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer) 341 void ScrollAnimatorNone::animationTimerFired(Timer<ScrollAnimatorNone>* timer)
345 { 342 {
346 double currentTime = WTF::currentTime(); 343 double currentTime = WTF::monotonicallyIncreasingTime();
347 if ((timer == &m_horizontalData.m_animationTimer) ? 344 double deltaToNextFrame = ceil((currentTime - m_startTime) * kFrameRate) / k FrameRate - (currentTime - m_startTime);
348 m_horizontalData.animateScroll(currentTime) : 345
349 m_verticalData.animateScroll(currentTime)) 346 bool continueAnimation = false;
350 { 347 if (m_horizontalData.m_startTime && m_horizontalData.animateScroll(currentTi me + deltaToNextFrame))
351 double delta = WTF::currentTime() - currentTime; 348 continueAnimation = true;
352 timer->startOneShot(kAnimationTimerDelay - delta); 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);
353 } 354 }
354 notityPositionChanged(); 355 notityPositionChanged();
355 } 356 }
356 357
357 void ScrollAnimatorNone::stopAnimationTimerIfNeeded(PerAxisData* data) 358 void ScrollAnimatorNone::stopAnimationTimerIfNeeded()
358 { 359 {
359 if (data->m_animationTimer.isActive()) 360 if (m_animationTimer.isActive())
360 data->m_animationTimer.stop(); 361 m_animationTimer.stop();
361 } 362 }
362 363
363 } // namespace WebCore 364 } // namespace WebCore
364 365
365 #endif // ENABLE(SMOOTH_SCROLLING) 366 #endif // ENABLE(SMOOTH_SCROLLING)
OLDNEW
« no previous file with comments | « Source/WebCore/platform/ScrollAnimatorNone.h ('k') | Source/WebKit/chromium/tests/ScrollAnimatorNoneTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698