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

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

Issue 2261443002: Replace SMILTime with double for elapsed time in SMILTimeContainer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@smilcontainer-canscheduleframe-pred
Patch Set: REbase 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 14 matching lines...) Expand all
25 25
26 #include "core/svg/animation/SMILTimeContainer.h" 26 #include "core/svg/animation/SMILTimeContainer.h"
27 27
28 #include "core/animation/AnimationClock.h" 28 #include "core/animation/AnimationClock.h"
29 #include "core/animation/DocumentTimeline.h" 29 #include "core/animation/DocumentTimeline.h"
30 #include "core/dom/ElementTraversal.h" 30 #include "core/dom/ElementTraversal.h"
31 #include "core/frame/FrameView.h" 31 #include "core/frame/FrameView.h"
32 #include "core/frame/Settings.h" 32 #include "core/frame/Settings.h"
33 #include "core/frame/UseCounter.h" 33 #include "core/frame/UseCounter.h"
34 #include "core/svg/SVGSVGElement.h" 34 #include "core/svg/SVGSVGElement.h"
35 #include "core/svg/animation/SMILTime.h"
35 #include "core/svg/animation/SVGSMILElement.h" 36 #include "core/svg/animation/SVGSMILElement.h"
36 #include <algorithm> 37 #include <algorithm>
37 38
38 namespace blink { 39 namespace blink {
39 40
40 static const double initialFrameDelay = 0.025; 41 static const double initialFrameDelay = 0.025;
41 static const double animationPolicyOnceDuration = 3.000; 42 static const double animationPolicyOnceDuration = 3.000;
42 43
43 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) 44 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
44 : m_presentationTime(0) 45 : m_presentationTime(0)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 if (!isStarted()) 127 if (!isStarted())
127 return; 128 return;
128 // Schedule updateAnimations() to be called asynchronously so multiple inter vals 129 // Schedule updateAnimations() to be called asynchronously so multiple inter vals
129 // can change with updateAnimations() only called once at the end. 130 // can change with updateAnimations() only called once at the end.
130 if (hasPendingSynchronization()) 131 if (hasPendingSynchronization())
131 return; 132 return;
132 cancelAnimationFrame(); 133 cancelAnimationFrame();
133 scheduleWakeUp(0, SynchronizeAnimations); 134 scheduleWakeUp(0, SynchronizeAnimations);
134 } 135 }
135 136
136 SMILTime SMILTimeContainer::elapsed() const 137 double SMILTimeContainer::elapsed() const
137 { 138 {
138 if (!isStarted()) 139 if (!isStarted())
139 return 0; 140 return 0;
140 141
141 if (isPaused()) 142 if (isPaused())
142 return m_presentationTime; 143 return m_presentationTime;
143 144
144 return m_presentationTime + (document().timeline().currentTimeInternal() - m _referenceTime); 145 return m_presentationTime + (document().timeline().currentTimeInternal() - m _referenceTime);
145 } 146 }
146 147
(...skipping 28 matching lines...) Expand all
175 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused)) 176 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
176 return; 177 return;
177 178
178 // Sample the document timeline to get a time reference for the "presentatio n time". 179 // Sample the document timeline to get a time reference for the "presentatio n time".
179 synchronizeToDocumentTimeline(); 180 synchronizeToDocumentTimeline();
180 m_started = true; 181 m_started = true;
181 182
182 // If the "presentation time" is non-zero, the timeline was modified via 183 // If the "presentation time" is non-zero, the timeline was modified via
183 // setElapsed() before the document began. 184 // setElapsed() before the document began.
184 // In this case pass on 'seekToTime=true' to updateAnimations() to issue a s eek. 185 // In this case pass on 'seekToTime=true' to updateAnimations() to issue a s eek.
185 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presentationTime), m _presentationTime ? true : false); 186 SMILTime earliestFireTime = updateAnimations(m_presentationTime, m_presentat ionTime ? true : false);
186 if (!canScheduleFrame(earliestFireTime)) 187 if (!canScheduleFrame(earliestFireTime))
187 return; 188 return;
188 // If the timeline is running, and there are pending animation updates, 189 // If the timeline is running, and there are pending animation updates,
189 // always perform the first update after the timeline was started using 190 // always perform the first update after the timeline was started using
190 // the wake-up mechanism. 191 // the wake-up mechanism.
191 SMILTime delay = earliestFireTime - m_presentationTime; 192 double delayTime = earliestFireTime.value() - m_presentationTime;
192 scheduleWakeUp(std::max(initialFrameDelay, delay.value()), SynchronizeAnimat ions); 193 scheduleWakeUp(std::max(initialFrameDelay, delayTime), SynchronizeAnimations );
193 } 194 }
194 195
195 void SMILTimeContainer::pause() 196 void SMILTimeContainer::pause()
196 { 197 {
197 if (!handleAnimationPolicy(CancelOnceTimer)) 198 if (!handleAnimationPolicy(CancelOnceTimer))
198 return; 199 return;
199 DCHECK(!isPaused()); 200 DCHECK(!isPaused());
200 201
201 if (isStarted()) { 202 if (isStarted()) {
202 m_presentationTime = elapsed().value(); 203 m_presentationTime = elapsed();
203 cancelAnimationFrame(); 204 cancelAnimationFrame();
204 } 205 }
205 // Update the flag after sampling elapsed(). 206 // Update the flag after sampling elapsed().
206 m_paused = true; 207 m_paused = true;
207 } 208 }
208 209
209 void SMILTimeContainer::resume() 210 void SMILTimeContainer::resume()
210 { 211 {
211 if (!handleAnimationPolicy(RestartOnceTimer)) 212 if (!handleAnimationPolicy(RestartOnceTimer))
212 return; 213 return;
213 DCHECK(isPaused()); 214 DCHECK(isPaused());
214 215
215 m_paused = false; 216 m_paused = false;
216 217
217 if (isStarted()) 218 if (isStarted())
218 synchronizeToDocumentTimeline(); 219 synchronizeToDocumentTimeline();
219 220
220 scheduleWakeUp(0, SynchronizeAnimations); 221 scheduleWakeUp(0, SynchronizeAnimations);
221 } 222 }
222 223
223 void SMILTimeContainer::setElapsed(SMILTime time) 224 void SMILTimeContainer::setElapsed(double elapsed)
224 { 225 {
225 m_presentationTime = time.value(); 226 m_presentationTime = elapsed;
226 227
227 // If the document hasn't finished loading, |m_presentationTime| will be 228 // If the document hasn't finished loading, |m_presentationTime| will be
228 // used as the start time to seek to once it's possible. 229 // used as the start time to seek to once it's possible.
229 if (!isStarted()) 230 if (!isStarted())
230 return; 231 return;
231 232
232 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused)) 233 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
233 return; 234 return;
234 235
235 cancelAnimationFrame(); 236 cancelAnimationFrame();
236 237
237 if (!isPaused()) 238 if (!isPaused())
238 synchronizeToDocumentTimeline(); 239 synchronizeToDocumentTimeline();
239 240
240 #if ENABLE(ASSERT) 241 #if ENABLE(ASSERT)
241 m_preventScheduledAnimationsChanges = true; 242 m_preventScheduledAnimationsChanges = true;
242 #endif 243 #endif
243 for (const auto& entry : m_scheduledAnimations) { 244 for (const auto& entry : m_scheduledAnimations) {
244 if (!entry.key.first) 245 if (!entry.key.first)
245 continue; 246 continue;
246 247
247 AnimationsLinkedHashSet* scheduled = entry.value.get(); 248 AnimationsLinkedHashSet* scheduled = entry.value.get();
248 for (SVGSMILElement* element : *scheduled) 249 for (SVGSMILElement* element : *scheduled)
249 element->reset(); 250 element->reset();
250 } 251 }
251 #if ENABLE(ASSERT) 252 #if ENABLE(ASSERT)
252 m_preventScheduledAnimationsChanges = false; 253 m_preventScheduledAnimationsChanges = false;
253 #endif 254 #endif
254 255
255 updateAnimationsAndScheduleFrameIfNeeded(time, true); 256 updateAnimationsAndScheduleFrameIfNeeded(elapsed, true);
256 } 257 }
257 258
258 void SMILTimeContainer::scheduleAnimationFrame(double delayTime) 259 void SMILTimeContainer::scheduleAnimationFrame(double delayTime)
259 { 260 {
260 DCHECK(std::isfinite(delayTime)); 261 DCHECK(std::isfinite(delayTime));
261 DCHECK(isTimelineRunning()); 262 DCHECK(isTimelineRunning());
262 DCHECK(!m_wakeupTimer.isActive()); 263 DCHECK(!m_wakeupTimer.isActive());
263 264
264 if (delayTime < AnimationTimeline::s_minimumDelay) { 265 if (delayTime < AnimationTimeline::s_minimumDelay) {
265 serviceOnNextFrame(); 266 serviceOnNextFrame();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 355
355 void SMILTimeContainer::updateDocumentOrderIndexes() 356 void SMILTimeContainer::updateDocumentOrderIndexes()
356 { 357 {
357 unsigned timingElementCount = 0; 358 unsigned timingElementCount = 0;
358 for (SVGSMILElement& element : Traversal<SVGSMILElement>::descendantsOf(owne rSVGElement())) 359 for (SVGSMILElement& element : Traversal<SVGSMILElement>::descendantsOf(owne rSVGElement()))
359 element.setDocumentOrderIndex(timingElementCount++); 360 element.setDocumentOrderIndex(timingElementCount++);
360 m_documentOrderIndexesDirty = false; 361 m_documentOrderIndexesDirty = false;
361 } 362 }
362 363
363 struct PriorityCompare { 364 struct PriorityCompare {
364 PriorityCompare(SMILTime elapsed) : m_elapsed(elapsed) {} 365 PriorityCompare(double elapsed) : m_elapsed(elapsed) {}
365 bool operator()(const Member<SVGSMILElement>& a, const Member<SVGSMILElement >& b) 366 bool operator()(const Member<SVGSMILElement>& a, const Member<SVGSMILElement >& b)
366 { 367 {
367 // FIXME: This should also consider possible timing relations between th e elements. 368 // FIXME: This should also consider possible timing relations between th e elements.
368 SMILTime aBegin = a->intervalBegin(); 369 SMILTime aBegin = a->intervalBegin();
369 SMILTime bBegin = b->intervalBegin(); 370 SMILTime bBegin = b->intervalBegin();
370 // Frozen elements need to be prioritized based on their previous interv al. 371 // Frozen elements need to be prioritized based on their previous interv al.
371 aBegin = a->isFrozen() && m_elapsed < aBegin ? a->previousIntervalBegin( ) : aBegin; 372 aBegin = a->isFrozen() && m_elapsed < aBegin ? a->previousIntervalBegin( ) : aBegin;
372 bBegin = b->isFrozen() && m_elapsed < bBegin ? b->previousIntervalBegin( ) : bBegin; 373 bBegin = b->isFrozen() && m_elapsed < bBegin ? b->previousIntervalBegin( ) : bBegin;
373 if (aBegin == bBegin) 374 if (aBegin == bBegin)
374 return a->documentOrderIndex() < b->documentOrderIndex(); 375 return a->documentOrderIndex() < b->documentOrderIndex();
375 return aBegin < bBegin; 376 return aBegin < bBegin;
376 } 377 }
377 SMILTime m_elapsed; 378 double m_elapsed;
378 }; 379 };
379 380
380 SVGSVGElement& SMILTimeContainer::ownerSVGElement() const 381 SVGSVGElement& SMILTimeContainer::ownerSVGElement() const
381 { 382 {
382 return *m_ownerSVGElement; 383 return *m_ownerSVGElement;
383 } 384 }
384 385
385 Document& SMILTimeContainer::document() const 386 Document& SMILTimeContainer::document() const
386 { 387 {
387 return ownerSVGElement().document(); 388 return ownerSVGElement().document();
(...skipping 20 matching lines...) Expand all
408 { 409 {
409 // If there's synchronization pending (most likely due to syncbases), then 410 // If there's synchronization pending (most likely due to syncbases), then
410 // let that complete first before attempting to schedule a frame. 411 // let that complete first before attempting to schedule a frame.
411 if (hasPendingSynchronization()) 412 if (hasPendingSynchronization())
412 return false; 413 return false;
413 if (!isTimelineRunning()) 414 if (!isTimelineRunning())
414 return false; 415 return false;
415 return earliestFireTime.isFinite(); 416 return earliestFireTime.isFinite();
416 } 417 }
417 418
418 void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapse d, bool seekToTime) 419 void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(double elapsed, bool seekToTime)
419 { 420 {
420 if (!document().isActive()) 421 if (!document().isActive())
421 return; 422 return;
422 423
423 SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime); 424 SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime);
424 if (!canScheduleFrame(earliestFireTime)) 425 if (!canScheduleFrame(earliestFireTime))
425 return; 426 return;
426 SMILTime delay = earliestFireTime - elapsed; 427 double delayTime = earliestFireTime.value() - elapsed;
427 scheduleAnimationFrame(delay.value()); 428 scheduleAnimationFrame(delayTime);
428 } 429 }
429 430
430 SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime) 431 SMILTime SMILTimeContainer::updateAnimations(double elapsed, bool seekToTime)
431 { 432 {
432 ASSERT(document().isActive()); 433 ASSERT(document().isActive());
433 SMILTime earliestFireTime = SMILTime::unresolved(); 434 SMILTime earliestFireTime = SMILTime::unresolved();
434 435
435 #if ENABLE(ASSERT) 436 #if ENABLE(ASSERT)
436 // This boolean will catch any attempts to schedule/unschedule scheduledAnim ations during this critical section. 437 // This boolean will catch any attempts to schedule/unschedule scheduledAnim ations during this critical section.
437 // Similarly, any elements removed will unschedule themselves, so this will catch modification of animationsToApply. 438 // Similarly, any elements removed will unschedule themselves, so this will catch modification of animationsToApply.
438 m_preventScheduledAnimationsChanges = true; 439 m_preventScheduledAnimationsChanges = true;
439 #endif 440 #endif
440 441
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 animDiscard->remove(IGNORE_EXCEPTION); 525 animDiscard->remove(IGNORE_EXCEPTION);
525 ASSERT(!animDiscard->isConnected()); 526 ASSERT(!animDiscard->isConnected());
526 } 527 }
527 } 528 }
528 } 529 }
529 return earliestFireTime; 530 return earliestFireTime;
530 } 531 }
531 532
532 void SMILTimeContainer::advanceFrameForTesting() 533 void SMILTimeContainer::advanceFrameForTesting()
533 { 534 {
534 setElapsed(elapsed().value() + initialFrameDelay); 535 setElapsed(elapsed() + initialFrameDelay);
535 } 536 }
536 537
537 DEFINE_TRACE(SMILTimeContainer) 538 DEFINE_TRACE(SMILTimeContainer)
538 { 539 {
539 visitor->trace(m_scheduledAnimations); 540 visitor->trace(m_scheduledAnimations);
540 visitor->trace(m_ownerSVGElement); 541 visitor->trace(m_ownerSVGElement);
541 } 542 }
542 543
543 } // namespace blink 544 } // 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