Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Unified Diff: Source/core/animation/InvalidatableStyleInterpolation.cpp

Issue 1329843002: Support per property CSS Animation stacks (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix TODO Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698