Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |