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

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

Issue 2387883002: Use float for scroll offset. (Closed)
Patch Set: Fix README.md 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 IntSize adjustment = 193 IntSize adjustment =
194 roundedIntPoint(position) - 194 roundedIntSize(offset) - roundedIntSize(m_scrollableArea->scrollOffset());
195 roundedIntPoint(m_scrollableArea->scrollPositionDouble()); 195 scrollOffsetChanged(offset, scrollType);
196
197 scrollPositionChanged(position, scrollType);
198 196
199 if (m_runState == RunState::Idle) { 197 if (m_runState == RunState::Idle) {
200 adjustImplOnlyScrollOffsetAnimation(adjustment); 198 adjustImplOnlyScrollOffsetAnimation(adjustment);
201 } else if (hasRunningAnimation()) { 199 } else if (hasRunningAnimation()) {
202 m_targetOffset += toFloatSize(adjustment); 200 m_targetOffset += ScrollOffset(adjustment);
203 if (m_animationCurve) { 201 if (m_animationCurve) {
204 m_animationCurve->applyAdjustment(adjustment); 202 m_animationCurve->applyAdjustment(adjustment);
205 if (m_runState != RunState::RunningOnMainThread && 203 if (m_runState != RunState::RunningOnMainThread &&
206 registerAndScheduleAnimation()) 204 registerAndScheduleAnimation())
207 m_runState = RunState::RunningOnCompositorButNeedsAdjustment; 205 m_runState = RunState::RunningOnCompositorButNeedsAdjustment;
208 } 206 }
209 } 207 }
210 } 208 }
211 209
212 void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { 210 void ScrollAnimator::scrollToOffsetWithoutAnimation(
213 m_currentPos = offset; 211 const ScrollOffset& offset) {
212 m_currentOffset = offset;
214 213
215 resetAnimationState(); 214 resetAnimationState();
216 notifyPositionChanged(); 215 notifyOffsetChanged();
217 } 216 }
218 217
219 void ScrollAnimator::tickAnimation(double monotonicTime) { 218 void ScrollAnimator::tickAnimation(double monotonicTime) {
220 if (m_runState != RunState::RunningOnMainThread) 219 if (m_runState != RunState::RunningOnMainThread)
221 return; 220 return;
222 221
223 TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation"); 222 TRACE_EVENT0("blink", "ScrollAnimator::tickAnimation");
224 double elapsedTime = monotonicTime - m_startTime; 223 double elapsedTime = monotonicTime - m_startTime;
225 224
226 bool isFinished = (elapsedTime > m_animationCurve->duration()); 225 bool isFinished = (elapsedTime > m_animationCurve->duration());
227 FloatPoint offset = blinkOffsetFromCompositorOffset( 226 ScrollOffset offset = blinkOffsetFromCompositorOffset(
228 isFinished ? m_animationCurve->targetValue() 227 isFinished ? m_animationCurve->targetValue()
229 : m_animationCurve->getValue(elapsedTime)); 228 : m_animationCurve->getValue(elapsedTime));
230 229
231 offset = FloatPoint(m_scrollableArea->clampScrollPosition(offset)); 230 offset = m_scrollableArea->clampScrollOffset(offset);
232 231
233 m_currentPos = offset; 232 m_currentOffset = offset;
234 233
235 if (isFinished) 234 if (isFinished)
236 m_runState = RunState::PostAnimationCleanup; 235 m_runState = RunState::PostAnimationCleanup;
237 else 236 else
238 getScrollableArea()->scheduleAnimation(); 237 getScrollableArea()->scheduleAnimation();
239 238
240 TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged"); 239 TRACE_EVENT0("blink", "ScrollAnimator::notifyOffsetChanged");
241 notifyPositionChanged(); 240 notifyOffsetChanged();
242 } 241 }
243 242
244 void ScrollAnimator::postAnimationCleanupAndReset() { 243 void ScrollAnimator::postAnimationCleanupAndReset() {
245 // Remove the temporary main thread scrolling reason that was added while 244 // Remove the temporary main thread scrolling reason that was added while
246 // main thread had scheduled an animation. 245 // main thread had scheduled an animation.
247 removeMainThreadScrollingReason(); 246 removeMainThreadScrollingReason();
248 247
249 resetAnimationState(); 248 resetAnimationState();
250 } 249 }
251 250
(...skipping 25 matching lines...) Expand all
277 } 276 }
278 277
279 void ScrollAnimator::createAnimationCurve() { 278 void ScrollAnimator::createAnimationCurve() {
280 DCHECK(!m_animationCurve); 279 DCHECK(!m_animationCurve);
281 m_animationCurve = CompositorScrollOffsetAnimationCurve::create( 280 m_animationCurve = CompositorScrollOffsetAnimationCurve::create(
282 compositorOffsetFromBlinkOffset(m_targetOffset), 281 compositorOffsetFromBlinkOffset(m_targetOffset),
283 m_lastGranularity == ScrollByPixel 282 m_lastGranularity == ScrollByPixel
284 ? CompositorScrollOffsetAnimationCurve::ScrollDurationInverseDelta 283 ? CompositorScrollOffsetAnimationCurve::ScrollDurationInverseDelta
285 : CompositorScrollOffsetAnimationCurve::ScrollDurationConstant); 284 : CompositorScrollOffsetAnimationCurve::ScrollDurationConstant);
286 m_animationCurve->setInitialValue( 285 m_animationCurve->setInitialValue(
287 compositorOffsetFromBlinkOffset(currentPosition())); 286 compositorOffsetFromBlinkOffset(currentOffset()));
288 } 287 }
289 288
290 void ScrollAnimator::updateCompositorAnimations() { 289 void ScrollAnimator::updateCompositorAnimations() {
291 ScrollAnimatorCompositorCoordinator::updateCompositorAnimations(); 290 ScrollAnimatorCompositorCoordinator::updateCompositorAnimations();
292 291
293 if (m_runState == RunState::PostAnimationCleanup) { 292 if (m_runState == RunState::PostAnimationCleanup) {
294 postAnimationCleanupAndReset(); 293 postAnimationCleanupAndReset();
295 return; 294 return;
296 } 295 }
297 296
(...skipping 24 matching lines...) Expand all
322 321
323 if (m_runState != RunState::RunningOnCompositorButNeedsAdjustment) { 322 if (m_runState != RunState::RunningOnCompositorButNeedsAdjustment) {
324 // When in RunningOnCompositorButNeedsAdjustment, the call to 323 // When in RunningOnCompositorButNeedsAdjustment, the call to
325 // ::adjustScrollOffsetAnimation should have made the necessary 324 // ::adjustScrollOffsetAnimation should have made the necessary
326 // adjustment to the curve. 325 // adjustment to the curve.
327 m_animationCurve->updateTarget( 326 m_animationCurve->updateTarget(
328 m_timeFunction() - m_startTime, 327 m_timeFunction() - m_startTime,
329 compositorOffsetFromBlinkOffset(m_targetOffset)); 328 compositorOffsetFromBlinkOffset(m_targetOffset));
330 } 329 }
331 330
332 if (m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) 331 if (m_runState == RunState::WaitingToCancelOnCompositorButNewScroll) {
333 m_animationCurve->setInitialValue( 332 m_animationCurve->setInitialValue(
334 compositorOffsetFromBlinkOffset(currentPosition())); 333 compositorOffsetFromBlinkOffset(currentOffset()));
334 }
335 335
336 m_runState = RunState::WaitingToSendToCompositor; 336 m_runState = RunState::WaitingToSendToCompositor;
337 } 337 }
338 338
339 if (m_runState == RunState::WaitingToSendToCompositor) { 339 if (m_runState == RunState::WaitingToSendToCompositor) {
340 if (!m_compositorAnimationAttachedToElementId) 340 if (!m_compositorAnimationAttachedToElementId)
341 reattachCompositorPlayerIfNeeded( 341 reattachCompositorPlayerIfNeeded(
342 getScrollableArea()->compositorAnimationTimeline()); 342 getScrollableArea()->compositorAnimationTimeline());
343 343
344 if (!m_animationCurve) 344 if (!m_animationCurve)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 double monotonicTime, 390 double monotonicTime,
391 double animationStartTime, 391 double animationStartTime,
392 std::unique_ptr<cc::AnimationCurve> curve) { 392 std::unique_ptr<cc::AnimationCurve> curve) {
393 // If there is already an animation running and the compositor asks to take 393 // If there is already an animation running and the compositor asks to take
394 // over an animation, do nothing to avoid judder. 394 // over an animation, do nothing to avoid judder.
395 if (hasRunningAnimation()) 395 if (hasRunningAnimation())
396 return; 396 return;
397 397
398 cc::ScrollOffsetAnimationCurve* scrollOffsetAnimationCurve = 398 cc::ScrollOffsetAnimationCurve* scrollOffsetAnimationCurve =
399 curve->ToScrollOffsetAnimationCurve(); 399 curve->ToScrollOffsetAnimationCurve();
400 FloatPoint targetValue(scrollOffsetAnimationCurve->target_value().x(), 400 ScrollOffset targetValue(scrollOffsetAnimationCurve->target_value().x(),
401 scrollOffsetAnimationCurve->target_value().y()); 401 scrollOffsetAnimationCurve->target_value().y());
402 if (willAnimateToOffset(targetValue)) { 402 if (willAnimateToOffset(targetValue)) {
403 m_animationCurve = CompositorScrollOffsetAnimationCurve::create( 403 m_animationCurve = CompositorScrollOffsetAnimationCurve::create(
404 std::move(scrollOffsetAnimationCurve)); 404 std::move(scrollOffsetAnimationCurve));
405 m_startTime = animationStartTime; 405 m_startTime = animationStartTime;
406 } 406 }
407 } 407 }
408 408
409 void ScrollAnimator::cancelAnimation() { 409 void ScrollAnimator::cancelAnimation() {
410 ScrollAnimatorCompositorCoordinator::cancelAnimation(); 410 ScrollAnimatorCompositorCoordinator::cancelAnimation();
411 } 411 }
(...skipping 20 matching lines...) Expand all
432 return false; 432 return false;
433 } 433 }
434 return true; 434 return true;
435 } 435 }
436 436
437 DEFINE_TRACE(ScrollAnimator) { 437 DEFINE_TRACE(ScrollAnimator) {
438 ScrollAnimatorBase::trace(visitor); 438 ScrollAnimatorBase::trace(visitor);
439 } 439 }
440 440
441 } // namespace blink 441 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698