OLD | NEW |
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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 } | 121 } |
122 | 122 |
123 bool SMILTimeContainer::hasPendingSynchronization() const { | 123 bool SMILTimeContainer::hasPendingSynchronization() const { |
124 return m_frameSchedulingState == SynchronizeAnimations && | 124 return m_frameSchedulingState == SynchronizeAnimations && |
125 m_wakeupTimer.isActive() && !m_wakeupTimer.nextFireInterval(); | 125 m_wakeupTimer.isActive() && !m_wakeupTimer.nextFireInterval(); |
126 } | 126 } |
127 | 127 |
128 void SMILTimeContainer::notifyIntervalsChanged() { | 128 void SMILTimeContainer::notifyIntervalsChanged() { |
129 if (!isStarted()) | 129 if (!isStarted()) |
130 return; | 130 return; |
131 // Schedule updateAnimations() to be called asynchronously so multiple interva
ls | 131 // Schedule updateAnimations() to be called asynchronously so multiple |
132 // can change with updateAnimations() only called once at the end. | 132 // intervals can change with updateAnimations() only called once at the end. |
133 if (hasPendingSynchronization()) | 133 if (hasPendingSynchronization()) |
134 return; | 134 return; |
135 cancelAnimationFrame(); | 135 cancelAnimationFrame(); |
136 scheduleWakeUp(0, SynchronizeAnimations); | 136 scheduleWakeUp(0, SynchronizeAnimations); |
137 } | 137 } |
138 | 138 |
139 double SMILTimeContainer::elapsed() const { | 139 double SMILTimeContainer::elapsed() const { |
140 if (!isStarted()) | 140 if (!isStarted()) |
141 return 0; | 141 return 0; |
142 | 142 |
(...skipping 23 matching lines...) Expand all Loading... |
166 | 166 |
167 void SMILTimeContainer::start() { | 167 void SMILTimeContainer::start() { |
168 RELEASE_ASSERT(!isStarted()); | 168 RELEASE_ASSERT(!isStarted()); |
169 | 169 |
170 if (!document().isActive()) | 170 if (!document().isActive()) |
171 return; | 171 return; |
172 | 172 |
173 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused)) | 173 if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused)) |
174 return; | 174 return; |
175 | 175 |
176 // Sample the document timeline to get a time reference for the "presentation
time". | 176 // Sample the document timeline to get a time reference for the "presentation |
| 177 // time". |
177 synchronizeToDocumentTimeline(); | 178 synchronizeToDocumentTimeline(); |
178 m_started = true; | 179 m_started = true; |
179 | 180 |
180 // If the "presentation time" is non-zero, the timeline was modified via | 181 // If the "presentation time" is non-zero, the timeline was modified via |
181 // setElapsed() before the document began. | 182 // setElapsed() before the document began. In this case pass on |
182 // In this case pass on 'seekToTime=true' to updateAnimations() to issue a see
k. | 183 // 'seekToTime=true' to updateAnimations() to issue a seek. |
183 SMILTime earliestFireTime = | 184 SMILTime earliestFireTime = |
184 updateAnimations(m_presentationTime, m_presentationTime ? true : false); | 185 updateAnimations(m_presentationTime, m_presentationTime ? true : false); |
185 if (!canScheduleFrame(earliestFireTime)) | 186 if (!canScheduleFrame(earliestFireTime)) |
186 return; | 187 return; |
187 // If the timeline is running, and there are pending animation updates, | 188 // If the timeline is running, and there are pending animation updates, |
188 // always perform the first update after the timeline was started using | 189 // always perform the first update after the timeline was started using |
189 // the wake-up mechanism. | 190 // the wake-up mechanism. |
190 double delayTime = earliestFireTime.value() - m_presentationTime; | 191 double delayTime = earliestFireTime.value() - m_presentationTime; |
191 scheduleWakeUp(std::max(initialFrameDelay, delayTime), SynchronizeAnimations); | 192 scheduleWakeUp(std::max(initialFrameDelay, delayTime), SynchronizeAnimations); |
192 } | 193 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 for (SVGSMILElement& element : | 353 for (SVGSMILElement& element : |
353 Traversal<SVGSMILElement>::descendantsOf(ownerSVGElement())) | 354 Traversal<SVGSMILElement>::descendantsOf(ownerSVGElement())) |
354 element.setDocumentOrderIndex(timingElementCount++); | 355 element.setDocumentOrderIndex(timingElementCount++); |
355 m_documentOrderIndexesDirty = false; | 356 m_documentOrderIndexesDirty = false; |
356 } | 357 } |
357 | 358 |
358 struct PriorityCompare { | 359 struct PriorityCompare { |
359 PriorityCompare(double elapsed) : m_elapsed(elapsed) {} | 360 PriorityCompare(double elapsed) : m_elapsed(elapsed) {} |
360 bool operator()(const Member<SVGSMILElement>& a, | 361 bool operator()(const Member<SVGSMILElement>& a, |
361 const Member<SVGSMILElement>& b) { | 362 const Member<SVGSMILElement>& b) { |
362 // FIXME: This should also consider possible timing relations between the el
ements. | 363 // FIXME: This should also consider possible timing relations between the |
| 364 // elements. |
363 SMILTime aBegin = a->intervalBegin(); | 365 SMILTime aBegin = a->intervalBegin(); |
364 SMILTime bBegin = b->intervalBegin(); | 366 SMILTime bBegin = b->intervalBegin(); |
365 // Frozen elements need to be prioritized based on their previous interval. | 367 // Frozen elements need to be prioritized based on their previous interval. |
366 aBegin = a->isFrozen() && m_elapsed < aBegin ? a->previousIntervalBegin() | 368 aBegin = a->isFrozen() && m_elapsed < aBegin ? a->previousIntervalBegin() |
367 : aBegin; | 369 : aBegin; |
368 bBegin = b->isFrozen() && m_elapsed < bBegin ? b->previousIntervalBegin() | 370 bBegin = b->isFrozen() && m_elapsed < bBegin ? b->previousIntervalBegin() |
369 : bBegin; | 371 : bBegin; |
370 if (aBegin == bBegin) | 372 if (aBegin == bBegin) |
371 return a->documentOrderIndex() < b->documentOrderIndex(); | 373 return a->documentOrderIndex() < b->documentOrderIndex(); |
372 return aBegin < bBegin; | 374 return aBegin < bBegin; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 return; | 420 return; |
419 double delayTime = earliestFireTime.value() - elapsed; | 421 double delayTime = earliestFireTime.value() - elapsed; |
420 scheduleAnimationFrame(delayTime); | 422 scheduleAnimationFrame(delayTime); |
421 } | 423 } |
422 | 424 |
423 SMILTime SMILTimeContainer::updateAnimations(double elapsed, bool seekToTime) { | 425 SMILTime SMILTimeContainer::updateAnimations(double elapsed, bool seekToTime) { |
424 ASSERT(document().isActive()); | 426 ASSERT(document().isActive()); |
425 SMILTime earliestFireTime = SMILTime::unresolved(); | 427 SMILTime earliestFireTime = SMILTime::unresolved(); |
426 | 428 |
427 #if ENABLE(ASSERT) | 429 #if ENABLE(ASSERT) |
428 // This boolean will catch any attempts to schedule/unschedule scheduledAnimat
ions during this critical section. | 430 // This boolean will catch any attempts to schedule/unschedule |
429 // Similarly, any elements removed will unschedule themselves, so this will ca
tch modification of animationsToApply. | 431 // scheduledAnimations during this critical section. Similarly, any elements |
| 432 // removed will unschedule themselves, so this will catch modification of |
| 433 // animationsToApply. |
430 m_preventScheduledAnimationsChanges = true; | 434 m_preventScheduledAnimationsChanges = true; |
431 #endif | 435 #endif |
432 | 436 |
433 if (m_documentOrderIndexesDirty) | 437 if (m_documentOrderIndexesDirty) |
434 updateDocumentOrderIndexes(); | 438 updateDocumentOrderIndexes(); |
435 | 439 |
436 HeapHashSet<ElementAttributePair> invalidKeys; | 440 HeapHashSet<ElementAttributePair> invalidKeys; |
437 using AnimationsVector = HeapVector<Member<SVGSMILElement>>; | 441 using AnimationsVector = HeapVector<Member<SVGSMILElement>>; |
438 AnimationsVector animationsToApply; | 442 AnimationsVector animationsToApply; |
439 AnimationsVector scheduledAnimationsInSameGroup; | 443 AnimationsVector scheduledAnimationsInSameGroup; |
440 for (const auto& entry : m_scheduledAnimations) { | 444 for (const auto& entry : m_scheduledAnimations) { |
441 if (!entry.key.first || entry.value->isEmpty()) { | 445 if (!entry.key.first || entry.value->isEmpty()) { |
442 invalidKeys.add(entry.key); | 446 invalidKeys.add(entry.key); |
443 continue; | 447 continue; |
444 } | 448 } |
445 | 449 |
446 // Sort according to priority. Elements with later begin time have higher pr
iority. | 450 // Sort according to priority. Elements with later begin time have higher |
447 // In case of a tie, document order decides. | 451 // priority. In case of a tie, document order decides. |
448 // FIXME: This should also consider timing relationships between the element
s. Dependents | 452 // FIXME: This should also consider timing relationships between the |
449 // have higher priority. | 453 // elements. Dependents have higher priority. |
450 copyToVector(*entry.value, scheduledAnimationsInSameGroup); | 454 copyToVector(*entry.value, scheduledAnimationsInSameGroup); |
451 std::sort(scheduledAnimationsInSameGroup.begin(), | 455 std::sort(scheduledAnimationsInSameGroup.begin(), |
452 scheduledAnimationsInSameGroup.end(), PriorityCompare(elapsed)); | 456 scheduledAnimationsInSameGroup.end(), PriorityCompare(elapsed)); |
453 | 457 |
454 AnimationsVector sandwich; | 458 AnimationsVector sandwich; |
455 for (const auto& itAnimation : scheduledAnimationsInSameGroup) { | 459 for (const auto& itAnimation : scheduledAnimationsInSameGroup) { |
456 SVGSMILElement* animation = itAnimation.get(); | 460 SVGSMILElement* animation = itAnimation.get(); |
457 ASSERT(animation->timeContainer() == this); | 461 ASSERT(animation->timeContainer() == this); |
458 ASSERT(animation->targetElement()); | 462 ASSERT(animation->targetElement()); |
459 ASSERT(animation->hasValidAttributeName()); | 463 ASSERT(animation->hasValidAttributeName()); |
460 ASSERT(animation->hasValidAttributeType()); | 464 ASSERT(animation->hasValidAttributeType()); |
461 | 465 |
462 // This will calculate the contribution from the animation and update timi
ng. | 466 // This will calculate the contribution from the animation and update |
| 467 // timing. |
463 if (animation->progress(elapsed, seekToTime)) { | 468 if (animation->progress(elapsed, seekToTime)) { |
464 sandwich.append(animation); | 469 sandwich.append(animation); |
465 } else { | 470 } else { |
466 animation->clearAnimatedType(); | 471 animation->clearAnimatedType(); |
467 } | 472 } |
468 | 473 |
469 SMILTime nextFireTime = animation->nextProgressTime(); | 474 SMILTime nextFireTime = animation->nextProgressTime(); |
470 if (nextFireTime.isFinite()) | 475 if (nextFireTime.isFinite()) |
471 earliestFireTime = std::min(nextFireTime, earliestFireTime); | 476 earliestFireTime = std::min(nextFireTime, earliestFireTime); |
472 } | 477 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 void SMILTimeContainer::advanceFrameForTesting() { | 535 void SMILTimeContainer::advanceFrameForTesting() { |
531 setElapsed(elapsed() + initialFrameDelay); | 536 setElapsed(elapsed() + initialFrameDelay); |
532 } | 537 } |
533 | 538 |
534 DEFINE_TRACE(SMILTimeContainer) { | 539 DEFINE_TRACE(SMILTimeContainer) { |
535 visitor->trace(m_scheduledAnimations); | 540 visitor->trace(m_scheduledAnimations); |
536 visitor->trace(m_ownerSVGElement); | 541 visitor->trace(m_ownerSVGElement); |
537 } | 542 } |
538 | 543 |
539 } // namespace blink | 544 } // namespace blink |
OLD | NEW |