| 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 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 | |
| 194 void InvalidatableInterpolation::setFlagIfInheritUsed( | 175 void InvalidatableInterpolation::setFlagIfInheritUsed( |
| 195 InterpolationEnvironment& environment) const { | 176 InterpolationEnvironment& environment) const { |
| 196 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) | 177 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) |
| 197 return; | 178 return; |
| 198 if (!environment.state().parentStyle()) | 179 if (!environment.state().parentStyle()) |
| 199 return; | 180 return; |
| 200 const CSSValue* startValue = | 181 const CSSValue* startValue = |
| 201 toCSSPropertySpecificKeyframe(*m_startKeyframe).value(); | 182 toCSSPropertySpecificKeyframe(*m_startKeyframe).value(); |
| 202 const CSSValue* endValue = | 183 const CSSValue* endValue = |
| 203 toCSSPropertySpecificKeyframe(*m_endKeyframe).value(); | 184 toCSSPropertySpecificKeyframe(*m_endKeyframe).value(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 220 void InvalidatableInterpolation::applyStack( | 201 void InvalidatableInterpolation::applyStack( |
| 221 const ActiveInterpolations& interpolations, | 202 const ActiveInterpolations& interpolations, |
| 222 InterpolationEnvironment& environment) { | 203 InterpolationEnvironment& environment) { |
| 223 DCHECK(!interpolations.isEmpty()); | 204 DCHECK(!interpolations.isEmpty()); |
| 224 size_t startingIndex = 0; | 205 size_t startingIndex = 0; |
| 225 | 206 |
| 226 // Compute the underlying value to composite onto. | 207 // Compute the underlying value to composite onto. |
| 227 UnderlyingValueOwner underlyingValueOwner; | 208 UnderlyingValueOwner underlyingValueOwner; |
| 228 const InvalidatableInterpolation& firstInterpolation = | 209 const InvalidatableInterpolation& firstInterpolation = |
| 229 toInvalidatableInterpolation(*interpolations.at(startingIndex)); | 210 toInvalidatableInterpolation(*interpolations.at(startingIndex)); |
| 230 firstInterpolation.ensureValidInterpolationTypes(environment); | |
| 231 if (firstInterpolation.dependsOnUnderlyingValue()) { | 211 if (firstInterpolation.dependsOnUnderlyingValue()) { |
| 232 underlyingValueOwner.set( | 212 underlyingValueOwner.set( |
| 233 firstInterpolation.maybeConvertUnderlyingValue(environment)); | 213 firstInterpolation.maybeConvertUnderlyingValue(environment)); |
| 234 } else { | 214 } else { |
| 235 const TypedInterpolationValue* firstValue = | 215 const TypedInterpolationValue* firstValue = |
| 236 firstInterpolation.ensureValidConversion(environment, | 216 firstInterpolation.ensureValidConversion(environment, |
| 237 underlyingValueOwner); | 217 underlyingValueOwner); |
| 238 // 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. |
| 239 if (interpolations.size() == 1) { | 219 if (interpolations.size() == 1) { |
| 240 if (firstValue) { | 220 if (firstValue) { |
| 241 firstInterpolation.setFlagIfInheritUsed(environment); | 221 firstInterpolation.setFlagIfInheritUsed(environment); |
| 242 firstValue->type().apply(firstValue->interpolableValue(), | 222 firstValue->type().apply(firstValue->interpolableValue(), |
| 243 firstValue->getNonInterpolableValue(), | 223 firstValue->getNonInterpolableValue(), |
| 244 environment); | 224 environment); |
| 245 } | 225 } |
| 246 return; | 226 return; |
| 247 } | 227 } |
| 248 underlyingValueOwner.set(firstValue); | 228 underlyingValueOwner.set(firstValue); |
| 249 startingIndex++; | 229 startingIndex++; |
| 250 } | 230 } |
| 251 | 231 |
| 252 // Composite interpolations onto the underlying value. | 232 // Composite interpolations onto the underlying value. |
| 253 bool shouldApply = false; | 233 bool shouldApply = false; |
| 254 for (size_t i = startingIndex; i < interpolations.size(); i++) { | 234 for (size_t i = startingIndex; i < interpolations.size(); i++) { |
| 255 const InvalidatableInterpolation& currentInterpolation = | 235 const InvalidatableInterpolation& currentInterpolation = |
| 256 toInvalidatableInterpolation(*interpolations.at(i)); | 236 toInvalidatableInterpolation(*interpolations.at(i)); |
| 257 DCHECK(currentInterpolation.dependsOnUnderlyingValue()); | 237 DCHECK(currentInterpolation.dependsOnUnderlyingValue()); |
| 258 currentInterpolation.ensureValidInterpolationTypes(environment); | |
| 259 const TypedInterpolationValue* currentValue = | 238 const TypedInterpolationValue* currentValue = |
| 260 currentInterpolation.ensureValidConversion(environment, | 239 currentInterpolation.ensureValidConversion(environment, |
| 261 underlyingValueOwner); | 240 underlyingValueOwner); |
| 262 if (!currentValue) | 241 if (!currentValue) |
| 263 continue; | 242 continue; |
| 264 shouldApply = true; | 243 shouldApply = true; |
| 265 currentInterpolation.setFlagIfInheritUsed(environment); | 244 currentInterpolation.setFlagIfInheritUsed(environment); |
| 266 double underlyingFraction = currentInterpolation.underlyingFraction(); | 245 double underlyingFraction = currentInterpolation.underlyingFraction(); |
| 267 if (underlyingFraction == 0 || !underlyingValueOwner || | 246 if (underlyingFraction == 0 || !underlyingValueOwner || |
| 268 underlyingValueOwner.type() != currentValue->type()) | 247 underlyingValueOwner.type() != currentValue->type()) |
| 269 underlyingValueOwner.set(currentValue); | 248 underlyingValueOwner.set(currentValue); |
| 270 else | 249 else |
| 271 currentValue->type().composite(underlyingValueOwner, underlyingFraction, | 250 currentValue->type().composite(underlyingValueOwner, underlyingFraction, |
| 272 currentValue->value(), | 251 currentValue->value(), |
| 273 currentInterpolation.m_currentFraction); | 252 currentInterpolation.m_currentFraction); |
| 274 } | 253 } |
| 275 | 254 |
| 276 if (shouldApply && underlyingValueOwner) | 255 if (shouldApply && underlyingValueOwner) |
| 277 underlyingValueOwner.type().apply( | 256 underlyingValueOwner.type().apply( |
| 278 *underlyingValueOwner.value().interpolableValue, | 257 *underlyingValueOwner.value().interpolableValue, |
| 279 underlyingValueOwner.value().nonInterpolableValue.get(), environment); | 258 underlyingValueOwner.value().nonInterpolableValue.get(), environment); |
| 280 } | 259 } |
| 281 | 260 |
| 282 } // namespace blink | 261 } // namespace blink |
| OLD | NEW |