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

Side by Side Diff: third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp

Issue 2248643003: Simplify time tracking in SMILTimeContainer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: begin() -> start(); touch-up comment Created 4 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
« no previous file with comments | « third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple 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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 23 matching lines...) Expand all
34 #include "core/svg/SVGSVGElement.h" 34 #include "core/svg/SVGSVGElement.h"
35 #include "core/svg/animation/SVGSMILElement.h" 35 #include "core/svg/animation/SVGSMILElement.h"
36 #include <algorithm> 36 #include <algorithm>
37 37
38 namespace blink { 38 namespace blink {
39 39
40 static const double initialFrameDelay = 0.025; 40 static const double initialFrameDelay = 0.025;
41 static const double animationPolicyOnceDuration = 3.000; 41 static const double animationPolicyOnceDuration = 3.000;
42 42
43 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) 43 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
44 : m_beginTime(0) 44 : m_presentationTime(0)
45 , m_pauseTime(0) 45 , m_referenceTime(0)
46 , m_resumeTime(0)
47 , m_accumulatedActiveTime(0)
48 , m_presetStartTime(0)
49 , m_frameSchedulingState(Idle) 46 , m_frameSchedulingState(Idle)
47 , m_started(false)
48 , m_paused(false)
50 , m_documentOrderIndexesDirty(false) 49 , m_documentOrderIndexesDirty(false)
51 , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired) 50 , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired)
52 , m_animationPolicyOnceTimer(this, &SMILTimeContainer::animationPolicyTimerF ired) 51 , m_animationPolicyOnceTimer(this, &SMILTimeContainer::animationPolicyTimerF ired)
53 , m_ownerSVGElement(&owner) 52 , m_ownerSVGElement(&owner)
54 #if ENABLE(ASSERT) 53 #if ENABLE(ASSERT)
55 , m_preventScheduledAnimationsChanges(false) 54 , m_preventScheduledAnimationsChanges(false)
56 #endif 55 #endif
57 { 56 {
58 } 57 }
59 58
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // Schedule updateAnimations() to be called asynchronously so multiple inter vals 128 // Schedule updateAnimations() to be called asynchronously so multiple inter vals
130 // can change with updateAnimations() only called once at the end. 129 // can change with updateAnimations() only called once at the end.
131 if (hasPendingSynchronization()) 130 if (hasPendingSynchronization())
132 return; 131 return;
133 cancelAnimationFrame(); 132 cancelAnimationFrame();
134 scheduleWakeUp(0, SynchronizeAnimations); 133 scheduleWakeUp(0, SynchronizeAnimations);
135 } 134 }
136 135
137 SMILTime SMILTimeContainer::elapsed() const 136 SMILTime SMILTimeContainer::elapsed() const
138 { 137 {
139 if (!m_beginTime) 138 if (!isStarted())
140 return 0; 139 return 0;
141 140
142 if (isPaused()) 141 if (isPaused())
143 return m_accumulatedActiveTime; 142 return m_presentationTime;
144 143
145 return currentTime() + m_accumulatedActiveTime - lastResumeTime(); 144 return m_presentationTime + (document().timeline().currentTimeInternal() - m _referenceTime);
145 }
146
147 void SMILTimeContainer::synchronizeToDocumentTimeline()
148 {
149 m_referenceTime = document().timeline().currentTimeInternal();
146 } 150 }
147 151
148 bool SMILTimeContainer::isPaused() const 152 bool SMILTimeContainer::isPaused() const
149 { 153 {
150 // If animation policy is "none", it is always paused. 154 // If animation policy is "none", the timeline is always paused.
151 return m_pauseTime || animationPolicy() == ImageAnimationPolicyNoAnimation; 155 return m_paused || animationPolicy() == ImageAnimationPolicyNoAnimation;
152 } 156 }
153 157
154 bool SMILTimeContainer::isStarted() const 158 bool SMILTimeContainer::isStarted() const
155 { 159 {
156 return m_beginTime; 160 return m_started;
157 } 161 }
158 162
159 void SMILTimeContainer::begin() 163 bool SMILTimeContainer::isTimelineRunning() const
160 { 164 {
161 RELEASE_ASSERT(!m_beginTime); 165 return isStarted() && !isPaused();
166 }
167
168 void SMILTimeContainer::start()
169 {
170 RELEASE_ASSERT(!isStarted());
162 171
163 if (!document().isActive()) 172 if (!document().isActive())
164 return; 173 return;
165 174
166 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused)) 175 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
167 return; 176 return;
168 177
169 double now = currentTime(); 178 // Sample the document timeline to get a time reference for the "presentatio n time".
179 synchronizeToDocumentTimeline();
180 m_started = true;
170 181
171 // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began. 182 // If the "presentation time" is non-zero, the timeline was modified via
172 // In this case pass on 'seekToTime=true' to updateAnimations(). 183 // setElapsed() before the document began.
173 m_beginTime = now - m_presetStartTime; 184 // In this case pass on 'seekToTime=true' to updateAnimations() to issue a s eek.
174 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_ presetStartTime ? true : false); 185 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presentationTime), m _presentationTime ? true : false);
175 m_presetStartTime = 0;
176 186
177 if (m_pauseTime) { 187 if (isPaused()) {
178 m_pauseTime = now; 188 // If updateAnimations() caused new syncbase instances to be generated,
179 // If updateAnimations() caused new syncbase instance to be generated,
180 // we don't want to cancel those. Excepting that, no frame should've 189 // we don't want to cancel those. Excepting that, no frame should've
181 // been scheduled at this point. 190 // been scheduled at this point.
182 ASSERT(m_frameSchedulingState == Idle || m_frameSchedulingState == Synch ronizeAnimations); 191 DCHECK(m_frameSchedulingState == Idle || m_frameSchedulingState == Synch ronizeAnimations);
183 } else if (!hasPendingSynchronization()) { 192 return;
184 ASSERT(isTimelineRunning());
185 // If the timeline is running, and there's pending animation updates,
186 // always perform the first update after the timeline was started using
187 // the wake-up mechanism.
188 if (earliestFireTime.isFinite()) {
189 SMILTime delay = earliestFireTime - elapsed();
190 scheduleWakeUp(std::max(initialFrameDelay, delay.value()), Synchroni zeAnimations);
191 }
192 } 193 }
194 // If synchronizations are pending, those will in turn schedule additional
195 // frames.
196 if (hasPendingSynchronization())
197 return;
198 DCHECK(isTimelineRunning());
199 if (!earliestFireTime.isFinite())
200 return;
201 // If the timeline is running, and there are pending animation updates,
202 // always perform the first update after the timeline was started using
203 // the wake-up mechanism.
204 SMILTime delay = earliestFireTime - m_presentationTime;
205 scheduleWakeUp(std::max(initialFrameDelay, delay.value()), SynchronizeAnimat ions);
193 } 206 }
194 207
195 void SMILTimeContainer::pause() 208 void SMILTimeContainer::pause()
196 { 209 {
197 if (!handleAnimationPolicy(CancelOnceTimer)) 210 if (!handleAnimationPolicy(CancelOnceTimer))
198 return; 211 return;
212 DCHECK(!isPaused());
199 213
200 ASSERT(!isPaused()); 214 if (isStarted()) {
201 m_pauseTime = currentTime(); 215 m_presentationTime = elapsed().value();
202
203 if (m_beginTime) {
204 m_accumulatedActiveTime += m_pauseTime - lastResumeTime();
205 cancelAnimationFrame(); 216 cancelAnimationFrame();
206 } 217 }
207 m_resumeTime = 0; 218 // Update the flag after sampling elapsed().
219 m_paused = true;
208 } 220 }
209 221
210 void SMILTimeContainer::resume() 222 void SMILTimeContainer::resume()
211 { 223 {
212 if (!handleAnimationPolicy(RestartOnceTimer)) 224 if (!handleAnimationPolicy(RestartOnceTimer))
213 return; 225 return;
226 DCHECK(isPaused());
214 227
215 ASSERT(isPaused()); 228 m_paused = false;
216 m_resumeTime = currentTime();
217 229
218 m_pauseTime = 0; 230 if (isStarted())
231 synchronizeToDocumentTimeline();
232
219 scheduleWakeUp(0, SynchronizeAnimations); 233 scheduleWakeUp(0, SynchronizeAnimations);
220 } 234 }
221 235
222 void SMILTimeContainer::setElapsed(SMILTime time) 236 void SMILTimeContainer::setElapsed(SMILTime time)
223 { 237 {
224 // If the documment didn't begin yet, record a new start time, we'll seek to once its possible. 238 m_presentationTime = time.value();
225 if (!m_beginTime) { 239
226 m_presetStartTime = time.value(); 240 // If the document hasn't finished loading, |m_presentationTime| will be
241 // used as the start time to seek to once it's possible.
242 if (!isStarted())
227 return; 243 return;
228 }
229 244
230 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused)) 245 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
231 return; 246 return;
232 247
233 cancelAnimationFrame(); 248 cancelAnimationFrame();
234 249
235 double now = currentTime(); 250 if (!isPaused())
236 m_beginTime = now - time.value(); 251 synchronizeToDocumentTimeline();
237 m_resumeTime = 0;
238 if (m_pauseTime) {
239 m_pauseTime = now;
240 m_accumulatedActiveTime = time.value();
241 } else {
242 m_accumulatedActiveTime = 0;
243 }
244 252
245 #if ENABLE(ASSERT) 253 #if ENABLE(ASSERT)
246 m_preventScheduledAnimationsChanges = true; 254 m_preventScheduledAnimationsChanges = true;
247 #endif 255 #endif
248 for (const auto& entry : m_scheduledAnimations) { 256 for (const auto& entry : m_scheduledAnimations) {
249 if (!entry.key.first) 257 if (!entry.key.first)
250 continue; 258 continue;
251 259
252 AnimationsLinkedHashSet* scheduled = entry.value.get(); 260 AnimationsLinkedHashSet* scheduled = entry.value.get();
253 for (SVGSMILElement* element : *scheduled) 261 for (SVGSMILElement* element : *scheduled)
254 element->reset(); 262 element->reset();
255 } 263 }
256 #if ENABLE(ASSERT) 264 #if ENABLE(ASSERT)
257 m_preventScheduledAnimationsChanges = false; 265 m_preventScheduledAnimationsChanges = false;
258 #endif 266 #endif
259 267
260 updateAnimationsAndScheduleFrameIfNeeded(time, true); 268 updateAnimationsAndScheduleFrameIfNeeded(time, true);
261 } 269 }
262 270
263 bool SMILTimeContainer::isTimelineRunning() const 271 void SMILTimeContainer::scheduleAnimationFrame(double delayTime)
264 { 272 {
265 return m_beginTime && !isPaused(); 273 DCHECK(std::isfinite(delayTime));
266 } 274 DCHECK(isTimelineRunning());
275 DCHECK(!m_wakeupTimer.isActive());
267 276
268 void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime) 277 if (delayTime < AnimationTimeline::s_minimumDelay) {
269 {
270 ASSERT(isTimelineRunning() && fireTime.isFinite());
271 ASSERT(!m_wakeupTimer.isActive());
272
273 SMILTime delay = fireTime - elapsed();
274 if (delay.value() < AnimationTimeline::s_minimumDelay) {
275 serviceOnNextFrame(); 278 serviceOnNextFrame();
276 } else { 279 } else {
277 scheduleWakeUp(delay.value() - AnimationTimeline::s_minimumDelay, Future AnimationFrame); 280 scheduleWakeUp(delayTime - AnimationTimeline::s_minimumDelay, FutureAnim ationFrame);
278 } 281 }
279 } 282 }
280 283
281 void SMILTimeContainer::cancelAnimationFrame() 284 void SMILTimeContainer::cancelAnimationFrame()
282 { 285 {
283 m_frameSchedulingState = Idle; 286 m_frameSchedulingState = Idle;
284 m_wakeupTimer.stop(); 287 m_wakeupTimer.stop();
285 } 288 }
286 289
287 void SMILTimeContainer::scheduleWakeUp(double delayTime, FrameSchedulingState fr ameSchedulingState) 290 void SMILTimeContainer::scheduleWakeUp(double delayTime, FrameSchedulingState fr ameSchedulingState)
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 SVGSVGElement& SMILTimeContainer::ownerSVGElement() const 393 SVGSVGElement& SMILTimeContainer::ownerSVGElement() const
391 { 394 {
392 return *m_ownerSVGElement; 395 return *m_ownerSVGElement;
393 } 396 }
394 397
395 Document& SMILTimeContainer::document() const 398 Document& SMILTimeContainer::document() const
396 { 399 {
397 return ownerSVGElement().document(); 400 return ownerSVGElement().document();
398 } 401 }
399 402
400 double SMILTimeContainer::currentTime() const
401 {
402 return document().timeline().currentTimeInternal();
403 }
404
405 void SMILTimeContainer::serviceOnNextFrame() 403 void SMILTimeContainer::serviceOnNextFrame()
406 { 404 {
407 if (document().view()) { 405 if (document().view()) {
408 document().view()->scheduleAnimation(); 406 document().view()->scheduleAnimation();
409 m_frameSchedulingState = AnimationFrame; 407 m_frameSchedulingState = AnimationFrame;
410 } 408 }
411 } 409 }
412 410
413 void SMILTimeContainer::serviceAnimations() 411 void SMILTimeContainer::serviceAnimations()
414 { 412 {
(...skipping 14 matching lines...) Expand all
429 // via syncbases), then give that priority. 427 // via syncbases), then give that priority.
430 if (hasPendingSynchronization()) 428 if (hasPendingSynchronization())
431 return; 429 return;
432 430
433 if (!isTimelineRunning()) 431 if (!isTimelineRunning())
434 return; 432 return;
435 433
436 if (!earliestFireTime.isFinite()) 434 if (!earliestFireTime.isFinite())
437 return; 435 return;
438 436
439 scheduleAnimationFrame(earliestFireTime); 437 SMILTime delay = earliestFireTime - elapsed;
438 scheduleAnimationFrame(delay.value());
440 } 439 }
441 440
442 SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime) 441 SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
443 { 442 {
444 ASSERT(document().isActive()); 443 ASSERT(document().isActive());
445 SMILTime earliestFireTime = SMILTime::unresolved(); 444 SMILTime earliestFireTime = SMILTime::unresolved();
446 445
447 #if ENABLE(ASSERT) 446 #if ENABLE(ASSERT)
448 // This boolean will catch any attempts to schedule/unschedule scheduledAnim ations during this critical section. 447 // This boolean will catch any attempts to schedule/unschedule scheduledAnim ations during this critical section.
449 // Similarly, any elements removed will unschedule themselves, so this will catch modification of animationsToApply. 448 // Similarly, any elements removed will unschedule themselves, so this will catch modification of animationsToApply.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 setElapsed(elapsed().value() + initialFrameDelay); 545 setElapsed(elapsed().value() + initialFrameDelay);
547 } 546 }
548 547
549 DEFINE_TRACE(SMILTimeContainer) 548 DEFINE_TRACE(SMILTimeContainer)
550 { 549 {
551 visitor->trace(m_scheduledAnimations); 550 visitor->trace(m_scheduledAnimations);
552 visitor->trace(m_ownerSVGElement); 551 visitor->trace(m_ownerSVGElement);
553 } 552 }
554 553
555 } // namespace blink 554 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698