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

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: Don't set compositor pending when paused for testing 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
« no previous file with comments | « Source/core/animation/AnimationPlayer.h ('k') | Source/core/animation/AnimationPlayerTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 m_currentTimePending = false;
118 setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand);
119 }
120
109 void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime, TimingUpdate Reason reason) 121 void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime, TimingUpdate Reason reason)
110 { 122 {
111 ASSERT(std::isfinite(newCurrentTime)); 123 ASSERT(std::isfinite(newCurrentTime));
112 124
113 bool oldHeld = m_held; 125 bool oldHeld = m_held;
114 bool outdated = false; 126 bool outdated = false;
115 bool isLimited = limited(newCurrentTime); 127 bool isLimited = limited(newCurrentTime);
116 m_held = m_paused || !m_playbackRate || isLimited || std::isnan(m_startTime) ; 128 m_held = m_paused || !m_playbackRate || isLimited || std::isnan(m_startTime) ;
117 if (m_held) { 129 if (m_held) {
118 if (!oldHeld || m_holdTime != newCurrentTime) 130 if (!oldHeld || m_holdTime != newCurrentTime)
119 outdated = true; 131 outdated = true;
120 m_holdTime = newCurrentTime; 132 m_holdTime = newCurrentTime;
121 if (m_paused || !m_playbackRate) { 133 if (m_paused || !m_playbackRate) {
122 m_startTime = nullValue(); 134 m_startTime = nullValue();
123 } else if (isLimited && std::isnan(m_startTime) && reason == TimingUpdat eForAnimationFrame) { 135 } else if (isLimited && std::isnan(m_startTime) && reason == TimingUpdat eForAnimationFrame) {
124 m_startTime = calculateStartTime(newCurrentTime); 136 m_startTime = calculateStartTime(newCurrentTime);
125 } 137 }
126 } else { 138 } else {
127 m_holdTime = nullValue(); 139 m_holdTime = nullValue();
128 m_startTime = calculateStartTime(newCurrentTime); 140 m_startTime = calculateStartTime(newCurrentTime);
129 setFinished(false); 141 m_finished = false;
130 outdated = true; 142 outdated = true;
131 } 143 }
132 144
133 if (outdated) { 145 if (outdated) {
134 setOutdated(); 146 setOutdated();
135 } 147 }
136 } 148 }
137 149
138 // Update timing to reflect updated animation clock due to tick 150 // Update timing to reflect updated animation clock due to tick
139 void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason) 151 void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason)
(...skipping 23 matching lines...) Expand all
163 175
164 double AnimationPlayer::currentTime(bool& isNull) 176 double AnimationPlayer::currentTime(bool& isNull)
165 { 177 {
166 double result = currentTime(); 178 double result = currentTime();
167 isNull = std::isnan(result); 179 isNull = std::isnan(result);
168 return result; 180 return result;
169 } 181 }
170 182
171 double AnimationPlayer::currentTime() 183 double AnimationPlayer::currentTime()
172 { 184 {
185 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
186
173 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetCurrentT ime); 187 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetCurrentT ime);
174 if (m_currentTimePending || m_idle) 188 if (m_currentTimePending || playStateInternal() == Idle)
175 return std::numeric_limits<double>::quiet_NaN(); 189 return std::numeric_limits<double>::quiet_NaN();
190
176 return currentTimeInternal() * 1000; 191 return currentTimeInternal() * 1000;
177 } 192 }
178 193
179 double AnimationPlayer::currentTimeInternal() 194 double AnimationPlayer::currentTimeInternal() const
180 { 195 {
181 updateCurrentTimingState(TimingUpdateOnDemand); 196 double result = m_held ? m_holdTime : calculateCurrentTime();
182 if (m_held) 197 #if ENABLE(ASSERT)
183 return m_holdTime; 198 const_cast<AnimationPlayer*>(this)->updateCurrentTimingState(TimingUpdateOnD emand);
184 return calculateCurrentTime(); 199 ASSERT(result == (m_held ? m_holdTime : calculateCurrentTime()));
200 #endif
201 return result;
185 } 202 }
186 203
187 void AnimationPlayer::preCommit(bool startOnCompositor) 204 void AnimationPlayer::preCommit(bool startOnCompositor)
188 { 205 {
189 if (m_compositorState && m_compositorState->pendingAction == Start) { 206 if (m_compositorState && m_compositorState->pendingAction == Start) {
190 // Still waiting for a start time. 207 // Still waiting for a start time.
191 return; 208 return;
192 } 209 }
193 210
211 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompos itorPending);
212
194 bool softChange = m_compositorState && (paused() || m_compositorState->playb ackRate != m_playbackRate); 213 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))); 214 bool hardChange = m_compositorState && (m_compositorState->sourceChanged || (m_compositorState->startTime != m_startTime && !std::isnan(m_compositorState->s tartTime) && !std::isnan(m_startTime)));
196 215
197 // FIXME: softChange && !hardChange should generate a Pause/ThenStart, 216 // FIXME: softChange && !hardChange should generate a Pause/ThenStart,
198 // not a Cancel, but we can't communicate these to the compositor yet. 217 // not a Cancel, but we can't communicate these to the compositor yet.
199 218
200 bool changed = softChange || hardChange; 219 bool changed = softChange || hardChange;
201 bool shouldCancel = (!playing() && m_compositorState) || changed; 220 bool shouldCancel = (!playing() && m_compositorState) || changed;
202 bool shouldStart = playing() && (!m_compositorState || changed); 221 bool shouldStart = playing() && (!m_compositorState || changed);
203 222
204 if (shouldCancel) { 223 if (shouldCancel) {
205 cancelAnimationOnCompositor(); 224 cancelAnimationOnCompositor();
206 m_compositorState = nullptr; 225 m_compositorState = nullptr;
207
208 } 226 }
209 227
210 if (!shouldStart) { 228 if (!shouldStart) {
211 m_currentTimePending = false; 229 m_currentTimePending = false;
212 } 230 }
213 231
214 if (shouldStart && startOnCompositor && maybeStartAnimationOnCompositor()) { 232 if (shouldStart && startOnCompositor && maybeStartAnimationOnCompositor()) {
215 m_compositorState = adoptPtr(new CompositorState(*this)); 233 m_compositorState = adoptPtr(new CompositorState(*this));
216 } 234 }
217 } 235 }
218 236
219 void AnimationPlayer::postCommit(double timelineTime) 237 void AnimationPlayer::postCommit(double timelineTime)
220 { 238 {
239 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompos itorPending);
240
221 m_compositorPending = false; 241 m_compositorPending = false;
222 242
223 if (!m_compositorState || m_compositorState->pendingAction == None) 243 if (!m_compositorState || m_compositorState->pendingAction == None)
224 return; 244 return;
225 245
226 switch (m_compositorState->pendingAction) { 246 switch (m_compositorState->pendingAction) {
227 case Start: 247 case Start:
228 if (!std::isnan(m_compositorState->startTime)) { 248 if (!std::isnan(m_compositorState->startTime)) {
229 ASSERT(m_startTime == m_compositorState->startTime); 249 ASSERT(m_startTime == m_compositorState->startTime);
230 m_compositorState->pendingAction = None; 250 m_compositorState->pendingAction = None;
231 } 251 }
232 break; 252 break;
233 case Pause: 253 case Pause:
234 case PauseThenStart: 254 case PauseThenStart:
235 ASSERT(std::isnan(m_startTime)); 255 ASSERT(std::isnan(m_startTime));
236 m_compositorState->pendingAction = None; 256 m_compositorState->pendingAction = None;
237 setCurrentTimeInternal((timelineTime - m_compositorState->startTime) * m _playbackRate, TimingUpdateForAnimationFrame); 257 setCurrentTimeInternal((timelineTime - m_compositorState->startTime) * m _playbackRate, TimingUpdateForAnimationFrame);
238 m_currentTimePending = false; 258 m_currentTimePending = false;
239 break; 259 break;
240 default: 260 default:
241 ASSERT_NOT_REACHED(); 261 ASSERT_NOT_REACHED();
242 } 262 }
243 } 263 }
244 264
245 void AnimationPlayer::notifyCompositorStartTime(double timelineTime) 265 void AnimationPlayer::notifyCompositorStartTime(double timelineTime)
246 { 266 {
267 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
268
247 if (m_compositorState) { 269 if (m_compositorState) {
248 ASSERT(m_compositorState->pendingAction == Start); 270 ASSERT(m_compositorState->pendingAction == Start);
249 ASSERT(std::isnan(m_compositorState->startTime)); 271 ASSERT(std::isnan(m_compositorState->startTime));
250 272
251 double initialCompositorHoldTime = m_compositorState->holdTime; 273 double initialCompositorHoldTime = m_compositorState->holdTime;
252 m_compositorState->pendingAction = None; 274 m_compositorState->pendingAction = None;
253 m_compositorState->startTime = timelineTime; 275 m_compositorState->startTime = timelineTime;
254 276
255 if (paused() || m_compositorState->playbackRate != m_playbackRate || m_c ompositorState->sourceChanged) {
256 // Paused state, playback rate, or source changed while starting.
257 setCompositorPending();
258 }
259
260 if (m_startTime == timelineTime) { 277 if (m_startTime == timelineTime) {
261 // The start time was set to the incoming compositor start time. 278 // The start time was set to the incoming compositor start time.
262 // Unlikely, but possible. 279 // Unlikely, but possible.
263 // FIXME: Depending on what changed above this might still be pendin g. 280 // FIXME: Depending on what changed above this might still be pendin g.
264 // Maybe... 281 // Maybe...
265 m_currentTimePending = false; 282 m_currentTimePending = false;
266 return; 283 return;
267 } 284 }
268 285
269 if (!std::isnan(m_startTime) || currentTimeInternal() != initialComposit orHoldTime) { 286 if (!std::isnan(m_startTime) || currentTimeInternal() != initialComposit orHoldTime) {
270 // A new start time or current time was set while starting. 287 // A new start time or current time was set while starting.
271 setCompositorPending(); 288 setCompositorPending(true);
272 return; 289 return;
273 } 290 }
274 } 291 }
275 292
293 notifyStartTime(timelineTime);
294 }
295
296 void AnimationPlayer::notifyStartTime(double timelineTime)
297 {
276 if (playing()) { 298 if (playing()) {
277 ASSERT(std::isnan(m_startTime)); 299 ASSERT(std::isnan(m_startTime));
278 ASSERT(m_held); 300 ASSERT(m_held);
279 301
280 if (m_playbackRate == 0) { 302 if (m_playbackRate == 0) {
281 setStartTimeInternal(timelineTime); 303 setStartTimeInternal(timelineTime);
282 } else { 304 } else {
283 setStartTimeInternal(timelineTime + currentTimeInternal() / -m_playb ackRate); 305 setStartTimeInternal(timelineTime + currentTimeInternal() / -m_playb ackRate);
284 } 306 }
285 307
(...skipping 11 matching lines...) Expand all
297 } 319 }
298 320
299 double AnimationPlayer::calculateCurrentTime() const 321 double AnimationPlayer::calculateCurrentTime() const
300 { 322 {
301 ASSERT(!m_held); 323 ASSERT(!m_held);
302 if (isNull(m_startTime) || !m_timeline) 324 if (isNull(m_startTime) || !m_timeline)
303 return 0; 325 return 0;
304 return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate; 326 return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate;
305 } 327 }
306 328
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) 329 void AnimationPlayer::setStartTime(double startTime)
319 { 330 {
331 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
332
320 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetStartTim e); 333 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetStartTim e);
321 if (m_paused || m_idle) 334 if (m_paused || playStateInternal() == Idle)
322 return; 335 return;
323 if (!std::isfinite(startTime)) 336 if (!std::isfinite(startTime))
324 return; 337 return;
325 if (startTime == m_startTime) 338 if (startTime == m_startTime)
326 return; 339 return;
327 340
328 setCompositorPending();
329 m_currentTimePending = false; 341 m_currentTimePending = false;
330 setStartTimeInternal(startTime / 1000); 342 setStartTimeInternal(startTime / 1000);
331 } 343 }
332 344
333 void AnimationPlayer::setStartTimeInternal(double newStartTime) 345 void AnimationPlayer::setStartTimeInternal(double newStartTime)
334 { 346 {
335 ASSERT(!m_paused); 347 ASSERT(!m_paused);
336 ASSERT(std::isfinite(newStartTime)); 348 ASSERT(std::isfinite(newStartTime));
337 ASSERT(newStartTime != m_startTime); 349 ASSERT(newStartTime != m_startTime);
338 350
339 bool hadStartTime = hasStartTime(); 351 bool hadStartTime = hasStartTime();
340 double previousCurrentTime = currentTimeInternal(); 352 double previousCurrentTime = currentTimeInternal();
341 m_startTime = newStartTime; 353 m_startTime = newStartTime;
342 if (m_held && m_playbackRate) { 354 if (m_held && m_playbackRate) {
343 // If held, the start time would still be derrived from the hold time. 355 // If held, the start time would still be derrived from the hold time.
344 // Force a new, limited, current time. 356 // Force a new, limited, current time.
345 m_held = false; 357 m_held = false;
346 double currentTime = calculateCurrentTime(); 358 double currentTime = calculateCurrentTime();
347 if (m_playbackRate > 0 && currentTime > sourceEnd()) { 359 if (m_playbackRate > 0 && currentTime > sourceEnd()) {
348 currentTime = sourceEnd(); 360 currentTime = sourceEnd();
349 } else if (m_playbackRate < 0 && currentTime < 0) { 361 } else if (m_playbackRate < 0 && currentTime < 0) {
350 currentTime = 0; 362 currentTime = 0;
351 } 363 }
352 setCurrentTimeInternal(currentTime, TimingUpdateOnDemand); 364 setCurrentTimeInternal(currentTime, TimingUpdateOnDemand);
353 } 365 }
366 updateCurrentTimingState(TimingUpdateOnDemand);
354 double newCurrentTime = currentTimeInternal(); 367 double newCurrentTime = currentTimeInternal();
355 368
356 if (previousCurrentTime != newCurrentTime) { 369 if (previousCurrentTime != newCurrentTime) {
357 setOutdated(); 370 setOutdated();
358 } else if (!hadStartTime && m_timeline) { 371 } else if (!hadStartTime && m_timeline) {
359 // Even though this player is not outdated, time to effect change is 372 // Even though this player is not outdated, time to effect change is
360 // infinity until start time is set. 373 // infinity until start time is set.
361 m_timeline->wake(); 374 m_timeline->wake();
362 } 375 }
363 } 376 }
364 377
365 void AnimationPlayer::setSource(AnimationNode* newSource) 378 void AnimationPlayer::setSource(AnimationNode* newSource)
366 { 379 {
367 if (m_content == newSource) 380 if (m_content == newSource)
368 return; 381 return;
369 382
370 setCompositorPending(true); 383 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, SetCompositorP endingWithSourceChanged);
371 384
372 double storedCurrentTime = currentTimeInternal(); 385 double storedCurrentTime = currentTimeInternal();
373 if (m_content) 386 if (m_content)
374 m_content->detach(); 387 m_content->detach();
375 m_content = newSource; 388 m_content = newSource;
376 if (newSource) { 389 if (newSource) {
377 // FIXME: This logic needs to be updated once groups are implemented 390 // FIXME: This logic needs to be updated once groups are implemented
378 if (newSource->player()) { 391 if (newSource->player()) {
379 newSource->player()->cancel(); 392 newSource->player()->cancel();
380 newSource->player()->setSource(0); 393 newSource->player()->setSource(0);
381 } 394 }
382 newSource->attach(this); 395 newSource->attach(this);
383 setOutdated(); 396 setOutdated();
384 } 397 }
385 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); 398 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
386 } 399 }
387 400
388 String AnimationPlayer::playState() 401 const char* AnimationPlayer::playStateString(AnimationPlayState playState)
389 { 402 {
390 switch (playStateInternal()) { 403 switch (playState) {
391 case Idle: 404 case Idle:
392 return "idle"; 405 return "idle";
393 case Pending: 406 case Pending:
394 return "pending"; 407 return "pending";
395 case Running: 408 case Running:
396 return "running"; 409 return "running";
397 case Paused: 410 case Paused:
398 return "paused"; 411 return "paused";
399 case Finished: 412 case Finished:
400 return "finished"; 413 return "finished";
401 default: 414 default:
402 ASSERT_NOT_REACHED(); 415 ASSERT_NOT_REACHED();
403 return ""; 416 return "";
404 } 417 }
405 } 418 }
406 419
407 AnimationPlayer::AnimationPlayState AnimationPlayer::playStateInternal() 420 AnimationPlayer::AnimationPlayState AnimationPlayer::playStateInternal() const
408 { 421 {
409 if (m_idle) 422 return m_playState;
423 }
424
425 AnimationPlayer::AnimationPlayState AnimationPlayer::calculatePlayState()
426 {
427 if (m_playState == Idle)
410 return Idle; 428 return Idle;
411 if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackR ate != 0)) 429 if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackR ate != 0))
412 return Pending; 430 return Pending;
413 if (m_paused) 431 if (m_paused)
414 return Paused; 432 return Paused;
415 if (finished()) 433 if (finished())
416 return Finished; 434 return Finished;
417 return Running; 435 return Running;
418 } 436 }
419 437
420 void AnimationPlayer::pause() 438 void AnimationPlayer::pause()
421 { 439 {
422 if (m_paused) 440 if (m_paused)
423 return; 441 return;
442
443 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
444
424 if (playing()) { 445 if (playing()) {
425 setCompositorPending();
426 m_currentTimePending = true; 446 m_currentTimePending = true;
427 } 447 }
428 m_paused = true; 448 m_paused = true;
429 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); 449 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
430 } 450 }
431 451
432 void AnimationPlayer::unpause() 452 void AnimationPlayer::unpause()
433 { 453 {
434 if (!m_paused) 454 if (!m_paused)
435 return; 455 return;
436 setCompositorPending(); 456
457 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
458
437 m_currentTimePending = true; 459 m_currentTimePending = true;
438 unpauseInternal(); 460 unpauseInternal();
439 } 461 }
440 462
441 void AnimationPlayer::unpauseInternal() 463 void AnimationPlayer::unpauseInternal()
442 { 464 {
443 if (!m_paused) 465 if (!m_paused)
444 return; 466 return;
445 m_paused = false; 467 m_paused = false;
446 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand); 468 setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
447 } 469 }
448 470
449 void AnimationPlayer::play() 471 void AnimationPlayer::play()
450 { 472 {
473 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
474
451 if (!playing()) 475 if (!playing())
452 m_startTime = nullValue(); 476 m_startTime = nullValue();
453 477
454 setCompositorPending();
455 uncancel(); 478 uncancel();
456 unpauseInternal(); 479 unpauseInternal();
457 if (!m_content) 480 if (!m_content)
458 return; 481 return;
459 double currentTime = this->currentTimeInternal(); 482 double currentTime = this->currentTimeInternal();
460 if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd())) 483 if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd()))
461 setCurrentTimeInternal(0, TimingUpdateOnDemand); 484 setCurrentTimeInternal(0, TimingUpdateOnDemand);
462 else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd( ))) 485 else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd( )))
463 setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand); 486 setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
464 setFinished(false); 487 m_finished = false;
465 } 488 }
466 489
467 void AnimationPlayer::reverse() 490 void AnimationPlayer::reverse()
468 { 491 {
469 if (!m_playbackRate) { 492 if (!m_playbackRate) {
470 return; 493 return;
471 } 494 }
472 495
473 uncancel(); 496 uncancel();
474 setPlaybackRateInternal(-m_playbackRate); 497 setPlaybackRateInternal(-m_playbackRate);
475 play(); 498 play();
476 } 499 }
477 500
478 void AnimationPlayer::finish(ExceptionState& exceptionState) 501 void AnimationPlayer::finish(ExceptionState& exceptionState)
479 { 502 {
480 if (!m_playbackRate || m_idle) { 503 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
504
505 if (!m_playbackRate || playStateInternal() == Idle) {
481 return; 506 return;
482 } 507 }
483 if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infini ty()) { 508 if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infini ty()) {
484 exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity."); 509 exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity.");
485 return; 510 return;
486 } 511 }
487 if (playing()) {
488 setCompositorPending();
489 }
490 512
491 uncancel(); 513 uncancel();
492 514
493 double newCurrentTime = m_playbackRate < 0 ? 0 : sourceEnd(); 515 double newCurrentTime = m_playbackRate < 0 ? 0 : sourceEnd();
494 setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand); 516 setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand);
495 if (!paused()) { 517 if (!paused()) {
496 m_startTime = calculateStartTime(newCurrentTime); 518 m_startTime = calculateStartTime(newCurrentTime);
497 } 519 }
498 520
499 m_currentTimePending = false; 521 m_currentTimePending = false;
(...skipping 10 matching lines...) Expand all
510 return ActiveDOMObject::executionContext(); 532 return ActiveDOMObject::executionContext();
511 } 533 }
512 534
513 bool AnimationPlayer::hasPendingActivity() const 535 bool AnimationPlayer::hasPendingActivity() const
514 { 536 {
515 return m_pendingFinishedEvent || (!m_finished && hasEventListeners(EventType Names::finish)); 537 return m_pendingFinishedEvent || (!m_finished && hasEventListeners(EventType Names::finish));
516 } 538 }
517 539
518 void AnimationPlayer::stop() 540 void AnimationPlayer::stop()
519 { 541 {
520 setFinished(true); 542 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
543
544 m_finished = true;
521 m_pendingFinishedEvent = nullptr; 545 m_pendingFinishedEvent = nullptr;
522 } 546 }
523 547
524 bool AnimationPlayer::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event) 548 bool AnimationPlayer::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
525 { 549 {
526 if (m_pendingFinishedEvent == event) 550 if (m_pendingFinishedEvent == event)
527 m_pendingFinishedEvent = nullptr; 551 m_pendingFinishedEvent = nullptr;
528 return EventTargetWithInlineData::dispatchEvent(event); 552 return EventTargetWithInlineData::dispatchEvent(event);
529 } 553 }
530 554
531 double AnimationPlayer::playbackRate() const 555 double AnimationPlayer::playbackRate() const
532 { 556 {
533 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetPlayback Rate); 557 UseCounter::count(executionContext(), UseCounter::AnimationPlayerGetPlayback Rate);
534 return m_playbackRate; 558 return m_playbackRate;
535 } 559 }
536 560
537 void AnimationPlayer::setPlaybackRate(double playbackRate) 561 void AnimationPlayer::setPlaybackRate(double playbackRate)
538 { 562 {
539 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetPlayback Rate); 563 UseCounter::count(executionContext(), UseCounter::AnimationPlayerSetPlayback Rate);
540 if (!std::isfinite(playbackRate)) 564 if (!std::isfinite(playbackRate))
541 return; 565 return;
542 if (playbackRate == m_playbackRate) 566 if (playbackRate == m_playbackRate)
543 return; 567 return;
544 568
569 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
570
545 setPlaybackRateInternal(playbackRate); 571 setPlaybackRateInternal(playbackRate);
546 } 572 }
547 573
548 void AnimationPlayer::setPlaybackRateInternal(double playbackRate) 574 void AnimationPlayer::setPlaybackRateInternal(double playbackRate)
549 { 575 {
550 ASSERT(std::isfinite(playbackRate)); 576 ASSERT(std::isfinite(playbackRate));
551 ASSERT(playbackRate != m_playbackRate); 577 ASSERT(playbackRate != m_playbackRate);
552 578
553 setCompositorPending();
554 if (!finished() && !paused() && hasStartTime()) 579 if (!finished() && !paused() && hasStartTime())
555 m_currentTimePending = true; 580 m_currentTimePending = true;
556 581
557 double storedCurrentTime = currentTimeInternal(); 582 double storedCurrentTime = currentTimeInternal();
558 if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && play backRate <= 0)) 583 if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && play backRate <= 0))
559 setFinished(false); 584 m_finished = false;
560 585
561 m_playbackRate = playbackRate; 586 m_playbackRate = playbackRate;
562 m_startTime = std::numeric_limits<double>::quiet_NaN(); 587 m_startTime = std::numeric_limits<double>::quiet_NaN();
563 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); 588 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
564 } 589 }
565 590
566 void AnimationPlayer::setOutdated() 591 void AnimationPlayer::setOutdated()
567 { 592 {
568 m_outdated = true; 593 m_outdated = true;
569 if (m_timeline) 594 if (m_timeline)
(...skipping 20 matching lines...) Expand all
590 } 615 }
591 return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(startTi me, timeOffset, m_playbackRate); 616 return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(startTi me, timeOffset, m_playbackRate);
592 } 617 }
593 618
594 void AnimationPlayer::setCompositorPending(bool sourceChanged) 619 void AnimationPlayer::setCompositorPending(bool sourceChanged)
595 { 620 {
596 // FIXME: Animation could notify this directly? 621 // FIXME: Animation could notify this directly?
597 if (!hasActiveAnimationsOnCompositor()) { 622 if (!hasActiveAnimationsOnCompositor()) {
598 m_compositorState.release(); 623 m_compositorState.release();
599 } 624 }
600 if (!m_compositorPending) { 625 if (sourceChanged && m_compositorState) {
626 m_compositorState->sourceChanged = true;
627 }
628 if (m_compositorPending || m_isPausedForTesting) {
629 return;
630 }
631
632 if (sourceChanged || !m_compositorState
633 || !playing() || m_compositorState->playbackRate != m_playbackRate
634 || m_compositorState->startTime != m_startTime) {
601 m_compositorPending = true; 635 m_compositorPending = true;
602 if (sourceChanged && m_compositorState)
603 m_compositorState->sourceChanged = true;
604 timeline()->document()->compositorPendingAnimations().add(this); 636 timeline()->document()->compositorPendingAnimations().add(this);
605 } 637 }
606 } 638 }
607 639
608 bool AnimationPlayer::hasActiveAnimationsOnCompositor() 640 bool AnimationPlayer::hasActiveAnimationsOnCompositor()
609 { 641 {
610 if (!m_content || !m_content->isAnimation()) 642 if (!m_content || !m_content->isAnimation())
611 return false; 643 return false;
612 644
613 return toAnimation(m_content.get())->hasActiveAnimationsOnCompositor(); 645 return toAnimation(m_content.get())->hasActiveAnimationsOnCompositor();
614 } 646 }
615 647
616 void AnimationPlayer::cancelAnimationOnCompositor() 648 void AnimationPlayer::cancelAnimationOnCompositor()
617 { 649 {
618 if (hasActiveAnimationsOnCompositor()) 650 if (hasActiveAnimationsOnCompositor())
619 toAnimation(m_content.get())->cancelAnimationOnCompositor(); 651 toAnimation(m_content.get())->cancelAnimationOnCompositor();
620 } 652 }
621 653
622 bool AnimationPlayer::update(TimingUpdateReason reason) 654 bool AnimationPlayer::update(TimingUpdateReason reason)
623 { 655 {
624 if (!m_timeline) 656 if (!m_timeline)
625 return false; 657 return false;
626 658
627 updateCurrentTimingState(reason); 659 PlayStateUpdateScope updateScope(*this, reason, DoNotSetCompositorPending);
660
628 m_outdated = false; 661 m_outdated = false;
662 bool idle = playStateInternal() == Idle;
629 663
630 if (m_content) { 664 if (m_content) {
631 double inheritedTime = m_idle || isNull(m_timeline->currentTimeInternal( )) ? nullValue() : currentTimeInternal(); 665 double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal();
632 // Special case for end-exclusivity when playing backwards. 666 // Special case for end-exclusivity when playing backwards.
633 if (inheritedTime == 0 && m_playbackRate < 0) 667 if (inheritedTime == 0 && m_playbackRate < 0)
634 inheritedTime = -1; 668 inheritedTime = -1;
635 m_content->updateInheritedTime(inheritedTime, reason); 669 m_content->updateInheritedTime(inheritedTime, reason);
636 } 670 }
637 671
638 if ((m_idle || finished()) && !m_finished) { 672 if ((idle || finished()) && !m_finished) {
639 if (reason == TimingUpdateForAnimationFrame && (m_idle || hasStartTime() )) { 673 if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) {
640 const AtomicString& eventType = EventTypeNames::finish; 674 const AtomicString& eventType = EventTypeNames::finish;
641 if (executionContext() && hasEventListeners(eventType)) { 675 if (executionContext() && hasEventListeners(eventType)) {
642 double eventCurrentTime = currentTimeInternal() * 1000; 676 double eventCurrentTime = currentTimeInternal() * 1000;
643 m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); 677 m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime());
644 m_pendingFinishedEvent->setTarget(this); 678 m_pendingFinishedEvent->setTarget(this);
645 m_pendingFinishedEvent->setCurrentTarget(this); 679 m_pendingFinishedEvent->setCurrentTarget(this);
646 m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFini shedEvent); 680 m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFini shedEvent);
647 } 681 }
648 setFinished(true); 682 m_finished = true;
649 } 683 }
650 } 684 }
651 ASSERT(!m_outdated); 685 ASSERT(!m_outdated);
652 return !m_finished; 686 return !m_finished;
653 } 687 }
654 688
655 double AnimationPlayer::timeToEffectChange() 689 double AnimationPlayer::timeToEffectChange()
656 { 690 {
657 ASSERT(!m_outdated); 691 ASSERT(!m_outdated);
658 if (m_held || !hasStartTime()) 692 if (m_held || !hasStartTime())
659 return std::numeric_limits<double>::infinity(); 693 return std::numeric_limits<double>::infinity();
660 if (!m_content) 694 if (!m_content)
661 return -currentTimeInternal() / m_playbackRate; 695 return -currentTimeInternal() / m_playbackRate;
662 if (m_playbackRate > 0) 696 if (m_playbackRate > 0)
663 return m_content->timeToForwardsEffectChange() / m_playbackRate; 697 return m_content->timeToForwardsEffectChange() / m_playbackRate;
664 return m_content->timeToReverseEffectChange() / -m_playbackRate; 698 return m_content->timeToReverseEffectChange() / -m_playbackRate;
665 } 699 }
666 700
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() 701 void AnimationPlayer::cancel()
683 { 702 {
684 if (m_idle) 703 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
704
705 if (playStateInternal() == Idle)
685 return; 706 return;
686 707
687 m_holdTime = currentTimeInternal(); 708 m_holdTime = currentTimeInternal();
688 m_held = true; 709 m_held = true;
689 m_idle = true; 710 // TODO
711 m_playState = Idle;
690 m_startTime = nullValue(); 712 m_startTime = nullValue();
691 m_currentTimePending = false; 713 m_currentTimePending = false;
692 setCompositorPending();
693 } 714 }
694 715
695 void AnimationPlayer::uncancel() 716 void AnimationPlayer::uncancel()
696 { 717 {
697 if (!m_idle) 718 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
719
720 if (playStateInternal() != Idle)
698 return; 721 return;
699 722
700 m_idle = false; 723 // We may not go into the pending state, but setting it to something other
724 // than Idle here will force an update.
725 ASSERT(isNull(m_startTime));
726 m_playState = Pending;
701 m_held = true; 727 m_held = true;
702 m_holdTime = 0; 728 m_holdTime = 0;
703 setFinished(false); 729 m_finished = false;
730 }
731
732 AnimationPlayer::PlayStateUpdateScope::PlayStateUpdateScope(AnimationPlayer& pla yer, TimingUpdateReason reason, CompositorPendingChange compositorPendingChange)
733 : m_player(player)
734 , m_initial(player.playStateInternal())
735 , m_compositorPendingChange(compositorPendingChange)
736 {
737 m_player.updateCurrentTimingState(reason);
738 }
739
740 AnimationPlayer::PlayStateUpdateScope::~PlayStateUpdateScope()
741 {
742 AnimationPlayState oldPlayState = m_initial;
743 AnimationPlayState newPlayState = m_player.calculatePlayState();
744 if (oldPlayState != newPlayState) {
745 bool wasActive = oldPlayState == Pending || oldPlayState == Running;
746 bool isActive = newPlayState == Pending || newPlayState == Running;
747 if (!wasActive && isActive) {
748 if (m_player.m_content) {
749 TRACE_EVENT_ASYNC_BEGIN1("blink", "Animation", &m_player, "Name" , TRACE_STR_COPY(m_player.m_content->name().utf8().data()));
750 } else {
751 TRACE_EVENT_ASYNC_BEGIN0("blink", "Animation", &m_player);
752 }
753 } else if (wasActive && !isActive) {
754 if (oldPlayState != Idle && oldPlayState != Finished) {
755 TRACE_EVENT_ASYNC_END0("blink", "Animation", &m_player);
756 }
757 }
758 if (isActive) {
759 TRACE_EVENT_ASYNC_STEP_INTO0("blink", "Animation", &m_player, playSt ateString(newPlayState));
760 }
761 }
762
763 m_player.m_playState = newPlayState;
764
765 #if ENABLE(ASSERT)
766 // Verify that current time is up to date.
767 m_player.currentTimeInternal();
768 #endif
769
770 switch (m_compositorPendingChange) {
771 case SetCompositorPending:
772 m_player.setCompositorPending();
773 break;
774 case SetCompositorPendingWithSourceChanged:
775 m_player.setCompositorPending(true);
776 break;
777 case DoNotSetCompositorPending:
778 break;
779 default:
780 ASSERT_NOT_REACHED();
781 break;
782 }
704 } 783 }
705 784
706 785
707 #if !ENABLE(OILPAN) 786 #if !ENABLE(OILPAN)
708 bool AnimationPlayer::canFree() const 787 bool AnimationPlayer::canFree() const
709 { 788 {
710 ASSERT(m_content); 789 ASSERT(m_content);
711 return hasOneRef() && m_content->isAnimation() && m_content->hasOneRef(); 790 return hasOneRef() && m_content->isAnimation() && m_content->hasOneRef();
712 } 791 }
713 #endif 792 #endif
(...skipping 17 matching lines...) Expand all
731 810
732 void AnimationPlayer::trace(Visitor* visitor) 811 void AnimationPlayer::trace(Visitor* visitor)
733 { 812 {
734 visitor->trace(m_content); 813 visitor->trace(m_content);
735 visitor->trace(m_timeline); 814 visitor->trace(m_timeline);
736 visitor->trace(m_pendingFinishedEvent); 815 visitor->trace(m_pendingFinishedEvent);
737 EventTargetWithInlineData::trace(visitor); 816 EventTargetWithInlineData::trace(visitor);
738 } 817 }
739 818
740 } // namespace 819 } // namespace
OLDNEW
« no previous file with comments | « Source/core/animation/AnimationPlayer.h ('k') | Source/core/animation/AnimationPlayerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698