Chromium Code Reviews| Index: Source/core/animation/InvalidatableStyleInterpolation.cpp |
| diff --git a/Source/core/animation/InvalidatableStyleInterpolation.cpp b/Source/core/animation/InvalidatableStyleInterpolation.cpp |
| index d0f20a686b362d16feadb1ca1e5c59b8d394b7e9..b6856731a3f5701b45becb9f59dfe2f1e96980dc 100644 |
| --- a/Source/core/animation/InvalidatableStyleInterpolation.cpp |
| +++ b/Source/core/animation/InvalidatableStyleInterpolation.cpp |
| @@ -120,20 +120,64 @@ void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s |
| } |
| } |
| -void InvalidatableStyleInterpolation::apply(StyleResolverState& state) const |
| +void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& interpolations, StyleResolverState& state) |
| { |
| - OwnPtr<InterpolationValue> underlyingValue = dependsOnUnderlyingValue() ? maybeConvertUnderlyingValue(state) : nullptr; |
| - ensureValidInterpolation(state, underlyingValue.get()); |
| - if (!m_cachedValue) |
| - return; |
| - const InterpolableValue* appliedInterpolableValue = &m_cachedValue->interpolableValue(); |
| - if (underlyingValue && m_cachedValue->type() == underlyingValue->type()) { |
| - double underlyingFraction = m_cachedConversion->interpolateUnderlyingFraction(m_startKeyframe->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction); |
| - underlyingValue->interpolableValue().scaleAndAdd(underlyingFraction, m_cachedValue->interpolableValue()); |
| - appliedInterpolableValue = &underlyingValue->interpolableValue(); |
| + ASSERT(interpolations.size() > 0); |
| + size_t startingIndex = 0; |
| + |
| + // Compute the underlying value to composite onto. |
| + OwnPtr<InterpolationValue> underlyingValueOwner = nullptr; |
|
dstockwell
2015/09/07 03:11:37
Let's see if we can encapsulate this ownptr/rawptr
alancutter (OOO until 2018)
2015/09/07 03:36:46
Done.
|
| + InterpolationValue* underlyingValue = nullptr; |
| + const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableStyleInterpolation(*interpolations.at(startingIndex)); |
| + if (firstInterpolation.dependsOnUnderlyingValue()) { |
| + underlyingValueOwner = firstInterpolation.maybeConvertUnderlyingValue(state); |
| + underlyingValue = underlyingValueOwner.get(); |
| + } else { |
| + firstInterpolation.ensureValidInterpolation(state, nullptr); |
|
dstockwell
2015/09/07 03:11:37
Should ensureValidInterpolation just return the m_
alancutter (OOO until 2018)
2015/09/07 03:36:46
Good idea, done.
|
| + // Fast path for replace interpolations that are the last to apply. |
| + if (interpolations.size() == 1) { |
| + const InterpolationValue* firstValue = firstInterpolation.m_cachedValue.get(); |
| + if (firstValue) { |
| + firstInterpolation.setFlagIfInheritUsed(state); |
| + firstValue->type().apply(firstValue->interpolableValue(), firstValue->nonInterpolableValue(), state); |
| + } |
| + return; |
| + } |
| + underlyingValue = firstInterpolation.m_cachedValue.get(); |
| + startingIndex++; |
| + } |
| + |
| + // Composite interpolations onto the underlying value. |
| + bool shouldApply = false; |
| + for (size_t i = startingIndex; i < interpolations.size(); i++) { |
| + const InvalidatableStyleInterpolation& currentInterpolation = toInvalidatableStyleInterpolation(*interpolations.at(i)); |
| + ASSERT(currentInterpolation.dependsOnUnderlyingValue()); |
| + currentInterpolation.ensureValidInterpolation(state, underlyingValue); |
| + const InterpolationValue* currentValue = currentInterpolation.m_cachedValue.get(); |
| + if (!currentValue) |
| + continue; |
| + shouldApply = true; |
| + currentInterpolation.setFlagIfInheritUsed(state); |
| + if (!underlyingValue || underlyingValue->type() != currentValue->type()) { |
| + // We keep track of the current value as the new underlying value but do not mutate it, instead perform copy on write. |
| + underlyingValue = const_cast<InterpolationValue*>(currentValue); |
| + underlyingValueOwner.clear(); |
| + } else { |
| + double underlyingFraction = currentInterpolation.m_cachedConversion->interpolateUnderlyingFraction( |
| + currentInterpolation.m_startKeyframe->underlyingFraction(), |
| + currentInterpolation.m_endKeyframe->underlyingFraction(), |
| + currentInterpolation.m_currentFraction); |
| + if (!underlyingValueOwner) { |
| + underlyingValueOwner = underlyingValue->clone(); |
| + underlyingValue = underlyingValueOwner.get(); |
| + } |
| + underlyingValue->interpolableValue().scaleAndAdd(underlyingFraction, currentInterpolation.m_cachedValue->interpolableValue()); |
| + } |
| + } |
| + |
| + if (shouldApply && underlyingValue) { |
| + underlyingValue->type().apply(underlyingValue->interpolableValue(), underlyingValue->nonInterpolableValue(), state); |
| } |
| - m_cachedValue->type().apply(*appliedInterpolableValue, m_cachedValue->nonInterpolableValue(), state); |
| - setFlagIfInheritUsed(state); |
| } |
| } // namespace blink |