Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: Source/core/animation/AnimationPlayer.cpp

Issue 638313002: Web Animations: Overhaul and trace play state in AnimationPlayer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove stray printf. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698