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

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

Issue 2228313002: Make a function to query whether a CSSPropertyID is valid and whether it has a name. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@asan
Patch Set: Adjust animation dchecks Created 4 years, 4 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 65
66 using PropertySet = HashSet<CSSPropertyID>; 66 using PropertySet = HashSet<CSSPropertyID>;
67 67
68 namespace { 68 namespace {
69 69
70 static StringKeyframeEffectModel* createKeyframeEffectModel(StyleResolver* resol ver, const Element* animatingElement, Element& element, const ComputedStyle* sty le, const ComputedStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction, size_t animationIndex) 70 static StringKeyframeEffectModel* createKeyframeEffectModel(StyleResolver* resol ver, const Element* animatingElement, Element& element, const ComputedStyle* sty le, const ComputedStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction, size_t animationIndex)
71 { 71 {
72 // When the animating element is null, use its parent for scoping purposes. 72 // When the animating element is null, use its parent for scoping purposes.
73 const Element* elementForScoping = animatingElement ? animatingElement : &el ement; 73 const Element* elementForScoping = animatingElement ? animatingElement : &el ement;
74 const StyleRuleKeyframes* keyframesRule = resolver->findKeyframesRule(elemen tForScoping, name); 74 const StyleRuleKeyframes* keyframesRule = resolver->findKeyframesRule(elemen tForScoping, name);
75 ASSERT(keyframesRule); 75 DCHECK(keyframesRule);
76 76
77 StringKeyframeVector keyframes; 77 StringKeyframeVector keyframes;
78 const HeapVector<Member<StyleRuleKeyframe>>& styleKeyframes = keyframesRule- >keyframes(); 78 const HeapVector<Member<StyleRuleKeyframe>>& styleKeyframes = keyframesRule- >keyframes();
79 79
80 // Construct and populate the style for each keyframe 80 // Construct and populate the style for each keyframe
81 PropertySet specifiedPropertiesForUseCounter; 81 PropertySet specifiedPropertiesForUseCounter;
82 for (size_t i = 0; i < styleKeyframes.size(); ++i) { 82 for (size_t i = 0; i < styleKeyframes.size(); ++i) {
83 const StyleRuleKeyframe* styleKeyframe = styleKeyframes[i].get(); 83 const StyleRuleKeyframe* styleKeyframe = styleKeyframes[i].get();
84 RefPtr<StringKeyframe> keyframe = StringKeyframe::create(); 84 RefPtr<StringKeyframe> keyframe = StringKeyframe::create();
85 const Vector<double>& offsets = styleKeyframe->keys(); 85 const Vector<double>& offsets = styleKeyframe->keys();
86 ASSERT(!offsets.isEmpty()); 86 DCHECK(!offsets.isEmpty());
87 keyframe->setOffset(offsets[0]); 87 keyframe->setOffset(offsets[0]);
88 keyframe->setEasing(defaultTimingFunction); 88 keyframe->setEasing(defaultTimingFunction);
89 const StylePropertySet& properties = styleKeyframe->properties(); 89 const StylePropertySet& properties = styleKeyframe->properties();
90 for (unsigned j = 0; j < properties.propertyCount(); j++) { 90 for (unsigned j = 0; j < properties.propertyCount(); j++) {
91 CSSPropertyID property = properties.propertyAt(j).id(); 91 CSSPropertyID property = properties.propertyAt(j).id();
92 specifiedPropertiesForUseCounter.add(property); 92 specifiedPropertiesForUseCounter.add(property);
93 if (property == CSSPropertyAnimationTimingFunction) { 93 if (property == CSSPropertyAnimationTimingFunction) {
94 const CSSValue& value = properties.propertyAt(j).value(); 94 const CSSValue& value = properties.propertyAt(j).value();
95 RefPtr<TimingFunction> timingFunction; 95 RefPtr<TimingFunction> timingFunction;
96 if (value.isInheritedValue() && parentStyle->animations()) { 96 if (value.isInheritedValue() && parentStyle->animations()) {
(...skipping 11 matching lines...) Expand all
108 } 108 }
109 keyframes.append(keyframe); 109 keyframes.append(keyframe);
110 // The last keyframe specified at a given offset is used. 110 // The last keyframe specified at a given offset is used.
111 for (size_t j = 1; j < offsets.size(); ++j) { 111 for (size_t j = 1; j < offsets.size(); ++j) {
112 keyframes.append(toStringKeyframe(keyframe->cloneWithOffset(offsets[ j]).get())); 112 keyframes.append(toStringKeyframe(keyframe->cloneWithOffset(offsets[ j]).get()));
113 } 113 }
114 } 114 }
115 115
116 DEFINE_STATIC_LOCAL(SparseHistogram, propertyHistogram, ("WebCore.Animation. CSSProperties")); 116 DEFINE_STATIC_LOCAL(SparseHistogram, propertyHistogram, ("WebCore.Animation. CSSProperties"));
117 for (CSSPropertyID property : specifiedPropertiesForUseCounter) { 117 for (CSSPropertyID property : specifiedPropertiesForUseCounter) {
118 ASSERT(property != CSSPropertyInvalid); 118 DCHECK_NE(property, CSSPropertyInvalid);
sashab 2016/08/15 07:23:13 Maybe this could use propertyHasName() too? Should
meade_UTC10 2016/09/29 07:39:56 Done.
119 propertyHistogram.sample(UseCounter::mapCSSPropertyIdToCSSSampleIdForHis togram(property)); 119 propertyHistogram.sample(UseCounter::mapCSSPropertyIdToCSSSampleIdForHis togram(property));
120 } 120 }
121 121
122 // Merge duplicate keyframes. 122 // Merge duplicate keyframes.
123 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s); 123 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s);
124 size_t targetIndex = 0; 124 size_t targetIndex = 0;
125 for (size_t i = 1; i < keyframes.size(); i++) { 125 for (size_t i = 1; i < keyframes.size(); i++) {
126 if (keyframes[i]->offset() == keyframes[targetIndex]->offset()) { 126 if (keyframes[i]->offset() == keyframes[targetIndex]->offset()) {
127 for (const auto& property : keyframes[i]->properties()) 127 for (const auto& property : keyframes[i]->properties())
128 keyframes[targetIndex]->setCSSPropertyValue(property.cssProperty (), keyframes[i]->cssPropertyValue(property.cssProperty())); 128 keyframes[targetIndex]->setCSSPropertyValue(property.cssProperty (), keyframes[i]->cssPropertyValue(property.cssProperty()));
(...skipping 13 matching lines...) Expand all
142 startKeyframe->setEasing(defaultTimingFunction); 142 startKeyframe->setEasing(defaultTimingFunction);
143 keyframes.prepend(startKeyframe); 143 keyframes.prepend(startKeyframe);
144 } 144 }
145 RefPtr<StringKeyframe> endKeyframe = keyframes[keyframes.size() - 1]; 145 RefPtr<StringKeyframe> endKeyframe = keyframes[keyframes.size() - 1];
146 if (endKeyframe->offset() != 1) { 146 if (endKeyframe->offset() != 1) {
147 endKeyframe = StringKeyframe::create(); 147 endKeyframe = StringKeyframe::create();
148 endKeyframe->setOffset(1); 148 endKeyframe->setOffset(1);
149 endKeyframe->setEasing(defaultTimingFunction); 149 endKeyframe->setEasing(defaultTimingFunction);
150 keyframes.append(endKeyframe); 150 keyframes.append(endKeyframe);
151 } 151 }
152 ASSERT(keyframes.size() >= 2); 152 DCHECK_GE(keyframes.size(), 2UL);
153 ASSERT(!keyframes.first()->offset()); 153 DCHECK(!keyframes.first()->offset());
154 ASSERT(keyframes.last()->offset() == 1); 154 DCHECK_EQ(keyframes.last()->offset(), 1);
155 155
156 // FIXME: This is only used for use counting neutral keyframes running on th e compositor. 156 // FIXME: This is only used for use counting neutral keyframes running on th e compositor.
157 PropertySet allProperties; 157 PropertySet allProperties;
158 for (const auto& keyframe : keyframes) { 158 for (const auto& keyframe : keyframes) {
159 for (const auto& property : keyframe->properties()) 159 for (const auto& property : keyframe->properties())
160 allProperties.add(property.cssProperty()); 160 allProperties.add(property.cssProperty());
161 } 161 }
162 const PropertyHandleSet& startKeyframeProperties = startKeyframe->properties (); 162 const PropertyHandleSet& startKeyframeProperties = startKeyframe->properties ();
163 const PropertyHandleSet& endKeyframeProperties = endKeyframe->properties(); 163 const PropertyHandleSet& endKeyframeProperties = endKeyframe->properties();
164 bool missingStartValues = startKeyframeProperties.size() < allProperties.siz e(); 164 bool missingStartValues = startKeyframeProperties.size() < allProperties.siz e();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 update.updateCompositorKeyframes(&animation); 262 update.updateCompositorKeyframes(&animation);
263 } 263 }
264 } 264 }
265 265
266 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate& update, const E lement* animatingElement, Element& element, const ComputedStyle& style, Computed Style* parentStyle, StyleResolver* resolver) 266 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate& update, const E lement* animatingElement, Element& element, const ComputedStyle& style, Computed Style* parentStyle, StyleResolver* resolver)
267 { 267 {
268 const ElementAnimations* elementAnimations = animatingElement ? animatingEle ment->elementAnimations() : nullptr; 268 const ElementAnimations* elementAnimations = animatingElement ? animatingEle ment->elementAnimations() : nullptr;
269 269
270 bool isAnimationStyleChange = elementAnimations && elementAnimations->isAnim ationStyleChange(); 270 bool isAnimationStyleChange = elementAnimations && elementAnimations->isAnim ationStyleChange();
271 271
272 #if !ENABLE(ASSERT) 272 #if DCHECK_IS_ON()
273 // If we're in an animation style change, no animations can have started, be en cancelled or changed play state. 273 // If we're in an animation style change, no animations can have started, be en cancelled or changed play state.
274 // When ASSERT is enabled, we verify this optimization. 274 // When DCHECK is enabled, we verify this optimization.
275 if (isAnimationStyleChange) 275 if (isAnimationStyleChange)
276 return; 276 return;
277 #endif 277 #endif
278 278
279 const CSSAnimationData* animationData = style.animations(); 279 const CSSAnimationData* animationData = style.animations();
280 const CSSAnimations* cssAnimations = elementAnimations ? &elementAnimations- >cssAnimations() : nullptr; 280 const CSSAnimations* cssAnimations = elementAnimations ? &elementAnimations- >cssAnimations() : nullptr;
281 const Element* elementForScoping = animatingElement ? animatingElement : &el ement; 281 const Element* elementForScoping = animatingElement ? animatingElement : &el ement;
282 282
283 Vector<bool> cancelRunningAnimationFlags(cssAnimations ? cssAnimations->m_ru nningAnimations.size() : 0); 283 Vector<bool> cancelRunningAnimationFlags(cssAnimations ? cssAnimations->m_ru nningAnimations.size() : 0);
284 for (bool& flag : cancelRunningAnimationFlags) 284 for (bool& flag : cancelRunningAnimationFlags)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 324 }
325 } 325 }
326 } 326 }
327 327
328 if (existingAnimation) { 328 if (existingAnimation) {
329 cancelRunningAnimationFlags[existingAnimationIndex] = false; 329 cancelRunningAnimationFlags[existingAnimationIndex] = false;
330 330
331 Animation* animation = existingAnimation->animation.get(); 331 Animation* animation = existingAnimation->animation.get();
332 332
333 if (keyframesRule != existingAnimation->styleRule || keyframesRu le->version() != existingAnimation->styleRuleVersion || existingAnimation->speci fiedTiming != specifiedTiming) { 333 if (keyframesRule != existingAnimation->styleRule || keyframesRu le->version() != existingAnimation->styleRuleVersion || existingAnimation->speci fiedTiming != specifiedTiming) {
334 ASSERT(!isAnimationStyleChange); 334 DCHECK(!isAnimationStyleChange);
335 update.updateAnimation(existingAnimationIndex, animation, *I nertEffect::create( 335 update.updateAnimation(existingAnimationIndex, animation, *I nertEffect::create(
336 createKeyframeEffectModel(resolver, animatingElement, el ement, &style, parentStyle, name, keyframeTimingFunction.get(), i), 336 createKeyframeEffectModel(resolver, animatingElement, el ement, &style, parentStyle, name, keyframeTimingFunction.get(), i),
337 timing, isPaused, animation->unlimitedCurrentTimeInterna l()), specifiedTiming, keyframesRule); 337 timing, isPaused, animation->unlimitedCurrentTimeInterna l()), specifiedTiming, keyframesRule);
338 } 338 }
339 339
340 if (isPaused != animation->paused()) { 340 if (isPaused != animation->paused()) {
341 ASSERT(!isAnimationStyleChange); 341 DCHECK(!isAnimationStyleChange);
342 update.toggleAnimationIndexPaused(existingAnimationIndex); 342 update.toggleAnimationIndexPaused(existingAnimationIndex);
343 } 343 }
344 } else { 344 } else {
345 ASSERT(!isAnimationStyleChange); 345 DCHECK(!isAnimationStyleChange);
346 update.startAnimation(name, nameIndex, *InertEffect::create( 346 update.startAnimation(name, nameIndex, *InertEffect::create(
347 createKeyframeEffectModel(resolver, animatingElement, elemen t, &style, parentStyle, name, keyframeTimingFunction.get(), i), 347 createKeyframeEffectModel(resolver, animatingElement, elemen t, &style, parentStyle, name, keyframeTimingFunction.get(), i),
348 timing, isPaused, 0), specifiedTiming, keyframesRule); 348 timing, isPaused, 0), specifiedTiming, keyframesRule);
349 } 349 }
350 } 350 }
351 } 351 }
352 352
353 for (size_t i = 0; i < cancelRunningAnimationFlags.size(); i++) { 353 for (size_t i = 0; i < cancelRunningAnimationFlags.size(); i++) {
354 if (cancelRunningAnimationFlags[i]) { 354 if (cancelRunningAnimationFlags[i]) {
355 ASSERT(cssAnimations && !isAnimationStyleChange); 355 DCHECK(cssAnimations && !isAnimationStyleChange);
356 update.cancelAnimation(i, *cssAnimations->m_runningAnimations[i]->an imation); 356 update.cancelAnimation(i, *cssAnimations->m_runningAnimations[i]->an imation);
357 } 357 }
358 } 358 }
359 } 359 }
360 360
361 void CSSAnimations::snapshotCompositorKeyframes(Element& element, CSSAnimationUp date& update, const ComputedStyle& style, const ComputedStyle* parentStyle) 361 void CSSAnimations::snapshotCompositorKeyframes(Element& element, CSSAnimationUp date& update, const ComputedStyle& style, const ComputedStyle* parentStyle)
362 { 362 {
363 const auto& snapshot = [&element, &style, parentStyle](const AnimationEffect * effect) 363 const auto& snapshot = [&element, &style, parentStyle](const AnimationEffect * effect)
364 { 364 {
365 const KeyframeEffectModelBase* keyframeEffect = getKeyframeEffectModelBa se(effect); 365 const KeyframeEffectModelBase* keyframeEffect = getKeyframeEffectModelBa se(effect);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect()); 413 KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect());
414 414
415 effect->setModel(entry.effect->model()); 415 effect->setModel(entry.effect->model());
416 effect->updateSpecifiedTiming(entry.effect->specifiedTiming()); 416 effect->updateSpecifiedTiming(entry.effect->specifiedTiming());
417 417
418 m_runningAnimations[entry.index]->update(entry); 418 m_runningAnimations[entry.index]->update(entry);
419 } 419 }
420 420
421 const Vector<size_t>& cancelledIndices = m_pendingUpdate.cancelledAnimationI ndices(); 421 const Vector<size_t>& cancelledIndices = m_pendingUpdate.cancelledAnimationI ndices();
422 for (size_t i = cancelledIndices.size(); i-- > 0;) { 422 for (size_t i = cancelledIndices.size(); i-- > 0;) {
423 ASSERT(i == cancelledIndices.size() - 1 || cancelledIndices[i] < cancell edIndices[i + 1]); 423 DCHECK(i == cancelledIndices.size() - 1 || cancelledIndices[i] < cancell edIndices[i + 1]);
424 Animation& animation = *m_runningAnimations[cancelledIndices[i]]->animat ion; 424 Animation& animation = *m_runningAnimations[cancelledIndices[i]]->animat ion;
425 animation.cancel(); 425 animation.cancel();
426 animation.update(TimingUpdateOnDemand); 426 animation.update(TimingUpdateOnDemand);
427 m_runningAnimations.remove(cancelledIndices[i]); 427 m_runningAnimations.remove(cancelledIndices[i]);
428 } 428 }
429 429
430 for (const auto& entry : m_pendingUpdate.newAnimations()) { 430 for (const auto& entry : m_pendingUpdate.newAnimations()) {
431 const InertEffect* inertAnimation = entry.effect.get(); 431 const InertEffect* inertAnimation = entry.effect.get();
432 AnimationEventDelegate* eventDelegate = new AnimationEventDelegate(eleme nt, entry.name); 432 AnimationEventDelegate* eventDelegate = new AnimationEventDelegate(eleme nt, entry.name);
433 KeyframeEffect* effect = KeyframeEffect::create(element, inertAnimation- >model(), inertAnimation->specifiedTiming(), KeyframeEffect::DefaultPriority, ev entDelegate); 433 KeyframeEffect* effect = KeyframeEffect::create(element, inertAnimation- >model(), inertAnimation->specifiedTiming(), KeyframeEffect::DefaultPriority, ev entDelegate);
434 Animation* animation = element->document().timeline().play(effect); 434 Animation* animation = element->document().timeline().play(effect);
435 animation->setId(entry.name); 435 animation->setId(entry.name);
436 if (inertAnimation->paused()) 436 if (inertAnimation->paused())
437 animation->pause(); 437 animation->pause();
438 animation->update(TimingUpdateOnDemand); 438 animation->update(TimingUpdateOnDemand);
439 439
440 m_runningAnimations.append(new RunningAnimation(animation, entry)); 440 m_runningAnimations.append(new RunningAnimation(animation, entry));
441 } 441 }
442 442
443 // Transitions that are run on the compositor only update main-thread state 443 // Transitions that are run on the compositor only update main-thread state
444 // lazily. However, we need the new state to know what the from state shoud 444 // lazily. However, we need the new state to know what the from state shoud
445 // be when transitions are retargeted. Instead of triggering complete style 445 // be when transitions are retargeted. Instead of triggering complete style
446 // recalculation, we find these cases by searching for new transitions that 446 // recalculation, we find these cases by searching for new transitions that
447 // have matching cancelled animation property IDs on the compositor. 447 // have matching cancelled animation property IDs on the compositor.
448 HeapHashMap<CSSPropertyID, std::pair<Member<KeyframeEffect>, double>> retarg etedCompositorTransitions; 448 HeapHashMap<CSSPropertyID, std::pair<Member<KeyframeEffect>, double>> retarg etedCompositorTransitions;
449 for (CSSPropertyID id : m_pendingUpdate.cancelledTransitions()) { 449 for (CSSPropertyID id : m_pendingUpdate.cancelledTransitions()) {
450 ASSERT(m_transitions.contains(id)); 450 DCHECK(m_transitions.contains(id));
451 451
452 Animation* animation = m_transitions.take(id).animation; 452 Animation* animation = m_transitions.take(id).animation;
453 KeyframeEffect* effect = toKeyframeEffect(animation->effect()); 453 KeyframeEffect* effect = toKeyframeEffect(animation->effect());
454 if (effect->hasActiveAnimationsOnCompositor(id) && m_pendingUpdate.newTr ansitions().find(id) != m_pendingUpdate.newTransitions().end() && !animation->li mited()) 454 if (effect->hasActiveAnimationsOnCompositor(id) && m_pendingUpdate.newTr ansitions().find(id) != m_pendingUpdate.newTransitions().end() && !animation->li mited())
455 retargetedCompositorTransitions.add(id, std::pair<KeyframeEffect*, d ouble>(effect, animation->startTimeInternal())); 455 retargetedCompositorTransitions.add(id, std::pair<KeyframeEffect*, d ouble>(effect, animation->startTimeInternal()));
456 animation->cancel(); 456 animation->cancel();
457 // after cancelation, transitions must be downgraded or they'll fail 457 // after cancelation, transitions must be downgraded or they'll fail
458 // to be considered when retriggering themselves. This can happen if 458 // to be considered when retriggering themselves. This can happen if
459 // the transition is captured through getAnimations then played. 459 // the transition is captured through getAnimations then played.
460 if (animation->effect() && animation->effect()->isKeyframeEffect()) 460 if (animation->effect() && animation->effect()->isKeyframeEffect())
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 515
516 KeyframeEffect* transition = KeyframeEffect::create(element, model, iner tAnimation->specifiedTiming(), KeyframeEffect::TransitionPriority, eventDelegate ); 516 KeyframeEffect* transition = KeyframeEffect::create(element, model, iner tAnimation->specifiedTiming(), KeyframeEffect::TransitionPriority, eventDelegate );
517 Animation* animation = element->document().timeline().play(transition); 517 Animation* animation = element->document().timeline().play(transition);
518 animation->setId(getPropertyName(newTransition.id)); 518 animation->setId(getPropertyName(newTransition.id));
519 // Set the current time as the start time for retargeted transitions 519 // Set the current time as the start time for retargeted transitions
520 if (retargetedCompositorTransitions.contains(id)) 520 if (retargetedCompositorTransitions.contains(id))
521 animation->setStartTime(element->document().timeline().currentTime() ); 521 animation->setStartTime(element->document().timeline().currentTime() );
522 animation->update(TimingUpdateOnDemand); 522 animation->update(TimingUpdateOnDemand);
523 runningTransition.animation = animation; 523 runningTransition.animation = animation;
524 m_transitions.set(id, runningTransition); 524 m_transitions.set(id, runningTransition);
525 ASSERT(id != CSSPropertyInvalid); 525 DCHECK_NE(id, CSSPropertyInvalid);
sashab 2016/08/15 07:23:13 Same comment as above
meade_UTC10 2016/09/29 07:39:56 Done.
526 526
527 DEFINE_STATIC_LOCAL(SparseHistogram, propertyHistogram, ("WebCore.Animat ion.CSSProperties")); 527 DEFINE_STATIC_LOCAL(SparseHistogram, propertyHistogram, ("WebCore.Animat ion.CSSProperties"));
528 propertyHistogram.sample(UseCounter::mapCSSPropertyIdToCSSSampleIdForHis togram(id)); 528 propertyHistogram.sample(UseCounter::mapCSSPropertyIdToCSSSampleIdForHis togram(id));
529 } 529 }
530 clearPendingUpdate(); 530 clearPendingUpdate();
531 } 531 }
532 532
533 void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, const CSSTransitionData& transitionData, size_t transitionIndex, const ComputedStyle& oldStyle, const ComputedStyle& style, const TransitionMap* activeTransitions, C SSAnimationUpdate& update, const Element* element) 533 void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, const CSSTransitionData& transitionData, size_t transitionIndex, const ComputedStyle& oldStyle, const ComputedStyle& style, const TransitionMap* activeTransitions, C SSAnimationUpdate& update, const Element* element)
534 { 534 {
535 RefPtr<AnimatableValue> to = nullptr; 535 RefPtr<AnimatableValue> to = nullptr;
536 const RunningTransition* interruptedTransition = nullptr; 536 const RunningTransition* interruptedTransition = nullptr;
537 if (activeTransitions) { 537 if (activeTransitions) {
538 TransitionMap::const_iterator activeTransitionIter = activeTransitions-> find(id); 538 TransitionMap::const_iterator activeTransitionIter = activeTransitions-> find(id);
539 if (activeTransitionIter != activeTransitions->end()) { 539 if (activeTransitionIter != activeTransitions->end()) {
540 const RunningTransition* runningTransition = &activeTransitionIter-> value; 540 const RunningTransition* runningTransition = &activeTransitionIter-> value;
541 to = CSSAnimatableValueFactory::create(id, style); 541 to = CSSAnimatableValueFactory::create(id, style);
542 const AnimatableValue* activeTo = runningTransition->to; 542 const AnimatableValue* activeTo = runningTransition->to;
543 if (to->equals(activeTo)) 543 if (to->equals(activeTo))
544 return; 544 return;
545 update.cancelTransition(id); 545 update.cancelTransition(id);
546 ASSERT(!element->elementAnimations() || !element->elementAnimations( )->isAnimationStyleChange()); 546 DCHECK(!element->elementAnimations() || !element->elementAnimations( )->isAnimationStyleChange());
547 547
548 if (to->equals(runningTransition->reversingAdjustedStartValue.get()) ) 548 if (to->equals(runningTransition->reversingAdjustedStartValue.get()) )
549 interruptedTransition = runningTransition; 549 interruptedTransition = runningTransition;
550 } 550 }
551 } 551 }
552 552
553 if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style)) 553 if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style))
554 return; 554 return;
555 if (!to) 555 if (!to)
556 to = CSSAnimatableValueFactory::create(id, style); 556 to = CSSAnimatableValueFactory::create(id, style);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 605
606 RefPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKeyframe::creat e(); 606 RefPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKeyframe::creat e();
607 endKeyframe->setPropertyValue(id, to.get()); 607 endKeyframe->setPropertyValue(id, to.get());
608 endKeyframe->setOffset(1); 608 endKeyframe->setOffset(1);
609 keyframes.append(endKeyframe); 609 keyframes.append(endKeyframe);
610 610
611 AnimatableValueKeyframeEffectModel* model = AnimatableValueKeyframeEffectMod el::create(keyframes); 611 AnimatableValueKeyframeEffectModel* model = AnimatableValueKeyframeEffectMod el::create(keyframes);
612 update.startTransition( 612 update.startTransition(
613 id, from.get(), to.get(), reversingAdjustedStartValue, reversingShorteni ngFactor, 613 id, from.get(), to.get(), reversingAdjustedStartValue, reversingShorteni ngFactor,
614 *InertEffect::create(model, timing, false, 0)); 614 *InertEffect::create(model, timing, false, 0));
615 ASSERT(!element->elementAnimations() || !element->elementAnimations()->isAni mationStyleChange()); 615 DCHECK(!element->elementAnimations() || !element->elementAnimations()->isAni mationStyleChange());
616 } 616 }
617 617
618 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate& update, const Element* animatingElement, const ComputedStyle& style) 618 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate& update, const Element* animatingElement, const ComputedStyle& style)
619 { 619 {
620 if (!animatingElement) 620 if (!animatingElement)
621 return; 621 return;
622 622
623 if (animatingElement->document().printing() || animatingElement->document(). wasPrinting()) 623 if (animatingElement->document().printing() || animatingElement->document(). wasPrinting())
624 return; 624 return;
625 625
626 ElementAnimations* elementAnimations = animatingElement->elementAnimations() ; 626 ElementAnimations* elementAnimations = animatingElement->elementAnimations() ;
627 const TransitionMap* activeTransitions = elementAnimations ? &elementAnimati ons->cssAnimations().m_transitions : nullptr; 627 const TransitionMap* activeTransitions = elementAnimations ? &elementAnimati ons->cssAnimations().m_transitions : nullptr;
628 const CSSTransitionData* transitionData = style.transitions(); 628 const CSSTransitionData* transitionData = style.transitions();
629 629
630 #if ENABLE(ASSERT) 630 #if DCHECK_IS_ON()
631 // In debug builds we verify that it would have been safe to avoid populatin g and testing listedProperties if the style recalc is due to animation. 631 // In debug builds we verify that it would have been safe to avoid populatin g and testing listedProperties if the style recalc is due to animation.
632 const bool animationStyleRecalc = false; 632 const bool animationStyleRecalc = false;
633 #else 633 #else
634 // In release builds we avoid the cost of checking for new and interrupted t ransitions if the style recalc is due to animation. 634 // In release builds we avoid the cost of checking for new and interrupted t ransitions if the style recalc is due to animation.
635 const bool animationStyleRecalc = elementAnimations && elementAnimations->is AnimationStyleChange(); 635 const bool animationStyleRecalc = elementAnimations && elementAnimations->is AnimationStyleChange();
636 #endif 636 #endif
637 637
638 std::bitset<numCSSProperties> listedProperties; 638 std::bitset<numCSSProperties> listedProperties;
639 bool anyTransitionHadTransitionAll = false; 639 bool anyTransitionHadTransitionAll = false;
640 const LayoutObject* layoutObject = animatingElement->layoutObject(); 640 const LayoutObject* layoutObject = animatingElement->layoutObject();
641 if (!animationStyleRecalc && style.display() != NONE && layoutObject && layo utObject->style() && transitionData) { 641 if (!animationStyleRecalc && style.display() != NONE && layoutObject && layo utObject->style() && transitionData) {
642 const ComputedStyle& oldStyle = *layoutObject->style(); 642 const ComputedStyle& oldStyle = *layoutObject->style();
643 643
644 for (size_t i = 0; i < transitionData->propertyList().size(); ++i) { 644 for (size_t i = 0; i < transitionData->propertyList().size(); ++i) {
645 const CSSTransitionData::TransitionProperty& transitionProperty = tr ansitionData->propertyList()[i]; 645 const CSSTransitionData::TransitionProperty& transitionProperty = tr ansitionData->propertyList()[i];
646 if (transitionProperty.propertyType != CSSTransitionData::Transition KnownProperty) 646 if (transitionProperty.propertyType != CSSTransitionData::Transition KnownProperty)
647 continue; 647 continue;
648 648
649 CSSPropertyID property = resolveCSSPropertyID(transitionProperty.unr esolvedProperty); 649 CSSPropertyID property = resolveCSSPropertyID(transitionProperty.unr esolvedProperty);
650 bool animateAll = property == CSSPropertyAll; 650 bool animateAll = property == CSSPropertyAll;
651 if (animateAll) 651 if (animateAll)
652 anyTransitionHadTransitionAll = true; 652 anyTransitionHadTransitionAll = true;
653 const StylePropertyShorthand& propertyList = animateAll ? CSSAnimati ons::propertiesForTransitionAll() : shorthandForProperty(property); 653 const StylePropertyShorthand& propertyList = animateAll ? CSSAnimati ons::propertiesForTransitionAll() : shorthandForProperty(property);
654 // If not a shorthand we only execute one iteration of this loop, an d refer to the property directly. 654 // If not a shorthand we only execute one iteration of this loop, an d refer to the property directly.
655 for (unsigned j = 0; !j || j < propertyList.length(); ++j) { 655 for (unsigned j = 0; !j || j < propertyList.length(); ++j) {
656 CSSPropertyID id = propertyList.length() ? propertyList.properti es()[j] : property; 656 CSSPropertyID id = propertyList.length() ? propertyList.properti es()[j] : property;
657 ASSERT(id >= firstCSSProperty); 657 DCHECK(propertyHasName(id));
658 658
659 if (!animateAll) { 659 if (!animateAll) {
660 if (CSSPropertyMetadata::isInterpolableProperty(id)) 660 if (CSSPropertyMetadata::isInterpolableProperty(id))
661 listedProperties.set(id - firstCSSProperty); 661 listedProperties.set(id - firstCSSProperty);
662 else 662 else
663 continue; 663 continue;
664 } 664 }
665 665
666 // FIXME: We should transition if an !important property changes even when an animation is running, 666 // FIXME: We should transition if an !important property changes even when an animation is running,
667 // but this is a bit hard to do with the current applyMatchedPro perties system. 667 // but this is a bit hard to do with the current applyMatchedPro perties system.
668 PropertyHandle property = PropertyHandle(id); 668 PropertyHandle property = PropertyHandle(id);
669 if (!update.activeInterpolationsForAnimations().contains(propert y) 669 if (!update.activeInterpolationsForAnimations().contains(propert y)
670 && (!elementAnimations || !elementAnimations->cssAnimations( ).m_previousActiveInterpolationsForAnimations.contains(property))) { 670 && (!elementAnimations || !elementAnimations->cssAnimations( ).m_previousActiveInterpolationsForAnimations.contains(property))) {
671 calculateTransitionUpdateForProperty(id, *transitionData, i, oldStyle, style, activeTransitions, update, animatingElement); 671 calculateTransitionUpdateForProperty(id, *transitionData, i, oldStyle, style, activeTransitions, update, animatingElement);
672 } 672 }
673 } 673 }
674 } 674 }
675 } 675 }
676 676
677 if (activeTransitions) { 677 if (activeTransitions) {
678 for (const auto& entry : *activeTransitions) { 678 for (const auto& entry : *activeTransitions) {
679 CSSPropertyID id = entry.key; 679 CSSPropertyID id = entry.key;
680 if (!anyTransitionHadTransitionAll && !animationStyleRecalc && !list edProperties.test(id - firstCSSProperty)) { 680 if (!anyTransitionHadTransitionAll && !animationStyleRecalc && !list edProperties.test(id - firstCSSProperty)) {
681 // TODO: Figure out why this fails on Chrome OS login page. crbu g.com/365507 681 // TODO: Figure out why this fails on Chrome OS login page. crbu g.com/365507
682 // ASSERT(animation.playStateInternal() == Animation::Finished | | !(elementAnimations && elementAnimations->isAnimationStyleChange())); 682 // DCHECK(animation.playStateInternal() == Animation::Finished | | !(elementAnimations && elementAnimations->isAnimationStyleChange()));
683 update.cancelTransition(id); 683 update.cancelTransition(id);
684 } else if (entry.value.animation->finishedInternal()) { 684 } else if (entry.value.animation->finishedInternal()) {
685 update.finishTransition(id); 685 update.finishTransition(id);
686 } 686 }
687 } 687 }
688 } 688 }
689 } 689 }
690 690
691 void CSSAnimations::cancel() 691 void CSSAnimations::cancel()
692 { 692 {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 ActiveInterpolationsMap activeInterpolationsForTransitions; 739 ActiveInterpolationsMap activeInterpolationsForTransitions;
740 if (update.newTransitions().isEmpty() && update.cancelledTransitions().isEmp ty()) { 740 if (update.newTransitions().isEmpty() && update.cancelledTransitions().isEmp ty()) {
741 activeInterpolationsForTransitions = AnimationStack::activeInterpolation s(animationStack, nullptr, nullptr, KeyframeEffect::TransitionPriority, isStyleP ropertyHandle); 741 activeInterpolationsForTransitions = AnimationStack::activeInterpolation s(animationStack, nullptr, nullptr, KeyframeEffect::TransitionPriority, isStyleP ropertyHandle);
742 } else { 742 } else {
743 HeapVector<Member<const InertEffect>> newTransitions; 743 HeapVector<Member<const InertEffect>> newTransitions;
744 for (const auto& entry : update.newTransitions()) 744 for (const auto& entry : update.newTransitions())
745 newTransitions.append(entry.value.effect.get()); 745 newTransitions.append(entry.value.effect.get());
746 746
747 HeapHashSet<Member<const Animation>> cancelledAnimations; 747 HeapHashSet<Member<const Animation>> cancelledAnimations;
748 if (!update.cancelledTransitions().isEmpty()) { 748 if (!update.cancelledTransitions().isEmpty()) {
749 ASSERT(elementAnimations); 749 DCHECK(elementAnimations);
750 const TransitionMap& transitionMap = elementAnimations->cssAnimation s().m_transitions; 750 const TransitionMap& transitionMap = elementAnimations->cssAnimation s().m_transitions;
751 for (CSSPropertyID id : update.cancelledTransitions()) { 751 for (CSSPropertyID id : update.cancelledTransitions()) {
752 ASSERT(transitionMap.contains(id)); 752 DCHECK(transitionMap.contains(id));
753 cancelledAnimations.add(transitionMap.get(id).animation.get()); 753 cancelledAnimations.add(transitionMap.get(id).animation.get());
754 } 754 }
755 } 755 }
756 756
757 activeInterpolationsForTransitions = AnimationStack::activeInterpolation s(animationStack, &newTransitions, &cancelledAnimations, KeyframeEffect::Transit ionPriority, isStylePropertyHandle); 757 activeInterpolationsForTransitions = AnimationStack::activeInterpolation s(animationStack, &newTransitions, &cancelledAnimations, KeyframeEffect::Transit ionPriority, isStylePropertyHandle);
758 } 758 }
759 759
760 // Properties being animated by animations don't get values from transitions applied. 760 // Properties being animated by animations don't get values from transitions applied.
761 if (!update.activeInterpolationsForAnimations().isEmpty() && !activeInterpol ationsForTransitions.isEmpty()) { 761 if (!update.activeInterpolationsForAnimations().isEmpty() && !activeInterpol ationsForTransitions.isEmpty()) {
762 for (const auto& entry : update.activeInterpolationsForAnimations()) 762 for (const auto& entry : update.activeInterpolationsForAnimations())
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 const double startDelay = animationNode.specifiedTiming().startDelay; 795 const double startDelay = animationNode.specifiedTiming().startDelay;
796 const double elapsedTime = startDelay < 0 ? -startDelay : 0; 796 const double elapsedTime = startDelay < 0 ? -startDelay : 0;
797 maybeDispatch(Document::ANIMATIONSTART_LISTENER, EventTypeNames::animati onstart, elapsedTime); 797 maybeDispatch(Document::ANIMATIONSTART_LISTENER, EventTypeNames::animati onstart, elapsedTime);
798 } 798 }
799 799
800 if (currentPhase == AnimationEffect::PhaseActive && m_previousPhase == curre ntPhase && m_previousIteration != currentIteration) { 800 if (currentPhase == AnimationEffect::PhaseActive && m_previousPhase == curre ntPhase && m_previousIteration != currentIteration) {
801 // We fire only a single event for all iterations thast terminate 801 // We fire only a single event for all iterations thast terminate
802 // between a single pair of samples. See http://crbug.com/275263. For 802 // between a single pair of samples. See http://crbug.com/275263. For
803 // compatibility with the existing implementation, this event uses 803 // compatibility with the existing implementation, this event uses
804 // the elapsedTime for the first iteration in question. 804 // the elapsedTime for the first iteration in question.
805 ASSERT(!std::isnan(animationNode.specifiedTiming().iterationDuration)); 805 DCHECK(!std::isnan(animationNode.specifiedTiming().iterationDuration));
806 const double elapsedTime = animationNode.specifiedTiming().iterationDura tion * (m_previousIteration + 1); 806 const double elapsedTime = animationNode.specifiedTiming().iterationDura tion * (m_previousIteration + 1);
807 maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::ani mationiteration, elapsedTime); 807 maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::ani mationiteration, elapsedTime);
808 } 808 }
809 809
810 if (currentPhase == AnimationEffect::PhaseAfter && m_previousPhase != Animat ionEffect::PhaseAfter) 810 if (currentPhase == AnimationEffect::PhaseAfter && m_previousPhase != Animat ionEffect::PhaseAfter)
811 maybeDispatch(Document::ANIMATIONEND_LISTENER, EventTypeNames::animation end, animationNode.activeDurationInternal()); 811 maybeDispatch(Document::ANIMATIONEND_LISTENER, EventTypeNames::animation end, animationNode.activeDurationInternal());
812 812
813 m_previousPhase = currentPhase; 813 m_previousPhase = currentPhase;
814 m_previousIteration = currentIteration; 814 m_previousIteration = currentIteration;
815 } 815 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } 897 }
898 898
899 DEFINE_TRACE(CSSAnimations) 899 DEFINE_TRACE(CSSAnimations)
900 { 900 {
901 visitor->trace(m_transitions); 901 visitor->trace(m_transitions);
902 visitor->trace(m_pendingUpdate); 902 visitor->trace(m_pendingUpdate);
903 visitor->trace(m_runningAnimations); 903 visitor->trace(m_runningAnimations);
904 } 904 }
905 905
906 } // namespace blink 906 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698