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()); |
147 if (isConversionCacheValid(environment, underlyingValueOwner)) | 150 if (isConversionCacheValid(environment, underlyingValueOwner)) |
148 return m_cachedValue.get(); | 151 return m_cachedValue.get(); |
149 clearConversionCache(); | 152 clearConversionCache(); |
150 if (m_currentFraction == 0) { | 153 if (m_currentFraction == 0) { |
151 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, | 154 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, |
152 underlyingValueOwner); | 155 underlyingValueOwner); |
153 } else if (m_currentFraction == 1) { | 156 } else if (m_currentFraction == 1) { |
154 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, | 157 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, |
155 underlyingValueOwner); | 158 underlyingValueOwner); |
156 } else { | 159 } else { |
157 std::unique_ptr<PairwisePrimitiveInterpolation> pairwiseConversion = | 160 std::unique_ptr<PairwisePrimitiveInterpolation> pairwiseConversion = |
158 maybeConvertPairwise(environment, underlyingValueOwner); | 161 maybeConvertPairwise(environment, underlyingValueOwner); |
159 if (pairwiseConversion) { | 162 if (pairwiseConversion) { |
160 m_cachedValue = pairwiseConversion->initialValue(); | 163 m_cachedValue = pairwiseConversion->initialValue(); |
161 m_cachedPairConversion = std::move(pairwiseConversion); | 164 m_cachedPairConversion = std::move(pairwiseConversion); |
162 } else { | 165 } else { |
163 m_cachedPairConversion = FlipPrimitiveInterpolation::create( | 166 m_cachedPairConversion = FlipPrimitiveInterpolation::create( |
164 convertSingleKeyframe(*m_startKeyframe, environment, | 167 convertSingleKeyframe(*m_startKeyframe, environment, |
165 underlyingValueOwner), | 168 underlyingValueOwner), |
166 convertSingleKeyframe(*m_endKeyframe, environment, | 169 convertSingleKeyframe(*m_endKeyframe, environment, |
167 underlyingValueOwner)); | 170 underlyingValueOwner)); |
168 } | 171 } |
169 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValue); | 172 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValue); |
170 } | 173 } |
171 m_isConversionCached = true; | 174 m_isConversionCached = true; |
172 return m_cachedValue.get(); | 175 return m_cachedValue.get(); |
173 } | 176 } |
174 | 177 |
| 178 void InvalidatableInterpolation::ensureValidInterpolationTypes( |
| 179 const InterpolationEnvironment& environment) const { |
| 180 const InterpolationTypesMap& map = environment.interpolationTypesMap(); |
| 181 size_t latestVersion = map.version(); |
| 182 if (m_interpolationTypes && m_interpolationTypesVersion == latestVersion) { |
| 183 return; |
| 184 } |
| 185 const InterpolationTypes* latestInterpolationTypes = &map.get(m_property); |
| 186 DCHECK(latestInterpolationTypes); |
| 187 if (m_interpolationTypes != latestInterpolationTypes) { |
| 188 clearConversionCache(); |
| 189 } |
| 190 m_interpolationTypes = latestInterpolationTypes; |
| 191 m_interpolationTypesVersion = latestVersion; |
| 192 } |
| 193 |
175 void InvalidatableInterpolation::setFlagIfInheritUsed( | 194 void InvalidatableInterpolation::setFlagIfInheritUsed( |
176 InterpolationEnvironment& environment) const { | 195 InterpolationEnvironment& environment) const { |
177 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) | 196 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) |
178 return; | 197 return; |
179 if (!environment.state().parentStyle()) | 198 if (!environment.state().parentStyle()) |
180 return; | 199 return; |
181 const CSSValue* startValue = | 200 const CSSValue* startValue = |
182 toCSSPropertySpecificKeyframe(*m_startKeyframe).value(); | 201 toCSSPropertySpecificKeyframe(*m_startKeyframe).value(); |
183 const CSSValue* endValue = | 202 const CSSValue* endValue = |
184 toCSSPropertySpecificKeyframe(*m_endKeyframe).value(); | 203 toCSSPropertySpecificKeyframe(*m_endKeyframe).value(); |
(...skipping 16 matching lines...) Expand all Loading... |
201 void InvalidatableInterpolation::applyStack( | 220 void InvalidatableInterpolation::applyStack( |
202 const ActiveInterpolations& interpolations, | 221 const ActiveInterpolations& interpolations, |
203 InterpolationEnvironment& environment) { | 222 InterpolationEnvironment& environment) { |
204 DCHECK(!interpolations.isEmpty()); | 223 DCHECK(!interpolations.isEmpty()); |
205 size_t startingIndex = 0; | 224 size_t startingIndex = 0; |
206 | 225 |
207 // Compute the underlying value to composite onto. | 226 // Compute the underlying value to composite onto. |
208 UnderlyingValueOwner underlyingValueOwner; | 227 UnderlyingValueOwner underlyingValueOwner; |
209 const InvalidatableInterpolation& firstInterpolation = | 228 const InvalidatableInterpolation& firstInterpolation = |
210 toInvalidatableInterpolation(*interpolations.at(startingIndex)); | 229 toInvalidatableInterpolation(*interpolations.at(startingIndex)); |
| 230 firstInterpolation.ensureValidInterpolationTypes(environment); |
211 if (firstInterpolation.dependsOnUnderlyingValue()) { | 231 if (firstInterpolation.dependsOnUnderlyingValue()) { |
212 underlyingValueOwner.set( | 232 underlyingValueOwner.set( |
213 firstInterpolation.maybeConvertUnderlyingValue(environment)); | 233 firstInterpolation.maybeConvertUnderlyingValue(environment)); |
214 } else { | 234 } else { |
215 const TypedInterpolationValue* firstValue = | 235 const TypedInterpolationValue* firstValue = |
216 firstInterpolation.ensureValidConversion(environment, | 236 firstInterpolation.ensureValidConversion(environment, |
217 underlyingValueOwner); | 237 underlyingValueOwner); |
218 // Fast path for replace interpolations that are the only one to apply. | 238 // Fast path for replace interpolations that are the only one to apply. |
219 if (interpolations.size() == 1) { | 239 if (interpolations.size() == 1) { |
220 if (firstValue) { | 240 if (firstValue) { |
221 firstInterpolation.setFlagIfInheritUsed(environment); | 241 firstInterpolation.setFlagIfInheritUsed(environment); |
222 firstValue->type().apply(firstValue->interpolableValue(), | 242 firstValue->type().apply(firstValue->interpolableValue(), |
223 firstValue->getNonInterpolableValue(), | 243 firstValue->getNonInterpolableValue(), |
224 environment); | 244 environment); |
225 } | 245 } |
226 return; | 246 return; |
227 } | 247 } |
228 underlyingValueOwner.set(firstValue); | 248 underlyingValueOwner.set(firstValue); |
229 startingIndex++; | 249 startingIndex++; |
230 } | 250 } |
231 | 251 |
232 // Composite interpolations onto the underlying value. | 252 // Composite interpolations onto the underlying value. |
233 bool shouldApply = false; | 253 bool shouldApply = false; |
234 for (size_t i = startingIndex; i < interpolations.size(); i++) { | 254 for (size_t i = startingIndex; i < interpolations.size(); i++) { |
235 const InvalidatableInterpolation& currentInterpolation = | 255 const InvalidatableInterpolation& currentInterpolation = |
236 toInvalidatableInterpolation(*interpolations.at(i)); | 256 toInvalidatableInterpolation(*interpolations.at(i)); |
237 DCHECK(currentInterpolation.dependsOnUnderlyingValue()); | 257 DCHECK(currentInterpolation.dependsOnUnderlyingValue()); |
| 258 currentInterpolation.ensureValidInterpolationTypes(environment); |
238 const TypedInterpolationValue* currentValue = | 259 const TypedInterpolationValue* currentValue = |
239 currentInterpolation.ensureValidConversion(environment, | 260 currentInterpolation.ensureValidConversion(environment, |
240 underlyingValueOwner); | 261 underlyingValueOwner); |
241 if (!currentValue) | 262 if (!currentValue) |
242 continue; | 263 continue; |
243 shouldApply = true; | 264 shouldApply = true; |
244 currentInterpolation.setFlagIfInheritUsed(environment); | 265 currentInterpolation.setFlagIfInheritUsed(environment); |
245 double underlyingFraction = currentInterpolation.underlyingFraction(); | 266 double underlyingFraction = currentInterpolation.underlyingFraction(); |
246 if (underlyingFraction == 0 || !underlyingValueOwner || | 267 if (underlyingFraction == 0 || !underlyingValueOwner || |
247 underlyingValueOwner.type() != currentValue->type()) | 268 underlyingValueOwner.type() != currentValue->type()) |
248 underlyingValueOwner.set(currentValue); | 269 underlyingValueOwner.set(currentValue); |
249 else | 270 else |
250 currentValue->type().composite(underlyingValueOwner, underlyingFraction, | 271 currentValue->type().composite(underlyingValueOwner, underlyingFraction, |
251 currentValue->value(), | 272 currentValue->value(), |
252 currentInterpolation.m_currentFraction); | 273 currentInterpolation.m_currentFraction); |
253 } | 274 } |
254 | 275 |
255 if (shouldApply && underlyingValueOwner) | 276 if (shouldApply && underlyingValueOwner) |
256 underlyingValueOwner.type().apply( | 277 underlyingValueOwner.type().apply( |
257 *underlyingValueOwner.value().interpolableValue, | 278 *underlyingValueOwner.value().interpolableValue, |
258 underlyingValueOwner.value().nonInterpolableValue.get(), environment); | 279 underlyingValueOwner.value().nonInterpolableValue.get(), environment); |
259 } | 280 } |
260 | 281 |
261 } // namespace blink | 282 } // namespace blink |
OLD | NEW |