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

Side by Side Diff: third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp

Issue 2387883002: Use float for scroll offset. (Closed)
Patch Set: Created 4 years, 2 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 } 60 }
61 61
62 ScrollAnimator::ScrollAnimator(ScrollableArea* scrollableArea, 62 ScrollAnimator::ScrollAnimator(ScrollableArea* scrollableArea,
63 WTF::TimeFunction timeFunction) 63 WTF::TimeFunction timeFunction)
64 : ScrollAnimatorBase(scrollableArea), 64 : ScrollAnimatorBase(scrollableArea),
65 m_timeFunction(timeFunction), 65 m_timeFunction(timeFunction),
66 m_lastGranularity(ScrollByPixel) {} 66 m_lastGranularity(ScrollByPixel) {}
67 67
68 ScrollAnimator::~ScrollAnimator() {} 68 ScrollAnimator::~ScrollAnimator() {}
69 69
70 FloatPoint ScrollAnimator::desiredTargetPosition() const { 70 ScrollOffset ScrollAnimator::desiredTargetOffset() const {
71 if (m_runState == RunState::WaitingToCancelOnCompositor) 71 if (m_runState == RunState::WaitingToCancelOnCompositor)
72 return currentPosition(); 72 return currentOffset();
73 return (m_animationCurve || m_runState == RunState::WaitingToSendToCompositor) 73 return (m_animationCurve || m_runState == RunState::WaitingToSendToCompositor)
74 ? m_targetOffset 74 ? m_targetOffset
75 : currentPosition(); 75 : currentOffset();
76 } 76 }
77 77
78 bool ScrollAnimator::hasRunningAnimation() const { 78 bool ScrollAnimator::hasRunningAnimation() const {
79 return m_runState != RunState::PostAnimationCleanup && 79 return m_runState != RunState::PostAnimationCleanup &&
80 (m_animationCurve || 80 (m_animationCurve ||
81 m_runState == RunState::WaitingToSendToCompositor); 81 m_runState == RunState::WaitingToSendToCompositor);
82 } 82 }
83 83
84 FloatSize ScrollAnimator::computeDeltaToConsume(const FloatSize& delta) const { 84 ScrollOffset ScrollAnimator::computeDeltaToConsume(
85 FloatPoint pos = desiredTargetPosition(); 85 const ScrollOffset& delta) const {
86 FloatPoint newPos = 86 ScrollOffset pos = desiredTargetOffset();
87 toFloatPoint(m_scrollableArea->clampScrollPosition(pos + delta)); 87 ScrollOffset newPos = m_scrollableArea->clampScrollOffset(pos + delta);
88 return newPos - pos; 88 return newPos - pos;
89 } 89 }
90 90
91 void ScrollAnimator::resetAnimationState() { 91 void ScrollAnimator::resetAnimationState() {
92 ScrollAnimatorCompositorCoordinator::resetAnimationState(); 92 ScrollAnimatorCompositorCoordinator::resetAnimationState();
93 if (m_animationCurve) 93 if (m_animationCurve)
94 m_animationCurve.reset(); 94 m_animationCurve.reset();
95 m_startTime = 0.0; 95 m_startTime = 0.0;
96 } 96 }
97 97
98 ScrollResult ScrollAnimator::userScroll(ScrollGranularity granularity, 98 ScrollResult ScrollAnimator::userScroll(ScrollGranularity granularity,
99 const FloatSize& delta) { 99 const ScrollOffset& delta) {
100 if (!m_scrollableArea->scrollAnimatorEnabled()) 100 if (!m_scrollableArea->scrollAnimatorEnabled())
101 return ScrollAnimatorBase::userScroll(granularity, delta); 101 return ScrollAnimatorBase::userScroll(granularity, delta);
102 102
103 TRACE_EVENT0("blink", "ScrollAnimator::scroll"); 103 TRACE_EVENT0("blink", "ScrollAnimator::scroll");
104 104
105 if (granularity == ScrollByPrecisePixel) { 105 if (granularity == ScrollByPrecisePixel) {
106 // Cancel scroll animation because asked to instant scroll. 106 // Cancel scroll animation because asked to instant scroll.
107 if (hasRunningAnimation()) 107 if (hasRunningAnimation())
108 cancelAnimation(); 108 cancelAnimation();
109 return ScrollAnimatorBase::userScroll(granularity, delta); 109 return ScrollAnimatorBase::userScroll(granularity, delta);
110 } 110 }
111 111
112 bool needsPostAnimationCleanup = m_runState == RunState::PostAnimationCleanup; 112 bool needsPostAnimationCleanup = m_runState == RunState::PostAnimationCleanup;
113 if (m_runState == RunState::PostAnimationCleanup) 113 if (m_runState == RunState::PostAnimationCleanup)
114 resetAnimationState(); 114 resetAnimationState();
115 115
116 FloatSize consumedDelta = computeDeltaToConsume(delta); 116 ScrollOffset consumedDelta = computeDeltaToConsume(delta);
117 FloatPoint targetPos = desiredTargetPosition(); 117 ScrollOffset targetOffset = desiredTargetOffset();
118 targetPos.move(consumedDelta); 118 targetOffset += consumedDelta;
119 119
120 if (willAnimateToOffset(targetPos)) { 120 if (willAnimateToOffset(targetOffset)) {
121 m_lastGranularity = granularity; 121 m_lastGranularity = granularity;
122 // Report unused delta only if there is no animation running. See 122 // Report unused delta only if there is no animation running. See
123 // comment below regarding scroll latching. 123 // comment below regarding scroll latching.
124 // TODO(bokan): Need to standardize how ScrollAnimators report 124 // TODO(bokan): Need to standardize how ScrollAnimators report
125 // unusedDelta. This differs from ScrollAnimatorMac currently. 125 // unusedDelta. This differs from ScrollAnimatorMac currently.
126 return ScrollResult(true, true, 0, 0); 126 return ScrollResult(true, true, 0, 0);
127 } 127 }
128 128
129 // If the run state when this method was called was PostAnimationCleanup and 129 // If the run state when this method was called was PostAnimationCleanup and
130 // we're not starting an animation, stay in PostAnimationCleanup state so 130 // we're not starting an animation, stay in PostAnimationCleanup state so
131 // that the main thread scrolling reason can be removed. 131 // that the main thread scrolling reason can be removed.
132 if (needsPostAnimationCleanup) 132 if (needsPostAnimationCleanup)
133 m_runState = RunState::PostAnimationCleanup; 133 m_runState = RunState::PostAnimationCleanup;
134 134
135 // Report unused delta only if there is no animation and we are not 135 // Report unused delta only if there is no animation and we are not
136 // starting one. This ensures we latch for the duration of the 136 // starting one. This ensures we latch for the duration of the
137 // animation rather than animating multiple scrollers at the same time. 137 // animation rather than animating multiple scrollers at the same time.
138 return ScrollResult(false, false, delta.width(), delta.height()); 138 return ScrollResult(false, false, delta.width(), delta.height());
139 } 139 }
140 140
141 bool ScrollAnimator::willAnimateToOffset(const FloatPoint& targetPos) { 141 bool ScrollAnimator::willAnimateToOffset(const ScrollOffset& targetOffset) {
142 if (m_runState == RunState::PostAnimationCleanup) 142 if (m_runState == RunState::PostAnimationCleanup)
143 resetAnimationState(); 143 resetAnimationState();
144 144
145 if (m_runState == RunState::WaitingToCancelOnCompositor || 145 if (m_runState == RunState::WaitingToCancelOnCompositor ||
146 m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) { 146 m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) {
147 ASSERT(m_animationCurve); 147 ASSERT(m_animationCurve);
148 m_targetOffset = targetPos; 148 m_targetOffset = targetOffset;
149 if (registerAndScheduleAnimation()) 149 if (registerAndScheduleAnimation())
150 m_runState = RunState::WaitingToCancelOnCompositorButNewScroll; 150 m_runState = RunState::WaitingToCancelOnCompositorButNewScroll;
151 return true; 151 return true;
152 } 152 }
153 153
154 if (m_animationCurve) { 154 if (m_animationCurve) {
155 if ((targetPos - m_targetOffset).isZero()) 155 if ((targetOffset - m_targetOffset).isZero())
156 return true; 156 return true;
157 157
158 m_targetOffset = targetPos; 158 m_targetOffset = targetOffset;
159 ASSERT(m_runState == RunState::RunningOnMainThread || 159 ASSERT(m_runState == RunState::RunningOnMainThread ||
160 m_runState == RunState::RunningOnCompositor || 160 m_runState == RunState::RunningOnCompositor ||
161 m_runState == RunState::RunningOnCompositorButNeedsUpdate || 161 m_runState == RunState::RunningOnCompositorButNeedsUpdate ||
162 m_runState == RunState::RunningOnCompositorButNeedsTakeover); 162 m_runState == RunState::RunningOnCompositorButNeedsTakeover);
163 163
164 // Running on the main thread, simply update the target offset instead 164 // Running on the main thread, simply update the target offset instead
165 // of sending to the compositor. 165 // of sending to the compositor.
166 if (m_runState == RunState::RunningOnMainThread) { 166 if (m_runState == RunState::RunningOnMainThread) {
167 m_animationCurve->updateTarget( 167 m_animationCurve->updateTarget(
168 m_timeFunction() - m_startTime, 168 m_timeFunction() - m_startTime,
169 compositorOffsetFromBlinkOffset(targetPos)); 169 compositorOffsetFromBlinkOffset(targetOffset));
170 return true; 170 return true;
171 } 171 }
172 172
173 if (registerAndScheduleAnimation()) 173 if (registerAndScheduleAnimation())
174 m_runState = RunState::RunningOnCompositorButNeedsUpdate; 174 m_runState = RunState::RunningOnCompositorButNeedsUpdate;
175 return true; 175 return true;
176 } 176 }
177 177
178 if ((targetPos - currentPosition()).isZero()) 178 if ((targetOffset - currentOffset()).isZero())
179 return false; 179 return false;
180 180
181 m_targetOffset = targetPos; 181 m_targetOffset = targetOffset;
182 m_startTime = m_timeFunction(); 182 m_startTime = m_timeFunction();
183 183
184 if (registerAndScheduleAnimation()) 184 if (registerAndScheduleAnimation())
185 m_runState = RunState::WaitingToSendToCompositor; 185 m_runState = RunState::WaitingToSendToCompositor;
186 186
187 return true; 187 return true;
188 } 188 }
189 189
190 void ScrollAnimator::adjustAnimationAndSetScrollPosition( 190 void ScrollAnimator::adjustAnimationAndSetScrollOffset(
191 const DoublePoint& position, 191 const ScrollOffset& offset,
192 ScrollType scrollType) { 192 ScrollType scrollType) {
193 DoublePoint adjustedPos = m_scrollableArea->clampScrollPosition(position);
194 IntSize actualAdjustment = 193 IntSize actualAdjustment =
195 roundedIntPoint(adjustedPos) - 194 roundedIntSize(offset) - roundedIntSize(m_scrollableArea->scrollOffset());
196 roundedIntPoint(m_scrollableArea->scrollPositionDouble());
197 195
198 scrollPositionChanged(adjustedPos, scrollType); 196 scrollOffsetChanged(offset, scrollType);
199 197
200 if (m_runState == RunState::Idle) { 198 if (m_runState == RunState::Idle) {
201 adjustImplOnlyScrollOffsetAnimation(actualAdjustment); 199 adjustImplOnlyScrollOffsetAnimation(actualAdjustment);
202 } else if (hasRunningAnimation()) { 200 } else if (hasRunningAnimation()) {
203 m_targetOffset += toFloatSize(actualAdjustment); 201 m_targetOffset += ScrollOffset(actualAdjustment);
204 if (m_animationCurve) { 202 if (m_animationCurve) {
205 m_animationCurve->applyAdjustment(actualAdjustment); 203 m_animationCurve->applyAdjustment(actualAdjustment);
206 if (m_runState != RunState::RunningOnMainThread && 204 if (m_runState != RunState::RunningOnMainThread &&
207 registerAndScheduleAnimation()) 205 registerAndScheduleAnimation())
208 m_runState = RunState::RunningOnCompositorButNeedsAdjustment; 206 m_runState = RunState::RunningOnCompositorButNeedsAdjustment;
209 } 207 }
210 } 208 }
211 } 209 }
212 210
213 void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { 211 void ScrollAnimator::scrollToOffsetWithoutAnimation(
214 m_currentPos = offset; 212 const ScrollOffset& offset) {
213 m_currentOffset = offset;
215 214
216 resetAnimationState(); 215 resetAnimationState();
217 notifyPositionChanged(); 216 notifyOffsetChanged();
218 } 217 }
219 218
220 void ScrollAnimator::tickAnimation(double monotonicTime) { 219 void ScrollAnimator::tickAnimation(double monotonicTime) {
221 if (m_runState != RunState::RunningOnMainThread) 220 if (m_runState != RunState::RunningOnMainThread)
222 return; 221 return;
223 222
224 TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation"); 223 TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation");
225 double elapsedTime = monotonicTime - m_startTime; 224 double elapsedTime = monotonicTime - m_startTime;
226 225
227 bool isFinished = (elapsedTime > m_animationCurve->duration()); 226 bool isFinished = (elapsedTime > m_animationCurve->duration());
228 FloatPoint offset = blinkOffsetFromCompositorOffset( 227 ScrollOffset offset = blinkOffsetFromCompositorOffset(
229 isFinished ? m_animationCurve->targetValue() 228 isFinished ? m_animationCurve->targetValue()
230 : m_animationCurve->getValue(elapsedTime)); 229 : m_animationCurve->getValue(elapsedTime));
231 230
232 offset = FloatPoint(m_scrollableArea->clampScrollPosition(offset)); 231 offset = m_scrollableArea->clampScrollOffset(offset);
233 232
234 m_currentPos = offset; 233 m_currentOffset = offset;
235 234
236 if (isFinished) 235 if (isFinished)
237 m_runState = RunState::PostAnimationCleanup; 236 m_runState = RunState::PostAnimationCleanup;
238 else 237 else
239 getScrollableArea()->scheduleAnimation(); 238 getScrollableArea()->scheduleAnimation();
240 239
241 TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged"); 240 TRACE_EVENT0("blink", "ScrollAnimator::notifyOffsetChanged");
242 notifyPositionChanged(); 241 notifyOffsetChanged();
243 } 242 }
244 243
245 void ScrollAnimator::postAnimationCleanupAndReset() { 244 void ScrollAnimator::postAnimationCleanupAndReset() {
246 // Remove the temporary main thread scrolling reason that was added while 245 // Remove the temporary main thread scrolling reason that was added while
247 // main thread had scheduled an animation. 246 // main thread had scheduled an animation.
248 removeMainThreadScrollingReason(); 247 removeMainThreadScrollingReason();
249 248
250 resetAnimationState(); 249 resetAnimationState();
251 } 250 }
252 251
(...skipping 25 matching lines...) Expand all
278 } 277 }
279 278
280 void ScrollAnimator::createAnimationCurve() { 279 void ScrollAnimator::createAnimationCurve() {
281 DCHECK(!m_animationCurve); 280 DCHECK(!m_animationCurve);
282 m_animationCurve = CompositorScrollOffsetAnimationCurve::create( 281 m_animationCurve = CompositorScrollOffsetAnimationCurve::create(
283 compositorOffsetFromBlinkOffset(m_targetOffset), 282 compositorOffsetFromBlinkOffset(m_targetOffset),
284 m_lastGranularity == ScrollByPixel 283 m_lastGranularity == ScrollByPixel
285 ? CompositorScrollOffsetAnimationCurve::ScrollDurationInverseDelta 284 ? CompositorScrollOffsetAnimationCurve::ScrollDurationInverseDelta
286 : CompositorScrollOffsetAnimationCurve::ScrollDurationConstant); 285 : CompositorScrollOffsetAnimationCurve::ScrollDurationConstant);
287 m_animationCurve->setInitialValue( 286 m_animationCurve->setInitialValue(
288 compositorOffsetFromBlinkOffset(currentPosition())); 287 compositorOffsetFromBlinkOffset(currentOffset()));
289 } 288 }
290 289
291 void ScrollAnimator::updateCompositorAnimations() { 290 void ScrollAnimator::updateCompositorAnimations() {
292 ScrollAnimatorCompositorCoordinator::updateCompositorAnimations(); 291 ScrollAnimatorCompositorCoordinator::updateCompositorAnimations();
293 292
294 if (m_runState == RunState::PostAnimationCleanup) { 293 if (m_runState == RunState::PostAnimationCleanup) {
295 postAnimationCleanupAndReset(); 294 postAnimationCleanupAndReset();
296 return; 295 return;
297 } 296 }
298 297
(...skipping 24 matching lines...) Expand all
323 322
324 if (m_runState != RunState::RunningOnCompositorButNeedsAdjustment) { 323 if (m_runState != RunState::RunningOnCompositorButNeedsAdjustment) {
325 // When in RunningOnCompositorButNeedsAdjustment, the call to 324 // When in RunningOnCompositorButNeedsAdjustment, the call to
326 // ::adjustScrollOffsetAnimation should have made the necessary 325 // ::adjustScrollOffsetAnimation should have made the necessary
327 // adjustment to the curve. 326 // adjustment to the curve.
328 m_animationCurve->updateTarget( 327 m_animationCurve->updateTarget(
329 m_timeFunction() - m_startTime, 328 m_timeFunction() - m_startTime,
330 compositorOffsetFromBlinkOffset(m_targetOffset)); 329 compositorOffsetFromBlinkOffset(m_targetOffset));
331 } 330 }
332 331
333 if (m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) 332 if (m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) {
334 m_animationCurve->setInitialValue( 333 m_animationCurve->setInitialValue(
335 compositorOffsetFromBlinkOffset(currentPosition())); 334 compositorOffsetFromBlinkOffset(currentOffset()));
335 }
336 336
337 m_runState = RunState::WaitingToSendToCompositor; 337 m_runState = RunState::WaitingToSendToCompositor;
338 } 338 }
339 339
340 if (m_runState == RunState::WaitingToSendToCompositor) { 340 if (m_runState == RunState::WaitingToSendToCompositor) {
341 if (!m_compositorAnimationAttachedToElementId) 341 if (!m_compositorAnimationAttachedToElementId)
342 reattachCompositorPlayerIfNeeded( 342 reattachCompositorPlayerIfNeeded(
343 getScrollableArea()->compositorAnimationTimeline()); 343 getScrollableArea()->compositorAnimationTimeline());
344 344
345 if (!m_animationCurve) 345 if (!m_animationCurve)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 double monotonicTime, 391 double monotonicTime,
392 double animationStartTime, 392 double animationStartTime,
393 std::unique_ptr<cc::AnimationCurve> curve) { 393 std::unique_ptr<cc::AnimationCurve> curve) {
394 // If there is already an animation running and the compositor asks to take 394 // If there is already an animation running and the compositor asks to take
395 // over an animation, do nothing to avoid judder. 395 // over an animation, do nothing to avoid judder.
396 if (hasRunningAnimation()) 396 if (hasRunningAnimation())
397 return; 397 return;
398 398
399 cc::ScrollOffsetAnimationCurve* scrollOffsetAnimationCurve = 399 cc::ScrollOffsetAnimationCurve* scrollOffsetAnimationCurve =
400 curve->ToScrollOffsetAnimationCurve(); 400 curve->ToScrollOffsetAnimationCurve();
401 FloatPoint targetValue(scrollOffsetAnimationCurve->target_value().x(), 401 ScrollOffset targetValue(scrollOffsetAnimationCurve->target_value().x(),
402 scrollOffsetAnimationCurve->target_value().y()); 402 scrollOffsetAnimationCurve->target_value().y());
403 if (willAnimateToOffset(targetValue)) { 403 if (willAnimateToOffset(targetValue)) {
404 m_animationCurve = CompositorScrollOffsetAnimationCurve::create( 404 m_animationCurve = CompositorScrollOffsetAnimationCurve::create(
405 std::move(scrollOffsetAnimationCurve)); 405 std::move(scrollOffsetAnimationCurve));
406 m_startTime = animationStartTime; 406 m_startTime = animationStartTime;
407 } 407 }
408 } 408 }
409 409
410 void ScrollAnimator::cancelAnimation() { 410 void ScrollAnimator::cancelAnimation() {
411 ScrollAnimatorCompositorCoordinator::cancelAnimation(); 411 ScrollAnimatorCompositorCoordinator::cancelAnimation();
412 } 412 }
(...skipping 20 matching lines...) Expand all
433 return false; 433 return false;
434 } 434 }
435 return true; 435 return true;
436 } 436 }
437 437
438 DEFINE_TRACE(ScrollAnimator) { 438 DEFINE_TRACE(ScrollAnimator) {
439 ScrollAnimatorBase::trace(visitor); 439 ScrollAnimatorBase::trace(visitor);
440 } 440 }
441 441
442 } // namespace blink 442 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698