Chromium Code Reviews| 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 |