Chromium Code Reviews| Index: third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp |
| diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp |
| index 55eb59dcf8000bb3af57908432e94f934ca3af93..3e5a916e28add87bc6bb611bde6a197a0d034857 100644 |
| --- a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp |
| +++ b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp |
| @@ -231,19 +231,15 @@ bool CSSAnimations::isTransitionAnimationForInspector( |
| return false; |
| } |
| -void CSSAnimations::calculateUpdate(const Element* animatingElement, |
| - Element& element, |
| - const ComputedStyle& style, |
| - ComputedStyle* parentStyle, |
| - CSSAnimationUpdate& animationUpdate, |
| - StyleResolver* resolver) { |
| +void CSSAnimations::calculateCompositorAndTransitionUpdate( |
| + const Element* animatingElement, |
| + Element& element, |
| + const ComputedStyle& style, |
| + ComputedStyle* parentStyle, |
| + CSSAnimationUpdate& animationUpdate) { |
| calculateCompositorAnimationUpdate(animationUpdate, animatingElement, element, |
| style, parentStyle); |
| - calculateAnimationUpdate(animationUpdate, animatingElement, element, style, |
| - parentStyle, resolver); |
| - calculateAnimationActiveInterpolations(animationUpdate, animatingElement); |
| calculateTransitionUpdate(animationUpdate, animatingElement, style); |
| - calculateTransitionActiveInterpolations(animationUpdate, animatingElement); |
| } |
| static const KeyframeEffectModelBase* getKeyframeEffectModelBase( |
| @@ -320,113 +316,122 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate& update, |
| bool isAnimationStyleChange = |
| elementAnimations && elementAnimations->isAnimationStyleChange(); |
| + bool checkAnimationProperties = true; |
| #if !DCHECK_IS_ON() |
| // If we're in an animation style change, no animations can have started, been |
| // cancelled or changed play state. When DCHECK is enabled, we verify this |
| // optimization. |
| if (isAnimationStyleChange) |
| - return; |
| + checkAnimationProperties = false; |
|
Timothy Loh
2016/12/01 03:41:48
maybe just calculateAnimationActiveInterpolations+
|
| #endif |
| - const CSSAnimationData* animationData = style.animations(); |
| - const CSSAnimations* cssAnimations = |
| - elementAnimations ? &elementAnimations->cssAnimations() : nullptr; |
| - const Element* elementForScoping = |
| - animatingElement ? animatingElement : &element; |
| - |
| - Vector<bool> cancelRunningAnimationFlags( |
| - cssAnimations ? cssAnimations->m_runningAnimations.size() : 0); |
| - for (bool& flag : cancelRunningAnimationFlags) |
| - flag = true; |
| - |
| - if (animationData && style.display() != EDisplay::None) { |
| - const Vector<AtomicString>& nameList = animationData->nameList(); |
| - for (size_t i = 0; i < nameList.size(); ++i) { |
| - AtomicString name = nameList[i]; |
| - if (name == CSSAnimationData::initialName()) |
| - continue; |
| - |
| - // Find n where this is the nth occurence of this animation name. |
| - size_t nameIndex = 0; |
| - for (size_t j = 0; j < i; j++) { |
| - if (nameList[j] == name) |
| - nameIndex++; |
| - } |
| + if (checkAnimationProperties) { |
| + // All mutations to "update" in this block must be accompanied by a DCHECK |
| + // for !isAnimationStyleChange. |
| + const CSSAnimationData* animationData = style.animations(); |
| + const CSSAnimations* cssAnimations = |
| + elementAnimations ? &elementAnimations->cssAnimations() : nullptr; |
| + const Element* elementForScoping = |
| + animatingElement ? animatingElement : &element; |
| + |
| + Vector<bool> cancelRunningAnimationFlags( |
| + cssAnimations ? cssAnimations->m_runningAnimations.size() : 0); |
| + for (bool& flag : cancelRunningAnimationFlags) |
| + flag = true; |
| + |
| + if (animationData && style.display() != EDisplay::None) { |
| + const Vector<AtomicString>& nameList = animationData->nameList(); |
| + for (size_t i = 0; i < nameList.size(); ++i) { |
| + AtomicString name = nameList[i]; |
| + if (name == CSSAnimationData::initialName()) |
| + continue; |
| + |
| + // Find n where this is the nth occurence of this animation name. |
| + size_t nameIndex = 0; |
| + for (size_t j = 0; j < i; j++) { |
| + if (nameList[j] == name) |
| + nameIndex++; |
| + } |
| - const bool isPaused = |
| - CSSTimingData::getRepeated(animationData->playStateList(), i) == |
| - AnimPlayStatePaused; |
| - |
| - Timing timing = animationData->convertToTiming(i); |
| - Timing specifiedTiming = timing; |
| - RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction; |
| - timing.timingFunction = Timing::defaults().timingFunction; |
| - |
| - StyleRuleKeyframes* keyframesRule = |
| - resolver->findKeyframesRule(elementForScoping, name); |
| - if (!keyframesRule) |
| - continue; // Cancel the animation if there's no style rule for it. |
| - |
| - const RunningAnimation* existingAnimation = nullptr; |
| - size_t existingAnimationIndex = 0; |
| - |
| - if (cssAnimations) { |
| - for (size_t i = 0; i < cssAnimations->m_runningAnimations.size(); i++) { |
| - const RunningAnimation& runningAnimation = |
| - *cssAnimations->m_runningAnimations[i]; |
| - if (runningAnimation.name == name && |
| - runningAnimation.nameIndex == nameIndex) { |
| - existingAnimation = &runningAnimation; |
| - existingAnimationIndex = i; |
| - break; |
| + const bool isPaused = |
| + CSSTimingData::getRepeated(animationData->playStateList(), i) == |
| + AnimPlayStatePaused; |
| + |
| + Timing timing = animationData->convertToTiming(i); |
| + Timing specifiedTiming = timing; |
| + RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction; |
| + timing.timingFunction = Timing::defaults().timingFunction; |
| + |
| + StyleRuleKeyframes* keyframesRule = |
| + resolver->findKeyframesRule(elementForScoping, name); |
| + if (!keyframesRule) |
| + continue; // Cancel the animation if there's no style rule for it. |
| + |
| + const RunningAnimation* existingAnimation = nullptr; |
| + size_t existingAnimationIndex = 0; |
| + |
| + if (cssAnimations) { |
| + for (size_t i = 0; i < cssAnimations->m_runningAnimations.size(); |
| + i++) { |
| + const RunningAnimation& runningAnimation = |
| + *cssAnimations->m_runningAnimations[i]; |
| + if (runningAnimation.name == name && |
| + runningAnimation.nameIndex == nameIndex) { |
| + existingAnimation = &runningAnimation; |
| + existingAnimationIndex = i; |
| + break; |
| + } |
| } |
| } |
| - } |
| - |
| - if (existingAnimation) { |
| - cancelRunningAnimationFlags[existingAnimationIndex] = false; |
| - Animation* animation = existingAnimation->animation.get(); |
| + if (existingAnimation) { |
| + cancelRunningAnimationFlags[existingAnimationIndex] = false; |
| + |
| + Animation* animation = existingAnimation->animation.get(); |
| + |
| + if (keyframesRule != existingAnimation->styleRule || |
| + keyframesRule->version() != existingAnimation->styleRuleVersion || |
| + existingAnimation->specifiedTiming != specifiedTiming) { |
| + DCHECK(!isAnimationStyleChange); |
| + update.updateAnimation( |
| + existingAnimationIndex, animation, |
| + *InertEffect::create( |
| + createKeyframeEffectModel( |
| + resolver, animatingElement, element, &style, |
| + parentStyle, name, keyframeTimingFunction.get(), i), |
| + timing, isPaused, |
| + animation->unlimitedCurrentTimeInternal()), |
| + specifiedTiming, keyframesRule); |
| + } |
| - if (keyframesRule != existingAnimation->styleRule || |
| - keyframesRule->version() != existingAnimation->styleRuleVersion || |
| - existingAnimation->specifiedTiming != specifiedTiming) { |
| + if (isPaused != animation->paused()) { |
| + DCHECK(!isAnimationStyleChange); |
| + update.toggleAnimationIndexPaused(existingAnimationIndex); |
| + } |
| + } else { |
| DCHECK(!isAnimationStyleChange); |
| - update.updateAnimation( |
| - existingAnimationIndex, animation, |
| + update.startAnimation( |
| + name, nameIndex, |
| *InertEffect::create( |
| createKeyframeEffectModel(resolver, animatingElement, element, |
| &style, parentStyle, name, |
| keyframeTimingFunction.get(), i), |
| - timing, isPaused, animation->unlimitedCurrentTimeInternal()), |
| + timing, isPaused, 0), |
| specifiedTiming, keyframesRule); |
| } |
| - |
| - if (isPaused != animation->paused()) { |
| - DCHECK(!isAnimationStyleChange); |
| - update.toggleAnimationIndexPaused(existingAnimationIndex); |
| - } |
| - } else { |
| - DCHECK(!isAnimationStyleChange); |
| - update.startAnimation( |
| - name, nameIndex, |
| - *InertEffect::create( |
| - createKeyframeEffectModel(resolver, animatingElement, element, |
| - &style, parentStyle, name, |
| - keyframeTimingFunction.get(), i), |
| - timing, isPaused, 0), |
| - specifiedTiming, keyframesRule); |
| } |
| } |
| - } |
| - for (size_t i = 0; i < cancelRunningAnimationFlags.size(); i++) { |
| - if (cancelRunningAnimationFlags[i]) { |
| - DCHECK(cssAnimations && !isAnimationStyleChange); |
| - update.cancelAnimation(i, |
| - *cssAnimations->m_runningAnimations[i]->animation); |
| + for (size_t i = 0; i < cancelRunningAnimationFlags.size(); i++) { |
| + if (cancelRunningAnimationFlags[i]) { |
| + DCHECK(cssAnimations && !isAnimationStyleChange); |
| + update.cancelAnimation( |
| + i, *cssAnimations->m_runningAnimations[i]->animation); |
| + } |
| } |
| } |
| + |
| + calculateAnimationActiveInterpolations(update, animatingElement); |
| } |
| void CSSAnimations::snapshotCompositorKeyframes( |
| @@ -826,6 +831,7 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate& update, |
| } |
| } |
| } |
| + calculateTransitionActiveInterpolations(update, animatingElement); |
| } |
| void CSSAnimations::cancel() { |
| @@ -1094,6 +1100,18 @@ bool CSSAnimations::isAffectedByKeyframesFromScope(const Element& element, |
| return toShadowRoot(treeScope.rootNode()).host() == element; |
| } |
| +bool CSSAnimations::isCustomPropertyHandle(const PropertyHandle& property) { |
| + return property.isCSSProperty() && |
| + property.cssProperty() == CSSPropertyVariable; |
| +} |
| + |
| +bool CSSAnimations::isAnimatingCustomProperties( |
| + const ElementAnimations* elementAnimations) { |
| + return elementAnimations && |
| + elementAnimations->effectStack().affectsProperties( |
| + isCustomPropertyHandle); |
| +} |
| + |
| DEFINE_TRACE(CSSAnimations) { |
| visitor->trace(m_transitions); |
| visitor->trace(m_pendingUpdate); |