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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 snapshot(new_animation.effect.Get()); | 426 snapshot(new_animation.effect.Get()); |
427 | 427 |
428 for (const auto& updated_animation : update.AnimationsWithUpdates()) | 428 for (const auto& updated_animation : update.AnimationsWithUpdates()) |
429 snapshot(updated_animation.effect.Get()); | 429 snapshot(updated_animation.effect.Get()); |
430 | 430 |
431 for (const auto& new_transition : update.NewTransitions()) | 431 for (const auto& new_transition : update.NewTransitions()) |
432 snapshot(new_transition.value.effect.Get()); | 432 snapshot(new_transition.value.effect.Get()); |
433 } | 433 } |
434 | 434 |
435 void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { | 435 void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { |
436 previous_active_interpolations_for_animations_.clear(); | 436 previous_active_interpolations_for_custom_animations_.clear(); |
| 437 previous_active_interpolations_for_standard_animations_.clear(); |
437 if (pending_update_.IsEmpty()) | 438 if (pending_update_.IsEmpty()) |
438 return; | 439 return; |
439 | 440 |
440 previous_active_interpolations_for_animations_.swap( | 441 previous_active_interpolations_for_custom_animations_.swap( |
441 pending_update_.ActiveInterpolationsForAnimations()); | 442 pending_update_.ActiveInterpolationsForCustomAnimations()); |
| 443 previous_active_interpolations_for_standard_animations_.swap( |
| 444 pending_update_.ActiveInterpolationsForStandardAnimations()); |
442 | 445 |
443 // FIXME: cancelling, pausing, unpausing animations all query | 446 // FIXME: cancelling, pausing, unpausing animations all query |
444 // compositingState, which is not necessarily up to date here | 447 // compositingState, which is not necessarily up to date here |
445 // since we call this from recalc style. | 448 // since we call this from recalc style. |
446 // https://code.google.com/p/chromium/issues/detail?id=339847 | 449 // https://code.google.com/p/chromium/issues/detail?id=339847 |
447 DisableCompositingQueryAsserts disabler; | 450 DisableCompositingQueryAsserts disabler; |
448 | 451 |
449 for (size_t paused_index : | 452 for (size_t paused_index : |
450 pending_update_.AnimationIndicesWithPauseToggled()) { | 453 pending_update_.AnimationIndicesWithPauseToggled()) { |
451 Animation& animation = *running_animations_[paused_index]->animation; | 454 Animation& animation = *running_animations_[paused_index]->animation; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 | 632 |
630 void CSSAnimations::CalculateTransitionUpdateForProperty( | 633 void CSSAnimations::CalculateTransitionUpdateForProperty( |
631 TransitionUpdateState& state, | 634 TransitionUpdateState& state, |
632 const PropertyHandle& property, | 635 const PropertyHandle& property, |
633 size_t transition_index) { | 636 size_t transition_index) { |
634 state.listed_properties.insert(property); | 637 state.listed_properties.insert(property); |
635 | 638 |
636 // FIXME: We should transition if an !important property changes even when an | 639 // FIXME: We should transition if an !important property changes even when an |
637 // animation is running, but this is a bit hard to do with the current | 640 // animation is running, but this is a bit hard to do with the current |
638 // applyMatchedProperties system. | 641 // applyMatchedProperties system. |
639 if (state.update.ActiveInterpolationsForAnimations().Contains(property) || | 642 if (property.IsCSSCustomProperty()) { |
640 (state.animating_element->GetElementAnimations() && | 643 if (state.update.ActiveInterpolationsForCustomAnimations().Contains( |
641 state.animating_element->GetElementAnimations() | 644 property) || |
642 ->CssAnimations() | 645 (state.animating_element->GetElementAnimations() && |
643 .previous_active_interpolations_for_animations_.Contains( | 646 state.animating_element->GetElementAnimations() |
644 property))) { | 647 ->CssAnimations() |
| 648 .previous_active_interpolations_for_custom_animations_.Contains( |
| 649 property))) { |
| 650 return; |
| 651 } |
| 652 } else if (state.update.ActiveInterpolationsForStandardAnimations().Contains( |
| 653 property) || |
| 654 (state.animating_element->GetElementAnimations() && |
| 655 state.animating_element->GetElementAnimations() |
| 656 ->CssAnimations() |
| 657 .previous_active_interpolations_for_standard_animations_ |
| 658 .Contains(property))) { |
645 return; | 659 return; |
646 } | 660 } |
647 | 661 |
648 RefPtr<AnimatableValue> to = nullptr; | 662 RefPtr<AnimatableValue> to = nullptr; |
649 const RunningTransition* interrupted_transition = nullptr; | 663 const RunningTransition* interrupted_transition = nullptr; |
650 if (state.active_transitions) { | 664 if (state.active_transitions) { |
651 TransitionMap::const_iterator active_transition_iter = | 665 TransitionMap::const_iterator active_transition_iter = |
652 state.active_transitions->find(property); | 666 state.active_transitions->find(property); |
653 if (active_transition_iter != state.active_transitions->end()) { | 667 if (active_transition_iter != state.active_transitions->end()) { |
654 const RunningTransition* running_transition = | 668 const RunningTransition* running_transition = |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 for (const auto& entry : transitions_) { | 942 for (const auto& entry : transitions_) { |
929 entry.value.animation->cancel(); | 943 entry.value.animation->cancel(); |
930 entry.value.animation->Update(kTimingUpdateOnDemand); | 944 entry.value.animation->Update(kTimingUpdateOnDemand); |
931 } | 945 } |
932 | 946 |
933 running_animations_.clear(); | 947 running_animations_.clear(); |
934 transitions_.clear(); | 948 transitions_.clear(); |
935 ClearPendingUpdate(); | 949 ClearPendingUpdate(); |
936 } | 950 } |
937 | 951 |
| 952 static bool IsCustomPropertyHandle(const PropertyHandle& property) { |
| 953 return property.IsCSSCustomProperty(); |
| 954 } |
| 955 |
938 // TODO(alancutter): CSS properties and presentation attributes may have | 956 // TODO(alancutter): CSS properties and presentation attributes may have |
939 // identical effects. By grouping them in the same set we introduce a bug where | 957 // identical effects. By grouping them in the same set we introduce a bug where |
940 // arbitrary hash iteration will determine the order the apply in and thus which | 958 // arbitrary hash iteration will determine the order the apply in and thus which |
941 // one "wins". We should be more deliberate about the order of application in | 959 // one "wins". We should be more deliberate about the order of application in |
942 // the case of effect collisions. | 960 // the case of effect collisions. |
943 // Example: Both 'color' and 'svg-color' set the color on ComputedStyle but are | 961 // Example: Both 'color' and 'svg-color' set the color on ComputedStyle but are |
944 // considered distinct properties in the ActiveInterpolationsMap. | 962 // considered distinct properties in the ActiveInterpolationsMap. |
945 static bool IsStylePropertyHandle(const PropertyHandle& property_handle) { | 963 static bool IsStandardPropertyHandle(const PropertyHandle& property) { |
946 return property_handle.IsCSSProperty() || | 964 return (property.IsCSSProperty() && !property.IsCSSCustomProperty()) || |
947 property_handle.IsPresentationAttribute(); | 965 property.IsPresentationAttribute(); |
| 966 } |
| 967 |
| 968 static void AdoptActiveAnimationInterpolations( |
| 969 EffectStack* effect_stack, |
| 970 CSSAnimationUpdate& update, |
| 971 const HeapVector<Member<const InertEffect>>* new_animations, |
| 972 const HeapHashSet<Member<const Animation>>* suppressed_animations) { |
| 973 ActiveInterpolationsMap custom_interpolations( |
| 974 EffectStack::ActiveInterpolations( |
| 975 effect_stack, new_animations, suppressed_animations, |
| 976 KeyframeEffectReadOnly::kDefaultPriority, IsCustomPropertyHandle)); |
| 977 update.AdoptActiveInterpolationsForCustomAnimations(custom_interpolations); |
| 978 |
| 979 ActiveInterpolationsMap standard_interpolations( |
| 980 EffectStack::ActiveInterpolations( |
| 981 effect_stack, new_animations, suppressed_animations, |
| 982 KeyframeEffectReadOnly::kDefaultPriority, IsStandardPropertyHandle)); |
| 983 update.AdoptActiveInterpolationsForStandardAnimations( |
| 984 standard_interpolations); |
948 } | 985 } |
949 | 986 |
950 void CSSAnimations::CalculateAnimationActiveInterpolations( | 987 void CSSAnimations::CalculateAnimationActiveInterpolations( |
951 CSSAnimationUpdate& update, | 988 CSSAnimationUpdate& update, |
952 const Element* animating_element) { | 989 const Element* animating_element) { |
953 ElementAnimations* element_animations = | 990 ElementAnimations* element_animations = |
954 animating_element ? animating_element->GetElementAnimations() : nullptr; | 991 animating_element ? animating_element->GetElementAnimations() : nullptr; |
955 EffectStack* effect_stack = | 992 EffectStack* effect_stack = |
956 element_animations ? &element_animations->GetEffectStack() : nullptr; | 993 element_animations ? &element_animations->GetEffectStack() : nullptr; |
957 | 994 |
958 if (update.NewAnimations().IsEmpty() && | 995 if (update.NewAnimations().IsEmpty() && |
959 update.SuppressedAnimations().IsEmpty()) { | 996 update.SuppressedAnimations().IsEmpty()) { |
960 ActiveInterpolationsMap active_interpolations_for_animations( | 997 AdoptActiveAnimationInterpolations(effect_stack, update, nullptr, nullptr); |
961 EffectStack::ActiveInterpolations( | |
962 effect_stack, nullptr, nullptr, | |
963 KeyframeEffectReadOnly::kDefaultPriority, IsStylePropertyHandle)); | |
964 update.AdoptActiveInterpolationsForAnimations( | |
965 active_interpolations_for_animations); | |
966 return; | 998 return; |
967 } | 999 } |
968 | 1000 |
969 HeapVector<Member<const InertEffect>> new_effects; | 1001 HeapVector<Member<const InertEffect>> new_effects; |
970 for (const auto& new_animation : update.NewAnimations()) | 1002 for (const auto& new_animation : update.NewAnimations()) |
971 new_effects.push_back(new_animation.effect); | 1003 new_effects.push_back(new_animation.effect); |
972 | 1004 |
973 // Animations with updates use a temporary InertEffect for the current frame. | 1005 // Animations with updates use a temporary InertEffect for the current frame. |
974 for (const auto& updated_animation : update.AnimationsWithUpdates()) | 1006 for (const auto& updated_animation : update.AnimationsWithUpdates()) |
975 new_effects.push_back(updated_animation.effect); | 1007 new_effects.push_back(updated_animation.effect); |
976 | 1008 |
977 ActiveInterpolationsMap active_interpolations_for_animations( | 1009 AdoptActiveAnimationInterpolations(effect_stack, update, &new_effects, |
978 EffectStack::ActiveInterpolations( | 1010 &update.SuppressedAnimations()); |
979 effect_stack, &new_effects, &update.SuppressedAnimations(), | |
980 KeyframeEffectReadOnly::kDefaultPriority, IsStylePropertyHandle)); | |
981 update.AdoptActiveInterpolationsForAnimations( | |
982 active_interpolations_for_animations); | |
983 } | 1011 } |
984 | 1012 |
985 static bool IsCustomStylePropertyHandle(const PropertyHandle& property) { | 1013 static EffectStack::PropertyHandleFilter PropertyFilter( |
986 return property.IsCSSCustomProperty(); | |
987 } | |
988 | |
989 static bool IsStandardStylePropertyHandle(const PropertyHandle& property) { | |
990 return IsStylePropertyHandle(property) && !property.IsCSSCustomProperty(); | |
991 } | |
992 | |
993 static EffectStack::PropertyHandleFilter StylePropertyFilter( | |
994 CSSAnimations::PropertyPass property_pass) { | 1014 CSSAnimations::PropertyPass property_pass) { |
995 if (property_pass == CSSAnimations::PropertyPass::kCustom) { | 1015 if (property_pass == CSSAnimations::PropertyPass::kCustom) { |
996 return IsCustomStylePropertyHandle; | 1016 return IsCustomPropertyHandle; |
997 } | 1017 } |
998 DCHECK_EQ(property_pass, CSSAnimations::PropertyPass::kStandard); | 1018 DCHECK_EQ(property_pass, CSSAnimations::PropertyPass::kStandard); |
999 return IsStandardStylePropertyHandle; | 1019 return IsStandardPropertyHandle; |
1000 } | 1020 } |
1001 | 1021 |
1002 void CSSAnimations::CalculateTransitionActiveInterpolations( | 1022 void CSSAnimations::CalculateTransitionActiveInterpolations( |
1003 CSSAnimationUpdate& update, | 1023 CSSAnimationUpdate& update, |
1004 PropertyPass property_pass, | 1024 PropertyPass property_pass, |
1005 const Element* animating_element) { | 1025 const Element* animating_element) { |
1006 ElementAnimations* element_animations = | 1026 ElementAnimations* element_animations = |
1007 animating_element ? animating_element->GetElementAnimations() : nullptr; | 1027 animating_element ? animating_element->GetElementAnimations() : nullptr; |
1008 EffectStack* effect_stack = | 1028 EffectStack* effect_stack = |
1009 element_animations ? &element_animations->GetEffectStack() : nullptr; | 1029 element_animations ? &element_animations->GetEffectStack() : nullptr; |
1010 | 1030 |
1011 ActiveInterpolationsMap active_interpolations_for_transitions; | 1031 ActiveInterpolationsMap active_interpolations_for_transitions; |
1012 if (update.NewTransitions().IsEmpty() && | 1032 if (update.NewTransitions().IsEmpty() && |
1013 update.CancelledTransitions().IsEmpty()) { | 1033 update.CancelledTransitions().IsEmpty()) { |
1014 active_interpolations_for_transitions = EffectStack::ActiveInterpolations( | 1034 active_interpolations_for_transitions = EffectStack::ActiveInterpolations( |
1015 effect_stack, nullptr, nullptr, | 1035 effect_stack, nullptr, nullptr, |
1016 KeyframeEffectReadOnly::kTransitionPriority, | 1036 KeyframeEffectReadOnly::kTransitionPriority, |
1017 StylePropertyFilter(property_pass)); | 1037 PropertyFilter(property_pass)); |
1018 } else { | 1038 } else { |
1019 HeapVector<Member<const InertEffect>> new_transitions; | 1039 HeapVector<Member<const InertEffect>> new_transitions; |
1020 for (const auto& entry : update.NewTransitions()) | 1040 for (const auto& entry : update.NewTransitions()) |
1021 new_transitions.push_back(entry.value.effect.Get()); | 1041 new_transitions.push_back(entry.value.effect.Get()); |
1022 | 1042 |
1023 HeapHashSet<Member<const Animation>> cancelled_animations; | 1043 HeapHashSet<Member<const Animation>> cancelled_animations; |
1024 if (!update.CancelledTransitions().IsEmpty()) { | 1044 if (!update.CancelledTransitions().IsEmpty()) { |
1025 DCHECK(element_animations); | 1045 DCHECK(element_animations); |
1026 const TransitionMap& transition_map = | 1046 const TransitionMap& transition_map = |
1027 element_animations->CssAnimations().transitions_; | 1047 element_animations->CssAnimations().transitions_; |
1028 for (const PropertyHandle& property : update.CancelledTransitions()) { | 1048 for (const PropertyHandle& property : update.CancelledTransitions()) { |
1029 DCHECK(transition_map.Contains(property)); | 1049 DCHECK(transition_map.Contains(property)); |
1030 cancelled_animations.insert( | 1050 cancelled_animations.insert( |
1031 transition_map.at(property).animation.Get()); | 1051 transition_map.at(property).animation.Get()); |
1032 } | 1052 } |
1033 } | 1053 } |
1034 | 1054 |
1035 active_interpolations_for_transitions = EffectStack::ActiveInterpolations( | 1055 active_interpolations_for_transitions = EffectStack::ActiveInterpolations( |
1036 effect_stack, &new_transitions, &cancelled_animations, | 1056 effect_stack, &new_transitions, &cancelled_animations, |
1037 KeyframeEffectReadOnly::kTransitionPriority, | 1057 KeyframeEffectReadOnly::kTransitionPriority, |
1038 StylePropertyFilter(property_pass)); | 1058 PropertyFilter(property_pass)); |
1039 } | 1059 } |
1040 | 1060 |
| 1061 const ActiveInterpolationsMap& animations = |
| 1062 property_pass == PropertyPass::kCustom |
| 1063 ? update.ActiveInterpolationsForCustomAnimations() |
| 1064 : update.ActiveInterpolationsForStandardAnimations(); |
1041 // Properties being animated by animations don't get values from transitions | 1065 // Properties being animated by animations don't get values from transitions |
1042 // applied. | 1066 // applied. |
1043 if (!update.ActiveInterpolationsForAnimations().IsEmpty() && | 1067 if (!animations.IsEmpty() && |
1044 !active_interpolations_for_transitions.IsEmpty()) { | 1068 !active_interpolations_for_transitions.IsEmpty()) { |
1045 for (const auto& entry : update.ActiveInterpolationsForAnimations()) | 1069 for (const auto& entry : animations) |
1046 active_interpolations_for_transitions.erase(entry.key); | 1070 active_interpolations_for_transitions.erase(entry.key); |
1047 } | 1071 } |
1048 | 1072 |
1049 if (property_pass == PropertyPass::kCustom) { | 1073 if (property_pass == PropertyPass::kCustom) { |
1050 update.AdoptActiveInterpolationsForCustomTransitions( | 1074 update.AdoptActiveInterpolationsForCustomTransitions( |
1051 active_interpolations_for_transitions); | 1075 active_interpolations_for_transitions); |
1052 } else { | 1076 } else { |
1053 DCHECK_EQ(property_pass, PropertyPass::kStandard); | 1077 DCHECK_EQ(property_pass, PropertyPass::kStandard); |
1054 update.AdoptActiveInterpolationsForStandardTransitions( | 1078 update.AdoptActiveInterpolationsForStandardTransitions( |
1055 active_interpolations_for_transitions); | 1079 active_interpolations_for_transitions); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 // and from their shadow sub-trees if they are shadow hosts. | 1235 // and from their shadow sub-trees if they are shadow hosts. |
1212 if (element.GetTreeScope() == tree_scope) | 1236 if (element.GetTreeScope() == tree_scope) |
1213 return true; | 1237 return true; |
1214 if (!IsShadowHost(element)) | 1238 if (!IsShadowHost(element)) |
1215 return false; | 1239 return false; |
1216 if (tree_scope.RootNode() == tree_scope.GetDocument()) | 1240 if (tree_scope.RootNode() == tree_scope.GetDocument()) |
1217 return false; | 1241 return false; |
1218 return ToShadowRoot(tree_scope.RootNode()).host() == element; | 1242 return ToShadowRoot(tree_scope.RootNode()).host() == element; |
1219 } | 1243 } |
1220 | 1244 |
1221 bool CSSAnimations::IsCustomPropertyHandle(const PropertyHandle& property) { | |
1222 return property.IsCSSProperty() && | |
1223 property.CssProperty() == CSSPropertyVariable; | |
1224 } | |
1225 | |
1226 bool CSSAnimations::IsAnimatingCustomProperties( | 1245 bool CSSAnimations::IsAnimatingCustomProperties( |
1227 const ElementAnimations* element_animations) { | 1246 const ElementAnimations* element_animations) { |
1228 return element_animations && | 1247 return element_animations && |
1229 element_animations->GetEffectStack().AffectsProperties( | 1248 element_animations->GetEffectStack().AffectsProperties( |
1230 IsCustomPropertyHandle); | 1249 IsCustomPropertyHandle); |
1231 } | 1250 } |
1232 | 1251 |
1233 DEFINE_TRACE(CSSAnimations) { | 1252 DEFINE_TRACE(CSSAnimations) { |
1234 visitor->Trace(transitions_); | 1253 visitor->Trace(transitions_); |
1235 visitor->Trace(pending_update_); | 1254 visitor->Trace(pending_update_); |
1236 visitor->Trace(running_animations_); | 1255 visitor->Trace(running_animations_); |
1237 } | 1256 } |
1238 | 1257 |
1239 } // namespace blink | 1258 } // namespace blink |
OLD | NEW |