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 #include "core/css/resolver/StyleResolverState.h" |
10 | 10 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s
tate) const | 114 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s
tate) const |
115 { | 115 { |
116 if (!state.parentStyle()) | 116 if (!state.parentStyle()) |
117 return; | 117 return; |
118 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue(
)) | 118 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue(
)) |
119 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue()
)) { | 119 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue()
)) { |
120 state.parentStyle()->setHasExplicitlyInheritedProperties(); | 120 state.parentStyle()->setHasExplicitlyInheritedProperties(); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
| 124 double InvalidatableStyleInterpolation::underlyingFraction() const |
| 125 { |
| 126 return m_cachedConversion->interpolateUnderlyingFraction(m_startKeyframe->un
derlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction); |
| 127 } |
| 128 |
124 // Handles memory management of underlying InterpolationValues in applyStack() | 129 // Handles memory management of underlying InterpolationValues in applyStack() |
125 // Ensures we perform copy on write if we are not the owner of an underlying Int
erpolationValue. | 130 // Ensures we perform copy on write if we are not the owner of an underlying Int
erpolationValue. |
126 // This functions similar to a DataRef except on OwnPtr'd objects. | 131 // This functions similar to a DataRef except on OwnPtr'd objects. |
127 class UnderlyingValue { | 132 class UnderlyingValue { |
128 STACK_ALLOCATED(); | 133 STACK_ALLOCATED(); |
| 134 |
129 public: | 135 public: |
130 UnderlyingValue() | 136 UnderlyingValue() |
131 : m_owner() | 137 : m_valueOwner(nullptr) |
132 , m_pointer(nullptr) | 138 , m_value(nullptr) |
133 { } | 139 { } |
134 | 140 |
135 void set(const InterpolationValue* interpolationValue) | 141 void set(const InterpolationValue* interpolationValue) |
136 { | 142 { |
137 // By clearing m_owner we will perform a copy when attempting to access(
) | 143 // By clearing m_valueOwner we will perform a copy before attempting to
mutate m_value, |
138 // m_pointer as a mutable reference, thus upholding the const contract f
or | 144 // thus upholding the const contract for this instance of interpolationV
alue despite the const_cast. |
139 // this instance of interpolationValue despite the const_cast. | 145 m_valueOwner.clear(); |
140 m_owner.clear(); | 146 m_value = const_cast<InterpolationValue*>(interpolationValue); |
141 m_pointer = const_cast<InterpolationValue*>(interpolationValue); | |
142 } | 147 } |
143 void set(PassOwnPtr<InterpolationValue> interpolationValue) | 148 void set(PassOwnPtr<InterpolationValue> interpolationValue) |
144 { | 149 { |
145 m_owner = interpolationValue; | 150 m_valueOwner = interpolationValue; |
146 m_pointer = m_owner.get(); | 151 m_value = m_valueOwner.get(); |
147 } | 152 } |
148 InterpolationValue& access() | 153 InterpolationComponentValue& mutableComponent() |
149 { | 154 { |
150 ASSERT(m_pointer); | 155 ASSERT(m_value); |
151 if (!m_owner) | 156 if (!m_valueOwner) |
152 set(m_pointer->clone()); | 157 set(m_value->clone()); |
153 return *m_pointer; | 158 return m_value->mutableComponent(); |
154 } | 159 } |
155 const InterpolationValue* get() const { return m_pointer; } | 160 const InterpolationValue* get() const { return m_value; } |
156 operator bool() const { return m_pointer; } | 161 operator bool() const { return m_value; } |
157 const InterpolationValue* operator->() const | 162 const InterpolationValue* operator->() const |
158 { | 163 { |
159 ASSERT(m_pointer); | 164 ASSERT(m_value); |
160 return m_pointer; | 165 return m_value; |
161 } | 166 } |
162 | 167 |
163 private: | 168 private: |
164 OwnPtr<InterpolationValue> m_owner; | 169 OwnPtr<InterpolationValue> m_valueOwner; |
165 InterpolationValue* m_pointer; | 170 InterpolationValue* m_value; |
166 }; | 171 }; |
167 | 172 |
168 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int
erpolations, StyleResolverState& state) | 173 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int
erpolations, StyleResolverState& state) |
169 { | 174 { |
170 ASSERT(!interpolations.isEmpty()); | 175 ASSERT(!interpolations.isEmpty()); |
171 size_t startingIndex = 0; | 176 size_t startingIndex = 0; |
172 | 177 |
173 // Compute the underlying value to composite onto. | 178 // Compute the underlying value to composite onto. |
174 UnderlyingValue underlyingValue; | 179 UnderlyingValue underlyingValue; |
175 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS
tyleInterpolation(*interpolations.at(startingIndex)); | 180 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS
tyleInterpolation(*interpolations.at(startingIndex)); |
(...skipping 16 matching lines...) Expand all Loading... |
192 // Composite interpolations onto the underlying value. | 197 // Composite interpolations onto the underlying value. |
193 bool shouldApply = false; | 198 bool shouldApply = false; |
194 for (size_t i = startingIndex; i < interpolations.size(); i++) { | 199 for (size_t i = startingIndex; i < interpolations.size(); i++) { |
195 const InvalidatableStyleInterpolation& currentInterpolation = toInvalida
tableStyleInterpolation(*interpolations.at(i)); | 200 const InvalidatableStyleInterpolation& currentInterpolation = toInvalida
tableStyleInterpolation(*interpolations.at(i)); |
196 ASSERT(currentInterpolation.dependsOnUnderlyingValue()); | 201 ASSERT(currentInterpolation.dependsOnUnderlyingValue()); |
197 const InterpolationValue* currentValue = currentInterpolation.ensureVali
dInterpolation(state, underlyingValue.get()); | 202 const InterpolationValue* currentValue = currentInterpolation.ensureVali
dInterpolation(state, underlyingValue.get()); |
198 if (!currentValue) | 203 if (!currentValue) |
199 continue; | 204 continue; |
200 shouldApply = true; | 205 shouldApply = true; |
201 currentInterpolation.setFlagIfInheritUsed(state); | 206 currentInterpolation.setFlagIfInheritUsed(state); |
202 if (!underlyingValue || underlyingValue->type() != currentValue->type())
{ | 207 double underlyingFraction = currentInterpolation.underlyingFraction(); |
| 208 if (underlyingFraction == 0 || !underlyingValue || underlyingValue->type
() != currentValue->type()) |
203 underlyingValue.set(currentValue); | 209 underlyingValue.set(currentValue); |
204 } else { | 210 else |
205 double underlyingFraction = currentInterpolation.m_cachedConversion-
>interpolateUnderlyingFraction( | 211 underlyingValue.mutableComponent().interpolableValue->scaleAndAdd(un
derlyingFraction, currentValue->interpolableValue()); |
206 currentInterpolation.m_startKeyframe->underlyingFraction(), | |
207 currentInterpolation.m_endKeyframe->underlyingFraction(), | |
208 currentInterpolation.m_currentFraction); | |
209 underlyingValue.access().interpolableValue().scaleAndAdd(underlyingF
raction, currentInterpolation.m_cachedValue->interpolableValue()); | |
210 } | |
211 } | 212 } |
212 | 213 |
213 if (shouldApply && underlyingValue) | 214 if (shouldApply && underlyingValue) |
214 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde
rlyingValue->nonInterpolableValue(), state); | 215 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde
rlyingValue->nonInterpolableValue(), state); |
215 } | 216 } |
216 | 217 |
217 } // namespace blink | 218 } // namespace blink |
OLD | NEW |