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 12 matching lines...) Expand all Loading... | |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "config.h" | 26 #include "config.h" |
27 #include "core/svg/animation/SMILTimeContainer.h" | 27 #include "core/svg/animation/SMILTimeContainer.h" |
28 | 28 |
29 #include "core/animation/AnimationClock.h" | 29 #include "core/animation/AnimationClock.h" |
30 #include "core/animation/AnimationTimeline.h" | 30 #include "core/animation/AnimationTimeline.h" |
31 #include "core/dom/ElementTraversal.h" | 31 #include "core/dom/ElementTraversal.h" |
32 #include "core/frame/FrameView.h" | 32 #include "core/frame/FrameView.h" |
33 #include "core/frame/Settings.h" | |
33 #include "core/svg/SVGSVGElement.h" | 34 #include "core/svg/SVGSVGElement.h" |
34 #include "core/svg/animation/SVGSMILElement.h" | 35 #include "core/svg/animation/SVGSMILElement.h" |
35 | 36 |
36 namespace blink { | 37 namespace blink { |
37 | 38 |
38 static const double initialFrameDelay = 0.025; | 39 static const double initialFrameDelay = 0.025; |
40 static const double animationPolicyOnceDuration = 3.000; | |
39 | 41 |
40 #if !ENABLE(OILPAN) | 42 #if !ENABLE(OILPAN) |
41 // Every entry-point that calls updateAnimations() should instantiate a | 43 // Every entry-point that calls updateAnimations() should instantiate a |
42 // DiscardScope to prevent deletion of the ownerElement (and hence itself.) | 44 // DiscardScope to prevent deletion of the ownerElement (and hence itself.) |
43 class DiscardScope { | 45 class DiscardScope { |
44 public: | 46 public: |
45 explicit DiscardScope(SVGSVGElement& timeContainerOwner) : m_discardScopeEle ment(&timeContainerOwner) { } | 47 explicit DiscardScope(SVGSVGElement& timeContainerOwner) : m_discardScopeEle ment(&timeContainerOwner) { } |
46 | 48 |
47 private: | 49 private: |
48 RefPtr<SVGSVGElement> m_discardScopeElement; | 50 RefPtr<SVGSVGElement> m_discardScopeElement; |
49 }; | 51 }; |
50 #endif | 52 #endif |
51 | 53 |
52 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) | 54 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) |
53 : m_beginTime(0) | 55 : m_beginTime(0) |
54 , m_pauseTime(0) | 56 , m_pauseTime(0) |
55 , m_resumeTime(0) | 57 , m_resumeTime(0) |
56 , m_accumulatedActiveTime(0) | 58 , m_accumulatedActiveTime(0) |
57 , m_presetStartTime(0) | 59 , m_presetStartTime(0) |
58 , m_frameSchedulingState(Idle) | 60 , m_frameSchedulingState(Idle) |
59 , m_documentOrderIndexesDirty(false) | 61 , m_documentOrderIndexesDirty(false) |
60 , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired) | 62 , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired) |
63 , m_animationPolicyOnceTimer(this, &SMILTimeContainer::animationPolicyTimerF ired) | |
61 , m_ownerSVGElement(owner) | 64 , m_ownerSVGElement(owner) |
62 #if ENABLE(ASSERT) | 65 #if ENABLE(ASSERT) |
63 , m_preventScheduledAnimationsChanges(false) | 66 , m_preventScheduledAnimationsChanges(false) |
64 #endif | 67 #endif |
65 { | 68 { |
66 } | 69 } |
67 | 70 |
68 SMILTimeContainer::~SMILTimeContainer() | 71 SMILTimeContainer::~SMILTimeContainer() |
69 { | 72 { |
70 cancelAnimationFrame(); | 73 cancelAnimationFrame(); |
74 cancelAnimationPolicyTimer(); | |
71 ASSERT(!m_wakeupTimer.isActive()); | 75 ASSERT(!m_wakeupTimer.isActive()); |
72 #if ENABLE(ASSERT) | 76 #if ENABLE(ASSERT) |
73 ASSERT(!m_preventScheduledAnimationsChanges); | 77 ASSERT(!m_preventScheduledAnimationsChanges); |
74 #endif | 78 #endif |
75 } | 79 } |
76 | 80 |
77 void SMILTimeContainer::schedule(SVGSMILElement* animation, SVGElement* target, const QualifiedName& attributeName) | 81 void SMILTimeContainer::schedule(SVGSMILElement* animation, SVGElement* target, const QualifiedName& attributeName) |
78 { | 82 { |
79 ASSERT(animation->timeContainer() == this); | 83 ASSERT(animation->timeContainer() == this); |
80 ASSERT(target); | 84 ASSERT(target); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 return 0; | 149 return 0; |
146 | 150 |
147 if (isPaused()) | 151 if (isPaused()) |
148 return m_accumulatedActiveTime; | 152 return m_accumulatedActiveTime; |
149 | 153 |
150 return currentTime() + m_accumulatedActiveTime - lastResumeTime(); | 154 return currentTime() + m_accumulatedActiveTime - lastResumeTime(); |
151 } | 155 } |
152 | 156 |
153 bool SMILTimeContainer::isPaused() const | 157 bool SMILTimeContainer::isPaused() const |
154 { | 158 { |
159 // If animation policy is "none", it is always paused. | |
160 if (animationPolicy() == ImageAnimationPolicyNoAnimation) | |
161 return true; | |
155 return m_pauseTime; | 162 return m_pauseTime; |
fs
2014/12/25 17:32:08
return m_oauseTime || animationPolicy() == ...;
(
je_julie(Not used)
2014/12/27 07:08:54
Done.
I assumed that it has the same effect whenev
fs
2014/12/27 15:36:34
That sounds fine. I suppose if the policy could ch
| |
156 } | 163 } |
157 | 164 |
158 bool SMILTimeContainer::isStarted() const | 165 bool SMILTimeContainer::isStarted() const |
159 { | 166 { |
160 return m_beginTime; | 167 return m_beginTime; |
161 } | 168 } |
162 | 169 |
163 void SMILTimeContainer::begin() | 170 void SMILTimeContainer::begin() |
164 { | 171 { |
165 RELEASE_ASSERT(!m_beginTime); | 172 RELEASE_ASSERT(!m_beginTime); |
173 | |
174 if (!handleAnimationPolicy(true, false)) | |
fs
2014/12/25 17:32:08
handleAnimationPolicy(RestartOnceTimerIfNotPaused)
je_julie(Not used)
2014/12/27 07:08:53
Done.
| |
175 return; | |
176 | |
166 double now = currentTime(); | 177 double now = currentTime(); |
167 | 178 |
168 // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began. | 179 // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began. |
169 // In this case pass on 'seekToTime=true' to updateAnimations(). | 180 // In this case pass on 'seekToTime=true' to updateAnimations(). |
170 m_beginTime = now - m_presetStartTime; | 181 m_beginTime = now - m_presetStartTime; |
171 #if !ENABLE(OILPAN) | 182 #if !ENABLE(OILPAN) |
172 DiscardScope discardScope(m_ownerSVGElement); | 183 DiscardScope discardScope(m_ownerSVGElement); |
173 #endif | 184 #endif |
174 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_ presetStartTime ? true : false); | 185 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_ presetStartTime ? true : false); |
175 m_presetStartTime = 0; | 186 m_presetStartTime = 0; |
(...skipping 11 matching lines...) Expand all Loading... | |
187 // the wake-up mechanism. | 198 // the wake-up mechanism. |
188 if (earliestFireTime.isFinite()) { | 199 if (earliestFireTime.isFinite()) { |
189 SMILTime delay = earliestFireTime - elapsed(); | 200 SMILTime delay = earliestFireTime - elapsed(); |
190 scheduleWakeUp(std::max(initialFrameDelay, delay.value()), Synchroni zeAnimations); | 201 scheduleWakeUp(std::max(initialFrameDelay, delay.value()), Synchroni zeAnimations); |
191 } | 202 } |
192 } | 203 } |
193 } | 204 } |
194 | 205 |
195 void SMILTimeContainer::pause() | 206 void SMILTimeContainer::pause() |
196 { | 207 { |
208 if (!handleAnimationPolicy(false, true)) | |
fs
2014/12/25 17:32:08
handleAnimationPolicy(CancelOnceTimer)
je_julie(Not used)
2014/12/27 07:08:53
Done.
| |
209 return; | |
210 | |
197 ASSERT(!isPaused()); | 211 ASSERT(!isPaused()); |
198 m_pauseTime = currentTime(); | 212 m_pauseTime = currentTime(); |
199 | 213 |
200 if (m_beginTime) { | 214 if (m_beginTime) { |
201 m_accumulatedActiveTime += m_pauseTime - lastResumeTime(); | 215 m_accumulatedActiveTime += m_pauseTime - lastResumeTime(); |
202 cancelAnimationFrame(); | 216 cancelAnimationFrame(); |
203 } | 217 } |
204 m_resumeTime = 0; | 218 m_resumeTime = 0; |
205 } | 219 } |
206 | 220 |
207 void SMILTimeContainer::resume() | 221 void SMILTimeContainer::resume() |
208 { | 222 { |
223 if (!handleAnimationPolicy(false, false)) | |
fs
2014/12/25 17:32:08
handleAnimationPolicy(RestartOnceTimer)
je_julie(Not used)
2014/12/27 07:08:53
Done.
| |
224 return; | |
225 | |
209 ASSERT(isPaused()); | 226 ASSERT(isPaused()); |
210 m_resumeTime = currentTime(); | 227 m_resumeTime = currentTime(); |
211 | 228 |
212 m_pauseTime = 0; | 229 m_pauseTime = 0; |
213 scheduleWakeUp(0, SynchronizeAnimations); | 230 scheduleWakeUp(0, SynchronizeAnimations); |
214 } | 231 } |
215 | 232 |
216 void SMILTimeContainer::setElapsed(SMILTime time) | 233 void SMILTimeContainer::setElapsed(SMILTime time) |
217 { | 234 { |
218 // If the documment didn't begin yet, record a new start time, we'll seek to once its possible. | 235 // If the documment didn't begin yet, record a new start time, we'll seek to once its possible. |
219 if (!m_beginTime) { | 236 if (!m_beginTime) { |
220 m_presetStartTime = time.value(); | 237 m_presetStartTime = time.value(); |
221 return; | 238 return; |
222 } | 239 } |
223 | 240 |
241 if (!handleAnimationPolicy(true, false)) | |
fs
2014/12/25 17:32:08
Same as in begin().
je_julie(Not used)
2014/12/27 07:08:53
Done.
| |
242 return; | |
243 | |
224 cancelAnimationFrame(); | 244 cancelAnimationFrame(); |
225 | 245 |
226 double now = currentTime(); | 246 double now = currentTime(); |
227 m_beginTime = now - time.value(); | 247 m_beginTime = now - time.value(); |
228 m_resumeTime = 0; | 248 m_resumeTime = 0; |
229 if (m_pauseTime) { | 249 if (m_pauseTime) { |
230 m_pauseTime = now; | 250 m_pauseTime = now; |
231 m_accumulatedActiveTime = time.value(); | 251 m_accumulatedActiveTime = time.value(); |
232 } else { | 252 } else { |
233 m_accumulatedActiveTime = 0; | 253 m_accumulatedActiveTime = 0; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
288 if (m_frameSchedulingState == FutureAnimationFrame) { | 308 if (m_frameSchedulingState == FutureAnimationFrame) { |
289 ASSERT(isTimelineRunning()); | 309 ASSERT(isTimelineRunning()); |
290 m_frameSchedulingState = Idle; | 310 m_frameSchedulingState = Idle; |
291 serviceOnNextFrame(); | 311 serviceOnNextFrame(); |
292 } else { | 312 } else { |
293 m_frameSchedulingState = Idle; | 313 m_frameSchedulingState = Idle; |
294 updateAnimationsAndScheduleFrameIfNeeded(elapsed()); | 314 updateAnimationsAndScheduleFrameIfNeeded(elapsed()); |
295 } | 315 } |
296 } | 316 } |
297 | 317 |
318 void SMILTimeContainer::scheduleAnimationPolicyTimer() | |
319 { | |
320 m_animationPolicyOnceTimer.startOneShot(animationPolicyOnceDuration, FROM_HE RE); | |
321 } | |
322 | |
323 void SMILTimeContainer::cancelAnimationPolicyTimer() | |
324 { | |
325 if (m_animationPolicyOnceTimer.isActive()) | |
326 m_animationPolicyOnceTimer.stop(); | |
327 } | |
328 | |
329 void SMILTimeContainer::animationPolicyTimerFired(Timer<SMILTimeContainer>*) | |
330 { | |
331 pause(); | |
332 } | |
333 | |
334 ImageAnimationPolicy SMILTimeContainer::animationPolicy() const | |
335 { | |
336 Settings* settings = document().settings(); | |
337 if (!settings) | |
338 return ImageAnimationPolicyAllowed; | |
339 | |
340 return settings->imageAnimationPolicy(); | |
341 } | |
342 | |
343 bool SMILTimeContainer::handleAnimationPolicy(bool checkPausedState, bool cancel Timer) | |
344 { | |
345 ImageAnimationPolicy policy = animationPolicy(); | |
346 // If the animation policy is "none", control is not allowed. | |
347 // returns false to exit flow. | |
348 if (policy == ImageAnimationPolicyNoAnimation) | |
349 return false; | |
350 // If the animation policy is "once", | |
351 if (policy == ImageAnimationPolicyAnimateOnce) { | |
352 // checkPausedState: the paused state should be checked. | |
353 bool passed = checkPausedState ? !m_pauseTime : true; | |
354 if (passed) { | |
fs
2014/12/25 17:32:08
This could've been !checkPausedState || !isPaused(
je_julie(Not used)
2014/12/27 07:08:54
Done.
| |
355 // cancelTimer: cancel or start timer. | |
356 if (cancelTimer) | |
357 cancelAnimationPolicyTimer(); | |
358 else | |
359 scheduleAnimationPolicyTimer(); | |
360 } | |
361 } | |
362 return true; | |
363 } | |
364 | |
298 void SMILTimeContainer::updateDocumentOrderIndexes() | 365 void SMILTimeContainer::updateDocumentOrderIndexes() |
299 { | 366 { |
300 unsigned timingElementCount = 0; | 367 unsigned timingElementCount = 0; |
301 for (SVGSMILElement& element : Traversal<SVGSMILElement>::descendantsOf(m_ow nerSVGElement)) | 368 for (SVGSMILElement& element : Traversal<SVGSMILElement>::descendantsOf(m_ow nerSVGElement)) |
302 element.setDocumentOrderIndex(timingElementCount++); | 369 element.setDocumentOrderIndex(timingElementCount++); |
303 m_documentOrderIndexesDirty = false; | 370 m_documentOrderIndexesDirty = false; |
304 } | 371 } |
305 | 372 |
306 struct PriorityCompare { | 373 struct PriorityCompare { |
307 PriorityCompare(SMILTime elapsed) : m_elapsed(elapsed) {} | 374 PriorityCompare(SMILTime elapsed) : m_elapsed(elapsed) {} |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 } | 532 } |
466 | 533 |
467 void SMILTimeContainer::trace(Visitor* visitor) | 534 void SMILTimeContainer::trace(Visitor* visitor) |
468 { | 535 { |
469 #if ENABLE(OILPAN) | 536 #if ENABLE(OILPAN) |
470 visitor->trace(m_scheduledAnimations); | 537 visitor->trace(m_scheduledAnimations); |
471 #endif | 538 #endif |
472 } | 539 } |
473 | 540 |
474 } | 541 } |
OLD | NEW |