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

Side by Side Diff: third_party/WebKit/Source/core/animation/InvalidatableInterpolation.cpp

Issue 2555923003: Make InvalidatableInterpolation's InterpolationTypes decided at effect application time (Closed)
Patch Set: Extended InterpolationTypesMap lifetime scope to fix release crash Created 4 years 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
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 "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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698