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

Side by Side Diff: Source/core/animation/KeyframeEffectModel.cpp

Issue 216603008: Revert "Web Animations: Introduce String based KeyframeEffectModel" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 18 matching lines...) Expand all
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "core/animation/KeyframeEffectModel.h" 32 #include "core/animation/KeyframeEffectModel.h"
33 33
34 #include "core/animation/TimedItem.h" 34 #include "core/animation/TimedItem.h"
35 #include "wtf/text/StringHash.h" 35 #include "wtf/text/StringHash.h"
36 36
37 namespace WebCore { 37 namespace WebCore {
38 38
39 bool Keyframe::compareOffsets(const RefPtrWillBeRawPtr<Keyframe>& a, const RefPt rWillBeRawPtr<Keyframe>& b) 39 Keyframe::Keyframe()
40 : m_offset(nullValue())
41 , m_composite(AnimationEffect::CompositeReplace)
42 , m_easing(LinearTimingFunction::preset())
43 { }
44
45 Keyframe::Keyframe(const Keyframe& copyFrom)
46 : m_offset(copyFrom.m_offset)
47 , m_composite(copyFrom.m_composite)
48 , m_easing(copyFrom.m_easing)
40 { 49 {
41 return a->offset() < b->offset(); 50 ASSERT(m_easing);
51 for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin (); iter != copyFrom.m_propertyValues.end(); ++iter)
52 setPropertyValue(iter->key, iter->value.get());
42 } 53 }
43 54
44 PropertySet KeyframeEffectModelBase::properties() const 55 void Keyframe::setEasing(PassRefPtr<TimingFunction> easing)
56 {
57 ASSERT(easing);
58 m_easing = easing;
59 }
60
61 void Keyframe::setPropertyValue(CSSPropertyID property, const AnimatableValue* v alue)
62 {
63 m_propertyValues.add(property, const_cast<AnimatableValue*>(value));
64 }
65
66 void Keyframe::clearPropertyValue(CSSPropertyID property)
67 {
68 m_propertyValues.remove(property);
69 }
70
71 const AnimatableValue* Keyframe::propertyValue(CSSPropertyID property) const
72 {
73 ASSERT(m_propertyValues.contains(property));
74 return m_propertyValues.get(property);
75 }
76
77 PropertySet Keyframe::properties() const
78 {
79 // This is not used in time-critical code, so we probably don't need to
80 // worry about caching this result.
81 PropertySet properties;
82 for (PropertyValueMap::const_iterator iter = m_propertyValues.begin(); iter != m_propertyValues.end(); ++iter)
83 properties.add(*iter.keys());
84 return properties;
85 }
86
87 PassRefPtrWillBeRawPtr<Keyframe> Keyframe::cloneWithOffset(double offset) const
88 {
89 RefPtrWillBeRawPtr<Keyframe> theClone = clone();
90 theClone->setOffset(offset);
91 return theClone.release();
92 }
93
94 void Keyframe::trace(Visitor* visitor)
95 {
96 visitor->trace(m_propertyValues);
97 }
98
99 KeyframeEffectModel::KeyframeEffectModel(const KeyframeVector& keyframes)
100 : m_keyframes(keyframes)
101 {
102 }
103
104 PropertySet KeyframeEffectModel::properties() const
45 { 105 {
46 PropertySet result; 106 PropertySet result;
47 if (!m_keyframes.size()) { 107 if (!m_keyframes.size()) {
48 return result; 108 return result;
49 } 109 }
50 result = m_keyframes[0]->properties(); 110 result = m_keyframes[0]->properties();
51 for (size_t i = 1; i < m_keyframes.size(); i++) { 111 for (size_t i = 1; i < m_keyframes.size(); i++) {
52 PropertySet extras = m_keyframes[i]->properties(); 112 PropertySet extras = m_keyframes[i]->properties();
53 for (PropertySet::const_iterator it = extras.begin(); it != extras.end() ; ++it) { 113 for (PropertySet::const_iterator it = extras.begin(); it != extras.end() ; ++it) {
54 result.add(*it); 114 result.add(*it);
55 } 115 }
56 } 116 }
57 return result; 117 return result;
58 } 118 }
59 119
60 PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > Ke yframeEffectModelBase::sample(int iteration, double fraction, double iterationDu ration) const 120 PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > Ke yframeEffectModel::sample(int iteration, double fraction, double iterationDurati on) const
61 { 121 {
62 ASSERT(iteration >= 0); 122 ASSERT(iteration >= 0);
63 ASSERT(!isNull(fraction)); 123 ASSERT(!isNull(fraction));
64 ensureKeyframeGroups(); 124 ensureKeyframeGroups();
65 ensureInterpolationEffect(); 125 ensureInterpolationEffect();
66 126
67 return m_interpolationEffect->getActiveInterpolations(fraction, iterationDur ation); 127 return m_interpolationEffect->getActiveInterpolations(fraction, iterationDur ation);
68 } 128 }
69 129
70 KeyframeEffectModelBase::KeyframeVector KeyframeEffectModelBase::normalizedKeyfr ames(const KeyframeVector& keyframes) 130 KeyframeEffectModel::KeyframeVector KeyframeEffectModel::normalizedKeyframes(con st KeyframeVector& keyframes)
71 { 131 {
72 // keyframes [beginIndex, endIndex) will remain after removing all keyframes if they are not 132 // keyframes [beginIndex, endIndex) will remain after removing all keyframes if they are not
73 // loosely sorted by offset, and after removing keyframes with positional of fset outide [0, 1]. 133 // loosely sorted by offset, and after removing keyframes with positional of fset outide [0, 1].
74 size_t beginIndex = 0; 134 size_t beginIndex = 0;
75 size_t endIndex = keyframes.size(); 135 size_t endIndex = keyframes.size();
76 136
77 // Becomes the most recent keyframe with an explicit offset. 137 // Becomes the most recent keyframe with an explicit offset.
78 size_t lastIndex = endIndex; 138 size_t lastIndex = endIndex;
79 double lastOffset = std::numeric_limits<double>::quiet_NaN(); 139 double lastOffset = std::numeric_limits<double>::quiet_NaN();
80 140
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 result[lastIndex + j]->setOffset(lastOffset + (offset - lastOffset) * j / (i - lastIndex)); 184 result[lastIndex + j]->setOffset(lastOffset + (offset - lastOffset) * j / (i - lastIndex));
125 } 185 }
126 lastIndex = i; 186 lastIndex = i;
127 lastOffset = offset; 187 lastOffset = offset;
128 } 188 }
129 } 189 }
130 } 190 }
131 return result; 191 return result;
132 } 192 }
133 193
134 194 void KeyframeEffectModel::ensureKeyframeGroups() const
135 void KeyframeEffectModelBase::ensureKeyframeGroups() const
136 { 195 {
137 if (m_keyframeGroups) 196 if (m_keyframeGroups)
138 return; 197 return;
139 198
140 m_keyframeGroups = adoptPtrWillBeNoop(new KeyframeGroupMap); 199 m_keyframeGroups = adoptPtrWillBeNoop(new KeyframeGroupMap);
141 const KeyframeVector keyframes = normalizedKeyframes(getFrames()); 200 const KeyframeVector keyframes = normalizedKeyframes(getFrames());
142 for (KeyframeVector::const_iterator keyframeIter = keyframes.begin(); keyfra meIter != keyframes.end(); ++keyframeIter) { 201 for (KeyframeVector::const_iterator keyframeIter = keyframes.begin(); keyfra meIter != keyframes.end(); ++keyframeIter) {
143 const Keyframe* keyframe = keyframeIter->get(); 202 const Keyframe* keyframe = keyframeIter->get();
144 PropertySet keyframeProperties = keyframe->properties(); 203 PropertySet keyframeProperties = keyframe->properties();
145 for (PropertySet::const_iterator propertyIter = keyframeProperties.begin (); propertyIter != keyframeProperties.end(); ++propertyIter) { 204 for (PropertySet::const_iterator propertyIter = keyframeProperties.begin (); propertyIter != keyframeProperties.end(); ++propertyIter) {
146 CSSPropertyID property = *propertyIter; 205 CSSPropertyID property = *propertyIter;
147 KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(proper ty); 206 KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(proper ty);
148 PropertySpecificKeyframeGroup* group; 207 PropertySpecificKeyframeGroup* group;
149 if (groupIter == m_keyframeGroups->end()) 208 if (groupIter == m_keyframeGroups->end())
150 group = m_keyframeGroups->add(property, adoptPtrWillBeNoop(new P ropertySpecificKeyframeGroup)).storedValue->value.get(); 209 group = m_keyframeGroups->add(property, adoptPtrWillBeNoop(new P ropertySpecificKeyframeGroup)).storedValue->value.get();
151 else 210 else
152 group = groupIter->value.get(); 211 group = groupIter->value.get();
153 212
154 ASSERT(keyframe->composite() == AnimationEffect::CompositeReplace); 213 ASSERT(keyframe->composite() == AnimationEffect::CompositeReplace);
155 group->appendKeyframe(keyframe->createPropertySpecificKeyframe(prope rty)); 214 group->appendKeyframe(adoptPtrWillBeNoop(
215 new PropertySpecificKeyframe(keyframe->offset(), keyframe->easin g(), keyframe->propertyValue(property), keyframe->composite())));
156 } 216 }
157 } 217 }
158 218
159 // Add synthetic keyframes. 219 // Add synthetic keyframes.
160 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) { 220 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) {
161 iter->value->addSyntheticKeyframeIfRequired(this); 221 iter->value->addSyntheticKeyframeIfRequired();
162 iter->value->removeRedundantKeyframes(); 222 iter->value->removeRedundantKeyframes();
163 } 223 }
164 } 224 }
165 225
166 void KeyframeEffectModelBase::ensureInterpolationEffect() const 226 void KeyframeEffectModel::ensureInterpolationEffect() const
167 { 227 {
168 if (m_interpolationEffect) 228 if (m_interpolationEffect)
169 return; 229 return;
170 m_interpolationEffect = InterpolationEffect::create(); 230 m_interpolationEffect = InterpolationEffect::create();
171 231
172 for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) { 232 for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
173 const PropertySpecificKeyframeVector& keyframes = iter->value->keyframes (); 233 const PropertySpecificKeyframeVector& keyframes = iter->value->keyframes ();
174 ASSERT(keyframes[0]->composite() == AnimationEffect::CompositeReplace); 234 ASSERT(keyframes[0]->composite() == AnimationEffect::CompositeReplace);
235 const AnimatableValue* start;
236 const AnimatableValue* end = keyframes[0]->value();
175 for (size_t i = 0; i < keyframes.size() - 1; i++) { 237 for (size_t i = 0; i < keyframes.size() - 1; i++) {
176 ASSERT(keyframes[i + 1]->composite() == AnimationEffect::CompositeRe place); 238 ASSERT(keyframes[i + 1]->composite() == AnimationEffect::CompositeRe place);
239 start = end;
240 end = keyframes[i + 1]->value();
177 double applyFrom = i ? keyframes[i]->offset() : (-std::numeric_limit s<double>::infinity()); 241 double applyFrom = i ? keyframes[i]->offset() : (-std::numeric_limit s<double>::infinity());
178 double applyTo = i == keyframes.size() - 2 ? std::numeric_limits<dou ble>::infinity() : keyframes[i + 1]->offset(); 242 double applyTo = i == keyframes.size() - 2 ? std::numeric_limits<dou ble>::infinity() : keyframes[i + 1]->offset();
179 if (applyTo == 1) 243 if (applyTo == 1)
180 applyTo = std::numeric_limits<double>::infinity(); 244 applyTo = std::numeric_limits<double>::infinity();
181 245 m_interpolationEffect->addInterpolation(
182 m_interpolationEffect->addInterpolation(keyframes[i]->createInterpol ation(iter->key, keyframes[i + 1].get()), 246 LegacyStyleInterpolation::create(
247 AnimatableValue::takeConstRef(start),
248 AnimatableValue::takeConstRef(end), iter->key),
183 keyframes[i]->easing(), keyframes[i]->offset(), keyframes[i + 1] ->offset(), applyFrom, applyTo); 249 keyframes[i]->easing(), keyframes[i]->offset(), keyframes[i + 1] ->offset(), applyFrom, applyTo);
184 } 250 }
185 } 251 }
186 } 252 }
187 253
188 bool KeyframeEffectModelBase::isReplaceOnly() 254 bool KeyframeEffectModel::isReplaceOnly()
189 { 255 {
190 ensureKeyframeGroups(); 256 ensureKeyframeGroups();
191 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) { 257 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) {
192 const PropertySpecificKeyframeVector& keyframeVector = iter->value->keyf rames(); 258 const PropertySpecificKeyframeVector& keyframeVector = iter->value->keyf rames();
193 for (size_t i = 0; i < keyframeVector.size(); ++i) { 259 for (size_t i = 0; i < keyframeVector.size(); ++i) {
194 if (keyframeVector[i]->composite() != AnimationEffect::CompositeRepl ace) 260 if (keyframeVector[i]->composite() != AnimationEffect::CompositeRepl ace)
195 return false; 261 return false;
196 } 262 }
197 } 263 }
198 return true; 264 return true;
199 } 265 }
200 266
201 void KeyframeEffectModelBase::trace(Visitor* visitor) 267 void KeyframeEffectModel::trace(Visitor* visitor)
202 { 268 {
203 visitor->trace(m_keyframes); 269 visitor->trace(m_keyframes);
204 visitor->trace(m_interpolationEffect); 270 visitor->trace(m_interpolationEffect);
205 #if ENABLE_OILPAN 271 #if ENABLE_OILPAN
206 visitor->trace(m_keyframeGroups); 272 visitor->trace(m_keyframeGroups);
207 #endif 273 #endif
208 } 274 }
209 275
210 Keyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, Pass RefPtr<TimingFunction> easing, AnimationEffect::CompositeOperation composite) 276 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, Composit eOperation composite)
211 : m_offset(offset) 277 : m_offset(offset)
212 , m_easing(easing) 278 , m_easing(easing)
213 , m_composite(composite) 279 , m_composite(composite)
214 { 280 {
281 m_value = AnimatableValue::takeConstRef(value);
215 } 282 }
216 283
217 void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::appendKeyframe(Pass OwnPtr<PropertySpecificKeyframe> keyframe) 284 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, PassRefPtrWillBeRawPtr<AnimatableValue > value, CompositeOperation composite)
285 : m_offset(offset)
286 , m_easing(easing)
287 , m_value(value)
288 , m_composite(composite)
289 {
290 ASSERT(!isNull(m_offset));
291 }
292
293 PassOwnPtrWillBeRawPtr<KeyframeEffectModel::PropertySpecificKeyframe> KeyframeEf fectModel::PropertySpecificKeyframe::cloneWithOffset(double offset) const
294 {
295 return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, m_easing, m_v alue.get(), m_composite));
296 }
297
298 void KeyframeEffectModel::PropertySpecificKeyframe::trace(Visitor* visitor)
299 {
300 visitor->trace(m_value);
301 }
302
303 void KeyframeEffectModel::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnP trWillBeRawPtr<PropertySpecificKeyframe> keyframe)
218 { 304 {
219 ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->of fset()); 305 ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->of fset());
220 m_keyframes.append(keyframe); 306 m_keyframes.append(keyframe);
221 } 307 }
222 308
223 void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::removeRedundantKeyf rames() 309 void KeyframeEffectModel::PropertySpecificKeyframeGroup::removeRedundantKeyframe s()
224 { 310 {
225 // As an optimization, removes keyframes in the following categories, as 311 // As an optimization, removes keyframes in the following categories, as
226 // they will never be used by sample(). 312 // they will never be used by sample().
227 // - End keyframes with the same offset as their neighbor 313 // - End keyframes with the same offset as their neighbor
228 // - Interior keyframes with the same offset as both their neighbors 314 // - Interior keyframes with the same offset as both their neighbors
229 // Note that synthetic keyframes must be added before this method is 315 // Note that synthetic keyframes must be added before this method is
230 // called. 316 // called.
231 ASSERT(m_keyframes.size() >= 2); 317 ASSERT(m_keyframes.size() >= 2);
232 for (int i = m_keyframes.size() - 1; i >= 0; --i) { 318 for (int i = m_keyframes.size() - 1; i >= 0; --i) {
233 double offset = m_keyframes[i]->offset(); 319 double offset = m_keyframes[i]->offset();
234 bool hasSameOffsetAsPreviousNeighbor = !i || m_keyframes[i - 1]->offset( ) == offset; 320 bool hasSameOffsetAsPreviousNeighbor = !i || m_keyframes[i - 1]->offset( ) == offset;
235 bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.siz e() - 1) || m_keyframes[i + 1]->offset() == offset; 321 bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.siz e() - 1) || m_keyframes[i + 1]->offset() == offset;
236 if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor) 322 if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor)
237 m_keyframes.remove(i); 323 m_keyframes.remove(i);
238 } 324 }
239 ASSERT(m_keyframes.size() >= 2); 325 ASSERT(m_keyframes.size() >= 2);
240 } 326 }
241 327
242 void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::addSyntheticKeyfram eIfRequired(const KeyframeEffectModelBase* context) 328 void KeyframeEffectModel::PropertySpecificKeyframeGroup::addSyntheticKeyframeIfR equired()
243 { 329 {
244 ASSERT(!m_keyframes.isEmpty()); 330 ASSERT(!m_keyframes.isEmpty());
245 if (m_keyframes.first()->offset() != 0.0) 331 if (m_keyframes.first()->offset() != 0.0)
246 m_keyframes.insert(0, m_keyframes.first()->neutralKeyframe(0, nullptr)); 332 m_keyframes.insert(0, adoptPtrWillBeNoop(new PropertySpecificKeyframe(0, nullptr, AnimatableValue::neutralValue(), CompositeAdd)));
247 if (m_keyframes.last()->offset() != 1.0) 333 if (m_keyframes.last()->offset() != 1.0)
248 appendKeyframe(m_keyframes.last()->neutralKeyframe(1, nullptr)); 334 appendKeyframe(adoptPtrWillBeNoop(new PropertySpecificKeyframe(1, nullpt r, AnimatableValue::neutralValue(), CompositeAdd)));
249 } 335 }
250 336
251 void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::trace(Visitor* visi tor) 337 void KeyframeEffectModel::PropertySpecificKeyframeGroup::trace(Visitor* visitor)
252 { 338 {
253 #if ENABLE(OILPAN) 339 #if ENABLE_OILPAN
254 visitor->trace(m_keyframes); 340 visitor->trace(m_keyframes);
255 #endif 341 #endif
256 } 342 }
257 343
258 template <>
259 bool KeyframeEffectModel<AnimatableValueKeyframe>::isAnimatableValueKeyframeEffe ctModel() const { return true; }
260
261 template <>
262 bool KeyframeEffectModel<StringKeyframe>::isStringKeyframeEffectModel() const { return true; }
263
264 } // namespace 344 } // namespace
OLDNEW
« no previous file with comments | « Source/core/animation/KeyframeEffectModel.h ('k') | Source/core/animation/KeyframeEffectModelTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698