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

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

Issue 2532953008: Apply custom property animations (Closed)
Patch Set: Created 4 years 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698