| Index: Source/core/animation/InvalidatableStyleInterpolation.cpp
|
| diff --git a/Source/core/animation/InvalidatableStyleInterpolation.cpp b/Source/core/animation/InvalidatableStyleInterpolation.cpp
|
| index 0b787637b2c21f15f926df526a477adaa882ca44..659e4e7420d8b924add1e4cfda1ccffab61a8ba5 100644
|
| --- a/Source/core/animation/InvalidatableStyleInterpolation.cpp
|
| +++ b/Source/core/animation/InvalidatableStyleInterpolation.cpp
|
| @@ -121,48 +121,53 @@ void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s
|
| }
|
| }
|
|
|
| +double InvalidatableStyleInterpolation::underlyingFraction() const
|
| +{
|
| + return m_cachedConversion->interpolateUnderlyingFraction(m_startKeyframe->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction);
|
| +}
|
| +
|
| // Handles memory management of underlying InterpolationValues in applyStack()
|
| // Ensures we perform copy on write if we are not the owner of an underlying InterpolationValue.
|
| // This functions similar to a DataRef except on OwnPtr'd objects.
|
| class UnderlyingValue {
|
| STACK_ALLOCATED();
|
| +
|
| public:
|
| UnderlyingValue()
|
| - : m_owner()
|
| - , m_pointer(nullptr)
|
| + : m_valueOwner(nullptr)
|
| + , m_value(nullptr)
|
| { }
|
|
|
| void set(const InterpolationValue* interpolationValue)
|
| {
|
| - // By clearing m_owner we will perform a copy when attempting to access()
|
| - // m_pointer as a mutable reference, thus upholding the const contract for
|
| - // this instance of interpolationValue despite the const_cast.
|
| - m_owner.clear();
|
| - m_pointer = const_cast<InterpolationValue*>(interpolationValue);
|
| + // By clearing m_valueOwner we will perform a copy before attempting to mutate m_value,
|
| + // thus upholding the const contract for this instance of interpolationValue despite the const_cast.
|
| + m_valueOwner.clear();
|
| + m_value = const_cast<InterpolationValue*>(interpolationValue);
|
| }
|
| void set(PassOwnPtr<InterpolationValue> interpolationValue)
|
| {
|
| - m_owner = interpolationValue;
|
| - m_pointer = m_owner.get();
|
| + m_valueOwner = interpolationValue;
|
| + m_value = m_valueOwner.get();
|
| }
|
| - InterpolationValue& access()
|
| + InterpolationComponentValue& mutableComponent()
|
| {
|
| - ASSERT(m_pointer);
|
| - if (!m_owner)
|
| - set(m_pointer->clone());
|
| - return *m_pointer;
|
| + ASSERT(m_value);
|
| + if (!m_valueOwner)
|
| + set(m_value->clone());
|
| + return m_value->mutableComponent();
|
| }
|
| - const InterpolationValue* get() const { return m_pointer; }
|
| - operator bool() const { return m_pointer; }
|
| + const InterpolationValue* get() const { return m_value; }
|
| + operator bool() const { return m_value; }
|
| const InterpolationValue* operator->() const
|
| {
|
| - ASSERT(m_pointer);
|
| - return m_pointer;
|
| + ASSERT(m_value);
|
| + return m_value;
|
| }
|
|
|
| private:
|
| - OwnPtr<InterpolationValue> m_owner;
|
| - InterpolationValue* m_pointer;
|
| + OwnPtr<InterpolationValue> m_valueOwner;
|
| + InterpolationValue* m_value;
|
| };
|
|
|
| void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& interpolations, StyleResolverState& state)
|
| @@ -199,15 +204,11 @@ void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int
|
| continue;
|
| shouldApply = true;
|
| currentInterpolation.setFlagIfInheritUsed(state);
|
| - if (!underlyingValue || underlyingValue->type() != currentValue->type()) {
|
| + double underlyingFraction = currentInterpolation.underlyingFraction();
|
| + if (underlyingFraction == 0 || !underlyingValue || underlyingValue->type() != currentValue->type())
|
| underlyingValue.set(currentValue);
|
| - } else {
|
| - double underlyingFraction = currentInterpolation.m_cachedConversion->interpolateUnderlyingFraction(
|
| - currentInterpolation.m_startKeyframe->underlyingFraction(),
|
| - currentInterpolation.m_endKeyframe->underlyingFraction(),
|
| - currentInterpolation.m_currentFraction);
|
| - underlyingValue.access().interpolableValue().scaleAndAdd(underlyingFraction, currentInterpolation.m_cachedValue->interpolableValue());
|
| - }
|
| + else
|
| + underlyingValue.mutableComponent().interpolableValue->scaleAndAdd(underlyingFraction, currentValue->interpolableValue());
|
| }
|
|
|
| if (shouldApply && underlyingValue)
|
|
|