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 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (const StyleRuleKeyframes* keyframesRule = stack.at(i)->keyframeStyle
sForAnimation(animationName)) | 317 if (const StyleRuleKeyframes* keyframesRule = stack.at(i)->keyframeStyle
sForAnimation(animationName)) |
318 return keyframesRule; | 318 return keyframesRule; |
319 } | 319 } |
320 return 0; | 320 return 0; |
321 } | 321 } |
322 | 322 |
323 PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element,
const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle
, StyleResolver* resolver) | 323 PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element,
const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle
, StyleResolver* resolver) |
324 { | 324 { |
325 OwnPtr<CSSAnimationUpdate> update = adoptPtr(new CSSAnimationUpdate()); | 325 OwnPtr<CSSAnimationUpdate> update = adoptPtr(new CSSAnimationUpdate()); |
326 calculateAnimationUpdate(update.get(), element, parentElement, style, parent
Style, resolver); | 326 calculateAnimationUpdate(update.get(), element, parentElement, style, parent
Style, resolver); |
327 calculateAnimationCompositableValues(update.get(), element); | 327 calculateAnimationActiveInterpolations(update.get(), element); |
328 calculateTransitionUpdate(update.get(), element, style); | 328 calculateTransitionUpdate(update.get(), element, style); |
329 calculateTransitionCompositableValues(update.get(), element); | 329 calculateTransitionActiveInterpolations(update.get(), element); |
330 return update->isEmpty() ? nullptr : update.release(); | 330 return update->isEmpty() ? nullptr : update.release(); |
331 } | 331 } |
332 | 332 |
333 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, Element
* element, const Element& parentElement, const RenderStyle& style, RenderStyle*
parentStyle, StyleResolver* resolver) | 333 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, Element
* element, const Element& parentElement, const RenderStyle& style, RenderStyle*
parentStyle, StyleResolver* resolver) |
334 { | 334 { |
335 const ActiveAnimations* activeAnimations = element ? element->activeAnimatio
ns() : 0; | 335 const ActiveAnimations* activeAnimations = element ? element->activeAnimatio
ns() : 0; |
336 | 336 |
337 #if ASSERT_DISABLED | 337 #if ASSERT_DISABLED |
338 // If we're in an animation style change, no animations can have started, be
en cancelled or changed play state. | 338 // If we're in an animation style change, no animations can have started, be
en cancelled or changed play state. |
339 // When ASSERT is enabled, we verify this optimization. | 339 // When ASSERT is enabled, we verify this optimization. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 ASSERT(inactive.isEmpty() || cssAnimations); | 401 ASSERT(inactive.isEmpty() || cssAnimations); |
402 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter !=
inactive.end(); ++iter) { | 402 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter !=
inactive.end(); ++iter) { |
403 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; | 403 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange())
; |
404 update->cancelAnimation(*iter, cssAnimations->m_animations.get(*iter)); | 404 update->cancelAnimation(*iter, cssAnimations->m_animations.get(*iter)); |
405 } | 405 } |
406 } | 406 } |
407 | 407 |
408 void CSSAnimations::maybeApplyPendingUpdate(Element* element) | 408 void CSSAnimations::maybeApplyPendingUpdate(Element* element) |
409 { | 409 { |
410 if (!m_pendingUpdate) { | 410 if (!m_pendingUpdate) { |
411 m_previousCompositableValuesForAnimations.clear(); | 411 m_previousActiveInterpolationsForAnimations.clear(); |
412 return; | 412 return; |
413 } | 413 } |
414 | 414 |
415 OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release(); | 415 OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release(); |
416 | 416 |
417 m_previousCompositableValuesForAnimations.swap(update->compositableValuesFor
Animations()); | 417 m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolation
sForAnimations()); |
418 | 418 |
419 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here | 419 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here |
420 // since we call this from recalc style. | 420 // since we call this from recalc style. |
421 // https://code.google.com/p/chromium/issues/detail?id=339847 | 421 // https://code.google.com/p/chromium/issues/detail?id=339847 |
422 DisableCompositingQueryAsserts disabler; | 422 DisableCompositingQueryAsserts disabler; |
423 | 423 |
424 for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationN
ames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) { | 424 for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationN
ames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) { |
425 const HashSet<RefPtr<AnimationPlayer> >& players = m_animations.take(*it
er); | 425 const HashSet<RefPtr<AnimationPlayer> >& players = m_animations.take(*it
er); |
426 for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.be
gin(); iter != players.end(); ++iter) | 426 for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.be
gin(); iter != players.end(); ++iter) |
427 (*iter)->cancel(); | 427 (*iter)->cancel(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 const std::pair<RefPtr<Animation>, double>& oldTransition = retarget
edCompositorTransitions.get(id); | 492 const std::pair<RefPtr<Animation>, double>& oldTransition = retarget
edCompositorTransitions.get(id); |
493 RefPtr<Animation> oldAnimation = oldTransition.first; | 493 RefPtr<Animation> oldAnimation = oldTransition.first; |
494 double oldStartTime = oldTransition.second; | 494 double oldStartTime = oldTransition.second; |
495 double inheritedTime = isNull(oldStartTime) ? 0 : element->document(
).transitionTimeline().currentTime() - oldStartTime; | 495 double inheritedTime = isNull(oldStartTime) ? 0 : element->document(
).transitionTimeline().currentTime() - oldStartTime; |
496 oldAnimation->updateInheritedTime(inheritedTime); | 496 oldAnimation->updateInheritedTime(inheritedTime); |
497 KeyframeEffectModel* oldEffect = toKeyframeEffectModel(inertAnimatio
n->effect()); | 497 KeyframeEffectModel* oldEffect = toKeyframeEffectModel(inertAnimatio
n->effect()); |
498 const KeyframeEffectModel::KeyframeVector& frames = oldEffect->getFr
ames(); | 498 const KeyframeEffectModel::KeyframeVector& frames = oldEffect->getFr
ames(); |
499 KeyframeEffectModel::KeyframeVector newFrames; | 499 KeyframeEffectModel::KeyframeVector newFrames; |
500 newFrames.append(frames[0]->clone()); | 500 newFrames.append(frames[0]->clone()); |
501 newFrames[0]->clearPropertyValue(id); | 501 newFrames[0]->clearPropertyValue(id); |
502 ASSERT(oldAnimation->compositableValues()->size() == 1); | 502 ASSERT(oldAnimation->activeInterpolations().size() == 1); |
503 const AnimationEffect::CompositableValue* compositableValue = oldAni
mation->compositableValues()->at(0).second.get(); | 503 const AnimatableValue* value = toLegacyStyleInterpolation(oldAnimati
on->activeInterpolations()[0].get())->currentValue(); |
504 ASSERT(!compositableValue->dependsOnUnderlyingValue()); | 504 newFrames[0]->setPropertyValue(id, value); |
505 newFrames[0]->setPropertyValue(id, compositableValue->compositeOnto(
0).get()); | |
506 newFrames.append(frames[1]->clone()); | 505 newFrames.append(frames[1]->clone()); |
507 effect = KeyframeEffectModel::create(newFrames); | 506 effect = KeyframeEffectModel::create(newFrames); |
508 } | 507 } |
509 RefPtr<Animation> transition = Animation::create(element, effect, inertA
nimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.releas
e()); | 508 RefPtr<Animation> transition = Animation::create(element, effect, inertA
nimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.releas
e()); |
510 RefPtr<AnimationPlayer> player = element->document().transitionTimeline(
).createAnimationPlayer(transition.get()); | 509 RefPtr<AnimationPlayer> player = element->document().transitionTimeline(
).createAnimationPlayer(transition.get()); |
511 player->update(); | 510 player->update(); |
512 element->document().cssPendingAnimations().add(player.get()); | 511 element->document().cssPendingAnimations().add(player.get()); |
513 runningTransition.transition = transition.get(); | 512 runningTransition.transition = transition.get(); |
514 m_transitions.set(id, runningTransition); | 513 m_transitions.set(id, runningTransition); |
515 ASSERT(id != CSSPropertyInvalid); | 514 ASSERT(id != CSSPropertyInvalid); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 | 610 |
612 if (!animateAll) { | 611 if (!animateAll) { |
613 if (CSSAnimations::isAnimatableProperty(id)) | 612 if (CSSAnimations::isAnimatableProperty(id)) |
614 listedProperties.set(id); | 613 listedProperties.set(id); |
615 else | 614 else |
616 continue; | 615 continue; |
617 } | 616 } |
618 | 617 |
619 // FIXME: We should transition if an !important property changes
even when an animation is running, | 618 // FIXME: We should transition if an !important property changes
even when an animation is running, |
620 // but this is a bit hard to do with the current applyMatchedPro
perties system. | 619 // but this is a bit hard to do with the current applyMatchedPro
perties system. |
621 if (!update->compositableValuesForAnimations().contains(id) | 620 if (!update->activeInterpolationsForAnimations().contains(id) |
622 && (!activeAnimations || !activeAnimations->cssAnimations().
m_previousCompositableValuesForAnimations.contains(id))) { | 621 && (!activeAnimations || !activeAnimations->cssAnimations().
m_previousActiveInterpolationsForAnimations.contains(id))) { |
623 calculateTransitionUpdateForProperty(id, anim, oldStyle, sty
le, activeTransitions, update, element); | 622 calculateTransitionUpdateForProperty(id, anim, oldStyle, sty
le, activeTransitions, update, element); |
624 } | 623 } |
625 } | 624 } |
626 } | 625 } |
627 } | 626 } |
628 | 627 |
629 if (activeTransitions) { | 628 if (activeTransitions) { |
630 for (TransitionMap::const_iterator iter = activeTransitions->begin(); it
er != activeTransitions->end(); ++iter) { | 629 for (TransitionMap::const_iterator iter = activeTransitions->begin(); it
er != activeTransitions->end(); ++iter) { |
631 const TimedItem* timedItem = iter->value.transition; | 630 const TimedItem* timedItem = iter->value.transition; |
632 CSSPropertyID id = iter->key; | 631 CSSPropertyID id = iter->key; |
(...skipping 14 matching lines...) Expand all Loading... |
647 } | 646 } |
648 | 647 |
649 for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transit
ions.end(); ++iter) | 648 for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transit
ions.end(); ++iter) |
650 iter->value.transition->player()->cancel(); | 649 iter->value.transition->player()->cancel(); |
651 | 650 |
652 m_animations.clear(); | 651 m_animations.clear(); |
653 m_transitions.clear(); | 652 m_transitions.clear(); |
654 m_pendingUpdate = nullptr; | 653 m_pendingUpdate = nullptr; |
655 } | 654 } |
656 | 655 |
657 void CSSAnimations::calculateAnimationCompositableValues(CSSAnimationUpdate* upd
ate, const Element* element) | 656 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u
pdate, const Element* element) |
658 { | 657 { |
659 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; | 658 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; |
660 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; | 659 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; |
661 | 660 |
662 if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimation
Players().isEmpty()) { | 661 if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimation
Players().isEmpty()) { |
663 AnimationEffect::CompositableValueMap compositableValuesForAnimations(An
imationStack::compositableValues(animationStack, 0, 0, Animation::DefaultPriorit
y)); | 662 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForAn
imations(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::D
efaultPriority)); |
664 update->adoptCompositableValuesForAnimations(compositableValuesForAnimat
ions); | 663 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn
imations); |
665 return; | 664 return; |
666 } | 665 } |
667 | 666 |
668 Vector<InertAnimation*> newAnimations; | 667 Vector<InertAnimation*> newAnimations; |
669 for (size_t i = 0; i < update->newAnimations().size(); ++i) { | 668 for (size_t i = 0; i < update->newAnimations().size(); ++i) { |
670 HashSet<RefPtr<InertAnimation> > animations = update->newAnimations()[i]
.animations; | 669 HashSet<RefPtr<InertAnimation> > animations = update->newAnimations()[i]
.animations; |
671 for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = a
nimations.begin(); animationsIter != animations.end(); ++animationsIter) | 670 for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = a
nimations.begin(); animationsIter != animations.end(); ++animationsIter) |
672 newAnimations.append(animationsIter->get()); | 671 newAnimations.append(animationsIter->get()); |
673 } | 672 } |
674 AnimationEffect::CompositableValueMap compositableValuesForAnimations(Animat
ionStack::compositableValues(animationStack, &newAnimations, &update->cancelledA
nimationAnimationPlayers(), Animation::DefaultPriority)); | 673 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForAnimat
ions(AnimationStack::activeInterpolations(animationStack, &newAnimations, &updat
e->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority)); |
675 update->adoptCompositableValuesForAnimations(compositableValuesForAnimations
); | 674 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat
ions); |
676 } | 675 } |
677 | 676 |
678 void CSSAnimations::calculateTransitionCompositableValues(CSSAnimationUpdate* up
date, const Element* element) | 677 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
update, const Element* element) |
679 { | 678 { |
680 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; | 679 ActiveAnimations* activeAnimations = element ? element->activeAnimations() :
0; |
681 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; | 680 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau
ltStack() : 0; |
682 | 681 |
683 AnimationEffect::CompositableValueMap compositableValuesForTransitions; | 682 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForTransi
tions; |
684 if (update->newTransitions().isEmpty() && update->cancelledTransitions().isE
mpty()) { | 683 if (update->newTransitions().isEmpty() && update->cancelledTransitions().isE
mpty()) { |
685 compositableValuesForTransitions = AnimationStack::compositableValues(an
imationStack, 0, 0, Animation::TransitionPriority); | 684 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, 0, 0, Animation::TransitionPriority); |
686 } else { | 685 } else { |
687 Vector<InertAnimation*> newTransitions; | 686 Vector<InertAnimation*> newTransitions; |
688 for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update-
>newTransitions().begin(); iter != update->newTransitions().end(); ++iter) | 687 for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update-
>newTransitions().begin(); iter != update->newTransitions().end(); ++iter) |
689 newTransitions.append(iter->value.animation.get()); | 688 newTransitions.append(iter->value.animation.get()); |
690 | 689 |
691 HashSet<const AnimationPlayer*> cancelledAnimationPlayers; | 690 HashSet<const AnimationPlayer*> cancelledAnimationPlayers; |
692 if (!update->cancelledTransitions().isEmpty()) { | 691 if (!update->cancelledTransitions().isEmpty()) { |
693 ASSERT(activeAnimations); | 692 ASSERT(activeAnimations); |
694 const TransitionMap& transitionMap = activeAnimations->cssAnimations
().m_transitions; | 693 const TransitionMap& transitionMap = activeAnimations->cssAnimations
().m_transitions; |
695 for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransi
tions().begin(); iter != update->cancelledTransitions().end(); ++iter) { | 694 for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransi
tions().begin(); iter != update->cancelledTransitions().end(); ++iter) { |
696 ASSERT(transitionMap.contains(*iter)); | 695 ASSERT(transitionMap.contains(*iter)); |
697 cancelledAnimationPlayers.add(transitionMap.get(*iter).transitio
n->player()); | 696 cancelledAnimationPlayers.add(transitionMap.get(*iter).transitio
n->player()); |
698 } | 697 } |
699 } | 698 } |
700 | 699 |
701 compositableValuesForTransitions = AnimationStack::compositableValues(an
imationStack, &newTransitions, &cancelledAnimationPlayers, Animation::Transition
Priority); | 700 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, &newTransitions, &cancelledAnimationPlayers, Animation::Transi
tionPriority); |
702 } | 701 } |
703 | 702 |
704 // Properties being animated by animations don't get values from transitions
applied. | 703 // Properties being animated by animations don't get values from transitions
applied. |
705 if (!update->compositableValuesForAnimations().isEmpty() && !compositableVal
uesForTransitions.isEmpty()) { | 704 if (!update->activeInterpolationsForAnimations().isEmpty() && !activeInterpo
lationsForTransitions.isEmpty()) { |
706 for (AnimationEffect::CompositableValueMap::const_iterator iter = update
->compositableValuesForAnimations().begin(); iter != update->compositableValuesF
orAnimations().end(); ++iter) | 705 for (HashMap<CSSPropertyID, RefPtr<Interpolation> >::const_iterator iter
= update->activeInterpolationsForAnimations().begin(); iter != update->activeIn
terpolationsForAnimations().end(); ++iter) |
707 compositableValuesForTransitions.remove(iter->key); | 706 activeInterpolationsForTransitions.remove(iter->key); |
708 } | 707 } |
709 update->adoptCompositableValuesForTransitions(compositableValuesForTransitio
ns); | 708 update->adoptActiveInterpolationsForTransitions(activeInterpolationsForTrans
itions); |
710 } | 709 } |
711 | 710 |
712 void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType
listenerType, const AtomicString& eventName, double elapsedTime) | 711 void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType
listenerType, const AtomicString& eventName, double elapsedTime) |
713 { | 712 { |
714 if (m_target->document().hasListenerType(listenerType)) { | 713 if (m_target->document().hasListenerType(listenerType)) { |
715 RefPtr<WebKitAnimationEvent> event = WebKitAnimationEvent::create(eventN
ame, m_name, elapsedTime); | 714 RefPtr<WebKitAnimationEvent> event = WebKitAnimationEvent::create(eventN
ame, m_name, elapsedTime); |
716 event->setTarget(m_target); | 715 event->setTarget(m_target); |
717 m_target->document().enqueueAnimationFrameEvent(event); | 716 m_target->document().enqueueAnimationFrameEvent(event); |
718 } | 717 } |
719 } | 718 } |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 CSSPropertyID id = convertToCSSPropertyID(i); | 890 CSSPropertyID id = convertToCSSPropertyID(i); |
892 if (isAnimatableProperty(id)) | 891 if (isAnimatableProperty(id)) |
893 properties.append(id); | 892 properties.append(id); |
894 } | 893 } |
895 propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, propertie
s.begin(), properties.size()); | 894 propertyShorthand = StylePropertyShorthand(CSSPropertyInvalid, propertie
s.begin(), properties.size()); |
896 } | 895 } |
897 return propertyShorthand; | 896 return propertyShorthand; |
898 } | 897 } |
899 | 898 |
900 } // namespace WebCore | 899 } // namespace WebCore |
OLD | NEW |