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

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

Issue 1394343003: Web Animations: Remove CSS dependence from InterpolationType (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@_specialCase0and1
Patch Set: NIVs Created 5 years, 1 month 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 "config.h" 5 #include "config.h"
6 #include "core/animation/InvalidatableStyleInterpolation.h" 6 #include "core/animation/InvalidatableStyleInterpolation.h"
7 7
8 #include "core/animation/InterpolationEnvironment.h"
8 #include "core/animation/StringKeyframe.h" 9 #include "core/animation/StringKeyframe.h"
9 #include "core/css/resolver/StyleResolverState.h" 10 #include "core/css/resolver/StyleResolverState.h"
10 11
11 namespace blink { 12 namespace blink {
12 13
13 void InvalidatableStyleInterpolation::interpolate(int, double fraction) 14 void InvalidatableStyleInterpolation::interpolate(int, double fraction)
14 { 15 {
15 if (fraction == m_currentFraction) 16 if (fraction == m_currentFraction)
16 return; 17 return;
17 18
18 if (m_currentFraction == 0 || m_currentFraction == 1 || fraction == 0 || fra ction == 1) 19 if (m_currentFraction == 0 || m_currentFraction == 1 || fraction == 0 || fra ction == 1)
19 clearCache(); 20 clearCache();
20 21
21 m_currentFraction = fraction; 22 m_currentFraction = fraction;
22 if (m_isCached && m_cachedPairConversion) 23 if (m_isCached && m_cachedPairConversion)
23 m_cachedPairConversion->interpolateValue(fraction, m_cachedValue); 24 m_cachedPairConversion->interpolateValue(fraction, m_cachedValue);
24 // We defer the interpolation to ensureValidInterpolation() if m_cachedPairC onversion is null. 25 // We defer the interpolation to ensureValidInterpolation() if m_cachedPairC onversion is null.
25 } 26 }
26 27
27 PassOwnPtr<PairwisePrimitiveInterpolation> InvalidatableStyleInterpolation::mayb eConvertPairwise(const StyleResolverState* state, const UnderlyingValue& underly ingValue) const 28 PassOwnPtr<PairwisePrimitiveInterpolation> InvalidatableStyleInterpolation::mayb eConvertPairwise(const InterpolationEnvironment* environment, const UnderlyingVa lue& underlyingValue) const
28 { 29 {
29 ASSERT(m_currentFraction != 0 && m_currentFraction != 1); 30 ASSERT(m_currentFraction != 0 && m_currentFraction != 1);
30 for (const auto& interpolationType : m_interpolationTypes) { 31 for (const auto& interpolationType : m_interpolationTypes) {
31 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!un derlyingValue || underlyingValue->type() != *interpolationType)) 32 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!un derlyingValue || underlyingValue->type() != *interpolationType))
32 continue; 33 continue;
33 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = interpolatio nType->maybeConvertPairwise(*m_startKeyframe, *m_endKeyframe, state, underlyingV alue, m_conversionCheckers); 34 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = interpolatio nType->maybeConvertPairwise(*m_startKeyframe, *m_endKeyframe, environment, under lyingValue, m_conversionCheckers);
34 if (pairwiseConversion) { 35 if (pairwiseConversion) {
35 ASSERT(pairwiseConversion->type() == *interpolationType); 36 ASSERT(pairwiseConversion->type() == *interpolationType);
36 return pairwiseConversion.release(); 37 return pairwiseConversion.release();
37 } 38 }
38 } 39 }
39 return nullptr; 40 return nullptr;
40 } 41 }
41 42
42 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::convertSingleKey frame(const CSSPropertySpecificKeyframe& keyframe, const StyleResolverState& sta te, const UnderlyingValue& underlyingValue) const 43 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::convertSingleKey frame(const PropertySpecificKeyframe& keyframe, const InterpolationEnvironment& environment, const UnderlyingValue& underlyingValue) const
43 { 44 {
44 if (keyframe.isNeutral() && !underlyingValue) 45 if (keyframe.isNeutral() && !underlyingValue)
45 return nullptr; 46 return nullptr;
46 for (const auto& interpolationType : m_interpolationTypes) { 47 for (const auto& interpolationType : m_interpolationTypes) {
47 if (keyframe.isNeutral() && underlyingValue->type() != *interpolationTyp e) 48 if (keyframe.isNeutral() && underlyingValue->type() != *interpolationTyp e)
48 continue; 49 continue;
49 OwnPtr<InterpolationValue> result = interpolationType->maybeConvertSingl e(keyframe, &state, underlyingValue, m_conversionCheckers); 50 OwnPtr<InterpolationValue> result = interpolationType->maybeConvertSingl e(keyframe, &environment, underlyingValue, m_conversionCheckers);
50 if (result) { 51 if (result) {
51 ASSERT(result->type() == *interpolationType); 52 ASSERT(result->type() == *interpolationType);
52 return result.release(); 53 return result.release();
53 } 54 }
54 } 55 }
55 ASSERT(keyframe.isNeutral()); 56 ASSERT(keyframe.isNeutral());
56 return nullptr; 57 return nullptr;
57 } 58 }
58 59
59 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::maybeConvertUnde rlyingValue(const StyleResolverState& state) const 60 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::maybeConvertUnde rlyingValue(const InterpolationEnvironment& environment) const
60 { 61 {
61 for (const auto& interpolationType : m_interpolationTypes) { 62 for (const auto& interpolationType : m_interpolationTypes) {
62 OwnPtr<InterpolationValue> result = interpolationType->maybeConvertUnder lyingValue(state); 63 OwnPtr<InterpolationValue> result = interpolationType->maybeConvertUnder lyingValue(environment);
63 if (result) 64 if (result)
64 return result.release(); 65 return result.release();
65 } 66 }
66 return nullptr; 67 return nullptr;
67 } 68 }
68 69
69 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const 70 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const
70 { 71 {
71 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0); 72 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0);
72 } 73 }
73 74
74 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const 75 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const
75 { 76 {
76 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0); 77 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0);
77 } 78 }
78 79
79 void InvalidatableStyleInterpolation::clearCache() const 80 void InvalidatableStyleInterpolation::clearCache() const
80 { 81 {
81 m_isCached = false; 82 m_isCached = false;
82 m_cachedPairConversion.clear(); 83 m_cachedPairConversion.clear();
83 m_conversionCheckers.clear(); 84 m_conversionCheckers.clear();
84 m_cachedValue.clear(); 85 m_cachedValue.clear();
85 } 86 }
86 87
87 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta te, const UnderlyingValue& underlyingValue) const 88 bool InvalidatableStyleInterpolation::isCacheValid(const InterpolationEnvironmen t& environment, const UnderlyingValue& underlyingValue) const
88 { 89 {
89 if (!m_isCached) 90 if (!m_isCached)
90 return false; 91 return false;
91 if (isNeutralKeyframeActive()) { 92 if (isNeutralKeyframeActive()) {
92 if (m_cachedPairConversion && m_cachedPairConversion->isFlip()) 93 if (m_cachedPairConversion && m_cachedPairConversion->isFlip())
93 return false; 94 return false;
94 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value. 95 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value.
95 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type()) 96 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type())
96 return false; 97 return false;
97 } 98 }
98 for (const auto& checker : m_conversionCheckers) { 99 for (const auto& checker : m_conversionCheckers) {
99 if (!checker->isValid(state, underlyingValue)) 100 if (!checker->isValid(environment, underlyingValue))
100 return false; 101 return false;
101 } 102 }
102 return true; 103 return true;
103 } 104 }
104 105
105 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const UnderlyingValue& underlyingValue) con st 106 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const InterpolationEnvironment& environment, const UnderlyingValue& underlyi ngValue) const
106 { 107 {
107 ASSERT(!std::isnan(m_currentFraction)); 108 ASSERT(!std::isnan(m_currentFraction));
108 if (isCacheValid(state, underlyingValue)) 109 if (isCacheValid(environment, underlyingValue))
109 return m_cachedValue.get(); 110 return m_cachedValue.get();
110 clearCache(); 111 clearCache();
111 if (m_currentFraction == 0) { 112 if (m_currentFraction == 0) {
112 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, state, underlyin gValue); 113 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, environment, und erlyingValue);
113 } else if (m_currentFraction == 1) { 114 } else if (m_currentFraction == 1) {
114 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, state, underlyingV alue); 115 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, environment, under lyingValue);
115 } else { 116 } else {
116 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = maybeConvert Pairwise(&state, underlyingValue); 117 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = maybeConvert Pairwise(&environment, underlyingValue);
117 if (pairwiseConversion) { 118 if (pairwiseConversion) {
118 m_cachedValue = pairwiseConversion->initialValue(); 119 m_cachedValue = pairwiseConversion->initialValue();
119 m_cachedPairConversion = pairwiseConversion.release(); 120 m_cachedPairConversion = pairwiseConversion.release();
120 } else { 121 } else {
121 m_cachedPairConversion = FlipPrimitiveInterpolation::create( 122 m_cachedPairConversion = FlipPrimitiveInterpolation::create(
122 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue), 123 convertSingleKeyframe(*m_startKeyframe, environment, underlyingV alue),
123 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue)); 124 convertSingleKeyframe(*m_endKeyframe, environment, underlyingVal ue));
124 } 125 }
125 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e); 126 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e);
126 } 127 }
127 m_isCached = true; 128 m_isCached = true;
128 return m_cachedValue.get(); 129 return m_cachedValue.get();
129 } 130 }
130 131
131 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const 132 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(InterpolationEnvironm ent& environment) const
132 { 133 {
133 if (!state.parentStyle()) 134 if (!property().isCSSProperty())
134 return; 135 return;
135 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( )) 136 if (!environment.state().parentStyle())
136 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) { 137 return;
137 state.parentStyle()->setHasExplicitlyInheritedProperties(); 138 const CSSValue* startValue = toCSSPropertySpecificKeyframe(m_startKeyframe)- >value();
139 const CSSValue* endValue = toCSSPropertySpecificKeyframe(m_endKeyframe)->val ue();
140 if ((startValue && startValue->isInheritedValue())
141 || (endValue && endValue->isInheritedValue())) {
142 environment.state().parentStyle()->setHasExplicitlyInheritedProperties() ;
138 } 143 }
139 } 144 }
140 145
141 double InvalidatableStyleInterpolation::underlyingFraction() const 146 double InvalidatableStyleInterpolation::underlyingFraction() const
142 { 147 {
143 if (m_currentFraction == 0) 148 if (m_currentFraction == 0)
144 return m_startKeyframe->underlyingFraction(); 149 return m_startKeyframe->underlyingFraction();
145 if (m_currentFraction == 1) 150 if (m_currentFraction == 1)
146 return m_endKeyframe->underlyingFraction(); 151 return m_endKeyframe->underlyingFraction();
147 return m_cachedPairConversion->interpolateUnderlyingFraction(m_startKeyframe ->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction); 152 return m_cachedPairConversion->interpolateUnderlyingFraction(m_startKeyframe ->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction);
148 } 153 }
149 154
150 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state) 155 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, InterpolationEnvironment& environment)
151 { 156 {
152 ASSERT(!interpolations.isEmpty()); 157 ASSERT(!interpolations.isEmpty());
153 size_t startingIndex = 0; 158 size_t startingIndex = 0;
154 159
155 // Compute the underlying value to composite onto. 160 // Compute the underlying value to composite onto.
156 UnderlyingValue underlyingValue; 161 UnderlyingValue underlyingValue;
157 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex)); 162 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex));
158 if (firstInterpolation.dependsOnUnderlyingValue()) { 163 if (firstInterpolation.dependsOnUnderlyingValue()) {
159 underlyingValue.set(firstInterpolation.maybeConvertUnderlyingValue(state )); 164 underlyingValue.set(firstInterpolation.maybeConvertUnderlyingValue(envir onment));
160 } else { 165 } else {
161 const InterpolationValue* firstValue = firstInterpolation.ensureValidInt erpolation(state, UnderlyingValue()); 166 const InterpolationValue* firstValue = firstInterpolation.ensureValidInt erpolation(environment, UnderlyingValue());
162 // Fast path for replace interpolations that are the only one to apply. 167 // Fast path for replace interpolations that are the only one to apply.
163 if (interpolations.size() == 1) { 168 if (interpolations.size() == 1) {
164 if (firstValue) { 169 if (firstValue) {
165 firstInterpolation.setFlagIfInheritUsed(state); 170 firstInterpolation.setFlagIfInheritUsed(environment);
166 firstValue->type().apply(firstValue->interpolableValue(), firstV alue->nonInterpolableValue(), state); 171 firstValue->type().apply(firstValue->interpolableValue(), firstV alue->nonInterpolableValue(), environment);
167 } 172 }
168 return; 173 return;
169 } 174 }
170 underlyingValue.set(firstValue); 175 underlyingValue.set(firstValue);
171 startingIndex++; 176 startingIndex++;
172 } 177 }
173 178
174 // Composite interpolations onto the underlying value. 179 // Composite interpolations onto the underlying value.
175 bool shouldApply = false; 180 bool shouldApply = false;
176 for (size_t i = startingIndex; i < interpolations.size(); i++) { 181 for (size_t i = startingIndex; i < interpolations.size(); i++) {
177 const InvalidatableStyleInterpolation& currentInterpolation = toInvalida tableStyleInterpolation(*interpolations.at(i)); 182 const InvalidatableStyleInterpolation& currentInterpolation = toInvalida tableStyleInterpolation(*interpolations.at(i));
178 ASSERT(currentInterpolation.dependsOnUnderlyingValue()); 183 ASSERT(currentInterpolation.dependsOnUnderlyingValue());
179 const InterpolationValue* currentValue = currentInterpolation.ensureVali dInterpolation(state, underlyingValue); 184 const InterpolationValue* currentValue = currentInterpolation.ensureVali dInterpolation(environment, underlyingValue);
180 if (!currentValue) 185 if (!currentValue)
181 continue; 186 continue;
182 shouldApply = true; 187 shouldApply = true;
183 currentInterpolation.setFlagIfInheritUsed(state); 188 currentInterpolation.setFlagIfInheritUsed(environment);
184 double underlyingFraction = currentInterpolation.underlyingFraction(); 189 double underlyingFraction = currentInterpolation.underlyingFraction();
185 if (underlyingFraction == 0 || !underlyingValue || underlyingValue->type () != currentValue->type()) 190 if (underlyingFraction == 0 || !underlyingValue || underlyingValue->type () != currentValue->type())
186 underlyingValue.set(currentValue); 191 underlyingValue.set(currentValue);
187 else 192 else
188 currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue); 193 currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue);
189 } 194 }
190 195
191 if (shouldApply && underlyingValue) 196 if (shouldApply && underlyingValue)
192 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state); 197 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), environment);
193 } 198 }
194 199
195 } // namespace blink 200 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698