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

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

Issue 2236193002: WIP: Implement CSS transitions on top of InterpolationTypes instead of AnimatableValues (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@_environmentStyle
Patch Set: Created 4 years, 4 months 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/KeyframeInterpolation.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>
11 11
12 namespace blink { 12 namespace blink {
13 13
14 void InvalidatableInterpolation::interpolate(int, double fraction) 14 void KeyframeInterpolation::interpolateImpl()
15 { 15 {
16 if (fraction == m_currentFraction) 16 DCHECK(m_previousFraction != m_currentFraction);
17 return;
18 17
19 if (m_currentFraction == 0 || m_currentFraction == 1 || fraction == 0 || fra ction == 1) 18 if (m_previousFraction == 0 || m_previousFraction == 1 || m_currentFraction == 0 || m_currentFraction == 1)
20 clearCache(); 19 clearCache();
21 20
22 m_currentFraction = fraction; 21 m_previousFraction = m_currentFraction;
23 if (m_isCached && m_cachedPairConversion) 22 if (m_isCached && m_cachedPairConversion)
24 m_cachedPairConversion->interpolateValue(fraction, m_cachedValue); 23 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e);
25 // We defer the interpolation to ensureValidInterpolation() if m_cachedPairC onversion is null. 24 // We defer the interpolation to ensureValidInterpolation() if m_cachedPairC onversion is null.
26 } 25 }
27 26
28 std::unique_ptr<PairwisePrimitiveInterpolation> InvalidatableInterpolation::mayb eConvertPairwise(const InterpolationEnvironment& environment, const UnderlyingVa lueOwner& underlyingValueOwner) const 27 std::unique_ptr<PairwisePrimitiveInterpolation> KeyframeInterpolation::maybeConv ertPairwise(const InterpolationEnvironment& environment, const UnderlyingValueOw ner& underlyingValueOwner) const
29 { 28 {
30 ASSERT(m_currentFraction != 0 && m_currentFraction != 1); 29 DCHECK(m_currentFraction != 0 && m_currentFraction != 1);
31 for (const auto& interpolationType : m_interpolationTypes) { 30 for (const auto& interpolationType : m_interpolationTypes) {
32 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!un derlyingValueOwner || underlyingValueOwner.type() != *interpolationType)) 31 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!un derlyingValueOwner || underlyingValueOwner.type() != *interpolationType))
33 continue; 32 continue;
34 ConversionCheckers conversionCheckers; 33 ConversionCheckers conversionCheckers;
35 PairwiseInterpolationValue result = interpolationType->maybeConvertPairw ise(*m_startKeyframe, *m_endKeyframe, environment, underlyingValueOwner.value(), conversionCheckers); 34 PairwiseInterpolationValue result = interpolationType->maybeConvertPairw ise(*m_startKeyframe, *m_endKeyframe, environment, underlyingValueOwner.value(), conversionCheckers);
36 addConversionCheckers(*interpolationType, conversionCheckers); 35 addConversionCheckers(*interpolationType, conversionCheckers);
37 if (result) { 36 if (result)
38 return PairwisePrimitiveInterpolation::create(*interpolationType, 37 return PairwisePrimitiveInterpolation::create(*interpolationType, st d::move(result));
39 std::move(result.startInterpolableValue),
40 std::move(result.endInterpolableValue),
41 result.nonInterpolableValue.release());
42 }
43 } 38 }
44 return nullptr; 39 return nullptr;
45 } 40 }
46 41
47 std::unique_ptr<TypedInterpolationValue> InvalidatableInterpolation::convertSing leKeyframe(const PropertySpecificKeyframe& keyframe, const InterpolationEnvironm ent& environment, const UnderlyingValueOwner& underlyingValueOwner) const 42 std::unique_ptr<TypedInterpolationValue> KeyframeInterpolation::convertSingleKey frame(const PropertySpecificKeyframe& keyframe, const InterpolationEnvironment& environment, const UnderlyingValueOwner& underlyingValueOwner) const
48 { 43 {
49 if (keyframe.isNeutral() && !underlyingValueOwner) 44 if (keyframe.isNeutral() && !underlyingValueOwner)
50 return nullptr; 45 return nullptr;
51 for (const auto& interpolationType : m_interpolationTypes) { 46 for (const auto& interpolationType : m_interpolationTypes) {
52 if (keyframe.isNeutral() && underlyingValueOwner.type() != *interpolatio nType) 47 if (keyframe.isNeutral() && underlyingValueOwner.type() != *interpolatio nType)
53 continue; 48 continue;
54 ConversionCheckers conversionCheckers; 49 ConversionCheckers conversionCheckers;
55 InterpolationValue result = interpolationType->maybeConvertSingle(keyfra me, environment, underlyingValueOwner.value(), conversionCheckers); 50 InterpolationValue result = interpolationType->maybeConvertSingle(keyfra me, environment, underlyingValueOwner.value(), conversionCheckers);
56 addConversionCheckers(*interpolationType, conversionCheckers); 51 addConversionCheckers(*interpolationType, conversionCheckers);
57 if (result) 52 if (result)
58 return TypedInterpolationValue::create(*interpolationType, std::move (result.interpolableValue), result.nonInterpolableValue.release()); 53 return TypedInterpolationValue::create(*interpolationType, std::move (result));
59 } 54 }
60 ASSERT(keyframe.isNeutral()); 55 DCHECK(keyframe.isNeutral());
61 return nullptr; 56 return nullptr;
62 } 57 }
63 58
64 void InvalidatableInterpolation::addConversionCheckers(const InterpolationType& type, ConversionCheckers& conversionCheckers) const 59 void KeyframeInterpolation::addConversionCheckers(const InterpolationType& type, ConversionCheckers& conversionCheckers) const
65 { 60 {
66 for (size_t i = 0; i < conversionCheckers.size(); i++) { 61 for (size_t i = 0; i < conversionCheckers.size(); i++) {
67 conversionCheckers[i]->setType(type); 62 conversionCheckers[i]->setType(type);
68 m_conversionCheckers.append(std::move(conversionCheckers[i])); 63 m_conversionCheckers.append(std::move(conversionCheckers[i]));
69 } 64 }
70 } 65 }
71 66
72 std::unique_ptr<TypedInterpolationValue> InvalidatableInterpolation::maybeConver tUnderlyingValue(const InterpolationEnvironment& environment) const 67 std::unique_ptr<TypedInterpolationValue> KeyframeInterpolation::maybeConvertUnde rlyingValue(const InterpolationEnvironment& environment) const
73 { 68 {
74 for (const auto& interpolationType : m_interpolationTypes) { 69 for (const auto& interpolationType : m_interpolationTypes) {
75 InterpolationValue result = interpolationType->maybeConvertUnderlyingVal ue(environment); 70 InterpolationValue result = interpolationType->maybeConvertUnderlyingVal ue(environment);
76 if (result) 71 if (result)
77 return TypedInterpolationValue::create(*interpolationType, std::move (result.interpolableValue), result.nonInterpolableValue.release()); 72 return TypedInterpolationValue::create(*interpolationType, std::move (result));
78 } 73 }
79 return nullptr; 74 return nullptr;
80 } 75 }
81 76
82 bool InvalidatableInterpolation::dependsOnUnderlyingValue() const 77 bool KeyframeInterpolation::dependsOnUnderlyingValue() const
83 { 78 {
84 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0); 79 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0);
85 } 80 }
86 81
87 bool InvalidatableInterpolation::isNeutralKeyframeActive() const 82 bool KeyframeInterpolation::isNeutralKeyframeActive() const
88 { 83 {
89 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0); 84 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0);
90 } 85 }
91 86
92 void InvalidatableInterpolation::clearCache() const 87 void KeyframeInterpolation::clearCache() const
93 { 88 {
94 m_isCached = false; 89 m_isCached = false;
95 m_cachedPairConversion.reset(); 90 m_cachedPairConversion.reset();
96 m_conversionCheckers.clear(); 91 m_conversionCheckers.clear();
97 m_cachedValue.reset(); 92 m_cachedValue.reset();
98 } 93 }
99 94
100 bool InvalidatableInterpolation::isCacheValid(const InterpolationEnvironment& en vironment, const UnderlyingValueOwner& underlyingValueOwner) const 95 bool KeyframeInterpolation::isCacheValid(const InterpolationEnvironment& environ ment, const UnderlyingValueOwner& underlyingValueOwner) const
101 { 96 {
102 if (!m_isCached) 97 if (!m_isCached)
103 return false; 98 return false;
104 if (isNeutralKeyframeActive()) { 99 if (isNeutralKeyframeActive()) {
105 if (m_cachedPairConversion && m_cachedPairConversion->isFlip()) 100 if (m_cachedPairConversion && m_cachedPairConversion->isFlip())
106 return false; 101 return false;
107 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value. 102 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value.
108 if (!underlyingValueOwner || !m_cachedValue || m_cachedValue->type() != underlyingValueOwner.type()) 103 if (!underlyingValueOwner || !m_cachedValue || m_cachedValue->type() != underlyingValueOwner.type())
109 return false; 104 return false;
110 } 105 }
111 for (const auto& checker : m_conversionCheckers) { 106 for (const auto& checker : m_conversionCheckers) {
112 if (!checker->isValid(environment, underlyingValueOwner.value())) 107 if (!checker->isValid(environment, underlyingValueOwner.value()))
113 return false; 108 return false;
114 } 109 }
115 return true; 110 return true;
116 } 111 }
117 112
118 const TypedInterpolationValue* InvalidatableInterpolation::ensureValidInterpolat ion(const InterpolationEnvironment& environment, const UnderlyingValueOwner& und erlyingValueOwner) const 113 const TypedInterpolationValue* KeyframeInterpolation::ensureValidInterpolation(c onst InterpolationEnvironment& environment, const UnderlyingValueOwner& underlyi ngValueOwner) const
119 { 114 {
120 ASSERT(!std::isnan(m_currentFraction)); 115 DCHECK(!std::isnan(m_currentFraction));
121 if (isCacheValid(environment, underlyingValueOwner)) 116 if (isCacheValid(environment, underlyingValueOwner))
122 return m_cachedValue.get(); 117 return m_cachedValue.get();
123 clearCache(); 118 clearCache();
124 if (m_currentFraction == 0) { 119 if (m_currentFraction == 0) {
125 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, und erlyingValueOwner); 120 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, und erlyingValueOwner);
126 } else if (m_currentFraction == 1) { 121 } else if (m_currentFraction == 1) {
127 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, under lyingValueOwner); 122 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, under lyingValueOwner);
128 } else { 123 } else {
129 std::unique_ptr<PairwisePrimitiveInterpolation> pairwiseConversion = may beConvertPairwise(environment, underlyingValueOwner); 124 std::unique_ptr<PairwisePrimitiveInterpolation> pairwiseConversion = may beConvertPairwise(environment, underlyingValueOwner);
130 if (pairwiseConversion) { 125 if (pairwiseConversion) {
131 m_cachedValue = pairwiseConversion->initialValue(); 126 m_cachedValue = pairwiseConversion->initialValue();
132 m_cachedPairConversion = std::move(pairwiseConversion); 127 m_cachedPairConversion = std::move(pairwiseConversion);
133 } else { 128 } else {
134 m_cachedPairConversion = FlipPrimitiveInterpolation::create( 129 m_cachedPairConversion = FlipPrimitiveInterpolation::create(
135 convertSingleKeyframe(*m_startKeyframe, environment, underlyingV alueOwner), 130 convertSingleKeyframe(*m_startKeyframe, environment, underlyingV alueOwner),
136 convertSingleKeyframe(*m_endKeyframe, environment, underlyingVal ueOwner)); 131 convertSingleKeyframe(*m_endKeyframe, environment, underlyingVal ueOwner));
137 } 132 }
138 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e); 133 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e);
139 } 134 }
140 m_isCached = true; 135 m_isCached = true;
141 return m_cachedValue.get(); 136 return m_cachedValue.get();
142 } 137 }
143 138
144 void InvalidatableInterpolation::setFlagIfInheritUsed(InterpolationEnvironment& environment) const 139 void KeyframeInterpolation::setFlagIfInheritUsed(InterpolationEnvironment& envir onment) const
145 { 140 {
146 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute()) 141 if (!m_property.isCSSProperty() && !m_property.isPresentationAttribute())
147 return; 142 return;
148 if (!environment.state().parentStyle()) 143 if (!environment.state().parentStyle())
149 return; 144 return;
150 const CSSValue* startValue = toCSSPropertySpecificKeyframe(*m_startKeyframe) .value(); 145 const CSSValue* startValue = toCSSPropertySpecificKeyframe(*m_startKeyframe) .value();
151 const CSSValue* endValue = toCSSPropertySpecificKeyframe(*m_endKeyframe).val ue(); 146 const CSSValue* endValue = toCSSPropertySpecificKeyframe(*m_endKeyframe).val ue();
152 if ((startValue && startValue->isInheritedValue()) 147 if ((startValue && startValue->isInheritedValue())
153 || (endValue && endValue->isInheritedValue())) { 148 || (endValue && endValue->isInheritedValue())) {
154 environment.state().parentStyle()->setHasExplicitlyInheritedProperties() ; 149 environment.state().parentStyle()->setHasExplicitlyInheritedProperties() ;
155 } 150 }
156 } 151 }
157 152
158 double InvalidatableInterpolation::underlyingFraction() const 153 double KeyframeInterpolation::underlyingFraction() const
159 { 154 {
160 if (m_currentFraction == 0) 155 if (m_currentFraction == 0)
161 return m_startKeyframe->underlyingFraction(); 156 return m_startKeyframe->underlyingFraction();
162 if (m_currentFraction == 1) 157 if (m_currentFraction == 1)
163 return m_endKeyframe->underlyingFraction(); 158 return m_endKeyframe->underlyingFraction();
164 return m_cachedPairConversion->interpolateUnderlyingFraction(m_startKeyframe ->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction); 159 return m_cachedPairConversion->interpolateUnderlyingFraction(m_startKeyframe ->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction);
165 } 160 }
166 161
167 void InvalidatableInterpolation::applyStack(const ActiveInterpolations& interpol ations, InterpolationEnvironment& environment) 162 void KeyframeInterpolation::applyStack(const ActiveInterpolations& interpolation s, InterpolationEnvironment& environment)
168 { 163 {
169 ASSERT(!interpolations.isEmpty()); 164 DCHECK(!interpolations.isEmpty());
170 size_t startingIndex = 0; 165 size_t startingIndex = 0;
171 166
172 // Compute the underlying value to composite onto. 167 // Compute the underlying value to composite onto.
173 UnderlyingValueOwner underlyingValueOwner; 168 UnderlyingValueOwner underlyingValueOwner;
174 const InvalidatableInterpolation& firstInterpolation = toInvalidatableInterp olation(*interpolations.at(startingIndex)); 169 const KeyframeInterpolation& firstInterpolation = toKeyframeInterpolation(*i nterpolations.at(startingIndex));
175 if (firstInterpolation.dependsOnUnderlyingValue()) { 170 if (firstInterpolation.dependsOnUnderlyingValue()) {
176 underlyingValueOwner.set(firstInterpolation.maybeConvertUnderlyingValue( environment)); 171 underlyingValueOwner.set(firstInterpolation.maybeConvertUnderlyingValue( environment));
177 } else { 172 } else {
178 const TypedInterpolationValue* firstValue = firstInterpolation.ensureVal idInterpolation(environment, underlyingValueOwner); 173 const TypedInterpolationValue* firstValue = firstInterpolation.ensureVal idInterpolation(environment, underlyingValueOwner);
179 // Fast path for replace interpolations that are the only one to apply. 174 // Fast path for replace interpolations that are the only one to apply.
180 if (interpolations.size() == 1) { 175 if (interpolations.size() == 1) {
181 if (firstValue) { 176 if (firstValue) {
182 firstInterpolation.setFlagIfInheritUsed(environment); 177 firstInterpolation.setFlagIfInheritUsed(environment);
183 firstValue->type().apply(firstValue->interpolableValue(), firstV alue->getNonInterpolableValue(), environment); 178 firstValue->type().apply(firstValue->interpolableValue(), firstV alue->getNonInterpolableValue(), environment);
184 } 179 }
185 return; 180 return;
186 } 181 }
187 underlyingValueOwner.set(firstValue); 182 underlyingValueOwner.set(firstValue);
188 startingIndex++; 183 startingIndex++;
189 } 184 }
190 185
191 // Composite interpolations onto the underlying value. 186 // Composite interpolations onto the underlying value.
192 bool shouldApply = false; 187 bool shouldApply = false;
193 for (size_t i = startingIndex; i < interpolations.size(); i++) { 188 for (size_t i = startingIndex; i < interpolations.size(); i++) {
194 const InvalidatableInterpolation& currentInterpolation = toInvalidatable Interpolation(*interpolations.at(i)); 189 const KeyframeInterpolation& currentInterpolation = toKeyframeInterpolat ion(*interpolations.at(i));
195 ASSERT(currentInterpolation.dependsOnUnderlyingValue()); 190 DCHECK(currentInterpolation.dependsOnUnderlyingValue());
196 const TypedInterpolationValue* currentValue = currentInterpolation.ensur eValidInterpolation(environment, underlyingValueOwner); 191 const TypedInterpolationValue* currentValue = currentInterpolation.ensur eValidInterpolation(environment, underlyingValueOwner);
197 if (!currentValue) 192 if (!currentValue)
198 continue; 193 continue;
199 shouldApply = true; 194 shouldApply = true;
200 currentInterpolation.setFlagIfInheritUsed(environment); 195 currentInterpolation.setFlagIfInheritUsed(environment);
201 double underlyingFraction = currentInterpolation.underlyingFraction(); 196 double underlyingFraction = currentInterpolation.underlyingFraction();
202 if (underlyingFraction == 0 || !underlyingValueOwner || underlyingValueO wner.type() != currentValue->type()) 197 if (underlyingFraction == 0 || !underlyingValueOwner || underlyingValueO wner.type() != currentValue->type())
203 underlyingValueOwner.set(currentValue); 198 underlyingValueOwner.set(currentValue);
204 else 199 else
205 currentValue->type().composite(underlyingValueOwner, underlyingFract ion, currentValue->value(), currentInterpolation.m_currentFraction); 200 currentValue->type().composite(underlyingValueOwner, underlyingFract ion, currentValue->value(), currentInterpolation.m_currentFraction);
206 } 201 }
207 202
208 if (shouldApply && underlyingValueOwner) 203 if (shouldApply && underlyingValueOwner)
209 underlyingValueOwner.type().apply(*underlyingValueOwner.value().interpol ableValue, underlyingValueOwner.value().nonInterpolableValue.get(), environment) ; 204 underlyingValueOwner.type().apply(*underlyingValueOwner.value().interpol ableValue, underlyingValueOwner.value().nonInterpolableValue.get(), environment) ;
210 } 205 }
211 206
212 } // namespace blink 207 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698