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) |