OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google 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 are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 { | 54 { |
55 RefPtrWillBeRawPtr<AnimationPlayer> player = adoptRefWillBeNoop(new Animatio nPlayer(executionContext, timeline, content)); | 55 RefPtrWillBeRawPtr<AnimationPlayer> player = adoptRefWillBeNoop(new Animatio nPlayer(executionContext, timeline, content)); |
56 player->uncancel(); | 56 player->uncancel(); |
57 timeline.document()->compositorPendingAnimations().add(player.get()); | 57 timeline.document()->compositorPendingAnimations().add(player.get()); |
58 player->suspendIfNeeded(); | 58 player->suspendIfNeeded(); |
59 return player.release(); | 59 return player.release(); |
60 } | 60 } |
61 | 61 |
62 AnimationPlayer::AnimationPlayer(ExecutionContext* executionContext, AnimationTi meline& timeline, AnimationNode* content) | 62 AnimationPlayer::AnimationPlayer(ExecutionContext* executionContext, AnimationTi meline& timeline, AnimationNode* content) |
63 : ActiveDOMObject(executionContext) | 63 : ActiveDOMObject(executionContext) |
64 , m_playState(Idle) | |
64 , m_playbackRate(1) | 65 , m_playbackRate(1) |
65 , m_startTime(nullValue()) | 66 , m_startTime(nullValue()) |
66 , m_holdTime(0) | 67 , m_holdTime(0) |
67 , m_sequenceNumber(nextSequenceNumber()) | 68 , m_sequenceNumber(nextSequenceNumber()) |
68 , m_content(content) | 69 , m_content(content) |
69 , m_timeline(&timeline) | 70 , m_timeline(&timeline) |
70 , m_paused(false) | 71 , m_paused(false) |
71 , m_held(true) | 72 , m_held(true) |
72 , m_isPausedForTesting(false) | 73 , m_isPausedForTesting(false) |
73 , m_outdated(true) | 74 , m_outdated(true) |
74 , m_finished(true) | 75 , m_finished(true) |
75 , m_compositorState(nullptr) | 76 , m_compositorState(nullptr) |
76 , m_compositorPending(true) | 77 , m_compositorPending(true) |
77 , m_currentTimePending(false) | 78 , m_currentTimePending(false) |
78 , m_idle(true) | |
79 { | 79 { |
80 if (m_content) { | 80 if (m_content) { |
81 if (m_content->player()) { | 81 if (m_content->player()) { |
82 m_content->player()->cancel(); | 82 m_content->player()->cancel(); |
83 m_content->player()->setSource(0); | 83 m_content->player()->setSource(0); |
84 } | 84 } |
85 m_content->attach(this); | 85 m_content->attach(this); |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
(...skipping 10 matching lines...) Expand all Loading... | |
99 double AnimationPlayer::sourceEnd() const | 99 double AnimationPlayer::sourceEnd() const |
100 { | 100 { |
101 return m_content ? m_content->endTimeInternal() : 0; | 101 return m_content ? m_content->endTimeInternal() : 0; |
102 } | 102 } |
103 | 103 |
104 bool AnimationPlayer::limited(double currentTime) const | 104 bool AnimationPlayer::limited(double currentTime) const |
105 { | 105 { |
106 return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && cu rrentTime >= sourceEnd()); | 106 return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && cu rrentTime >= sourceEnd()); |
107 } | 107 } |
108 | 108 |
109 void AnimationPlayer::setCurrentTime(double newCurrentTime) | |
110 { | |
111 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetCurrentT ime); | |
112 if (!std::isfinite(newCurrentTime)) | |
113 return; | |
114 | |
115 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
116 | |
117 setCompositorPending(); | |
118 m_currentTimePending = false; | |
119 setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand); | |
120 } | |
121 | |
109 void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime, TimingUpdate Reason reason) | 122 void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime, TimingUpdate Reason reason) |
110 { | 123 { |
111 ASSERT(std::isfinite(newCurrentTime)); | 124 ASSERT(std::isfinite(newCurrentTime)); |
112 | 125 |
113 bool oldHeld = m_held; | 126 bool oldHeld = m_held; |
114 bool outdated = false; | 127 bool outdated = false; |
115 bool isLimited = limited(newCurrentTime); | 128 bool isLimited = limited(newCurrentTime); |
116 m_held = m_paused || !m_playbackRate || isLimited || std::isnan(m_startTime) ; | 129 m_held = m_paused || !m_playbackRate || isLimited || std::isnan(m_startTime) ; |
117 if (m_held) { | 130 if (m_held) { |
118 if (!oldHeld || m_holdTime != newCurrentTime) | 131 if (!oldHeld || m_holdTime != newCurrentTime) |
119 outdated = true; | 132 outdated = true; |
120 m_holdTime = newCurrentTime; | 133 m_holdTime = newCurrentTime; |
121 if (m_paused || !m_playbackRate) { | 134 if (m_paused || !m_playbackRate) { |
122 m_startTime = nullValue(); | 135 m_startTime = nullValue(); |
123 } else if (isLimited && std::isnan(m_startTime) && reason == TimingUpdat eForAnimationFrame) { | 136 } else if (isLimited && std::isnan(m_startTime) && reason == TimingUpdat eForAnimationFrame) { |
124 m_startTime = calculateStartTime(newCurrentTime); | 137 m_startTime = calculateStartTime(newCurrentTime); |
125 } | 138 } |
126 } else { | 139 } else { |
127 m_holdTime = nullValue(); | 140 m_holdTime = nullValue(); |
128 m_startTime = calculateStartTime(newCurrentTime); | 141 m_startTime = calculateStartTime(newCurrentTime); |
129 setFinished(false); | 142 m_finished = false; |
130 outdated = true; | 143 outdated = true; |
131 } | 144 } |
132 | 145 |
133 if (outdated) { | 146 if (outdated) { |
134 setOutdated(); | 147 setOutdated(); |
135 } | 148 } |
136 } | 149 } |
137 | 150 |
138 // Update timing to reflect updated animation clock due to tick | 151 // Update timing to reflect updated animation clock due to tick |
139 void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason) | 152 void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason) |
(...skipping 23 matching lines...) Expand all Loading... | |
163 | 176 |
164 double AnimationPlayer::currentTime(bool& isNull) | 177 double AnimationPlayer::currentTime(bool& isNull) |
165 { | 178 { |
166 double result = currentTime(); | 179 double result = currentTime(); |
167 isNull = std::isnan(result); | 180 isNull = std::isnan(result); |
168 return result; | 181 return result; |
169 } | 182 } |
170 | 183 |
171 double AnimationPlayer::currentTime() | 184 double AnimationPlayer::currentTime() |
172 { | 185 { |
186 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
187 | |
173 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetCurrentT ime); | 188 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetCurrentT ime); |
174 if (m_currentTimePending || m_idle) | 189 if (m_currentTimePending || playStateInternal() == Idle) |
175 return std::numeric_limits<double>::quiet_NaN(); | 190 return std::numeric_limits<double>::quiet_NaN(); |
191 | |
176 return currentTimeInternal() * 1000; | 192 return currentTimeInternal() * 1000; |
177 } | 193 } |
178 | 194 |
179 double AnimationPlayer::currentTimeInternal() | 195 double AnimationPlayer::currentTimeInternal() const |
180 { | 196 { |
181 updateCurrentTimingState(TimingUpdateOnDemand); | 197 double result = m_held ? m_holdTime : calculateCurrentTime(); |
182 if (m_held) | 198 #if ENABLE(ASSERT) |
shans
2014/10/15 03:38:00
is ASSERT stronger than DEBUG?
dstockwell
2014/10/15 08:30:04
ASSERT can be enabled outside of a debug build. Bu
| |
183 return m_holdTime; | 199 const_cast<AnimationPlayer*>(this)->updateCurrentTimingState(TimingUpdateOnD emand); |
184 return calculateCurrentTime(); | 200 ASSERT(result == (m_held ? m_holdTime : calculateCurrentTime())); |
201 #endif | |
202 return result; | |
185 } | 203 } |
186 | 204 |
187 void AnimationPlayer::preCommit(bool startOnCompositor) | 205 void AnimationPlayer::preCommit(bool startOnCompositor) |
188 { | 206 { |
189 if (m_compositorState && m_compositorState->pendingAction == Start) { | 207 if (m_compositorState && m_compositorState->pendingAction == Start) { |
190 // Still waiting for a start time. | 208 // Still waiting for a start time. |
191 return; | 209 return; |
192 } | 210 } |
193 | 211 |
212 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
213 | |
194 bool softChange = m_compositorState && (paused() || m_compositorState->playb ackRate != m_playbackRate); | 214 bool softChange = m_compositorState && (paused() || m_compositorState->playb ackRate != m_playbackRate); |
195 bool hardChange = m_compositorState && (m_compositorState->sourceChanged || (m_compositorState->startTime != m_startTime && !std::isnan(m_compositorState->s tartTime) && !std::isnan(m_startTime))); | 215 bool hardChange = m_compositorState && (m_compositorState->sourceChanged || (m_compositorState->startTime != m_startTime && !std::isnan(m_compositorState->s tartTime) && !std::isnan(m_startTime))); |
196 | 216 |
197 // FIXME: softChange && !hardChange should generate a Pause/ThenStart, | 217 // FIXME: softChange && !hardChange should generate a Pause/ThenStart, |
198 // not a Cancel, but we can't communicate these to the compositor yet. | 218 // not a Cancel, but we can't communicate these to the compositor yet. |
199 | 219 |
200 bool changed = softChange || hardChange; | 220 bool changed = softChange || hardChange; |
201 bool shouldCancel = (!playing() && m_compositorState) || changed; | 221 bool shouldCancel = (!playing() && m_compositorState) || changed; |
202 bool shouldStart = playing() && (!m_compositorState || changed); | 222 bool shouldStart = playing() && (!m_compositorState || changed); |
203 | 223 |
204 if (shouldCancel) { | 224 if (shouldCancel) { |
205 cancelAnimationOnCompositor(); | 225 cancelAnimationOnCompositor(); |
206 m_compositorState = nullptr; | 226 m_compositorState = nullptr; |
207 | 227 |
208 } | 228 } |
209 | 229 |
210 if (!shouldStart) { | 230 if (!shouldStart) { |
211 m_currentTimePending = false; | 231 m_currentTimePending = false; |
212 } | 232 } |
213 | 233 |
214 if (shouldStart && startOnCompositor && maybeStartAnimationOnCompositor()) { | 234 if (shouldStart && startOnCompositor && maybeStartAnimationOnCompositor()) { |
215 m_compositorState = adoptPtr(new CompositorState(*this)); | 235 m_compositorState = adoptPtr(new CompositorState(*this)); |
216 } | 236 } |
217 } | 237 } |
218 | 238 |
219 void AnimationPlayer::postCommit(double timelineTime) | 239 void AnimationPlayer::postCommit(double timelineTime) |
220 { | 240 { |
241 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
242 | |
221 m_compositorPending = false; | 243 m_compositorPending = false; |
222 | 244 |
223 if (!m_compositorState || m_compositorState->pendingAction == None) | 245 if (!m_compositorState || m_compositorState->pendingAction == None) |
224 return; | 246 return; |
225 | 247 |
226 switch (m_compositorState->pendingAction) { | 248 switch (m_compositorState->pendingAction) { |
227 case Start: | 249 case Start: |
228 if (!std::isnan(m_compositorState->startTime)) { | 250 if (!std::isnan(m_compositorState->startTime)) { |
229 ASSERT(m_startTime == m_compositorState->startTime); | 251 ASSERT(m_startTime == m_compositorState->startTime); |
230 m_compositorState->pendingAction = None; | 252 m_compositorState->pendingAction = None; |
231 } | 253 } |
232 break; | 254 break; |
233 case Pause: | 255 case Pause: |
234 case PauseThenStart: | 256 case PauseThenStart: |
235 ASSERT(std::isnan(m_startTime)); | 257 ASSERT(std::isnan(m_startTime)); |
236 m_compositorState->pendingAction = None; | 258 m_compositorState->pendingAction = None; |
237 setCurrentTimeInternal((timelineTime - m_compositorState->startTime) * m _playbackRate, TimingUpdateForAnimationFrame); | 259 setCurrentTimeInternal((timelineTime - m_compositorState->startTime) * m _playbackRate, TimingUpdateForAnimationFrame); |
238 m_currentTimePending = false; | 260 m_currentTimePending = false; |
239 break; | 261 break; |
240 default: | 262 default: |
241 ASSERT_NOT_REACHED(); | 263 ASSERT_NOT_REACHED(); |
242 } | 264 } |
243 } | 265 } |
244 | 266 |
245 void AnimationPlayer::notifyCompositorStartTime(double timelineTime) | 267 void AnimationPlayer::notifyCompositorStartTime(double timelineTime) |
246 { | 268 { |
269 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
270 | |
247 if (m_compositorState) { | 271 if (m_compositorState) { |
248 ASSERT(m_compositorState->pendingAction == Start); | 272 ASSERT(m_compositorState->pendingAction == Start); |
249 ASSERT(std::isnan(m_compositorState->startTime)); | 273 ASSERT(std::isnan(m_compositorState->startTime)); |
250 | 274 |
251 double initialCompositorHoldTime = m_compositorState->holdTime; | 275 double initialCompositorHoldTime = m_compositorState->holdTime; |
252 m_compositorState->pendingAction = None; | 276 m_compositorState->pendingAction = None; |
253 m_compositorState->startTime = timelineTime; | 277 m_compositorState->startTime = timelineTime; |
254 | 278 |
255 if (paused() || m_compositorState->playbackRate != m_playbackRate || m_c ompositorState->sourceChanged) { | 279 if (paused() || m_compositorState->playbackRate != m_playbackRate || m_c ompositorState->sourceChanged) { |
256 // Paused state, playback rate, or source changed while starting. | 280 // Paused state, playback rate, or source changed while starting. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 } | 321 } |
298 | 322 |
299 double AnimationPlayer::calculateCurrentTime() const | 323 double AnimationPlayer::calculateCurrentTime() const |
300 { | 324 { |
301 ASSERT(!m_held); | 325 ASSERT(!m_held); |
302 if (isNull(m_startTime) || !m_timeline) | 326 if (isNull(m_startTime) || !m_timeline) |
303 return 0; | 327 return 0; |
304 return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate; | 328 return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate; |
305 } | 329 } |
306 | 330 |
307 void AnimationPlayer::setCurrentTime(double newCurrentTime) | |
308 { | |
309 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetCurrentT ime); | |
310 if (!std::isfinite(newCurrentTime)) | |
311 return; | |
312 | |
313 setCompositorPending(); | |
314 m_currentTimePending = false; | |
315 setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand); | |
316 } | |
317 | |
318 void AnimationPlayer::setStartTime(double startTime) | 331 void AnimationPlayer::setStartTime(double startTime) |
319 { | 332 { |
333 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
334 | |
320 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetStartTim e); | 335 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetStartTim e); |
321 if (m_paused || m_idle) | 336 if (m_paused || playStateInternal() == Idle) |
322 return; | 337 return; |
323 if (!std::isfinite(startTime)) | 338 if (!std::isfinite(startTime)) |
324 return; | 339 return; |
325 if (startTime == m_startTime) | 340 if (startTime == m_startTime) |
326 return; | 341 return; |
327 | 342 |
328 setCompositorPending(); | 343 setCompositorPending(); |
329 m_currentTimePending = false; | 344 m_currentTimePending = false; |
330 setStartTimeInternal(startTime / 1000); | 345 setStartTimeInternal(startTime / 1000); |
331 } | 346 } |
(...skipping 12 matching lines...) Expand all Loading... | |
344 // Force a new, limited, current time. | 359 // Force a new, limited, current time. |
345 m_held = false; | 360 m_held = false; |
346 double currentTime = calculateCurrentTime(); | 361 double currentTime = calculateCurrentTime(); |
347 if (m_playbackRate > 0 && currentTime > sourceEnd()) { | 362 if (m_playbackRate > 0 && currentTime > sourceEnd()) { |
348 currentTime = sourceEnd(); | 363 currentTime = sourceEnd(); |
349 } else if (m_playbackRate < 0 && currentTime < 0) { | 364 } else if (m_playbackRate < 0 && currentTime < 0) { |
350 currentTime = 0; | 365 currentTime = 0; |
351 } | 366 } |
352 setCurrentTimeInternal(currentTime, TimingUpdateOnDemand); | 367 setCurrentTimeInternal(currentTime, TimingUpdateOnDemand); |
353 } | 368 } |
369 updateCurrentTimingState(TimingUpdateOnDemand); | |
354 double newCurrentTime = currentTimeInternal(); | 370 double newCurrentTime = currentTimeInternal(); |
355 | 371 |
356 if (previousCurrentTime != newCurrentTime) { | 372 if (previousCurrentTime != newCurrentTime) { |
357 setOutdated(); | 373 setOutdated(); |
358 } else if (!hadStartTime && m_timeline) { | 374 } else if (!hadStartTime && m_timeline) { |
359 // Even though this player is not outdated, time to effect change is | 375 // Even though this player is not outdated, time to effect change is |
360 // infinity until start time is set. | 376 // infinity until start time is set. |
361 m_timeline->wake(); | 377 m_timeline->wake(); |
362 } | 378 } |
363 } | 379 } |
364 | 380 |
365 void AnimationPlayer::setSource(AnimationNode* newSource) | 381 void AnimationPlayer::setSource(AnimationNode* newSource) |
366 { | 382 { |
367 if (m_content == newSource) | 383 if (m_content == newSource) |
368 return; | 384 return; |
369 | 385 |
386 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
387 | |
370 setCompositorPending(true); | 388 setCompositorPending(true); |
371 | 389 |
372 double storedCurrentTime = currentTimeInternal(); | 390 double storedCurrentTime = currentTimeInternal(); |
373 if (m_content) | 391 if (m_content) |
374 m_content->detach(); | 392 m_content->detach(); |
375 m_content = newSource; | 393 m_content = newSource; |
376 if (newSource) { | 394 if (newSource) { |
377 // FIXME: This logic needs to be updated once groups are implemented | 395 // FIXME: This logic needs to be updated once groups are implemented |
378 if (newSource->player()) { | 396 if (newSource->player()) { |
379 newSource->player()->cancel(); | 397 newSource->player()->cancel(); |
380 newSource->player()->setSource(0); | 398 newSource->player()->setSource(0); |
381 } | 399 } |
382 newSource->attach(this); | 400 newSource->attach(this); |
383 setOutdated(); | 401 setOutdated(); |
384 } | 402 } |
385 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); | 403 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); |
386 } | 404 } |
387 | 405 |
388 String AnimationPlayer::playState() | 406 const char* AnimationPlayer::playStateString(AnimationPlayState playState) |
389 { | 407 { |
390 switch (playStateInternal()) { | 408 switch (playState) { |
391 case Idle: | 409 case Idle: |
392 return "idle"; | 410 return "idle"; |
393 case Pending: | 411 case Pending: |
394 return "pending"; | 412 return "pending"; |
395 case Running: | 413 case Running: |
396 return "running"; | 414 return "running"; |
397 case Paused: | 415 case Paused: |
398 return "paused"; | 416 return "paused"; |
399 case Finished: | 417 case Finished: |
400 return "finished"; | 418 return "finished"; |
401 default: | 419 default: |
402 ASSERT_NOT_REACHED(); | 420 ASSERT_NOT_REACHED(); |
403 return ""; | 421 return ""; |
404 } | 422 } |
405 } | 423 } |
406 | 424 |
407 AnimationPlayer::AnimationPlayState AnimationPlayer::playStateInternal() | 425 AnimationPlayer::AnimationPlayState AnimationPlayer::playStateInternal() const |
408 { | 426 { |
409 if (m_idle) | 427 return m_playState; |
428 } | |
429 | |
430 AnimationPlayer::AnimationPlayState AnimationPlayer::calculatePlayState() | |
431 { | |
432 if (m_playState == Idle) | |
410 return Idle; | 433 return Idle; |
411 if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackR ate != 0)) | 434 if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackR ate != 0)) |
412 return Pending; | 435 return Pending; |
413 if (m_paused) | 436 if (m_paused) |
414 return Paused; | 437 return Paused; |
415 if (finished()) | 438 if (finished()) |
416 return Finished; | 439 return Finished; |
417 return Running; | 440 return Running; |
418 } | 441 } |
419 | 442 |
420 void AnimationPlayer::pause() | 443 void AnimationPlayer::pause() |
421 { | 444 { |
422 if (m_paused) | 445 if (m_paused) |
423 return; | 446 return; |
447 | |
448 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
449 | |
424 if (playing()) { | 450 if (playing()) { |
425 setCompositorPending(); | 451 setCompositorPending(); |
426 m_currentTimePending = true; | 452 m_currentTimePending = true; |
427 } | 453 } |
428 m_paused = true; | 454 m_paused = true; |
429 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); | 455 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); |
430 } | 456 } |
431 | 457 |
432 void AnimationPlayer::unpause() | 458 void AnimationPlayer::unpause() |
433 { | 459 { |
434 if (!m_paused) | 460 if (!m_paused) |
435 return; | 461 return; |
462 | |
463 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
464 | |
436 setCompositorPending(); | 465 setCompositorPending(); |
437 m_currentTimePending = true; | 466 m_currentTimePending = true; |
438 unpauseInternal(); | 467 unpauseInternal(); |
439 } | 468 } |
440 | 469 |
441 void AnimationPlayer::unpauseInternal() | 470 void AnimationPlayer::unpauseInternal() |
442 { | 471 { |
443 if (!m_paused) | 472 if (!m_paused) |
444 return; | 473 return; |
445 m_paused = false; | 474 m_paused = false; |
446 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); | 475 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); |
447 } | 476 } |
448 | 477 |
449 void AnimationPlayer::play() | 478 void AnimationPlayer::play() |
450 { | 479 { |
480 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
481 | |
451 if (!playing()) | 482 if (!playing()) |
452 m_startTime = nullValue(); | 483 m_startTime = nullValue(); |
453 | 484 |
454 setCompositorPending(); | 485 setCompositorPending(); |
455 uncancel(); | 486 uncancel(); |
456 unpauseInternal(); | 487 unpauseInternal(); |
457 if (!m_content) | 488 if (!m_content) |
458 return; | 489 return; |
459 double currentTime = this->currentTimeInternal(); | 490 double currentTime = this->currentTimeInternal(); |
460 if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd())) | 491 if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd())) |
461 setCurrentTimeInternal(0, TimingUpdateOnDemand); | 492 setCurrentTimeInternal(0, TimingUpdateOnDemand); |
462 else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd( ))) | 493 else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd( ))) |
463 setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand); | 494 setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand); |
464 setFinished(false); | 495 m_finished = false; |
465 } | 496 } |
466 | 497 |
467 void AnimationPlayer::reverse() | 498 void AnimationPlayer::reverse() |
468 { | 499 { |
469 if (!m_playbackRate) { | 500 if (!m_playbackRate) { |
470 return; | 501 return; |
471 } | 502 } |
472 | 503 |
473 uncancel(); | 504 uncancel(); |
474 setPlaybackRateInternal(-m_playbackRate); | 505 setPlaybackRateInternal(-m_playbackRate); |
475 play(); | 506 play(); |
476 } | 507 } |
477 | 508 |
478 void AnimationPlayer::finish(ExceptionState& exceptionState) | 509 void AnimationPlayer::finish(ExceptionState& exceptionState) |
479 { | 510 { |
480 if (!m_playbackRate || m_idle) { | 511 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); |
512 | |
513 if (!m_playbackRate || playStateInternal() == Idle) { | |
481 return; | 514 return; |
482 } | 515 } |
483 if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infini ty()) { | 516 if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infini ty()) { |
484 exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity."); | 517 exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity."); |
485 return; | 518 return; |
486 } | 519 } |
487 if (playing()) { | 520 if (playing()) { |
488 setCompositorPending(); | 521 setCompositorPending(); |
489 } | 522 } |
490 | 523 |
(...skipping 19 matching lines...) Expand all Loading... | |
510 return ActiveDOMObject::executionContext(); | 543 return ActiveDOMObject::executionContext(); |
511 } | 544 } |
512 | 545 |
513 bool AnimationPlayer::hasPendingActivity() const | 546 bool AnimationPlayer::hasPendingActivity() const |
514 { | 547 { |
515 return m_pendingFinishedEvent || (!m_finished && hasEventListeners(EventType Names::finish)); | 548 return m_pendingFinishedEvent || (!m_finished && hasEventListeners(EventType Names::finish)); |
516 } | 549 } |
517 | 550 |
518 void AnimationPlayer::stop() | 551 void AnimationPlayer::stop() |
519 { | 552 { |
520 setFinished(true); | 553 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); |
554 | |
555 m_finished = true; | |
521 m_pendingFinishedEvent = nullptr; | 556 m_pendingFinishedEvent = nullptr; |
522 } | 557 } |
523 | 558 |
524 bool AnimationPlayer::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event) | 559 bool AnimationPlayer::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event) |
525 { | 560 { |
526 if (m_pendingFinishedEvent == event) | 561 if (m_pendingFinishedEvent == event) |
527 m_pendingFinishedEvent = nullptr; | 562 m_pendingFinishedEvent = nullptr; |
528 return EventTargetWithInlineData::dispatchEvent(event); | 563 return EventTargetWithInlineData::dispatchEvent(event); |
529 } | 564 } |
530 | 565 |
531 double AnimationPlayer::playbackRate() const | 566 double AnimationPlayer::playbackRate() const |
532 { | 567 { |
533 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetPlayback Rate); | 568 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetPlayback Rate); |
534 return m_playbackRate; | 569 return m_playbackRate; |
535 } | 570 } |
536 | 571 |
537 void AnimationPlayer::setPlaybackRate(double playbackRate) | 572 void AnimationPlayer::setPlaybackRate(double playbackRate) |
538 { | 573 { |
539 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetPlayback Rate); | 574 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetPlayback Rate); |
540 if (!std::isfinite(playbackRate)) | 575 if (!std::isfinite(playbackRate)) |
541 return; | 576 return; |
542 if (playbackRate == m_playbackRate) | 577 if (playbackRate == m_playbackRate) |
543 return; | 578 return; |
544 | 579 |
580 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); | |
581 | |
545 setPlaybackRateInternal(playbackRate); | 582 setPlaybackRateInternal(playbackRate); |
546 } | 583 } |
547 | 584 |
548 void AnimationPlayer::setPlaybackRateInternal(double playbackRate) | 585 void AnimationPlayer::setPlaybackRateInternal(double playbackRate) |
549 { | 586 { |
550 ASSERT(std::isfinite(playbackRate)); | 587 ASSERT(std::isfinite(playbackRate)); |
551 ASSERT(playbackRate != m_playbackRate); | 588 ASSERT(playbackRate != m_playbackRate); |
552 | 589 |
553 setCompositorPending(); | 590 setCompositorPending(); |
554 if (!finished() && !paused() && hasStartTime()) | 591 if (!finished() && !paused() && hasStartTime()) |
555 m_currentTimePending = true; | 592 m_currentTimePending = true; |
556 | 593 |
557 double storedCurrentTime = currentTimeInternal(); | 594 double storedCurrentTime = currentTimeInternal(); |
558 if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && play backRate <= 0)) | 595 if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && play backRate <= 0)) |
559 setFinished(false); | 596 m_finished = false; |
560 | 597 |
561 m_playbackRate = playbackRate; | 598 m_playbackRate = playbackRate; |
562 m_startTime = std::numeric_limits<double>::quiet_NaN(); | 599 m_startTime = std::numeric_limits<double>::quiet_NaN(); |
563 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); | 600 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); |
564 } | 601 } |
565 | 602 |
566 void AnimationPlayer::setOutdated() | 603 void AnimationPlayer::setOutdated() |
567 { | 604 { |
568 m_outdated = true; | 605 m_outdated = true; |
569 if (m_timeline) | 606 if (m_timeline) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
617 { | 654 { |
618 if (hasActiveAnimationsOnCompositor()) | 655 if (hasActiveAnimationsOnCompositor()) |
619 toAnimation(m_content.get())->cancelAnimationOnCompositor(); | 656 toAnimation(m_content.get())->cancelAnimationOnCompositor(); |
620 } | 657 } |
621 | 658 |
622 bool AnimationPlayer::update(TimingUpdateReason reason) | 659 bool AnimationPlayer::update(TimingUpdateReason reason) |
623 { | 660 { |
624 if (!m_timeline) | 661 if (!m_timeline) |
625 return false; | 662 return false; |
626 | 663 |
627 updateCurrentTimingState(reason); | 664 PlayStateUpdateScope updateScope(*this, reason); |
665 | |
628 m_outdated = false; | 666 m_outdated = false; |
667 bool idle = playStateInternal() == Idle; | |
629 | 668 |
630 if (m_content) { | 669 if (m_content) { |
631 double inheritedTime = m_idle || isNull(m_timeline->currentTimeInternal( )) ? nullValue() : currentTimeInternal(); | 670 double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal(); |
632 // Special case for end-exclusivity when playing backwards. | 671 // Special case for end-exclusivity when playing backwards. |
633 if (inheritedTime == 0 && m_playbackRate < 0) | 672 if (inheritedTime == 0 && m_playbackRate < 0) |
634 inheritedTime = -1; | 673 inheritedTime = -1; |
635 m_content->updateInheritedTime(inheritedTime, reason); | 674 m_content->updateInheritedTime(inheritedTime, reason); |
636 } | 675 } |
637 | 676 |
638 if ((m_idle || finished()) && !m_finished) { | 677 if ((idle || finished()) && !m_finished) { |
639 if (reason == TimingUpdateForAnimationFrame && (m_idle || hasStartTime() )) { | 678 if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) { |
640 const AtomicString& eventType = EventTypeNames::finish; | 679 const AtomicString& eventType = EventTypeNames::finish; |
641 if (executionContext() && hasEventListeners(eventType)) { | 680 if (executionContext() && hasEventListeners(eventType)) { |
642 double eventCurrentTime = currentTimeInternal() * 1000; | 681 double eventCurrentTime = currentTimeInternal() * 1000; |
643 m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); | 682 m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); |
644 m_pendingFinishedEvent->setTarget(this); | 683 m_pendingFinishedEvent->setTarget(this); |
645 m_pendingFinishedEvent->setCurrentTarget(this); | 684 m_pendingFinishedEvent->setCurrentTarget(this); |
646 m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFini shedEvent); | 685 m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFini shedEvent); |
647 } | 686 } |
648 setFinished(true); | 687 m_finished = true; |
649 } | 688 } |
650 } | 689 } |
651 ASSERT(!m_outdated); | 690 ASSERT(!m_outdated); |
652 return !m_finished; | 691 return !m_finished; |
653 } | 692 } |
654 | 693 |
655 double AnimationPlayer::timeToEffectChange() | 694 double AnimationPlayer::timeToEffectChange() |
656 { | 695 { |
657 ASSERT(!m_outdated); | 696 ASSERT(!m_outdated); |
658 if (m_held || !hasStartTime()) | 697 if (m_held || !hasStartTime()) |
659 return std::numeric_limits<double>::infinity(); | 698 return std::numeric_limits<double>::infinity(); |
660 if (!m_content) | 699 if (!m_content) |
661 return -currentTimeInternal() / m_playbackRate; | 700 return -currentTimeInternal() / m_playbackRate; |
662 if (m_playbackRate > 0) | 701 if (m_playbackRate > 0) |
663 return m_content->timeToForwardsEffectChange() / m_playbackRate; | 702 return m_content->timeToForwardsEffectChange() / m_playbackRate; |
664 return m_content->timeToReverseEffectChange() / -m_playbackRate; | 703 return m_content->timeToReverseEffectChange() / -m_playbackRate; |
665 } | 704 } |
666 | 705 |
667 void AnimationPlayer::setFinished(bool finished) | |
668 { | |
669 if (m_finished && !finished) { | |
670 if (m_content) { | |
671 TRACE_EVENT_ASYNC_BEGIN1("blink", "Animation", this, "Name", TRACE_S TR_COPY(m_content->name().utf8().data())); | |
672 } else { | |
673 TRACE_EVENT_ASYNC_BEGIN0("blink", "Animation", this); | |
674 } | |
675 } | |
676 if (!m_finished && finished) { | |
677 TRACE_EVENT_ASYNC_END0("blink", "Animation", this); | |
678 } | |
679 m_finished = finished; | |
680 } | |
681 | |
682 void AnimationPlayer::cancel() | 706 void AnimationPlayer::cancel() |
683 { | 707 { |
684 if (m_idle) | 708 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); |
709 | |
710 if (playStateInternal() == Idle) | |
685 return; | 711 return; |
686 | 712 |
687 m_holdTime = currentTimeInternal(); | 713 m_holdTime = currentTimeInternal(); |
688 m_held = true; | 714 m_held = true; |
689 m_idle = true; | 715 // TODO |
716 m_playState = Idle; | |
690 m_startTime = nullValue(); | 717 m_startTime = nullValue(); |
691 m_currentTimePending = false; | 718 m_currentTimePending = false; |
692 setCompositorPending(); | 719 setCompositorPending(); |
693 } | 720 } |
694 | 721 |
695 void AnimationPlayer::uncancel() | 722 void AnimationPlayer::uncancel() |
696 { | 723 { |
697 if (!m_idle) | 724 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); |
725 | |
726 if (playStateInternal() != Idle) | |
698 return; | 727 return; |
699 | 728 |
700 m_idle = false; | 729 // We may not go into the pending state, but setting it to something other |
730 // than Idle here will force an update. | |
731 ASSERT(isNull(m_startTime)); | |
732 m_playState = Pending; | |
701 m_held = true; | 733 m_held = true; |
702 m_holdTime = 0; | 734 m_holdTime = 0; |
703 setFinished(false); | 735 m_finished = false; |
736 } | |
737 | |
738 AnimationPlayer::PlayStateUpdateScope::PlayStateUpdateScope(AnimationPlayer& pla yer, TimingUpdateReason reason) | |
739 : m_player(player) | |
740 , m_initial(player.playStateInternal()) | |
741 { | |
742 m_player.updateCurrentTimingState(reason); | |
743 } | |
744 | |
745 AnimationPlayer::PlayStateUpdateScope::~PlayStateUpdateScope() | |
shans
2014/10/15 03:38:00
can we setCompositorPending in here too?
dstockwell
2014/10/15 08:30:04
Done, this required a few flags as it's not safe t
| |
746 { | |
747 AnimationPlayState oldPlayState = m_initial; | |
748 AnimationPlayState newPlayState = m_player.calculatePlayState(); | |
749 if (oldPlayState != newPlayState) { | |
750 bool wasActive = oldPlayState == Pending || oldPlayState == Running; | |
751 bool isActive = newPlayState == Pending || newPlayState == Running; | |
752 if (!wasActive && isActive) { | |
753 if (m_player.m_content) { | |
754 TRACE_EVENT_ASYNC_BEGIN1("blink", "Animation", &m_player, "Name" , TRACE_STR_COPY(m_player.m_content->name().utf8().data())); | |
755 } else { | |
756 TRACE_EVENT_ASYNC_BEGIN0("blink", "Animation", &m_player); | |
757 } | |
758 } else if (wasActive && !isActive) { | |
759 if (oldPlayState != Idle && oldPlayState != Finished) { | |
760 TRACE_EVENT_ASYNC_END0("blink", "Animation", &m_player); | |
761 } | |
762 } | |
763 if (isActive) { | |
764 TRACE_EVENT_ASYNC_STEP_INTO0("blink", "Animation", &m_player, playSt ateString(newPlayState)); | |
765 } | |
766 } | |
767 | |
768 m_player.m_playState = newPlayState; | |
769 | |
770 #if ENABLE(ASSERT) | |
771 // Verify that current time is up to date. | |
772 m_player.currentTimeInternal(); | |
773 #endif | |
704 } | 774 } |
705 | 775 |
706 | 776 |
707 #if !ENABLE(OILPAN) | 777 #if !ENABLE(OILPAN) |
708 bool AnimationPlayer::canFree() const | 778 bool AnimationPlayer::canFree() const |
709 { | 779 { |
710 ASSERT(m_content); | 780 ASSERT(m_content); |
711 return hasOneRef() && m_content->isAnimation() && m_content->hasOneRef(); | 781 return hasOneRef() && m_content->isAnimation() && m_content->hasOneRef(); |
712 } | 782 } |
713 #endif | 783 #endif |
(...skipping 17 matching lines...) Expand all Loading... | |
731 | 801 |
732 void AnimationPlayer::trace(Visitor* visitor) | 802 void AnimationPlayer::trace(Visitor* visitor) |
733 { | 803 { |
734 visitor->trace(m_content); | 804 visitor->trace(m_content); |
735 visitor->trace(m_timeline); | 805 visitor->trace(m_timeline); |
736 visitor->trace(m_pendingFinishedEvent); | 806 visitor->trace(m_pendingFinishedEvent); |
737 EventTargetWithInlineData::trace(visitor); | 807 EventTargetWithInlineData::trace(visitor); |
738 } | 808 } |
739 | 809 |
740 } // namespace | 810 } // namespace |
OLD | NEW |