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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 | 224 |
| 225 bool CSSAnimations::isTransitionAnimationForInspector( | 225 bool CSSAnimations::isTransitionAnimationForInspector( |
| 226 const Animation& animation) const { | 226 const Animation& animation) const { |
| 227 for (const auto& it : m_transitions) { | 227 for (const auto& it : m_transitions) { |
| 228 if (it.value.animation->sequenceNumber() == animation.sequenceNumber()) | 228 if (it.value.animation->sequenceNumber() == animation.sequenceNumber()) |
| 229 return true; | 229 return true; |
| 230 } | 230 } |
| 231 return false; | 231 return false; |
| 232 } | 232 } |
| 233 | 233 |
| 234 void CSSAnimations::calculateUpdate(const Element* animatingElement, | 234 void CSSAnimations::calculateCompositorAndTransitionUpdate( |
| 235 Element& element, | 235 const Element* animatingElement, |
| 236 const ComputedStyle& style, | 236 Element& element, |
| 237 ComputedStyle* parentStyle, | 237 const ComputedStyle& style, |
| 238 CSSAnimationUpdate& animationUpdate, | 238 ComputedStyle* parentStyle, |
| 239 StyleResolver* resolver) { | 239 CSSAnimationUpdate& animationUpdate) { |
| 240 calculateCompositorAnimationUpdate(animationUpdate, animatingElement, element, | 240 calculateCompositorAnimationUpdate(animationUpdate, animatingElement, element, |
| 241 style, parentStyle); | 241 style, parentStyle); |
| 242 calculateAnimationUpdate(animationUpdate, animatingElement, element, style, | |
| 243 parentStyle, resolver); | |
| 244 calculateAnimationActiveInterpolations(animationUpdate, animatingElement); | |
| 245 calculateTransitionUpdate(animationUpdate, animatingElement, style); | 242 calculateTransitionUpdate(animationUpdate, animatingElement, style); |
| 246 calculateTransitionActiveInterpolations(animationUpdate, animatingElement); | |
| 247 } | 243 } |
| 248 | 244 |
| 249 static const KeyframeEffectModelBase* getKeyframeEffectModelBase( | 245 static const KeyframeEffectModelBase* getKeyframeEffectModelBase( |
| 250 const AnimationEffectReadOnly* effect) { | 246 const AnimationEffectReadOnly* effect) { |
| 251 if (!effect) | 247 if (!effect) |
| 252 return nullptr; | 248 return nullptr; |
| 253 const EffectModel* model = nullptr; | 249 const EffectModel* model = nullptr; |
| 254 if (effect->isKeyframeEffectReadOnly()) | 250 if (effect->isKeyframeEffectReadOnly()) |
| 255 model = toKeyframeEffectReadOnly(effect)->model(); | 251 model = toKeyframeEffectReadOnly(effect)->model(); |
| 256 else if (effect->isInertEffect()) | 252 else if (effect->isInertEffect()) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 Element& element, | 309 Element& element, |
| 314 const ComputedStyle& style, | 310 const ComputedStyle& style, |
| 315 ComputedStyle* parentStyle, | 311 ComputedStyle* parentStyle, |
| 316 StyleResolver* resolver) { | 312 StyleResolver* resolver) { |
| 317 const ElementAnimations* elementAnimations = | 313 const ElementAnimations* elementAnimations = |
| 318 animatingElement ? animatingElement->elementAnimations() : nullptr; | 314 animatingElement ? animatingElement->elementAnimations() : nullptr; |
| 319 | 315 |
| 320 bool isAnimationStyleChange = | 316 bool isAnimationStyleChange = |
| 321 elementAnimations && elementAnimations->isAnimationStyleChange(); | 317 elementAnimations && elementAnimations->isAnimationStyleChange(); |
| 322 | 318 |
| 319 bool checkAnimationProperties = true; | |
| 323 #if !DCHECK_IS_ON() | 320 #if !DCHECK_IS_ON() |
| 324 // If we're in an animation style change, no animations can have started, been | 321 // If we're in an animation style change, no animations can have started, been |
| 325 // cancelled or changed play state. When DCHECK is enabled, we verify this | 322 // cancelled or changed play state. When DCHECK is enabled, we verify this |
| 326 // optimization. | 323 // optimization. |
| 327 if (isAnimationStyleChange) | 324 if (isAnimationStyleChange) |
| 328 return; | 325 checkAnimationProperties = false; |
|
Timothy Loh
2016/12/01 03:41:48
maybe just calculateAnimationActiveInterpolations+
| |
| 329 #endif | 326 #endif |
| 330 | 327 |
| 331 const CSSAnimationData* animationData = style.animations(); | 328 if (checkAnimationProperties) { |
| 332 const CSSAnimations* cssAnimations = | 329 // All mutations to "update" in this block must be accompanied by a DCHECK |
| 333 elementAnimations ? &elementAnimations->cssAnimations() : nullptr; | 330 // for !isAnimationStyleChange. |
| 334 const Element* elementForScoping = | 331 const CSSAnimationData* animationData = style.animations(); |
| 335 animatingElement ? animatingElement : &element; | 332 const CSSAnimations* cssAnimations = |
| 333 elementAnimations ? &elementAnimations->cssAnimations() : nullptr; | |
| 334 const Element* elementForScoping = | |
| 335 animatingElement ? animatingElement : &element; | |
| 336 | 336 |
| 337 Vector<bool> cancelRunningAnimationFlags( | 337 Vector<bool> cancelRunningAnimationFlags( |
| 338 cssAnimations ? cssAnimations->m_runningAnimations.size() : 0); | 338 cssAnimations ? cssAnimations->m_runningAnimations.size() : 0); |
| 339 for (bool& flag : cancelRunningAnimationFlags) | 339 for (bool& flag : cancelRunningAnimationFlags) |
| 340 flag = true; | 340 flag = true; |
| 341 | 341 |
| 342 if (animationData && style.display() != EDisplay::None) { | 342 if (animationData && style.display() != EDisplay::None) { |
| 343 const Vector<AtomicString>& nameList = animationData->nameList(); | 343 const Vector<AtomicString>& nameList = animationData->nameList(); |
| 344 for (size_t i = 0; i < nameList.size(); ++i) { | 344 for (size_t i = 0; i < nameList.size(); ++i) { |
| 345 AtomicString name = nameList[i]; | 345 AtomicString name = nameList[i]; |
| 346 if (name == CSSAnimationData::initialName()) | 346 if (name == CSSAnimationData::initialName()) |
| 347 continue; | 347 continue; |
| 348 | 348 |
| 349 // Find n where this is the nth occurence of this animation name. | 349 // Find n where this is the nth occurence of this animation name. |
| 350 size_t nameIndex = 0; | 350 size_t nameIndex = 0; |
| 351 for (size_t j = 0; j < i; j++) { | 351 for (size_t j = 0; j < i; j++) { |
| 352 if (nameList[j] == name) | 352 if (nameList[j] == name) |
| 353 nameIndex++; | 353 nameIndex++; |
| 354 } | 354 } |
| 355 | 355 |
| 356 const bool isPaused = | 356 const bool isPaused = |
| 357 CSSTimingData::getRepeated(animationData->playStateList(), i) == | 357 CSSTimingData::getRepeated(animationData->playStateList(), i) == |
| 358 AnimPlayStatePaused; | 358 AnimPlayStatePaused; |
| 359 | 359 |
| 360 Timing timing = animationData->convertToTiming(i); | 360 Timing timing = animationData->convertToTiming(i); |
| 361 Timing specifiedTiming = timing; | 361 Timing specifiedTiming = timing; |
| 362 RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction; | 362 RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction; |
| 363 timing.timingFunction = Timing::defaults().timingFunction; | 363 timing.timingFunction = Timing::defaults().timingFunction; |
| 364 | 364 |
| 365 StyleRuleKeyframes* keyframesRule = | 365 StyleRuleKeyframes* keyframesRule = |
| 366 resolver->findKeyframesRule(elementForScoping, name); | 366 resolver->findKeyframesRule(elementForScoping, name); |
| 367 if (!keyframesRule) | 367 if (!keyframesRule) |
| 368 continue; // Cancel the animation if there's no style rule for it. | 368 continue; // Cancel the animation if there's no style rule for it. |
| 369 | 369 |
| 370 const RunningAnimation* existingAnimation = nullptr; | 370 const RunningAnimation* existingAnimation = nullptr; |
| 371 size_t existingAnimationIndex = 0; | 371 size_t existingAnimationIndex = 0; |
| 372 | 372 |
| 373 if (cssAnimations) { | 373 if (cssAnimations) { |
| 374 for (size_t i = 0; i < cssAnimations->m_runningAnimations.size(); i++) { | 374 for (size_t i = 0; i < cssAnimations->m_runningAnimations.size(); |
| 375 const RunningAnimation& runningAnimation = | 375 i++) { |
| 376 *cssAnimations->m_runningAnimations[i]; | 376 const RunningAnimation& runningAnimation = |
| 377 if (runningAnimation.name == name && | 377 *cssAnimations->m_runningAnimations[i]; |
| 378 runningAnimation.nameIndex == nameIndex) { | 378 if (runningAnimation.name == name && |
| 379 existingAnimation = &runningAnimation; | 379 runningAnimation.nameIndex == nameIndex) { |
| 380 existingAnimationIndex = i; | 380 existingAnimation = &runningAnimation; |
| 381 break; | 381 existingAnimationIndex = i; |
| 382 break; | |
| 383 } | |
| 382 } | 384 } |
| 383 } | 385 } |
| 384 } | |
| 385 | 386 |
| 386 if (existingAnimation) { | 387 if (existingAnimation) { |
| 387 cancelRunningAnimationFlags[existingAnimationIndex] = false; | 388 cancelRunningAnimationFlags[existingAnimationIndex] = false; |
| 388 | 389 |
| 389 Animation* animation = existingAnimation->animation.get(); | 390 Animation* animation = existingAnimation->animation.get(); |
| 390 | 391 |
| 391 if (keyframesRule != existingAnimation->styleRule || | 392 if (keyframesRule != existingAnimation->styleRule || |
| 392 keyframesRule->version() != existingAnimation->styleRuleVersion || | 393 keyframesRule->version() != existingAnimation->styleRuleVersion || |
| 393 existingAnimation->specifiedTiming != specifiedTiming) { | 394 existingAnimation->specifiedTiming != specifiedTiming) { |
| 395 DCHECK(!isAnimationStyleChange); | |
| 396 update.updateAnimation( | |
| 397 existingAnimationIndex, animation, | |
| 398 *InertEffect::create( | |
| 399 createKeyframeEffectModel( | |
| 400 resolver, animatingElement, element, &style, | |
| 401 parentStyle, name, keyframeTimingFunction.get(), i), | |
| 402 timing, isPaused, | |
| 403 animation->unlimitedCurrentTimeInternal()), | |
| 404 specifiedTiming, keyframesRule); | |
| 405 } | |
| 406 | |
| 407 if (isPaused != animation->paused()) { | |
| 408 DCHECK(!isAnimationStyleChange); | |
| 409 update.toggleAnimationIndexPaused(existingAnimationIndex); | |
| 410 } | |
| 411 } else { | |
| 394 DCHECK(!isAnimationStyleChange); | 412 DCHECK(!isAnimationStyleChange); |
| 395 update.updateAnimation( | 413 update.startAnimation( |
| 396 existingAnimationIndex, animation, | 414 name, nameIndex, |
| 397 *InertEffect::create( | 415 *InertEffect::create( |
| 398 createKeyframeEffectModel(resolver, animatingElement, element, | 416 createKeyframeEffectModel(resolver, animatingElement, element, |
| 399 &style, parentStyle, name, | 417 &style, parentStyle, name, |
| 400 keyframeTimingFunction.get(), i), | 418 keyframeTimingFunction.get(), i), |
| 401 timing, isPaused, animation->unlimitedCurrentTimeInternal()), | 419 timing, isPaused, 0), |
| 402 specifiedTiming, keyframesRule); | 420 specifiedTiming, keyframesRule); |
| 403 } | 421 } |
| 422 } | |
| 423 } | |
| 404 | 424 |
| 405 if (isPaused != animation->paused()) { | 425 for (size_t i = 0; i < cancelRunningAnimationFlags.size(); i++) { |
| 406 DCHECK(!isAnimationStyleChange); | 426 if (cancelRunningAnimationFlags[i]) { |
| 407 update.toggleAnimationIndexPaused(existingAnimationIndex); | 427 DCHECK(cssAnimations && !isAnimationStyleChange); |
| 408 } | 428 update.cancelAnimation( |
| 409 } else { | 429 i, *cssAnimations->m_runningAnimations[i]->animation); |
| 410 DCHECK(!isAnimationStyleChange); | |
| 411 update.startAnimation( | |
| 412 name, nameIndex, | |
| 413 *InertEffect::create( | |
| 414 createKeyframeEffectModel(resolver, animatingElement, element, | |
| 415 &style, parentStyle, name, | |
| 416 keyframeTimingFunction.get(), i), | |
| 417 timing, isPaused, 0), | |
| 418 specifiedTiming, keyframesRule); | |
| 419 } | 430 } |
| 420 } | 431 } |
| 421 } | 432 } |
| 422 | 433 |
| 423 for (size_t i = 0; i < cancelRunningAnimationFlags.size(); i++) { | 434 calculateAnimationActiveInterpolations(update, animatingElement); |
| 424 if (cancelRunningAnimationFlags[i]) { | |
| 425 DCHECK(cssAnimations && !isAnimationStyleChange); | |
| 426 update.cancelAnimation(i, | |
| 427 *cssAnimations->m_runningAnimations[i]->animation); | |
| 428 } | |
| 429 } | |
| 430 } | 435 } |
| 431 | 436 |
| 432 void CSSAnimations::snapshotCompositorKeyframes( | 437 void CSSAnimations::snapshotCompositorKeyframes( |
| 433 Element& element, | 438 Element& element, |
| 434 CSSAnimationUpdate& update, | 439 CSSAnimationUpdate& update, |
| 435 const ComputedStyle& style, | 440 const ComputedStyle& style, |
| 436 const ComputedStyle* parentStyle) { | 441 const ComputedStyle* parentStyle) { |
| 437 const auto& snapshot = [&element, &style, | 442 const auto& snapshot = [&element, &style, |
| 438 parentStyle](const AnimationEffectReadOnly* effect) { | 443 parentStyle](const AnimationEffectReadOnly* effect) { |
| 439 const KeyframeEffectModelBase* keyframeEffect = | 444 const KeyframeEffectModelBase* keyframeEffect = |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 for (const auto& entry : *activeTransitions) { | 824 for (const auto& entry : *activeTransitions) { |
| 820 CSSPropertyID id = entry.key; | 825 CSSPropertyID id = entry.key; |
| 821 if (!anyTransitionHadTransitionAll && !animationStyleRecalc && | 826 if (!anyTransitionHadTransitionAll && !animationStyleRecalc && |
| 822 !listedProperties.test(id - firstCSSProperty)) { | 827 !listedProperties.test(id - firstCSSProperty)) { |
| 823 update.cancelTransition(id); | 828 update.cancelTransition(id); |
| 824 } else if (entry.value.animation->finishedInternal()) { | 829 } else if (entry.value.animation->finishedInternal()) { |
| 825 update.finishTransition(id); | 830 update.finishTransition(id); |
| 826 } | 831 } |
| 827 } | 832 } |
| 828 } | 833 } |
| 834 calculateTransitionActiveInterpolations(update, animatingElement); | |
| 829 } | 835 } |
| 830 | 836 |
| 831 void CSSAnimations::cancel() { | 837 void CSSAnimations::cancel() { |
| 832 for (const auto& runningAnimation : m_runningAnimations) { | 838 for (const auto& runningAnimation : m_runningAnimations) { |
| 833 runningAnimation->animation->cancel(); | 839 runningAnimation->animation->cancel(); |
| 834 runningAnimation->animation->update(TimingUpdateOnDemand); | 840 runningAnimation->animation->update(TimingUpdateOnDemand); |
| 835 } | 841 } |
| 836 | 842 |
| 837 for (const auto& entry : m_transitions) { | 843 for (const auto& entry : m_transitions) { |
| 838 entry.value.animation->cancel(); | 844 entry.value.animation->cancel(); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1087 // and from their shadow sub-trees if they are shadow hosts. | 1093 // and from their shadow sub-trees if they are shadow hosts. |
| 1088 if (element.treeScope() == treeScope) | 1094 if (element.treeScope() == treeScope) |
| 1089 return true; | 1095 return true; |
| 1090 if (!isShadowHost(element)) | 1096 if (!isShadowHost(element)) |
| 1091 return false; | 1097 return false; |
| 1092 if (treeScope.rootNode() == treeScope.document()) | 1098 if (treeScope.rootNode() == treeScope.document()) |
| 1093 return false; | 1099 return false; |
| 1094 return toShadowRoot(treeScope.rootNode()).host() == element; | 1100 return toShadowRoot(treeScope.rootNode()).host() == element; |
| 1095 } | 1101 } |
| 1096 | 1102 |
| 1103 bool CSSAnimations::isCustomPropertyHandle(const PropertyHandle& property) { | |
| 1104 return property.isCSSProperty() && | |
| 1105 property.cssProperty() == CSSPropertyVariable; | |
| 1106 } | |
| 1107 | |
| 1108 bool CSSAnimations::isAnimatingCustomProperties( | |
| 1109 const ElementAnimations* elementAnimations) { | |
| 1110 return elementAnimations && | |
| 1111 elementAnimations->effectStack().affectsProperties( | |
| 1112 isCustomPropertyHandle); | |
| 1113 } | |
| 1114 | |
| 1097 DEFINE_TRACE(CSSAnimations) { | 1115 DEFINE_TRACE(CSSAnimations) { |
| 1098 visitor->trace(m_transitions); | 1116 visitor->trace(m_transitions); |
| 1099 visitor->trace(m_pendingUpdate); | 1117 visitor->trace(m_pendingUpdate); |
| 1100 visitor->trace(m_runningAnimations); | 1118 visitor->trace(m_runningAnimations); |
| 1101 } | 1119 } |
| 1102 | 1120 |
| 1103 } // namespace blink | 1121 } // namespace blink |
| OLD | NEW |