Index: Source/core/css/resolver/StyleResolver.cpp |
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp |
index b9863ef505bc63654c93f2d5c5104f5c51d4daf8..eef458f4ff5d882ab5376e9963ef9ae2b1db9b5a 100644 |
--- a/Source/core/css/resolver/StyleResolver.cpp |
+++ b/Source/core/css/resolver/StyleResolver.cpp |
@@ -36,6 +36,7 @@ |
#include "core/animation/ActiveAnimations.h" |
#include "core/animation/Animation.h" |
#include "core/animation/AnimationTimeline.h" |
+#include "core/animation/InterpolationFactory.h" |
#include "core/animation/StyleInterpolation.h" |
#include "core/animation/animatable/AnimatableValue.h" |
#include "core/animation/css/CSSAnimatableValueFactory.h" |
@@ -53,6 +54,7 @@ |
#include "core/css/CSSValuePool.h" |
#include "core/css/ElementRuleCollector.h" |
#include "core/css/FontFace.h" |
+#include "core/css/LayoutStyleCSSValueMapping.h" |
#include "core/css/MediaQueryEvaluator.h" |
#include "core/css/PageRuleCollector.h" |
#include "core/css/StylePropertySet.h" |
@@ -1019,8 +1021,8 @@ bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, const Ele |
if (!state.animationUpdate()) |
return false; |
- const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations = state.animationUpdate()->activeInterpolationsForAnimations(); |
- const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForTransitions = state.animationUpdate()->activeInterpolationsForTransitions(); |
+ const InterpolationPipelineMap& activeInterpolationsForAnimations = state.animationUpdate()->activeInterpolationsForAnimations(); |
+ const InterpolationPipelineMap& activeInterpolationsForTransitions = state.animationUpdate()->activeInterpolationsForTransitions(); |
applyAnimatedProperties<HighPropertyPriority>(state, activeInterpolationsForAnimations); |
applyAnimatedProperties<HighPropertyPriority>(state, activeInterpolationsForTransitions); |
@@ -1052,14 +1054,72 @@ StyleRuleKeyframes* StyleResolver::findKeyframesRule(const Element* element, con |
} |
template <CSSPropertyPriority priority> |
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolations) |
+void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const InterpolationPipelineMap& activeInterpolations) |
{ |
for (const auto& interpolationEntry : activeInterpolations) { |
CSSPropertyID property = interpolationEntry.key; |
if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) |
continue; |
- const StyleInterpolation* interpolation = toStyleInterpolation(interpolationEntry.value.get()); |
- interpolation->apply(state); |
+ |
+ const InterpolationPipelineStage* firstStage = interpolationEntry.value->first().get(); |
+ RefPtrWillBeRawPtr<Interpolation> firstInterpolation = firstStage->interpolation(); |
+ |
+ RefPtrWillBeRawPtr<Interpolation> underlyingInterpolation = nullptr; |
+ |
+ OwnPtrWillBeRawPtr<InterpolableValue> underlyingValue = nullptr; |
+ OwnPtrWillBeRawPtr<InterpolableValue> multipliedValue = nullptr; |
+ |
+ if (!firstInterpolation->isReplaceOnly()) { |
+ // Pull CSSValue from the LayoutStyle |
+ RefPtrWillBeRawPtr<CSSValue> underlyingCSSValue = LayoutStyleCSSValueMapping::get(property, *state.style()); |
+ ASSERT(underlyingCSSValue); |
+ |
+ // Create interpolation from underlying value |
+ underlyingInterpolation = InterpolationFactory::createConstantInterpolation( |
+ property, |
+ underlyingCSSValue.get(), |
+ AnimationEffect::CompositeReplace, |
+ AnimationEffect::CompositeReplace |
+ ); |
+ |
+ multipliedValue = underlyingInterpolation->cachedValue().clone(); |
+ underlyingValue = underlyingInterpolation->cachedValue().clone(); |
+ |
+ if (underlyingInterpolation->cachedValue().typesMatch(firstInterpolation->cachedValue())) { |
+ // Multiply by the first interpolation's underlying |
+ // fraction |
+ underlyingInterpolation->cachedValue().multiply(firstInterpolation->cachedUnderlyingFraction(), *multipliedValue); |
+ |
+ // Add the multiplied underlying value and currentValue |
+ // to produce the final underlying value for use in the |
+ // additive pipeline |
+ multipliedValue->add(firstInterpolation->cachedValue(), *underlyingValue); |
+ } |
+ } else { |
+ underlyingInterpolation = firstInterpolation.release(); |
+ |
+ underlyingValue = underlyingInterpolation->cachedValue().clone(); |
+ multipliedValue = underlyingInterpolation->cachedValue().clone(); |
+ } |
+ |
+ const InterpolationPipelineStage* currentStage = firstStage->next().get(); |
+ RefPtrWillBeRawPtr<Interpolation> currentInterpolation = nullptr; |
+ |
+ while (currentStage) { |
+ currentInterpolation = currentStage->interpolation(); |
+ |
+ if (underlyingValue->typesMatch(currentInterpolation->cachedValue())) { |
+ underlyingValue->multiply(currentInterpolation->cachedUnderlyingFraction(), *multipliedValue); |
+ multipliedValue->add(currentInterpolation->cachedValue(), *underlyingValue); |
+ |
+ underlyingInterpolation = currentInterpolation; |
+ } |
+ |
+ currentStage = currentStage->next().get(); |
+ } |
+ |
+ const StyleInterpolation* interpolation = toStyleInterpolation(underlyingInterpolation.get()); |
+ interpolation->apply(state, *underlyingValue); |
} |
} |