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 "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 | 10 |
10 namespace blink { | 11 namespace blink { |
11 | 12 |
12 InvalidatableStyleInterpolation::InvalidatableStyleInterpolation( | 13 InvalidatableStyleInterpolation::InvalidatableStyleInterpolation( |
13 const Vector<const InterpolationType*>& interpolationTypes, | 14 const Vector<const InterpolationType*>& interpolationTypes, |
14 const CSSPropertySpecificKeyframe& startKeyframe, | 15 const CSSPropertySpecificKeyframe& startKeyframe, |
15 const CSSPropertySpecificKeyframe& endKeyframe) | 16 const CSSPropertySpecificKeyframe& endKeyframe) |
16 : StyleInterpolation(nullptr, nullptr, interpolationTypes.first()->property(
)) | 17 : StyleInterpolation(nullptr, nullptr, interpolationTypes.first()->property(
)) |
17 , m_interpolationTypes(interpolationTypes) | 18 , m_interpolationTypes(interpolationTypes) |
18 , m_startKeyframe(startKeyframe) | 19 , m_startKeyframe(startKeyframe) |
19 , m_endKeyframe(endKeyframe) | 20 , m_endKeyframe(endKeyframe) |
20 { | 21 { |
21 maybeCachePairwiseConversion(nullptr); | 22 maybeCachePairwiseConversion(nullptr, nullptr); |
22 interpolate(0, 0); | 23 interpolate(0, 0); |
23 } | 24 } |
24 | 25 |
25 bool InvalidatableStyleInterpolation::maybeCachePairwiseConversion(const StyleRe
solverState* state) const | 26 bool InvalidatableStyleInterpolation::maybeCachePairwiseConversion(const StyleRe
solverState* state, const InterpolationValue* underlyingValue) const |
26 { | 27 { |
27 for (const auto& interpolationType : m_interpolationTypes) { | 28 for (const auto& interpolationType : m_interpolationTypes) { |
| 29 if ((m_startKeyframe.isNeutral() || m_endKeyframe.isNeutral()) && (!unde
rlyingValue || underlyingValue->type() != *interpolationType)) |
| 30 continue; |
28 OwnPtrWillBeRawPtr<PairwisePrimitiveInterpolation> pairwiseConversion =
interpolationType->maybeConvertPairwise(m_startKeyframe, m_endKeyframe, state, m
_conversionCheckers); | 31 OwnPtrWillBeRawPtr<PairwisePrimitiveInterpolation> pairwiseConversion =
interpolationType->maybeConvertPairwise(m_startKeyframe, m_endKeyframe, state, m
_conversionCheckers); |
29 if (pairwiseConversion) { | 32 if (pairwiseConversion) { |
30 m_cachedValue = pairwiseConversion->initialValue(); | 33 m_cachedValue = pairwiseConversion->initialValue(); |
31 m_cachedConversion = pairwiseConversion.release(); | 34 m_cachedConversion = pairwiseConversion.release(); |
32 return true; | 35 return true; |
33 } | 36 } |
34 } | 37 } |
35 return false; | 38 return false; |
36 } | 39 } |
37 | 40 |
38 void InvalidatableStyleInterpolation::interpolate(int, double fraction) | 41 void InvalidatableStyleInterpolation::interpolate(int, double fraction) |
39 { | 42 { |
40 m_currentFraction = fraction; | 43 m_currentFraction = fraction; |
41 if (m_cachedConversion) | 44 if (m_cachedConversion) |
42 m_cachedConversion->interpolate(fraction, m_cachedValue); | 45 m_cachedConversion->interpolateValue(fraction, m_cachedValue); |
43 // We defer the interpolation to ensureValidInterpolation() if m_cachedConve
rsion is null. | 46 // We defer the interpolation to ensureValidInterpolation() if m_cachedConve
rsion is null. |
44 } | 47 } |
45 | 48 |
46 PassOwnPtrWillBeRawPtr<InterpolationValue> InvalidatableStyleInterpolation::conv
ertSingleKeyframe(const CSSPropertySpecificKeyframe& keyframe, const StyleResolv
erState& state) const | 49 PassOwnPtrWillBeRawPtr<InterpolationValue> InvalidatableStyleInterpolation::conv
ertSingleKeyframe(const CSSPropertySpecificKeyframe& keyframe, const StyleResolv
erState& state, const InterpolationValue* underlyingValue) const |
47 { | 50 { |
| 51 if (keyframe.isNeutral() && !underlyingValue) |
| 52 return nullptr; |
48 for (const auto& interpolationType : m_interpolationTypes) { | 53 for (const auto& interpolationType : m_interpolationTypes) { |
| 54 if (keyframe.isNeutral() && underlyingValue->type() != *interpolationTyp
e) |
| 55 continue; |
49 OwnPtrWillBeRawPtr<InterpolationValue> result = interpolationType->maybe
ConvertSingle(keyframe, &state, m_conversionCheckers); | 56 OwnPtrWillBeRawPtr<InterpolationValue> result = interpolationType->maybe
ConvertSingle(keyframe, &state, m_conversionCheckers); |
50 if (result) | 57 if (result) |
51 return result.release(); | 58 return result.release(); |
52 } | 59 } |
53 ASSERT_NOT_REACHED(); | 60 ASSERT(keyframe.isNeutral()); |
54 return nullptr; | 61 return nullptr; |
55 } | 62 } |
56 | 63 |
57 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta
te) const | 64 PassOwnPtrWillBeRawPtr<InterpolationValue> InvalidatableStyleInterpolation::mayb
eConvertUnderlyingValue(const StyleResolverState& state) const |
58 { | 65 { |
| 66 for (const auto& interpolationType : m_interpolationTypes) { |
| 67 OwnPtrWillBeRawPtr<InterpolationValue> result = interpolationType->maybe
ConvertUnderlyingValue(state); |
| 68 if (result) |
| 69 return result.release(); |
| 70 } |
| 71 return nullptr; |
| 72 } |
| 73 |
| 74 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const |
| 75 { |
| 76 return (m_startKeyframe.underlyingFraction() != 0 && m_currentFraction != 1)
|| (m_endKeyframe.underlyingFraction() != 0 && m_currentFraction != 0); |
| 77 } |
| 78 |
| 79 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const |
| 80 { |
| 81 return (m_startKeyframe.isNeutral() && m_currentFraction != 1) || (m_endKeyf
rame.isNeutral() && m_currentFraction != 0); |
| 82 } |
| 83 |
| 84 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta
te, const InterpolationValue* underlyingValue) const |
| 85 { |
| 86 if (isNeutralKeyframeActive()) { |
| 87 if (m_cachedConversion->isFlip()) |
| 88 return false; |
| 89 // Pairwise interpolation can never happen between different Interpolati
onTypes, neutral values always represent the underlying value. |
| 90 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under
lyingValue->type()) |
| 91 return false; |
| 92 } |
59 for (const auto& checker : m_conversionCheckers) { | 93 for (const auto& checker : m_conversionCheckers) { |
60 if (!checker->isValid(state)) | 94 if (!checker->isValid(state)) |
61 return false; | 95 return false; |
62 } | 96 } |
63 return true; | 97 return true; |
64 } | 98 } |
65 | 99 |
66 void InvalidatableStyleInterpolation::ensureValidInterpolation(const StyleResolv
erState& state) const | 100 void InvalidatableStyleInterpolation::ensureValidInterpolation(const StyleResolv
erState& state, const InterpolationValue* underlyingValue) const |
67 { | 101 { |
68 if (m_cachedConversion && isCacheValid(state)) | 102 if (m_cachedConversion && isCacheValid(state, underlyingValue)) |
69 return; | 103 return; |
70 m_conversionCheckers.clear(); | 104 m_conversionCheckers.clear(); |
71 if (!maybeCachePairwiseConversion(&state)) { | 105 if (!maybeCachePairwiseConversion(&state, underlyingValue)) { |
72 m_cachedConversion = FlipPrimitiveInterpolation::create( | 106 m_cachedConversion = FlipPrimitiveInterpolation::create( |
73 convertSingleKeyframe(m_startKeyframe, state), | 107 convertSingleKeyframe(m_startKeyframe, state, underlyingValue), |
74 convertSingleKeyframe(m_endKeyframe, state)); | 108 convertSingleKeyframe(m_endKeyframe, state, underlyingValue)); |
75 } | 109 } |
76 m_cachedConversion->interpolate(m_currentFraction, m_cachedValue); | 110 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue); |
| 111 } |
| 112 |
| 113 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s
tate) const |
| 114 { |
| 115 if (!state.parentStyle()) |
| 116 return; |
| 117 if ((m_startKeyframe.value() && m_startKeyframe.value()->isInheritedValue()) |
| 118 || (m_endKeyframe.value() && m_endKeyframe.value()->isInheritedValue()))
{ |
| 119 state.parentStyle()->setHasExplicitlyInheritedProperties(); |
| 120 } |
77 } | 121 } |
78 | 122 |
79 void InvalidatableStyleInterpolation::apply(StyleResolverState& state) const | 123 void InvalidatableStyleInterpolation::apply(StyleResolverState& state) const |
80 { | 124 { |
81 ensureValidInterpolation(state); | 125 OwnPtrWillBeRawPtr<InterpolationValue> underlyingValue = dependsOnUnderlying
Value() ? maybeConvertUnderlyingValue(state) : nullptr; |
82 m_cachedValue->type().apply(m_cachedValue->interpolableValue(), m_cachedValu
e->nonInterpolableValue(), state); | 126 ensureValidInterpolation(state, underlyingValue.get()); |
| 127 if (!m_cachedValue) |
| 128 return; |
| 129 const InterpolableValue* appliedInterpolableValue = &m_cachedValue->interpol
ableValue(); |
| 130 if (underlyingValue && m_cachedValue->type() == underlyingValue->type()) { |
| 131 double underlyingFraction = m_cachedConversion->interpolateUnderlyingFra
ction(m_startKeyframe.underlyingFraction(), m_endKeyframe.underlyingFraction(),
m_currentFraction); |
| 132 underlyingValue->interpolableValue().scaleAndAdd(underlyingFraction, m_c
achedValue->interpolableValue()); |
| 133 appliedInterpolableValue = &underlyingValue->interpolableValue(); |
| 134 } |
| 135 m_cachedValue->type().apply(*appliedInterpolableValue, m_cachedValue->nonInt
erpolableValue(), state); |
| 136 setFlagIfInheritUsed(state); |
83 } | 137 } |
84 | 138 |
85 } // namespace blink | 139 } // namespace blink |
OLD | NEW |