OLD | NEW |
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 "core/animation/InvalidatableInterpolation.h" | 5 #include "core/animation/InvalidatableInterpolation.h" |
6 | 6 |
7 #include "core/animation/InterpolationEnvironment.h" | 7 #include "core/animation/InterpolationEnvironment.h" |
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 #include <memory> | 10 #include <memory> |
(...skipping 14 matching lines...) Expand all Loading... |
25 m_cachedPairConversion->interpolateValue(fraction, m_cachedValue); | 25 m_cachedPairConversion->interpolateValue(fraction, m_cachedValue); |
26 // We defer the interpolation to ensureValidConversion() if | 26 // We defer the interpolation to ensureValidConversion() if |
27 // m_cachedPairConversion is null. | 27 // m_cachedPairConversion is null. |
28 } | 28 } |
29 | 29 |
30 std::unique_ptr<PairwisePrimitiveInterpolation> | 30 std::unique_ptr<PairwisePrimitiveInterpolation> |
31 InvalidatableInterpolation::maybeConvertPairwise( | 31 InvalidatableInterpolation::maybeConvertPairwise( |
32 const InterpolationEnvironment& environment, | 32 const InterpolationEnvironment& environment, |
33 const UnderlyingValueOwner& underlyingValueOwner) const { | 33 const UnderlyingValueOwner& underlyingValueOwner) const { |
34 DCHECK(m_currentFraction != 0 && m_currentFraction != 1); | 34 DCHECK(m_currentFraction != 0 && m_currentFraction != 1); |
35 for (const auto& interpolationType : *m_interpolationTypes) { | 35 for (const auto& interpolationType : m_interpolationTypes) { |
36 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && | 36 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && |
37 (!underlyingValueOwner || | 37 (!underlyingValueOwner || |
38 underlyingValueOwner.type() != *interpolationType)) | 38 underlyingValueOwner.type() != *interpolationType)) |
39 continue; | 39 continue; |
40 ConversionCheckers conversionCheckers; | 40 ConversionCheckers conversionCheckers; |
41 PairwiseInterpolationValue result = interpolationType->maybeConvertPairwise( | 41 PairwiseInterpolationValue result = interpolationType->maybeConvertPairwise( |
42 *m_startKeyframe, *m_endKeyframe, environment, | 42 *m_startKeyframe, *m_endKeyframe, environment, |
43 underlyingValueOwner.value(), conversionCheckers); | 43 underlyingValueOwner.value(), conversionCheckers); |
44 addConversionCheckers(*interpolationType, conversionCheckers); | 44 addConversionCheckers(*interpolationType, conversionCheckers); |
45 if (result) { | 45 if (result) { |
46 return PairwisePrimitiveInterpolation::create( | 46 return PairwisePrimitiveInterpolation::create( |
47 *interpolationType, std::move(result.startInterpolableValue), | 47 *interpolationType, std::move(result.startInterpolableValue), |
48 std::move(result.endInterpolableValue), | 48 std::move(result.endInterpolableValue), |
49 result.nonInterpolableValue.release()); | 49 result.nonInterpolableValue.release()); |
50 } | 50 } |
51 } | 51 } |
52 return nullptr; | 52 return nullptr; |
53 } | 53 } |
54 | 54 |
55 std::unique_ptr<TypedInterpolationValue> | 55 std::unique_ptr<TypedInterpolationValue> |
56 InvalidatableInterpolation::convertSingleKeyframe( | 56 InvalidatableInterpolation::convertSingleKeyframe( |
57 const PropertySpecificKeyframe& keyframe, | 57 const PropertySpecificKeyframe& keyframe, |
58 const InterpolationEnvironment& environment, | 58 const InterpolationEnvironment& environment, |
59 const UnderlyingValueOwner& underlyingValueOwner) const { | 59 const UnderlyingValueOwner& underlyingValueOwner) const { |
60 if (keyframe.isNeutral() && !underlyingValueOwner) | 60 if (keyframe.isNeutral() && !underlyingValueOwner) |
61 return nullptr; | 61 return nullptr; |
62 for (const auto& interpolationType : *m_interpolationTypes) { | 62 for (const auto& interpolationType : m_interpolationTypes) { |
63 if (keyframe.isNeutral() && | 63 if (keyframe.isNeutral() && |
64 underlyingValueOwner.type() != *interpolationType) | 64 underlyingValueOwner.type() != *interpolationType) |
65 continue; | 65 continue; |
66 ConversionCheckers conversionCheckers; | 66 ConversionCheckers conversionCheckers; |
67 InterpolationValue result = interpolationType->maybeConvertSingle( | 67 InterpolationValue result = interpolationType->maybeConvertSingle( |
68 keyframe, environment, underlyingValueOwner.value(), | 68 keyframe, environment, underlyingValueOwner.value(), |
69 conversionCheckers); | 69 conversionCheckers); |
70 addConversionCheckers(*interpolationType, conversionCheckers); | 70 addConversionCheckers(*interpolationType, conversionCheckers); |
71 if (result) | 71 if (result) |
72 return TypedInterpolationValue::create( | 72 return TypedInterpolationValue::create( |
73 *interpolationType, std::move(result.interpolableValue), | 73 *interpolationType, std::move(result.interpolableValue), |
74 result.nonInterpolableValue.release()); | 74 result.nonInterpolableValue.release()); |
75 } | 75 } |
76 DCHECK(keyframe.isNeutral()); | 76 DCHECK(keyframe.isNeutral()); |
77 return nullptr; | 77 return nullptr; |
78 } | 78 } |
79 | 79 |
80 void InvalidatableInterpolation::addConversionCheckers( | 80 void InvalidatableInterpolation::addConversionCheckers( |
81 const InterpolationType& type, | 81 const InterpolationType& type, |
82 ConversionCheckers& conversionCheckers) const { | 82 ConversionCheckers& conversionCheckers) const { |
83 for (size_t i = 0; i < conversionCheckers.size(); i++) { | 83 for (size_t i = 0; i < conversionCheckers.size(); i++) { |
84 conversionCheckers[i]->setType(type); | 84 conversionCheckers[i]->setType(type); |
85 m_conversionCheckers.append(std::move(conversionCheckers[i])); | 85 m_conversionCheckers.append(std::move(conversionCheckers[i])); |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 std::unique_ptr<TypedInterpolationValue> | 89 std::unique_ptr<TypedInterpolationValue> |
90 InvalidatableInterpolation::maybeConvertUnderlyingValue( | 90 InvalidatableInterpolation::maybeConvertUnderlyingValue( |
91 const InterpolationEnvironment& environment) const { | 91 const InterpolationEnvironment& environment) const { |
92 for (const auto& interpolationType : *m_interpolationTypes) { | 92 for (const auto& interpolationType : m_interpolationTypes) { |
93 InterpolationValue result = | 93 InterpolationValue result = |
94 interpolationType->maybeConvertUnderlyingValue(environment); | 94 interpolationType->maybeConvertUnderlyingValue(environment); |
95 if (result) | 95 if (result) |
96 return TypedInterpolationValue::create( | 96 return TypedInterpolationValue::create( |
97 *interpolationType, std::move(result.interpolableValue), | 97 *interpolationType, std::move(result.interpolableValue), |
98 result.nonInterpolableValue.release()); | 98 result.nonInterpolableValue.release()); |
99 } | 99 } |
100 return nullptr; | 100 return nullptr; |
101 } | 101 } |
102 | 102 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 return false; | 137 return false; |
138 } | 138 } |
139 return true; | 139 return true; |
140 } | 140 } |
141 | 141 |
142 const TypedInterpolationValue* | 142 const TypedInterpolationValue* |
143 InvalidatableInterpolation::ensureValidConversion( | 143 InvalidatableInterpolation::ensureValidConversion( |
144 const InterpolationEnvironment& environment, | 144 const InterpolationEnvironment& environment, |
145 const UnderlyingValueOwner& underlyingValueOwner) const { | 145 const UnderlyingValueOwner& underlyingValueOwner) const { |
146 DCHECK(!std::isnan(m_currentFraction)); | 146 DCHECK(!std::isnan(m_currentFraction)); |
147 DCHECK(m_interpolationTypes && | |
148 m_interpolationTypesVersion == | |
149 environment.interpolationTypesMap().version()); | |
150 if (isConversionCacheValid(environment, underlyingValueOwner)) | 147 if (isConversionCacheValid(environment, underlyingValueOwner)) |
151 return m_cachedValue.get(); | 148 return m_cachedValue.get(); |
152 clearConversionCache(); | 149 clearConversionCache(); |
153 if (m_currentFraction == 0) { | 150 if (m_currentFraction == 0) { |
154 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, | 151 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, |
155 underlyingValueOwner); | 152 underlyingValueOwner); |
156 } else if (m_currentFraction == 1) { | 153 } else if (m_currentFraction == 1) { |
157 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, | 154 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, |
158 underlyingValueOwner); | 155 underlyingValueOwner); |
159 } else { | 156 } else { |
160 std::unique_ptr<PairwisePrimitiveInterpolation> pairwiseConversion = | 157 std::unique_ptr<PairwisePrimitiveInterpolation> pairwiseConversion = |
161 maybeConvertPairwise(environment, underlyingValueOwner); | 158 maybeConvertPairwise(environment, underlyingValueOwner); |
162 if (pairwiseConversion) { | 159 if (pairwiseConversion) { |
163 m_cachedValue = pairwiseConversion->initialValue(); | 160 m_cachedValue = pairwiseConversion->initialValue(); |
164 m_cachedPairConversion = std::move(pairwiseConversion); | 161 m_cachedPairConversion = std::move(pairwiseConversion); |
165 } else { | 162 } else { |
166 m_cachedPairConversion = FlipPrimitiveInterpolation::create( | 163 m_cachedPairConversion = FlipPrimitiveInterpolation::create( |
167 convertSingleKeyframe(*m_startKeyframe, environment, | 164 convertSingleKeyframe(*m_startKeyframe, environment, |
168 underlyingValueOwner), | 165 underlyingValueOwner), |
169 convertSingleKeyframe(*m_endKeyframe, environment, | 166 convertSingleKeyframe(*m_endKeyframe, environment, |
170 underlyingValueOwner)); | 167 underlyingValueOwner)); |
171 } | 168 } |
172 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValue); | 169 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValue); |
173 } | 170 } |
174 m_isConversionCached = true; | 171 m_isConversionCached = true; |
175 return m_cachedValue.get(); | 172 return m_cachedValue.get(); |
176 } | 173 } |
177 | 174 |
178 void InvalidatableInterpolation::ensureValidInterpolationTypes( | |
179 const InterpolationEnvironment& environment) const { | |
180 const InterpolationTypesMap& map = environment.interpolationTypesMap(); | |
181 if (m_interpolationTypesVersion != map.version()) { | |
182 m_interpolationTypes = nullptr; | |
183 } | |
184 if (!m_interpolationTypes) { | |
185 m_interpolationTypes = &map.get(m_property); | |
186 clearConversionCache(); | |
187 } | |
188 } | |
189 | |
190 void InvalidatableInterpolation::setFlagIfInheritUsed( | 175 void InvalidatableInterpolation::setFlagIfInheritUsed( |
191 InterpolationEnvironment& environment) const { | 176 InterpolationEnvironment& environment) const { |
192 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) | 177 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) |
193 return; | 178 return; |
194 if (!environment.state().parentStyle()) | 179 if (!environment.state().parentStyle()) |
195 return; | 180 return; |
196 const CSSValue* startValue = | 181 const CSSValue* startValue = |
197 toCSSPropertySpecificKeyframe(*m_startKeyframe).value(); | 182 toCSSPropertySpecificKeyframe(*m_startKeyframe).value(); |
198 const CSSValue* endValue = | 183 const CSSValue* endValue = |
199 toCSSPropertySpecificKeyframe(*m_endKeyframe).value(); | 184 toCSSPropertySpecificKeyframe(*m_endKeyframe).value(); |
(...skipping 16 matching lines...) Expand all Loading... |
216 void InvalidatableInterpolation::applyStack( | 201 void InvalidatableInterpolation::applyStack( |
217 const ActiveInterpolations& interpolations, | 202 const ActiveInterpolations& interpolations, |
218 InterpolationEnvironment& environment) { | 203 InterpolationEnvironment& environment) { |
219 DCHECK(!interpolations.isEmpty()); | 204 DCHECK(!interpolations.isEmpty()); |
220 size_t startingIndex = 0; | 205 size_t startingIndex = 0; |
221 | 206 |
222 // Compute the underlying value to composite onto. | 207 // Compute the underlying value to composite onto. |
223 UnderlyingValueOwner underlyingValueOwner; | 208 UnderlyingValueOwner underlyingValueOwner; |
224 const InvalidatableInterpolation& firstInterpolation = | 209 const InvalidatableInterpolation& firstInterpolation = |
225 toInvalidatableInterpolation(*interpolations.at(startingIndex)); | 210 toInvalidatableInterpolation(*interpolations.at(startingIndex)); |
226 firstInterpolation.ensureValidInterpolationTypes(environment); | |
227 if (firstInterpolation.dependsOnUnderlyingValue()) { | 211 if (firstInterpolation.dependsOnUnderlyingValue()) { |
228 underlyingValueOwner.set( | 212 underlyingValueOwner.set( |
229 firstInterpolation.maybeConvertUnderlyingValue(environment)); | 213 firstInterpolation.maybeConvertUnderlyingValue(environment)); |
230 } else { | 214 } else { |
231 const TypedInterpolationValue* firstValue = | 215 const TypedInterpolationValue* firstValue = |
232 firstInterpolation.ensureValidConversion(environment, | 216 firstInterpolation.ensureValidConversion(environment, |
233 underlyingValueOwner); | 217 underlyingValueOwner); |
234 // Fast path for replace interpolations that are the only one to apply. | 218 // Fast path for replace interpolations that are the only one to apply. |
235 if (interpolations.size() == 1) { | 219 if (interpolations.size() == 1) { |
236 if (firstValue) { | 220 if (firstValue) { |
237 firstInterpolation.setFlagIfInheritUsed(environment); | 221 firstInterpolation.setFlagIfInheritUsed(environment); |
238 firstValue->type().apply(firstValue->interpolableValue(), | 222 firstValue->type().apply(firstValue->interpolableValue(), |
239 firstValue->getNonInterpolableValue(), | 223 firstValue->getNonInterpolableValue(), |
240 environment); | 224 environment); |
241 } | 225 } |
242 return; | 226 return; |
243 } | 227 } |
244 underlyingValueOwner.set(firstValue); | 228 underlyingValueOwner.set(firstValue); |
245 startingIndex++; | 229 startingIndex++; |
246 } | 230 } |
247 | 231 |
248 // Composite interpolations onto the underlying value. | 232 // Composite interpolations onto the underlying value. |
249 bool shouldApply = false; | 233 bool shouldApply = false; |
250 for (size_t i = startingIndex; i < interpolations.size(); i++) { | 234 for (size_t i = startingIndex; i < interpolations.size(); i++) { |
251 const InvalidatableInterpolation& currentInterpolation = | 235 const InvalidatableInterpolation& currentInterpolation = |
252 toInvalidatableInterpolation(*interpolations.at(i)); | 236 toInvalidatableInterpolation(*interpolations.at(i)); |
253 DCHECK(currentInterpolation.dependsOnUnderlyingValue()); | 237 DCHECK(currentInterpolation.dependsOnUnderlyingValue()); |
254 currentInterpolation.ensureValidInterpolationTypes(environment); | |
255 const TypedInterpolationValue* currentValue = | 238 const TypedInterpolationValue* currentValue = |
256 currentInterpolation.ensureValidConversion(environment, | 239 currentInterpolation.ensureValidConversion(environment, |
257 underlyingValueOwner); | 240 underlyingValueOwner); |
258 if (!currentValue) | 241 if (!currentValue) |
259 continue; | 242 continue; |
260 shouldApply = true; | 243 shouldApply = true; |
261 currentInterpolation.setFlagIfInheritUsed(environment); | 244 currentInterpolation.setFlagIfInheritUsed(environment); |
262 double underlyingFraction = currentInterpolation.underlyingFraction(); | 245 double underlyingFraction = currentInterpolation.underlyingFraction(); |
263 if (underlyingFraction == 0 || !underlyingValueOwner || | 246 if (underlyingFraction == 0 || !underlyingValueOwner || |
264 underlyingValueOwner.type() != currentValue->type()) | 247 underlyingValueOwner.type() != currentValue->type()) |
265 underlyingValueOwner.set(currentValue); | 248 underlyingValueOwner.set(currentValue); |
266 else | 249 else |
267 currentValue->type().composite(underlyingValueOwner, underlyingFraction, | 250 currentValue->type().composite(underlyingValueOwner, underlyingFraction, |
268 currentValue->value(), | 251 currentValue->value(), |
269 currentInterpolation.m_currentFraction); | 252 currentInterpolation.m_currentFraction); |
270 } | 253 } |
271 | 254 |
272 if (shouldApply && underlyingValueOwner) | 255 if (shouldApply && underlyingValueOwner) |
273 underlyingValueOwner.type().apply( | 256 underlyingValueOwner.type().apply( |
274 *underlyingValueOwner.value().interpolableValue, | 257 *underlyingValueOwner.value().interpolableValue, |
275 underlyingValueOwner.value().nonInterpolableValue.get(), environment); | 258 underlyingValueOwner.value().nonInterpolableValue.get(), environment); |
276 } | 259 } |
277 | 260 |
278 } // namespace blink | 261 } // namespace blink |
OLD | NEW |