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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 249 |
250 #if !ENABLE(ASSERT) | 250 #if !ENABLE(ASSERT) |
251 // If we're in an animation style change, no animations can have started, be
en cancelled or changed play state. | 251 // If we're in an animation style change, no animations can have started, be
en cancelled or changed play state. |
252 // When ASSERT is enabled, we verify this optimization. | 252 // When ASSERT is enabled, we verify this optimization. |
253 if (activeAnimations && activeAnimations->isAnimationStyleChange()) | 253 if (activeAnimations && activeAnimations->isAnimationStyleChange()) |
254 return; | 254 return; |
255 #endif | 255 #endif |
256 | 256 |
257 const CSSAnimationData* animationData = style.animations(); | 257 const CSSAnimationData* animationData = style.animations(); |
258 const CSSAnimations* cssAnimations = activeAnimations ? &activeAnimations->c
ssAnimations() : nullptr; | 258 const CSSAnimations* cssAnimations = activeAnimations ? &activeAnimations->c
ssAnimations() : nullptr; |
| 259 const Element* elementForScoping = animatingElement ? animatingElement : &el
ement; |
259 | 260 |
260 HashSet<AtomicString> inactive; | 261 HashSet<AtomicString> inactive; |
261 if (cssAnimations) { | 262 if (cssAnimations) { |
262 for (const auto& entry : cssAnimations->m_animations) | 263 for (const auto& entry : cssAnimations->m_animations) |
263 inactive.add(entry.key); | 264 inactive.add(entry.key); |
264 } | 265 } |
265 | 266 |
266 if (style.display() != NONE) { | 267 if (style.display() != NONE) { |
267 for (size_t i = 0; animationData && i < animationData->nameList().size()
; ++i) { | 268 for (size_t i = 0; animationData && i < animationData->nameList().size()
; ++i) { |
268 AtomicString animationName(animationData->nameList()[i]); | 269 AtomicString animationName(animationData->nameList()[i]); |
269 if (animationName == CSSAnimationData::initialName()) | 270 if (animationName == CSSAnimationData::initialName()) |
270 continue; | 271 continue; |
271 | 272 |
272 const bool isPaused = CSSTimingData::getRepeated(animationData->play
StateList(), i) == AnimPlayStatePaused; | 273 const bool isPaused = CSSTimingData::getRepeated(animationData->play
StateList(), i) == AnimPlayStatePaused; |
273 | 274 |
274 Timing timing = animationData->convertToTiming(i); | 275 Timing timing = animationData->convertToTiming(i); |
| 276 Timing newTiming = timing; |
275 RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunctio
n; | 277 RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunctio
n; |
276 timing.timingFunction = Timing::defaults().timingFunction; | 278 timing.timingFunction = Timing::defaults().timingFunction; |
277 | 279 |
278 if (cssAnimations) { | 280 if (cssAnimations) { |
279 AnimationMap::const_iterator existing(cssAnimations->m_animation
s.find(animationName)); | 281 AnimationMap::const_iterator existing(cssAnimations->m_animation
s.find(animationName)); |
280 if (existing != cssAnimations->m_animations.end()) { | 282 if (existing != cssAnimations->m_animations.end()) { |
281 inactive.remove(animationName); | 283 inactive.remove(animationName); |
282 | 284 |
283 AnimationPlayer* player = existing->value.get(); | 285 AnimationPlayer* player = existing->value.get(); |
284 | 286 |
285 // FIXME: Should handle changes in the timing function. | 287 const StyleRuleKeyframes* keyframesRule = CSSAnimations::mat
chScopedKeyframesRule(resolver, elementForScoping, animationName.impl()); |
286 if (timing != player->source()->specifiedTiming()) { | 288 ASSERT(keyframesRule); |
287 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); | |
288 | 289 |
| 290 auto prevTiming = cssAnimations->m_timings.find(animationNam
e); |
| 291 ASSERT(prevTiming != cssAnimations->m_timings.end()); |
| 292 |
| 293 if (keyframesRule->styleChangeCounter() > player->source()->
styleChangeCounter() || prevTiming->value != newTiming) { |
289 AnimatableValueKeyframeVector resolvedKeyframes; | 294 AnimatableValueKeyframeVector resolvedKeyframes; |
290 resolveKeyframes(resolver, animatingElement, element, st
yle, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes
); | 295 resolveKeyframes(resolver, animatingElement, element, st
yle, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes
); |
291 | 296 |
292 update->updateAnimationTiming(player, InertAnimation::cr
eate(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes), | 297 update->updateAnimation(player, InertAnimation::create(A
nimatableValueKeyframeEffectModel::create(resolvedKeyframes), |
293 timing, isPaused, player->currentTimeInternal()), ti
ming); | 298 timing, isPaused, player->currentTimeInternal()), ne
wTiming, keyframesRule->styleChangeCounter()); |
294 } | 299 } |
295 | 300 |
296 if (isPaused != player->paused()) { | 301 if (isPaused != player->paused()) { |
297 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); | 302 ASSERT(!activeAnimations || !activeAnimations->isAnimati
onStyleChange()); |
298 update->toggleAnimationPaused(animationName); | 303 update->toggleAnimationPaused(animationName); |
299 } | 304 } |
300 | 305 |
301 continue; | 306 continue; |
302 } | 307 } |
303 } | 308 } |
304 | 309 |
305 AnimatableValueKeyframeVector resolvedKeyframes; | 310 AnimatableValueKeyframeVector resolvedKeyframes; |
306 resolveKeyframes(resolver, animatingElement, element, style, parentS
tyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes); | 311 resolveKeyframes(resolver, animatingElement, element, style, parentS
tyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes); |
307 if (!resolvedKeyframes.isEmpty()) { | 312 if (!resolvedKeyframes.isEmpty()) { |
308 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC
hange()); | 313 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC
hange()); |
309 update->startAnimation(animationName, InertAnimation::create(Ani
matableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused, 0)
); | 314 update->startAnimation(animationName, InertAnimation::create(Ani
matableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused, 0)
, newTiming); |
310 } | 315 } |
311 } | 316 } |
312 } | 317 } |
313 | 318 |
314 ASSERT(inactive.isEmpty() || cssAnimations); | 319 ASSERT(inactive.isEmpty() || cssAnimations); |
315 for (const AtomicString& animationName : inactive) { | 320 for (const AtomicString& animationName : inactive) { |
316 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; | 321 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; |
317 update->cancelAnimation(animationName, *cssAnimations->m_animations.get(
animationName)); | 322 update->cancelAnimation(animationName, *cssAnimations->m_animations.get(
animationName)); |
318 } | 323 } |
319 } | 324 } |
(...skipping 23 matching lines...) Expand all Loading... |
343 for (const AtomicString& animationName : update->animationsWithPauseToggled(
)) { | 348 for (const AtomicString& animationName : update->animationsWithPauseToggled(
)) { |
344 AnimationPlayer* player = m_animations.get(animationName); | 349 AnimationPlayer* player = m_animations.get(animationName); |
345 if (player->paused()) | 350 if (player->paused()) |
346 player->unpause(); | 351 player->unpause(); |
347 else | 352 else |
348 player->pause(); | 353 player->pause(); |
349 if (player->outdated()) | 354 if (player->outdated()) |
350 player->update(TimingUpdateOnDemand); | 355 player->update(TimingUpdateOnDemand); |
351 } | 356 } |
352 | 357 |
353 for (const auto& timingUpdate : update->animationsWithTimingUpdates()) { | 358 for (const auto& entry : update->animationsWithUpdates()) { |
354 timingUpdate.player->source()->updateSpecifiedTiming(timingUpdate.newTim
ing); | 359 ASSERT(entry.player->source()->isAnimation()); |
355 timingUpdate.player->update(TimingUpdateOnDemand); | 360 Animation* animation = static_cast<Animation*>(entry.player->source()); |
| 361 |
| 362 animation->setEffect(entry.animation->effect()); |
| 363 animation->updateSpecifiedTiming(entry.animation->specifiedTiming()); |
| 364 animation->updateStyleChangeCounter(entry.styleChangeCounter); |
| 365 m_timings.set(AtomicString(entry.player->source()->name()), entry.newTim
ing); |
356 } | 366 } |
357 | 367 |
358 for (const auto& entry : update->newAnimations()) { | 368 for (const auto& entry : update->newAnimations()) { |
359 const InertAnimation* inertAnimation = entry.animation.get(); | 369 const InertAnimation* inertAnimation = entry.animation.get(); |
360 OwnPtrWillBeRawPtr<AnimationEventDelegate> eventDelegate = adoptPtrWillB
eNoop(new AnimationEventDelegate(element, entry.name)); | 370 OwnPtrWillBeRawPtr<AnimationEventDelegate> eventDelegate = adoptPtrWillB
eNoop(new AnimationEventDelegate(element, entry.name)); |
361 RefPtrWillBeRawPtr<Animation> animation = Animation::create(element, ine
rtAnimation->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPrio
rity, eventDelegate.release()); | 371 RefPtrWillBeRawPtr<Animation> animation = Animation::create(element, ine
rtAnimation->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPrio
rity, eventDelegate.release()); |
362 animation->setName(inertAnimation->name()); | 372 animation->setName(inertAnimation->name()); |
363 RefPtrWillBeRawPtr<AnimationPlayer> player = element->document().timelin
e().createAnimationPlayer(animation.get()); | 373 RefPtrWillBeRawPtr<AnimationPlayer> player = element->document().timelin
e().createAnimationPlayer(animation.get()); |
364 if (inertAnimation->paused()) | 374 if (inertAnimation->paused()) |
365 player->pause(); | 375 player->pause(); |
366 player->update(TimingUpdateOnDemand); | 376 player->update(TimingUpdateOnDemand); |
367 m_animations.set(entry.name, player.get()); | 377 m_animations.set(entry.name, player.get()); |
| 378 m_timings.set(entry.name, entry.newTiming); |
368 } | 379 } |
369 | 380 |
370 // Transitions that are run on the compositor only update main-thread state | 381 // Transitions that are run on the compositor only update main-thread state |
371 // lazily. However, we need the new state to know what the from state shoud | 382 // lazily. However, we need the new state to know what the from state shoud |
372 // be when transitions are retargeted. Instead of triggering complete style | 383 // be when transitions are retargeted. Instead of triggering complete style |
373 // recalculation, we find these cases by searching for new transitions that | 384 // recalculation, we find these cases by searching for new transitions that |
374 // have matching cancelled animation property IDs on the compositor. | 385 // have matching cancelled animation property IDs on the compositor. |
375 WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<Animation>, do
uble>> retargetedCompositorTransitions; | 386 WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<Animation>, do
uble>> retargetedCompositorTransitions; |
376 for (CSSPropertyID id : update->cancelledTransitions()) { | 387 for (CSSPropertyID id : update->cancelledTransitions()) { |
377 ASSERT(m_transitions.contains(id)); | 388 ASSERT(m_transitions.contains(id)); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 | 586 |
576 if (update->newAnimations().isEmpty() && update->suppressedAnimationAnimatio
nPlayers().isEmpty()) { | 587 if (update->newAnimations().isEmpty() && update->suppressedAnimationAnimatio
nPlayers().isEmpty()) { |
577 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation>> acti
veInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStac
k, 0, 0, Animation::DefaultPriority, timelineCurrentTime)); | 588 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation>> acti
veInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStac
k, 0, 0, Animation::DefaultPriority, timelineCurrentTime)); |
578 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn
imations); | 589 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn
imations); |
579 return; | 590 return; |
580 } | 591 } |
581 | 592 |
582 WillBeHeapVector<RawPtrWillBeMember<InertAnimation>> newAnimations; | 593 WillBeHeapVector<RawPtrWillBeMember<InertAnimation>> newAnimations; |
583 for (const auto& newAnimation : update->newAnimations()) | 594 for (const auto& newAnimation : update->newAnimations()) |
584 newAnimations.append(newAnimation.animation.get()); | 595 newAnimations.append(newAnimation.animation.get()); |
585 for (const auto& updatedAnimation : update->animationsWithTimingUpdates()) | 596 for (const auto& updatedAnimation : update->animationsWithUpdates()) |
586 newAnimations.append(updatedAnimation.animation.get()); // Animations wi
th timing updates use a temporary InertAnimation for the current frame. | 597 newAnimations.append(updatedAnimation.animation.get()); // Animations wi
th updates use a temporary InertAnimation for the current frame. |
587 | 598 |
588 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation>> activeIn
terpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &
newAnimations, &update->suppressedAnimationAnimationPlayers(), Animation::Defaul
tPriority, timelineCurrentTime)); | 599 WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation>> activeIn
terpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &
newAnimations, &update->suppressedAnimationAnimationPlayers(), Animation::Defaul
tPriority, timelineCurrentTime)); |
589 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat
ions); | 600 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat
ions); |
590 } | 601 } |
591 | 602 |
592 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
update, const Element* animatingElement, double timelineCurrentTime) | 603 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
update, const Element* animatingElement, double timelineCurrentTime) |
593 { | 604 { |
594 ActiveAnimations* activeAnimations = animatingElement ? animatingElement->ac
tiveAnimations() : nullptr; | 605 ActiveAnimations* activeAnimations = animatingElement ? animatingElement->ac
tiveAnimations() : nullptr; |
595 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : nullptr; | 606 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : nullptr; |
596 | 607 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 } | 773 } |
763 | 774 |
764 void CSSAnimationUpdate::trace(Visitor* visitor) | 775 void CSSAnimationUpdate::trace(Visitor* visitor) |
765 { | 776 { |
766 #if ENABLE(OILPAN) | 777 #if ENABLE(OILPAN) |
767 visitor->trace(m_newTransitions); | 778 visitor->trace(m_newTransitions); |
768 visitor->trace(m_activeInterpolationsForAnimations); | 779 visitor->trace(m_activeInterpolationsForAnimations); |
769 visitor->trace(m_activeInterpolationsForTransitions); | 780 visitor->trace(m_activeInterpolationsForTransitions); |
770 visitor->trace(m_newAnimations); | 781 visitor->trace(m_newAnimations); |
771 visitor->trace(m_suppressedAnimationPlayers); | 782 visitor->trace(m_suppressedAnimationPlayers); |
772 visitor->trace(m_animationsWithTimingUpdates); | 783 visitor->trace(m_animationsWithUpdates); |
773 #endif | 784 #endif |
774 } | 785 } |
775 | 786 |
776 } // namespace blink | 787 } // namespace blink |
OLD | NEW |