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

Side by Side Diff: sky/engine/core/animation/css/CSSAnimations.cpp

Issue 872893002: Remove lots of @keyframes related code. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « sky/engine/core/animation/css/CSSAnimations.h ('k') | sky/engine/core/css/RuleSet.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 24 matching lines...) Expand all
35 #include "sky/engine/core/animation/ActiveAnimations.h" 35 #include "sky/engine/core/animation/ActiveAnimations.h"
36 #include "sky/engine/core/animation/AnimationTimeline.h" 36 #include "sky/engine/core/animation/AnimationTimeline.h"
37 #include "sky/engine/core/animation/KeyframeEffectModel.h" 37 #include "sky/engine/core/animation/KeyframeEffectModel.h"
38 #include "sky/engine/core/animation/LegacyStyleInterpolation.h" 38 #include "sky/engine/core/animation/LegacyStyleInterpolation.h"
39 #include "sky/engine/core/animation/css/CSSAnimatableValueFactory.h" 39 #include "sky/engine/core/animation/css/CSSAnimatableValueFactory.h"
40 #include "sky/engine/core/animation/css/CSSPropertyEquality.h" 40 #include "sky/engine/core/animation/css/CSSPropertyEquality.h"
41 #include "sky/engine/core/css/CSSPropertyMetadata.h" 41 #include "sky/engine/core/css/CSSPropertyMetadata.h"
42 #include "sky/engine/core/css/CSSValueList.h" 42 #include "sky/engine/core/css/CSSValueList.h"
43 #include "sky/engine/core/css/StyleKeyframe.h" 43 #include "sky/engine/core/css/StyleKeyframe.h"
44 #include "sky/engine/core/css/StyleRuleKeyframes.h" 44 #include "sky/engine/core/css/StyleRuleKeyframes.h"
45 #include "sky/engine/core/css/resolver/CSSToStyleMap.h"
46 #include "sky/engine/core/css/resolver/StyleResolver.h"
47 #include "sky/engine/core/dom/Element.h" 45 #include "sky/engine/core/dom/Element.h"
48 #include "sky/engine/core/dom/StyleEngine.h"
49 #include "sky/engine/core/events/AnimationEvent.h" 46 #include "sky/engine/core/events/AnimationEvent.h"
50 #include "sky/engine/core/events/TransitionEvent.h" 47 #include "sky/engine/core/events/TransitionEvent.h"
51 #include "sky/engine/core/rendering/RenderLayer.h" 48 #include "sky/engine/core/rendering/RenderLayer.h"
52 #include "sky/engine/core/rendering/RenderObject.h" 49 #include "sky/engine/core/rendering/RenderObject.h"
53 #include "sky/engine/core/rendering/style/KeyframeList.h" 50 #include "sky/engine/core/rendering/style/KeyframeList.h"
54 #include "sky/engine/platform/animation/TimingFunction.h" 51 #include "sky/engine/platform/animation/TimingFunction.h"
55 #include "sky/engine/public/platform/Platform.h" 52 #include "sky/engine/public/platform/Platform.h"
56 #include "sky/engine/wtf/BitArray.h" 53 #include "sky/engine/wtf/BitArray.h"
57 #include "sky/engine/wtf/HashSet.h" 54 #include "sky/engine/wtf/HashSet.h"
58 55
(...skipping 14 matching lines...) Expand all
73 case CSSPropertyWebkitTransformOriginX: 70 case CSSPropertyWebkitTransformOriginX:
74 case CSSPropertyWebkitTransformOriginY: 71 case CSSPropertyWebkitTransformOriginY:
75 case CSSPropertyWebkitTransformOriginZ: 72 case CSSPropertyWebkitTransformOriginZ:
76 return CSSPropertyTransformOrigin; 73 return CSSPropertyTransformOrigin;
77 default: 74 default:
78 break; 75 break;
79 } 76 }
80 return property; 77 return property;
81 } 78 }
82 79
83 static void resolveKeyframes(StyleResolver* resolver, Element* element, const El ement& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction,
84 AnimatableValueKeyframeVector& keyframes)
85 {
86 // When the element is null, use its parent for scoping purposes.
87 const Element* elementForScoping = element ? element : &parentElement;
88 const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframe sRule(resolver, elementForScoping, name);
89 if (!keyframesRule)
90 return;
91
92 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra mes();
93 if (styleKeyframes.isEmpty())
94 return;
95
96 // Construct and populate the style for each keyframe
97 for (size_t i = 0; i < styleKeyframes.size(); ++i) {
98 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get();
99 // It's OK to pass a null element here.
100 RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name);
101 RefPtr<AnimatableValueKeyframe> keyframe = AnimatableValueKeyframe::crea te();
102 const Vector<double>& offsets = styleKeyframe->keys();
103 ASSERT(!offsets.isEmpty());
104 keyframe->setOffset(offsets[0]);
105 keyframe->setEasing(defaultTimingFunction);
106 const StylePropertySet& properties = styleKeyframe->properties();
107 for (unsigned j = 0; j < properties.propertyCount(); j++) {
108 CSSPropertyID property = propertyForAnimation(properties.propertyAt( j).id());
109 if (property == CSSPropertyAnimationTimingFunction) {
110 CSSValue* value = properties.propertyAt(j).value();
111 RefPtr<TimingFunction> timingFunction;
112 if (value->isInheritedValue() && parentStyle->animations())
113 timingFunction = parentStyle->animations()->timingFunctionLi st()[0];
114 else if (value->isInheritedValue() || value->isInitialValue())
115 timingFunction = CSSTimingData::initialTimingFunction();
116 else
117 timingFunction = CSSToStyleMap::mapAnimationTimingFunction(t oCSSValueList(value)->item(0));
118 keyframe->setEasing(timingFunction.release());
119 } else if (CSSPropertyMetadata::isAnimatableProperty(property)) {
120 keyframe->setPropertyValue(property, CSSAnimatableValueFactory:: create(property, *keyframeStyle).get());
121 }
122 }
123 keyframes.append(keyframe);
124 // The last keyframe specified at a given offset is used.
125 for (size_t j = 1; j < offsets.size(); ++j) {
126 keyframes.append(toAnimatableValueKeyframe(keyframe->cloneWithOffset (offsets[j]).get()));
127 }
128 }
129 ASSERT(!keyframes.isEmpty());
130
131 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta kes priority.
132 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s);
133 size_t targetIndex = 0;
134 for (size_t i = 1; i < keyframes.size(); i++) {
135 if (keyframes[i]->offset() != keyframes[targetIndex]->offset())
136 targetIndex++;
137 if (targetIndex != i)
138 keyframes[targetIndex] = keyframes[i];
139 }
140 keyframes.shrink(targetIndex + 1);
141
142 // Add 0% and 100% keyframes if absent.
143 RefPtr<AnimatableValueKeyframe> startKeyframe = keyframes[0];
144 if (startKeyframe->offset()) {
145 startKeyframe = AnimatableValueKeyframe::create();
146 startKeyframe->setOffset(0);
147 startKeyframe->setEasing(defaultTimingFunction);
148 keyframes.prepend(startKeyframe);
149 }
150 RefPtr<AnimatableValueKeyframe> endKeyframe = keyframes[keyframes.size() - 1 ];
151 if (endKeyframe->offset() != 1) {
152 endKeyframe = AnimatableValueKeyframe::create();
153 endKeyframe->setOffset(1);
154 endKeyframe->setEasing(defaultTimingFunction);
155 keyframes.append(endKeyframe);
156 }
157 ASSERT(keyframes.size() >= 2);
158 ASSERT(!keyframes.first()->offset());
159 ASSERT(keyframes.last()->offset() == 1);
160
161 // Snapshot current property values for 0% and 100% if missing.
162 PropertySet allProperties;
163 size_t numKeyframes = keyframes.size();
164 for (size_t i = 0; i < numKeyframes; i++) {
165 const PropertySet& keyframeProperties = keyframes[i]->properties();
166 for (PropertySet::const_iterator iter = keyframeProperties.begin(); iter != keyframeProperties.end(); ++iter)
167 allProperties.add(*iter);
168 }
169 const PropertySet& startKeyframeProperties = startKeyframe->properties();
170 const PropertySet& endKeyframeProperties = endKeyframe->properties();
171 bool missingStartValues = startKeyframeProperties.size() < allProperties.siz e();
172 bool missingEndValues = endKeyframeProperties.size() < allProperties.size();
173 if (missingStartValues || missingEndValues) {
174 for (PropertySet::const_iterator iter = allProperties.begin(); iter != a llProperties.end(); ++iter) {
175 const CSSPropertyID property = *iter;
176 bool startNeedsValue = missingStartValues && !startKeyframePropertie s.contains(property);
177 bool endNeedsValue = missingEndValues && !endKeyframeProperties.cont ains(property);
178 if (!startNeedsValue && !endNeedsValue)
179 continue;
180 RefPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::c reate(property, style);
181 if (startNeedsValue)
182 startKeyframe->setPropertyValue(property, snapshotValue.get());
183 if (endNeedsValue)
184 endKeyframe->setPropertyValue(property, snapshotValue.get());
185 }
186 }
187 ASSERT(startKeyframe->properties().size() == allProperties.size());
188 ASSERT(endKeyframe->properties().size() == allProperties.size());
189 }
190
191 } // namespace 80 } // namespace
192 81
193 const StyleRuleKeyframes* CSSAnimations::matchScopedKeyframesRule(StyleResolver* resolver, const Element* element, String animationName)
194 {
195 // FIXME: This is all implementation detail of style resolver, CSSAnimations shouldn't be reaching into any of it.
196 Vector<RawPtr<ScopedStyleResolver>, 8> stack;
197 resolver->styleTreeResolveScopedKeyframesRules(element, stack);
198 if (stack.isEmpty())
199 return 0;
200
201 for (size_t i = 0; i < stack.size(); ++i) {
202 if (const StyleRuleKeyframes* keyframesRule = stack.at(i)->keyframeStyle sForAnimation(animationName))
203 return keyframesRule;
204 }
205 return 0;
206 }
207
208 CSSAnimations::CSSAnimations() 82 CSSAnimations::CSSAnimations()
209 { 83 {
210 } 84 }
211 85
212 PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle , StyleResolver* resolver) 86 PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle )
213 { 87 {
214 OwnPtr<CSSAnimationUpdate> update = adoptPtr(new CSSAnimationUpdate()); 88 OwnPtr<CSSAnimationUpdate> update = adoptPtr(new CSSAnimationUpdate());
215 calculateAnimationUpdate(update.get(), element, parentElement, style, parent Style, resolver);
216 calculateAnimationActiveInterpolations(update.get(), element, parentElement. document().timeline().currentTimeInternal()); 89 calculateAnimationActiveInterpolations(update.get(), element, parentElement. document().timeline().currentTimeInternal());
217 calculateTransitionUpdate(update.get(), element, style); 90 calculateTransitionUpdate(update.get(), element, style);
218 calculateTransitionActiveInterpolations(update.get(), element, parentElement .document().timeline().currentTimeInternal()); 91 calculateTransitionActiveInterpolations(update.get(), element, parentElement .document().timeline().currentTimeInternal());
219 return update->isEmpty() ? nullptr : update.release(); 92 return update->isEmpty() ? nullptr : update.release();
220 } 93 }
221 94
222 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, Element * element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
223 {
224 const ActiveAnimations* activeAnimations = element ? element->activeAnimatio ns() : 0;
225
226 #if !ENABLE(ASSERT)
227 // If we're in an animation style change, no animations can have started, be en cancelled or changed play state.
228 // When ASSERT is enabled, we verify this optimization.
229 if (activeAnimations && activeAnimations->isAnimationStyleChange())
230 return;
231 #endif
232
233 const CSSAnimationData* animationData = style.animations();
234 const CSSAnimations* cssAnimations = activeAnimations ? &activeAnimations->c ssAnimations() : 0;
235
236 HashSet<AtomicString> inactive;
237 if (cssAnimations)
238 for (AnimationMap::const_iterator iter = cssAnimations->m_animations.beg in(); iter != cssAnimations->m_animations.end(); ++iter)
239 inactive.add(iter->key);
240
241 if (style.display() != NONE) {
242 for (size_t i = 0; animationData && i < animationData->nameList().size() ; ++i) {
243 AtomicString animationName(animationData->nameList()[i]);
244 if (animationName == CSSAnimationData::initialName())
245 continue;
246
247 bool isPaused = CSSTimingData::getRepeated(animationData->playStateL ist(), i) == AnimPlayStatePaused;
248
249 // Keyframes and animation properties are snapshotted when the
250 // animation starts, so we don't need to track changes to these,
251 // with the exception of play-state.
252 if (cssAnimations) {
253 AnimationMap::const_iterator existing(cssAnimations->m_animation s.find(animationName));
254 if (existing != cssAnimations->m_animations.end()) {
255 inactive.remove(animationName);
256 AnimationPlayer* player = existing->value.get();
257 if (isPaused != player->paused()) {
258 ASSERT(!activeAnimations || !activeAnimations->isAnimati onStyleChange());
259 update->toggleAnimationPaused(animationName);
260 }
261 continue;
262 }
263 }
264
265 Timing timing = animationData->convertToTiming(i);
266 RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunctio n;
267 timing.timingFunction = Timing::defaults().timingFunction;
268 AnimatableValueKeyframeVector resolvedKeyframes;
269 resolveKeyframes(resolver, element, parentElement, style, parentStyl e, animationName, keyframeTimingFunction.get(), resolvedKeyframes);
270 if (!resolvedKeyframes.isEmpty()) {
271 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleC hange());
272 update->startAnimation(animationName, InertAnimation::create(Ani matableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused));
273 }
274 }
275 }
276
277 ASSERT(inactive.isEmpty() || cssAnimations);
278 for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter != inactive.end(); ++iter) {
279 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange()) ;
280 update->cancelAnimation(*iter, *cssAnimations->m_animations.get(*iter));
281 }
282 }
283
284 void CSSAnimations::maybeApplyPendingUpdate(Element* element) 95 void CSSAnimations::maybeApplyPendingUpdate(Element* element)
285 { 96 {
286 if (!m_pendingUpdate) { 97 if (!m_pendingUpdate) {
287 m_previousActiveInterpolationsForAnimations.clear(); 98 m_previousActiveInterpolationsForAnimations.clear();
288 return; 99 return;
289 } 100 }
290 101
291 OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release(); 102 OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release();
292 103
293 m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolation sForAnimations()); 104 m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolation sForAnimations());
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 m_animations.clear(); 299 m_animations.clear();
489 m_transitions.clear(); 300 m_transitions.clear();
490 m_pendingUpdate = nullptr; 301 m_pendingUpdate = nullptr;
491 } 302 }
492 303
493 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u pdate, const Element* element, double timelineCurrentTime) 304 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u pdate, const Element* element, double timelineCurrentTime)
494 { 305 {
495 ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0; 306 ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
496 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau ltStack() : 0; 307 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau ltStack() : 0;
497 308
498 if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimation Players().isEmpty()) { 309 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForAnimat ions(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::Defau ltPriority, timelineCurrentTime));
499 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForAn imations(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::D efaultPriority, timelineCurrentTime));
500 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn imations);
501 return;
502 }
503
504 Vector<RawPtr<InertAnimation> > newAnimations;
505 for (size_t i = 0; i < update->newAnimations().size(); ++i) {
506 newAnimations.append(update->newAnimations()[i].animation.get());
507 }
508 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForAnimat ions(AnimationStack::activeInterpolations(animationStack, &newAnimations, &updat e->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority, timelineCur rentTime));
509 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat ions); 310 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat ions);
510 } 311 }
511 312
512 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* update, const Element* element, double timelineCurrentTime) 313 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* update, const Element* element, double timelineCurrentTime)
513 { 314 {
514 ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0; 315 ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
515 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau ltStack() : 0; 316 AnimationStack* animationStack = activeAnimations ? &activeAnimations->defau ltStack() : 0;
516 317
517 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForTransi tions; 318 HashMap<CSSPropertyID, RefPtr<Interpolation> > activeInterpolationsForTransi tions;
518 if (update->newTransitions().isEmpty() && update->cancelledTransitions().isE mpty()) { 319 if (update->newTransitions().isEmpty() && update->cancelledTransitions().isE mpty()) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 case CSSPropertyTransitionDuration: 435 case CSSPropertyTransitionDuration:
635 case CSSPropertyTransitionProperty: 436 case CSSPropertyTransitionProperty:
636 case CSSPropertyTransitionTimingFunction: 437 case CSSPropertyTransitionTimingFunction:
637 return false; 438 return false;
638 default: 439 default:
639 return true; 440 return true;
640 } 441 }
641 } 442 }
642 443
643 } // namespace blink 444 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/animation/css/CSSAnimations.h ('k') | sky/engine/core/css/RuleSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698