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

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

Issue 194673002: Web Animations: Refactor KeyframeEffectModel to work via an InterpolationEffect. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@interpolationWrap
Patch Set: Created 6 years, 9 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 /* 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 , m_after(const_cast<AnimationEffect::CompositableValue*>(after)) 80 , m_after(const_cast<AnimationEffect::CompositableValue*>(after))
81 , m_fraction(fraction) 81 , m_fraction(fraction)
82 , m_dependsOnUnderlyingValue(before->dependsOnUnderlyingValue() || after ->dependsOnUnderlyingValue()) 82 , m_dependsOnUnderlyingValue(before->dependsOnUnderlyingValue() || after ->dependsOnUnderlyingValue())
83 { } 83 { }
84 RefPtr<AnimationEffect::CompositableValue> m_before; 84 RefPtr<AnimationEffect::CompositableValue> m_before;
85 RefPtr<AnimationEffect::CompositableValue> m_after; 85 RefPtr<AnimationEffect::CompositableValue> m_after;
86 double m_fraction; 86 double m_fraction;
87 bool m_dependsOnUnderlyingValue; 87 bool m_dependsOnUnderlyingValue;
88 }; 88 };
89 89
90 const double accuracyForKeyframeEasing = 0.0000001;
91
92 } // namespace 90 } // namespace
93 91
94 92
95 namespace WebCore { 93 namespace WebCore {
96 94
97 Keyframe::Keyframe() 95 Keyframe::Keyframe()
98 : m_offset(nullValue()) 96 : m_offset(nullValue())
99 , m_composite(AnimationEffect::CompositeReplace) 97 , m_composite(AnimationEffect::CompositeReplace)
100 { } 98 { }
101 99
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 result = m_keyframes[0]->properties(); 153 result = m_keyframes[0]->properties();
156 for (size_t i = 1; i < m_keyframes.size(); i++) { 154 for (size_t i = 1; i < m_keyframes.size(); i++) {
157 PropertySet extras = m_keyframes[i]->properties(); 155 PropertySet extras = m_keyframes[i]->properties();
158 for (PropertySet::const_iterator it = extras.begin(); it != extras.end() ; ++it) { 156 for (PropertySet::const_iterator it = extras.begin(); it != extras.end() ; ++it) {
159 result.add(*it); 157 result.add(*it);
160 } 158 }
161 } 159 }
162 return result; 160 return result;
163 } 161 }
164 162
165 PassOwnPtr<AnimationEffect::CompositableValueList> KeyframeEffectModel::sample(i nt iteration, double fraction) const 163 PassOwnPtr<Vector<RefPtr<Interpolation> > > KeyframeEffectModel::sample(int iter ation, double fraction) const
166 { 164 {
167 ASSERT(iteration >= 0); 165 ASSERT(iteration >= 0);
168 ASSERT(!isNull(fraction)); 166 ASSERT(!isNull(fraction));
169 const_cast<KeyframeEffectModel*>(this)->ensureKeyframeGroups(); 167 ensureKeyframeGroups();
170 OwnPtr<CompositableValueList> map = adoptPtr(new CompositableValueList()); 168 ensureInterpolationEffect();
171 for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) 169
172 map->append(std::make_pair(iter->key, iter->value->sample(iteration, fra ction))); 170 return m_interpolationEffect->getActiveInterpolations(fraction);
173 return map.release();
174 } 171 }
175 172
176 KeyframeEffectModel::KeyframeVector KeyframeEffectModel::normalizedKeyframes(con st KeyframeVector& keyframes) 173 KeyframeEffectModel::KeyframeVector KeyframeEffectModel::normalizedKeyframes(con st KeyframeVector& keyframes)
177 { 174 {
178 // keyframes [beginIndex, endIndex) will remain after removing all keyframes if they are not 175 // keyframes [beginIndex, endIndex) will remain after removing all keyframes if they are not
179 // loosely sorted by offset, and after removing keyframes with positional of fset outide [0, 1]. 176 // loosely sorted by offset, and after removing keyframes with positional of fset outide [0, 1].
180 size_t beginIndex = 0; 177 size_t beginIndex = 0;
181 size_t endIndex = keyframes.size(); 178 size_t endIndex = keyframes.size();
182 179
183 // Becomes the most recent keyframe with an explicit offset. 180 // Becomes the most recent keyframe with an explicit offset.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 258 }
262 } 259 }
263 260
264 // Add synthetic keyframes. 261 // Add synthetic keyframes.
265 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) { 262 for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_ keyframeGroups->end(); ++iter) {
266 iter->value->addSyntheticKeyframeIfRequired(); 263 iter->value->addSyntheticKeyframeIfRequired();
267 iter->value->removeRedundantKeyframes(); 264 iter->value->removeRedundantKeyframes();
268 } 265 }
269 } 266 }
270 267
268 void KeyframeEffectModel::ensureInterpolationEffect() const
269 {
270 if (m_interpolationEffect)
271 return;
272 m_interpolationEffect = InterpolationEffect::create();
273
274 for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
275 const PropertySpecificKeyframeVector& keyframes = iter->value->keyframes ();
276 ASSERT(keyframes[0]->value()->isAnimatableValue());
277 const AnimatableValue* start;
278 const AnimatableValue* end = toAnimatableValue(keyframes[0]->value());
279 for (size_t i = 0; i < keyframes.size() - 1; i++) {
280 ASSERT(keyframes[i+1]->value()->isAnimatableValue());
281 start = end;
282 end = toAnimatableValue(keyframes[i+1]->value());
283 double applyFrom = i ? keyframes[i]->offset() : (-std::numeric_limit s<double>::infinity());
284 double applyTo = i == keyframes.size() - 2 ? std::numeric_limits<dou ble>::infinity() : keyframes[i+1]->offset();
285 if (applyTo == 1)
286 applyTo = std::numeric_limits<double>::infinity();
287 m_interpolationEffect->addInterpolation(
288 LegacyStyleInterpolation::create(
289 AnimatableValue::takeConstRef(start),
290 AnimatableValue::takeConstRef(end), iter->key),
291 keyframes[i]->easing(), keyframes[i]->offset(), keyframes[i+1]-> offset(), applyFrom, applyTo);
292 }
293 }
294 }
271 295
272 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, Composit eOperation composite) 296 KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double o ffset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, Composit eOperation composite)
273 : m_offset(offset) 297 : m_offset(offset)
274 , m_easing(easing) 298 , m_easing(easing)
275 , m_value(composite == AnimationEffect::CompositeReplace ? 299 , m_value(composite == AnimationEffect::CompositeReplace ?
276 AnimatableValue::takeConstRef(value) : 300 AnimatableValue::takeConstRef(value) :
277 static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create (value))) 301 static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create (value)))
278 { 302 {
279 } 303 }
280 304
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 } 354 }
331 if (!allOffsetsEqual) 355 if (!allOffsetsEqual)
332 return; 356 return;
333 357
334 if (!offset) 358 if (!offset)
335 appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0)); 359 appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0));
336 else 360 else
337 m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, nullptr , AnimatableValue::neutralValue(), CompositeAdd))); 361 m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, nullptr , AnimatableValue::neutralValue(), CompositeAdd)));
338 } 362 }
339 363
340 PassRefPtr<AnimationEffect::CompositableValue> KeyframeEffectModel::PropertySpec ificKeyframeGroup::sample(int iteration, double offset) const
341 {
342 // FIXME: Implement accumulation.
343 ASSERT_UNUSED(iteration, iteration >= 0);
344 ASSERT(!isNull(offset));
345
346 // Bail if offset is null, as this can lead to buffer overflow below.
347 if (isNull(offset))
348 return const_cast<CompositableValue*>(m_keyframes.first()->value());
349
350 double minimumOffset = m_keyframes.first()->offset();
351 double maximumOffset = m_keyframes.last()->offset();
352 ASSERT(minimumOffset != maximumOffset);
353
354 PropertySpecificKeyframeVector::const_iterator before;
355 PropertySpecificKeyframeVector::const_iterator after;
356
357 // Note that this algorithm is simpler than that in the spec because we
358 // have removed keyframes with equal offsets in
359 // removeRedundantKeyframes().
360 if (offset < minimumOffset) {
361 before = m_keyframes.begin();
362 after = before + 1;
363 ASSERT((*before)->offset() > offset);
364 ASSERT((*after)->offset() > offset);
365 } else if (offset >= maximumOffset) {
366 after = m_keyframes.end() - 1;
367 before = after - 1;
368 ASSERT((*before)->offset() < offset);
369 ASSERT((*after)->offset() <= offset);
370 } else {
371 // FIXME: This is inefficient for large numbers of keyframes. Consider
372 // using binary search.
373 after = m_keyframes.begin();
374 while ((*after)->offset() <= offset)
375 ++after;
376 before = after - 1;
377 ASSERT((*before)->offset() <= offset);
378 ASSERT((*after)->offset() > offset);
379 }
380
381 if ((*before)->offset() == offset)
382 return const_cast<CompositableValue*>((*before)->value());
383 if ((*after)->offset() == offset)
384 return const_cast<CompositableValue*>((*after)->value());
385
386 double fraction = (offset - (*before)->offset()) / ((*after)->offset() - (*b efore)->offset());
387 if (const TimingFunction* timingFunction = (*before)->easing())
388 fraction = timingFunction->evaluate(fraction, accuracyForKeyframeEasing) ;
389 return BlendedCompositableValue::create((*before)->value(), (*after)->value( ), fraction);
390 }
391
392 void KeyframeEffectModel::trace(Visitor* visitor) 364 void KeyframeEffectModel::trace(Visitor* visitor)
393 { 365 {
394 visitor->trace(m_keyframes); 366 visitor->trace(m_keyframes);
395 } 367 }
396 368
397 } // namespace 369 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698