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

Side by Side 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: Review comments 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/animation/InvalidatableStyleInterpolation.h" 6 #include "core/animation/InvalidatableStyleInterpolation.h"
7 7
8 #include "core/animation/StringKeyframe.h" 8 #include "core/animation/StringKeyframe.h"
9 #include "core/css/resolver/StyleResolverState.h" 9 #include "core/css/resolver/StyleResolverState.h"
10 10
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type()) 90 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type())
91 return false; 91 return false;
92 } 92 }
93 for (const auto& checker : m_conversionCheckers) { 93 for (const auto& checker : m_conversionCheckers) {
94 if (!checker->isValid(state)) 94 if (!checker->isValid(state))
95 return false; 95 return false;
96 } 96 }
97 return true; 97 return true;
98 } 98 }
99 99
100 void InvalidatableStyleInterpolation::ensureValidInterpolation(const StyleResolv erState& state, const InterpolationValue* underlyingValue) const 100 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const InterpolationValue* underlyingValue) const
101 { 101 {
102 if (m_cachedConversion && isCacheValid(state, underlyingValue)) 102 if (m_cachedConversion && isCacheValid(state, underlyingValue))
103 return; 103 return m_cachedValue.get();
104 m_conversionCheckers.clear(); 104 m_conversionCheckers.clear();
105 if (!maybeCachePairwiseConversion(&state, underlyingValue)) { 105 if (!maybeCachePairwiseConversion(&state, underlyingValue)) {
106 m_cachedConversion = FlipPrimitiveInterpolation::create( 106 m_cachedConversion = FlipPrimitiveInterpolation::create(
107 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue), 107 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue),
108 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue)); 108 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue));
109 } 109 }
110 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue); 110 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue);
111 return m_cachedValue.get();
111 } 112 }
112 113
113 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const 114 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const
114 { 115 {
115 if (!state.parentStyle()) 116 if (!state.parentStyle())
116 return; 117 return;
117 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( )) 118 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( ))
118 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) { 119 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) {
119 state.parentStyle()->setHasExplicitlyInheritedProperties(); 120 state.parentStyle()->setHasExplicitlyInheritedProperties();
120 } 121 }
121 } 122 }
122 123
123 void InvalidatableStyleInterpolation::apply(StyleResolverState& state) const 124 // Handles memory management of underlying InterpolationValues in applyStack()
125 // Ensures we perform copy on write if we are not the owner of an underlying Int erpolationValue.
126 // This functions similar to a DataRef except on OwnPtr'd objects.
127 class UnderlyingValue {
128 STACK_ALLOCATED();
129 public:
130 UnderlyingValue()
131 : m_owner()
132 , m_pointer(nullptr)
133 { }
134
135 void set(const InterpolationValue* interpolationValue)
136 {
137 m_owner.clear();
138 m_pointer = const_cast<InterpolationValue*>(interpolationValue);
dstockwell 2015/09/07 03:46:23 comment why this is safe
alancutter (OOO until 2018) 2015/09/07 04:34:12 Done.
139 }
140 void set(PassOwnPtr<InterpolationValue> interpolateValue)
141 {
142 m_owner = interpolateValue;
143 m_pointer = m_owner.get();
144 }
145 InterpolationValue& access()
146 {
147 ASSERT(m_pointer);
148 if (!m_owner)
149 set(m_pointer->clone());
150 return *m_pointer;
151 }
152 const InterpolationValue* get() const { return m_pointer; }
153 operator bool() const { return m_pointer; }
154 const InterpolationValue* operator->() const
155 {
156 ASSERT(m_pointer);
157 return m_pointer;
158 }
159
160 private:
161 OwnPtr<InterpolationValue> m_owner;
162 InterpolationValue* m_pointer;
163 };
164
165 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state)
124 { 166 {
125 OwnPtr<InterpolationValue> underlyingValue = dependsOnUnderlyingValue() ? ma ybeConvertUnderlyingValue(state) : nullptr; 167 ASSERT(interpolations.size() > 0);
126 ensureValidInterpolation(state, underlyingValue.get()); 168 size_t startingIndex = 0;
127 if (!m_cachedValue) 169
128 return; 170 // Compute the underlying value to composite onto.
129 const InterpolableValue* appliedInterpolableValue = &m_cachedValue->interpol ableValue(); 171 UnderlyingValue underlyingValue;
130 if (underlyingValue && m_cachedValue->type() == underlyingValue->type()) { 172 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex));
131 double underlyingFraction = m_cachedConversion->interpolateUnderlyingFra ction(m_startKeyframe->underlyingFraction(), m_endKeyframe->underlyingFraction() , m_currentFraction); 173 if (firstInterpolation.dependsOnUnderlyingValue()) {
132 underlyingValue->interpolableValue().scaleAndAdd(underlyingFraction, m_c achedValue->interpolableValue()); 174 underlyingValue.set(firstInterpolation.maybeConvertUnderlyingValue(state ));
133 appliedInterpolableValue = &underlyingValue->interpolableValue(); 175 } else {
176 const InterpolationValue* firstValue = firstInterpolation.ensureValidInt erpolation(state, nullptr);
177 // Fast path for replace interpolations that are the only one to apply.
178 if (interpolations.size() == 1) {
179 if (firstValue) {
dstockwell 2015/09/07 03:46:23 merge with previous line
alancutter (OOO until 2018) 2015/09/07 04:34:12 It would not be equivalent due to the return state
180 firstInterpolation.setFlagIfInheritUsed(state);
181 firstValue->type().apply(firstValue->interpolableValue(), firstV alue->nonInterpolableValue(), state);
182 }
183 return;
184 }
185 underlyingValue.set(firstValue);
186 startingIndex++;
134 } 187 }
135 m_cachedValue->type().apply(*appliedInterpolableValue, m_cachedValue->nonInt erpolableValue(), state); 188
136 setFlagIfInheritUsed(state); 189 // Composite interpolations onto the underlying value.
190 bool shouldApply = false;
191 for (size_t i = startingIndex; i < interpolations.size(); i++) {
192 const InvalidatableStyleInterpolation& currentInterpolation = toInvalida tableStyleInterpolation(*interpolations.at(i));
193 ASSERT(currentInterpolation.dependsOnUnderlyingValue());
194 const InterpolationValue* currentValue = currentInterpolation.ensureVali dInterpolation(state, underlyingValue.get());
195 if (!currentValue)
196 continue;
197 shouldApply = true;
198 currentInterpolation.setFlagIfInheritUsed(state);
199 if (!underlyingValue || underlyingValue->type() != currentValue->type()) {
200 underlyingValue.set(currentValue);
201 } else {
202 double underlyingFraction = currentInterpolation.m_cachedConversion- >interpolateUnderlyingFraction(
203 currentInterpolation.m_startKeyframe->underlyingFraction(),
204 currentInterpolation.m_endKeyframe->underlyingFraction(),
205 currentInterpolation.m_currentFraction);
206 underlyingValue.access().interpolableValue().scaleAndAdd(underlyingF raction, currentInterpolation.m_cachedValue->interpolableValue());
207 }
208 }
209
210 if (shouldApply && underlyingValue) {
211 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state);
212 }
137 } 213 }
138 214
139 } // namespace blink 215 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/animation/InvalidatableStyleInterpolation.h ('k') | Source/core/animation/css/CSSAnimationUpdate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698