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 19 matching lines...) Expand all Loading... | |
30 #include "core/animation/DocumentTimeline.h" | 30 #include "core/animation/DocumentTimeline.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/svg/SVGSVGElement.h" | 33 #include "core/svg/SVGSVGElement.h" |
34 #include "core/svg/animation/SVGSMILElement.h" | 34 #include "core/svg/animation/SVGSMILElement.h" |
35 | 35 |
36 using namespace std; | 36 using namespace std; |
37 | 37 |
38 namespace WebCore { | 38 namespace WebCore { |
39 | 39 |
40 // Every entry-point that calls updateAnimations() should instantiate a | |
41 // DiscardScope to prevent deletion of the ownerElement (and hence itself.) | |
42 class DiscardScope { | |
43 public: | |
44 explicit DiscardScope(SVGSVGElement& timeContainerOwner) : m_discardScopeEle ment(&timeContainerOwner) { } | |
45 | |
46 private: | |
47 RefPtr<SVGSVGElement> m_discardScopeElement; | |
48 }; | |
49 | |
40 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) | 50 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) |
41 : m_beginTime(0) | 51 : m_beginTime(0) |
42 , m_pauseTime(0) | 52 , m_pauseTime(0) |
43 , m_resumeTime(0) | 53 , m_resumeTime(0) |
44 , m_accumulatedActiveTime(0) | 54 , m_accumulatedActiveTime(0) |
45 , m_presetStartTime(0) | 55 , m_presetStartTime(0) |
46 , m_frameSchedulingState(Idle) | 56 , m_frameSchedulingState(Idle) |
47 , m_documentOrderIndexesDirty(false) | 57 , m_documentOrderIndexesDirty(false) |
48 , m_animationClock(AnimationClock::create()) | 58 , m_animationClock(AnimationClock::create()) |
49 , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired) | 59 , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 } | 150 } |
141 | 151 |
142 void SMILTimeContainer::begin() | 152 void SMILTimeContainer::begin() |
143 { | 153 { |
144 ASSERT(!m_beginTime); | 154 ASSERT(!m_beginTime); |
145 double now = currentTime(); | 155 double now = currentTime(); |
146 | 156 |
147 // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began. | 157 // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began. |
148 // In this case pass on 'seekToTime=true' to updateAnimations(). | 158 // In this case pass on 'seekToTime=true' to updateAnimations(). |
149 m_beginTime = now - m_presetStartTime; | 159 m_beginTime = now - m_presetStartTime; |
160 DiscardScope discardScope(m_ownerSVGElement); | |
150 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_ presetStartTime ? true : false); | 161 SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_ presetStartTime ? true : false); |
151 m_presetStartTime = 0; | 162 m_presetStartTime = 0; |
152 | 163 |
153 if (m_pauseTime) { | 164 if (m_pauseTime) { |
154 m_pauseTime = now; | 165 m_pauseTime = now; |
155 cancelAnimationFrame(); | 166 cancelAnimationFrame(); |
156 } else { | 167 } else { |
157 ASSERT(isTimelineRunning()); | 168 ASSERT(isTimelineRunning()); |
158 // If the timeline is running, and there's pending animation updates, | 169 // If the timeline is running, and there's pending animation updates, |
159 // always perform the first update after the timeline was started using | 170 // always perform the first update after the timeline was started using |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(); it ! = end; ++it) { | 223 for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(); it ! = end; ++it) { |
213 AnimationsVector* scheduled = it->value.get(); | 224 AnimationsVector* scheduled = it->value.get(); |
214 unsigned size = scheduled->size(); | 225 unsigned size = scheduled->size(); |
215 for (unsigned n = 0; n < size; n++) | 226 for (unsigned n = 0; n < size; n++) |
216 scheduled->at(n)->reset(); | 227 scheduled->at(n)->reset(); |
217 } | 228 } |
218 #ifndef NDEBUG | 229 #ifndef NDEBUG |
219 m_preventScheduledAnimationsChanges = false; | 230 m_preventScheduledAnimationsChanges = false; |
220 #endif | 231 #endif |
221 | 232 |
233 DiscardScope discardScope(m_ownerSVGElement); | |
222 updateAnimationsAndScheduleFrameIfNeeded(time, true); | 234 updateAnimationsAndScheduleFrameIfNeeded(time, true); |
223 } | 235 } |
224 | 236 |
225 bool SMILTimeContainer::isTimelineRunning() const | 237 bool SMILTimeContainer::isTimelineRunning() const |
226 { | 238 { |
227 return m_beginTime && !isPaused(); | 239 return m_beginTime && !isPaused(); |
228 } | 240 } |
229 | 241 |
230 void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime) | 242 void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime) |
231 { | 243 { |
(...skipping 22 matching lines...) Expand all Loading... | |
254 | 266 |
255 void SMILTimeContainer::wakeupTimerFired(Timer<SMILTimeContainer>*) | 267 void SMILTimeContainer::wakeupTimerFired(Timer<SMILTimeContainer>*) |
256 { | 268 { |
257 if (m_frameSchedulingState == AnimationFrame) { | 269 if (m_frameSchedulingState == AnimationFrame) { |
258 ASSERT(isTimelineRunning()); | 270 ASSERT(isTimelineRunning()); |
259 m_frameSchedulingState = Idle; | 271 m_frameSchedulingState = Idle; |
260 serviceOnNextFrame(); | 272 serviceOnNextFrame(); |
261 } else { | 273 } else { |
262 ASSERT(m_frameSchedulingState == SynchronizeAnimations); | 274 ASSERT(m_frameSchedulingState == SynchronizeAnimations); |
263 m_frameSchedulingState = Idle; | 275 m_frameSchedulingState = Idle; |
276 DiscardScope discardScope(m_ownerSVGElement); | |
264 updateAnimationsAndScheduleFrameIfNeeded(elapsed()); | 277 updateAnimationsAndScheduleFrameIfNeeded(elapsed()); |
265 } | 278 } |
266 } | 279 } |
267 | 280 |
268 void SMILTimeContainer::updateDocumentOrderIndexes() | 281 void SMILTimeContainer::updateDocumentOrderIndexes() |
269 { | 282 { |
270 unsigned timingElementCount = 0; | 283 unsigned timingElementCount = 0; |
271 for (SVGSMILElement* element = Traversal<SVGSMILElement>::firstWithin(m_owne rSVGElement); element; element = Traversal<SVGSMILElement>::next(*element, &m_ow nerSVGElement)) | 284 for (SVGSMILElement* element = Traversal<SVGSMILElement>::firstWithin(m_owne rSVGElement); element; element = Traversal<SVGSMILElement>::next(*element, &m_ow nerSVGElement)) |
272 element->setDocumentOrderIndex(timingElementCount++); | 285 element->setDocumentOrderIndex(timingElementCount++); |
273 m_documentOrderIndexesDirty = false; | 286 m_documentOrderIndexesDirty = false; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 } | 327 } |
315 } | 328 } |
316 | 329 |
317 void SMILTimeContainer::serviceAnimations(double monotonicAnimationStartTime) | 330 void SMILTimeContainer::serviceAnimations(double monotonicAnimationStartTime) |
318 { | 331 { |
319 if (m_frameSchedulingState != AnimationFrame) | 332 if (m_frameSchedulingState != AnimationFrame) |
320 return; | 333 return; |
321 | 334 |
322 m_frameSchedulingState = Idle; | 335 m_frameSchedulingState = Idle; |
323 animationClock().updateTime(monotonicAnimationStartTime); | 336 animationClock().updateTime(monotonicAnimationStartTime); |
337 DiscardScope discardScope(m_ownerSVGElement); | |
kouhei (in TOK)
2014/03/12 00:30:30
Can we put this inside updateAnimationsAndSchedule
fs
2014/03/12 07:32:14
No (unfortunately), because on the next line follo
| |
324 updateAnimationsAndScheduleFrameIfNeeded(elapsed()); | 338 updateAnimationsAndScheduleFrameIfNeeded(elapsed()); |
325 animationClock().unfreeze(); | 339 animationClock().unfreeze(); |
326 } | 340 } |
327 | 341 |
328 void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapse d, bool seekToTime) | 342 void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapse d, bool seekToTime) |
329 { | 343 { |
330 SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime); | 344 SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime); |
331 if (!isTimelineRunning()) | 345 if (!isTimelineRunning()) |
332 return; | 346 return; |
333 | 347 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 if (animDiscard->inDocument()) { | 434 if (animDiscard->inDocument()) { |
421 animDiscard->remove(IGNORE_EXCEPTION); | 435 animDiscard->remove(IGNORE_EXCEPTION); |
422 ASSERT(!animDiscard->inDocument()); | 436 ASSERT(!animDiscard->inDocument()); |
423 } | 437 } |
424 } | 438 } |
425 } | 439 } |
426 return earliestFireTime; | 440 return earliestFireTime; |
427 } | 441 } |
428 | 442 |
429 } | 443 } |
OLD | NEW |