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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 | 195 |
196 bool CSSAnimations::isTransitionAnimationForInspector(const Animation& animation
) const | 196 bool CSSAnimations::isTransitionAnimationForInspector(const Animation& animation
) const |
197 { | 197 { |
198 for (const auto& it : m_transitions) { | 198 for (const auto& it : m_transitions) { |
199 if (it.value.animation->sequenceNumber() == animation.sequenceNumber()) | 199 if (it.value.animation->sequenceNumber() == animation.sequenceNumber()) |
200 return true; | 200 return true; |
201 } | 201 } |
202 return false; | 202 return false; |
203 } | 203 } |
204 | 204 |
205 PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(const
Element* animatingElement, Element& element, const ComputedStyle& style, Compute
dStyle* parentStyle, StyleResolver* resolver) | 205 void CSSAnimations::calculateUpdate(const Element* animatingElement, Element& el
ement, const ComputedStyle& style, ComputedStyle* parentStyle, CSSAnimationUpdat
e& animationUpdate, StyleResolver* resolver) |
206 { | 206 { |
207 OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = adoptPtrWillBeNoop(new CSSAn
imationUpdate()); | 207 calculateAnimationUpdate(animationUpdate, animatingElement, element, style,
parentStyle, resolver); |
208 calculateAnimationUpdate(update.get(), animatingElement, element, style, par
entStyle, resolver); | 208 calculateAnimationActiveInterpolations(animationUpdate, animatingElement, el
ement.document().timeline().currentTimeInternal()); |
209 calculateAnimationActiveInterpolations(update.get(), animatingElement, eleme
nt.document().timeline().currentTimeInternal()); | 209 calculateTransitionUpdate(animationUpdate, animatingElement, style); |
210 calculateTransitionUpdate(update.get(), animatingElement, style); | 210 calculateTransitionActiveInterpolations(animationUpdate, animatingElement, e
lement.document().timeline().currentTimeInternal()); |
211 calculateTransitionActiveInterpolations(update.get(), animatingElement, elem
ent.document().timeline().currentTimeInternal()); | |
212 return update->isEmpty() ? nullptr : update.release(); | |
213 } | 211 } |
214 | 212 |
215 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E
lement* animatingElement, Element& element, const ComputedStyle& style, Computed
Style* parentStyle, StyleResolver* resolver) | 213 void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate& update, const E
lement* animatingElement, Element& element, const ComputedStyle& style, Computed
Style* parentStyle, StyleResolver* resolver) |
216 { | 214 { |
217 const ElementAnimations* elementAnimations = animatingElement ? animatingEle
ment->elementAnimations() : nullptr; | 215 const ElementAnimations* elementAnimations = animatingElement ? animatingEle
ment->elementAnimations() : nullptr; |
218 | 216 |
219 bool isAnimationStyleChange = elementAnimations && elementAnimations->isAnim
ationStyleChange(); | 217 bool isAnimationStyleChange = elementAnimations && elementAnimations->isAnim
ationStyleChange(); |
220 | 218 |
221 #if !ENABLE(ASSERT) | 219 #if !ENABLE(ASSERT) |
222 // If we're in an animation style change, no animations can have started, be
en cancelled or changed play state. | 220 // If we're in an animation style change, no animations can have started, be
en cancelled or changed play state. |
223 // When ASSERT is enabled, we verify this optimization. | 221 // When ASSERT is enabled, we verify this optimization. |
224 if (isAnimationStyleChange) | 222 if (isAnimationStyleChange) |
225 return; | 223 return; |
(...skipping 29 matching lines...) Expand all Loading... |
255 if (cssAnimations) { | 253 if (cssAnimations) { |
256 AnimationMap::const_iterator existing(cssAnimations->m_animation
s.find(animationName)); | 254 AnimationMap::const_iterator existing(cssAnimations->m_animation
s.find(animationName)); |
257 if (existing != cssAnimations->m_animations.end()) { | 255 if (existing != cssAnimations->m_animations.end()) { |
258 inactive.remove(animationName); | 256 inactive.remove(animationName); |
259 | 257 |
260 const RunningAnimation* runningAnimation = existing->value.g
et(); | 258 const RunningAnimation* runningAnimation = existing->value.g
et(); |
261 Animation* animation = runningAnimation->animation.get(); | 259 Animation* animation = runningAnimation->animation.get(); |
262 | 260 |
263 if (keyframesRule != runningAnimation->styleRule || keyframe
sRule->version() != runningAnimation->styleRuleVersion || runningAnimation->spec
ifiedTiming != specifiedTiming) { | 261 if (keyframesRule != runningAnimation->styleRule || keyframe
sRule->version() != runningAnimation->styleRuleVersion || runningAnimation->spec
ifiedTiming != specifiedTiming) { |
264 ASSERT(!isAnimationStyleChange); | 262 ASSERT(!isAnimationStyleChange); |
265 update->updateAnimation(animationName, animation, InertE
ffect::create( | 263 update.updateAnimation(animationName, animation, InertEf
fect::create( |
266 createKeyframeEffectModel(resolver, animatingElement
, element, &style, parentStyle, animationName, keyframeTimingFunction.get(), i), | 264 createKeyframeEffectModel(resolver, animatingElement
, element, &style, parentStyle, animationName, keyframeTimingFunction.get(), i), |
267 timing, isPaused, animation->unlimitedCurrentTimeInt
ernal()), specifiedTiming, keyframesRule); | 265 timing, isPaused, animation->unlimitedCurrentTimeInt
ernal()), specifiedTiming, keyframesRule); |
268 } else if (!isAnimationStyleChange && animation->effect() &&
animation->effect()->isAnimation()) { | 266 } else if (!isAnimationStyleChange && animation->effect() &&
animation->effect()->isAnimation()) { |
269 EffectModel* model = toKeyframeEffect(animation->effect(
))->model(); | 267 EffectModel* model = toKeyframeEffect(animation->effect(
))->model(); |
270 if (model && model->isKeyframeEffectModel()) { | 268 if (model && model->isKeyframeEffectModel()) { |
271 KeyframeEffectModelBase* keyframeEffect = toKeyframe
EffectModelBase(model); | 269 KeyframeEffectModelBase* keyframeEffect = toKeyframe
EffectModelBase(model); |
272 if (keyframeEffect->hasSyntheticKeyframes()) | 270 if (keyframeEffect->hasSyntheticKeyframes()) |
273 update->updateAnimationStyle(animation, keyframe
Effect, animatingElement->layoutObject(), style); | 271 update.updateAnimationStyle(animation, keyframeE
ffect, animatingElement->layoutObject(), style); |
274 } | 272 } |
275 } | 273 } |
276 | 274 |
277 if (isPaused != animation->paused()) { | 275 if (isPaused != animation->paused()) { |
278 ASSERT(!isAnimationStyleChange); | 276 ASSERT(!isAnimationStyleChange); |
279 update->toggleAnimationPaused(animationName); | 277 update.toggleAnimationPaused(animationName); |
280 } | 278 } |
281 | 279 |
282 continue; | 280 continue; |
283 } | 281 } |
284 } | 282 } |
285 | 283 |
286 ASSERT(!isAnimationStyleChange); | 284 ASSERT(!isAnimationStyleChange); |
287 update->startAnimation(animationName, InertEffect::create( | 285 update.startAnimation(animationName, InertEffect::create( |
288 createKeyframeEffectModel(resolver, animatingElement, element, &
style, parentStyle, animationName, keyframeTimingFunction.get(), i), | 286 createKeyframeEffectModel(resolver, animatingElement, element, &
style, parentStyle, animationName, keyframeTimingFunction.get(), i), |
289 timing, isPaused, 0), specifiedTiming, keyframesRule); | 287 timing, isPaused, 0), specifiedTiming, keyframesRule); |
290 } | 288 } |
291 } | 289 } |
292 | 290 |
293 ASSERT(inactive.isEmpty() || cssAnimations); | 291 ASSERT(inactive.isEmpty() || cssAnimations); |
294 for (const AtomicString& animationName : inactive) { | 292 for (const AtomicString& animationName : inactive) { |
295 ASSERT(!isAnimationStyleChange); | 293 ASSERT(!isAnimationStyleChange); |
296 update->cancelAnimation(animationName, *cssAnimations->m_animations.get(
animationName)->animation); | 294 update.cancelAnimation(animationName, *cssAnimations->m_animations.get(a
nimationName)->animation); |
297 } | 295 } |
298 } | 296 } |
299 | 297 |
300 void CSSAnimations::maybeApplyPendingUpdate(Element* element) | 298 void CSSAnimations::maybeApplyPendingUpdate(Element* element) |
301 { | 299 { |
302 if (!m_pendingUpdate) { | 300 if (m_pendingUpdate.isEmpty()) { |
303 m_previousActiveInterpolationsForAnimations.clear(); | 301 m_previousActiveInterpolationsForAnimations.clear(); |
304 return; | 302 return; |
305 } | 303 } |
306 | 304 |
307 OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = m_pendingUpdate.release(); | 305 m_previousActiveInterpolationsForAnimations.swap(m_pendingUpdate.activeInter
polationsForAnimations()); |
308 | |
309 m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolation
sForAnimations()); | |
310 | 306 |
311 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here | 307 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here |
312 // since we call this from recalc style. | 308 // since we call this from recalc style. |
313 // https://code.google.com/p/chromium/issues/detail?id=339847 | 309 // https://code.google.com/p/chromium/issues/detail?id=339847 |
314 DisableCompositingQueryAsserts disabler; | 310 DisableCompositingQueryAsserts disabler; |
315 | 311 |
316 for (const AtomicString& animationName : update->cancelledAnimationNames())
{ | 312 for (const AtomicString& animationName : m_pendingUpdate.cancelledAnimationN
ames()) { |
317 RefPtrWillBeRawPtr<Animation> animation = m_animations.take(animationNam
e)->animation; | 313 RefPtrWillBeRawPtr<Animation> animation = m_animations.take(animationNam
e)->animation; |
318 animation->cancel(); | 314 animation->cancel(); |
319 animation->update(TimingUpdateOnDemand); | 315 animation->update(TimingUpdateOnDemand); |
320 } | 316 } |
321 | 317 |
322 for (const AtomicString& animationName : update->animationsWithPauseToggled(
)) { | 318 for (const AtomicString& animationName : m_pendingUpdate.animationsWithPause
Toggled()) { |
323 Animation* animation = m_animations.get(animationName)->animation.get(); | 319 Animation* animation = m_animations.get(animationName)->animation.get(); |
324 if (animation->paused()) | 320 if (animation->paused()) |
325 animation->unpause(); | 321 animation->unpause(); |
326 else | 322 else |
327 animation->pause(); | 323 animation->pause(); |
328 if (animation->outdated()) | 324 if (animation->outdated()) |
329 animation->update(TimingUpdateOnDemand); | 325 animation->update(TimingUpdateOnDemand); |
330 } | 326 } |
331 | 327 |
332 for (const auto& styleUpdate : update->animationsWithStyleUpdates()) { | 328 for (const auto& styleUpdate : m_pendingUpdate.animationsWithStyleUpdates())
{ |
333 styleUpdate.model->forEachInterpolation([](Interpolation& interpolation)
{ | 329 styleUpdate.model->forEachInterpolation([](Interpolation& interpolation)
{ |
334 if (interpolation.isStyleInterpolation() && toStyleInterpolation(int
erpolation).isDeferredLegacyStyleInterpolation()) | 330 if (interpolation.isStyleInterpolation() && toStyleInterpolation(int
erpolation).isDeferredLegacyStyleInterpolation()) |
335 toDeferredLegacyStyleInterpolation(toStyleInterpolation(interpol
ation)).underlyingStyleChanged(); | 331 toDeferredLegacyStyleInterpolation(toStyleInterpolation(interpol
ation)).underlyingStyleChanged(); |
336 }); | 332 }); |
337 | 333 |
338 bool updated = false; | 334 bool updated = false; |
339 if (styleUpdate.snapshot.opacity) | 335 if (styleUpdate.snapshot.opacity) |
340 updated |= styleUpdate.model->updateNeutralKeyframeAnimatableValues(
CSSPropertyOpacity, styleUpdate.snapshot.opacity); | 336 updated |= styleUpdate.model->updateNeutralKeyframeAnimatableValues(
CSSPropertyOpacity, styleUpdate.snapshot.opacity); |
341 if (styleUpdate.snapshot.transform) | 337 if (styleUpdate.snapshot.transform) |
342 updated |= styleUpdate.model->updateNeutralKeyframeAnimatableValues(
CSSPropertyTransform, styleUpdate.snapshot.transform); | 338 updated |= styleUpdate.model->updateNeutralKeyframeAnimatableValues(
CSSPropertyTransform, styleUpdate.snapshot.transform); |
343 if (styleUpdate.snapshot.webkitFilter) | 339 if (styleUpdate.snapshot.webkitFilter) |
344 updated |= styleUpdate.model->updateNeutralKeyframeAnimatableValues(
CSSPropertyWebkitFilter, styleUpdate.snapshot.webkitFilter); | 340 updated |= styleUpdate.model->updateNeutralKeyframeAnimatableValues(
CSSPropertyWebkitFilter, styleUpdate.snapshot.webkitFilter); |
345 if (updated) { | 341 if (updated) { |
346 styleUpdate.animation->setOutdated(); | 342 styleUpdate.animation->setOutdated(); |
347 styleUpdate.animation->setCompositorPending(true); | 343 styleUpdate.animation->setCompositorPending(true); |
348 } | 344 } |
349 } | 345 } |
350 | 346 |
351 for (const auto& entry : update->animationsWithUpdates()) { | 347 for (const auto& entry : m_pendingUpdate.animationsWithUpdates()) { |
352 KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect()); | 348 KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect()); |
353 | 349 |
354 effect->setModel(entry.effect->model()); | 350 effect->setModel(entry.effect->model()); |
355 effect->updateSpecifiedTiming(entry.effect->specifiedTiming()); | 351 effect->updateSpecifiedTiming(entry.effect->specifiedTiming()); |
356 | 352 |
357 m_animations.find(entry.name)->value->update(entry); | 353 m_animations.find(entry.name)->value->update(entry); |
358 } | 354 } |
359 | 355 |
360 for (const auto& entry : update->newAnimations()) { | 356 for (const auto& entry : m_pendingUpdate.newAnimations()) { |
361 const InertEffect* inertAnimation = entry.effect.get(); | 357 const InertEffect* inertAnimation = entry.effect.get(); |
362 OwnPtrWillBeRawPtr<AnimationEventDelegate> eventDelegate = adoptPtrWillB
eNoop(new AnimationEventDelegate(element, entry.name)); | 358 OwnPtrWillBeRawPtr<AnimationEventDelegate> eventDelegate = adoptPtrWillB
eNoop(new AnimationEventDelegate(element, entry.name)); |
363 RefPtrWillBeRawPtr<KeyframeEffect> effect = KeyframeEffect::create(eleme
nt, inertAnimation->model(), inertAnimation->specifiedTiming(), KeyframeEffect::
DefaultPriority, eventDelegate.release()); | 359 RefPtrWillBeRawPtr<KeyframeEffect> effect = KeyframeEffect::create(eleme
nt, inertAnimation->model(), inertAnimation->specifiedTiming(), KeyframeEffect::
DefaultPriority, eventDelegate.release()); |
364 effect->setName(inertAnimation->name()); | 360 effect->setName(inertAnimation->name()); |
365 RefPtrWillBeRawPtr<Animation> animation = element->document().timeline()
.play(effect.get()); | 361 RefPtrWillBeRawPtr<Animation> animation = element->document().timeline()
.play(effect.get()); |
366 if (inertAnimation->paused()) | 362 if (inertAnimation->paused()) |
367 animation->pause(); | 363 animation->pause(); |
368 animation->update(TimingUpdateOnDemand); | 364 animation->update(TimingUpdateOnDemand); |
369 | 365 |
370 m_animations.set(entry.name, adoptRefWillBeNoop(new RunningAnimation(ani
mation, entry))); | 366 m_animations.set(entry.name, adoptRefWillBeNoop(new RunningAnimation(ani
mation, entry))); |
371 } | 367 } |
372 | 368 |
373 // Transitions that are run on the compositor only update main-thread state | 369 // Transitions that are run on the compositor only update main-thread state |
374 // lazily. However, we need the new state to know what the from state shoud | 370 // lazily. However, we need the new state to know what the from state shoud |
375 // be when transitions are retargeted. Instead of triggering complete style | 371 // be when transitions are retargeted. Instead of triggering complete style |
376 // recalculation, we find these cases by searching for new transitions that | 372 // recalculation, we find these cases by searching for new transitions that |
377 // have matching cancelled animation property IDs on the compositor. | 373 // have matching cancelled animation property IDs on the compositor. |
378 WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<KeyframeEffect
>, double>> retargetedCompositorTransitions; | 374 WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<KeyframeEffect
>, double>> retargetedCompositorTransitions; |
379 for (CSSPropertyID id : update->cancelledTransitions()) { | 375 for (CSSPropertyID id : m_pendingUpdate.cancelledTransitions()) { |
380 ASSERT(m_transitions.contains(id)); | 376 ASSERT(m_transitions.contains(id)); |
381 | 377 |
382 RefPtrWillBeRawPtr<Animation> animation = m_transitions.take(id).animati
on; | 378 RefPtrWillBeRawPtr<Animation> animation = m_transitions.take(id).animati
on; |
383 KeyframeEffect* effect = toKeyframeEffect(animation->effect()); | 379 KeyframeEffect* effect = toKeyframeEffect(animation->effect()); |
384 if (effect->hasActiveAnimationsOnCompositor(id) && update->newTransition
s().find(id) != update->newTransitions().end() && !animation->limited()) | 380 if (effect->hasActiveAnimationsOnCompositor(id) && m_pendingUpdate.newTr
ansitions().find(id) != m_pendingUpdate.newTransitions().end() && !animation->li
mited()) |
385 retargetedCompositorTransitions.add(id, std::pair<RefPtrWillBeMember
<KeyframeEffect>, double>(effect, animation->startTimeInternal())); | 381 retargetedCompositorTransitions.add(id, std::pair<RefPtrWillBeMember
<KeyframeEffect>, double>(effect, animation->startTimeInternal())); |
386 animation->cancel(); | 382 animation->cancel(); |
387 // after cancelation, transitions must be downgraded or they'll fail | 383 // after cancelation, transitions must be downgraded or they'll fail |
388 // to be considered when retriggering themselves. This can happen if | 384 // to be considered when retriggering themselves. This can happen if |
389 // the transition is captured through getAnimations then played. | 385 // the transition is captured through getAnimations then played. |
390 if (animation->effect() && animation->effect()->isAnimation()) | 386 if (animation->effect() && animation->effect()->isAnimation()) |
391 toKeyframeEffect(animation->effect())->downgradeToNormal(); | 387 toKeyframeEffect(animation->effect())->downgradeToNormal(); |
392 animation->update(TimingUpdateOnDemand); | 388 animation->update(TimingUpdateOnDemand); |
393 } | 389 } |
394 | 390 |
395 for (CSSPropertyID id : update->finishedTransitions()) { | 391 for (CSSPropertyID id : m_pendingUpdate.finishedTransitions()) { |
396 // This transition can also be cancelled and finished at the same time | 392 // This transition can also be cancelled and finished at the same time |
397 if (m_transitions.contains(id)) { | 393 if (m_transitions.contains(id)) { |
398 RefPtrWillBeRawPtr<Animation> animation = m_transitions.take(id).ani
mation; | 394 RefPtrWillBeRawPtr<Animation> animation = m_transitions.take(id).ani
mation; |
399 // Transition must be downgraded | 395 // Transition must be downgraded |
400 if (animation->effect() && animation->effect()->isAnimation()) | 396 if (animation->effect() && animation->effect()->isAnimation()) |
401 toKeyframeEffect(animation->effect())->downgradeToNormal(); | 397 toKeyframeEffect(animation->effect())->downgradeToNormal(); |
402 } | 398 } |
403 } | 399 } |
404 | 400 |
405 for (const auto& entry : update->newTransitions()) { | 401 for (const auto& entry : m_pendingUpdate.newTransitions()) { |
406 const CSSAnimationUpdate::NewTransition& newTransition = entry.value; | 402 const CSSAnimationUpdate::NewTransition& newTransition = entry.value; |
407 | 403 |
408 RunningTransition runningTransition; | 404 RunningTransition runningTransition; |
409 runningTransition.from = newTransition.from; | 405 runningTransition.from = newTransition.from; |
410 runningTransition.to = newTransition.to; | 406 runningTransition.to = newTransition.to; |
411 | 407 |
412 CSSPropertyID id = newTransition.id; | 408 CSSPropertyID id = newTransition.id; |
413 InertEffect* inertAnimation = newTransition.effect.get(); | 409 InertEffect* inertAnimation = newTransition.effect.get(); |
414 OwnPtrWillBeRawPtr<TransitionEventDelegate> eventDelegate = adoptPtrWill
BeNoop(new TransitionEventDelegate(element, id)); | 410 OwnPtrWillBeRawPtr<TransitionEventDelegate> eventDelegate = adoptPtrWill
BeNoop(new TransitionEventDelegate(element, id)); |
415 | 411 |
(...skipping 30 matching lines...) Expand all Loading... |
446 RefPtrWillBeRawPtr<Animation> animation = element->document().timeline()
.play(transition.get()); | 442 RefPtrWillBeRawPtr<Animation> animation = element->document().timeline()
.play(transition.get()); |
447 // Set the current time as the start time for retargeted transitions | 443 // Set the current time as the start time for retargeted transitions |
448 if (retargetedCompositorTransitions.contains(id)) | 444 if (retargetedCompositorTransitions.contains(id)) |
449 animation->setStartTime(element->document().timeline().currentTime()
); | 445 animation->setStartTime(element->document().timeline().currentTime()
); |
450 animation->update(TimingUpdateOnDemand); | 446 animation->update(TimingUpdateOnDemand); |
451 runningTransition.animation = animation; | 447 runningTransition.animation = animation; |
452 m_transitions.set(id, runningTransition); | 448 m_transitions.set(id, runningTransition); |
453 ASSERT(id != CSSPropertyInvalid); | 449 ASSERT(id != CSSPropertyInvalid); |
454 Platform::current()->histogramSparse("WebCore.Animation.CSSProperties",
UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); | 450 Platform::current()->histogramSparse("WebCore.Animation.CSSProperties",
UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); |
455 } | 451 } |
| 452 |
| 453 clearPendingUpdate(); |
456 } | 454 } |
457 | 455 |
458 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) | 456 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) |
459 { | 457 { |
460 RefPtrWillBeRawPtr<AnimatableValue> to = nullptr; | 458 RefPtrWillBeRawPtr<AnimatableValue> to = nullptr; |
461 if (activeTransitions) { | 459 if (activeTransitions) { |
462 TransitionMap::const_iterator activeTransitionIter = activeTransitions->
find(id); | 460 TransitionMap::const_iterator activeTransitionIter = activeTransitions->
find(id); |
463 if (activeTransitionIter != activeTransitions->end()) { | 461 if (activeTransitionIter != activeTransitions->end()) { |
464 to = CSSAnimatableValueFactory::create(id, style); | 462 to = CSSAnimatableValueFactory::create(id, style); |
465 const AnimatableValue* activeTo = activeTransitionIter->value.to; | 463 const AnimatableValue* activeTo = activeTransitionIter->value.to; |
466 if (to->equals(activeTo)) | 464 if (to->equals(activeTo)) |
467 return; | 465 return; |
468 update->cancelTransition(id); | 466 update.cancelTransition(id); |
469 ASSERT(!element->elementAnimations() || !element->elementAnimations(
)->isAnimationStyleChange()); | 467 ASSERT(!element->elementAnimations() || !element->elementAnimations(
)->isAnimationStyleChange()); |
470 } | 468 } |
471 } | 469 } |
472 | 470 |
473 if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style)) | 471 if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style)) |
474 return; | 472 return; |
475 if (!to) | 473 if (!to) |
476 to = CSSAnimatableValueFactory::create(id, style); | 474 to = CSSAnimatableValueFactory::create(id, style); |
477 | 475 |
478 RefPtrWillBeRawPtr<AnimatableValue> from = CSSAnimatableValueFactory::create
(id, oldStyle); | 476 RefPtrWillBeRawPtr<AnimatableValue> from = CSSAnimatableValueFactory::create
(id, oldStyle); |
(...skipping 26 matching lines...) Expand all Loading... |
505 startKeyframe->setEasing(timing.timingFunction.release()); | 503 startKeyframe->setEasing(timing.timingFunction.release()); |
506 timing.timingFunction = LinearTimingFunction::shared(); | 504 timing.timingFunction = LinearTimingFunction::shared(); |
507 keyframes.append(startKeyframe); | 505 keyframes.append(startKeyframe); |
508 | 506 |
509 RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKey
frame::create(); | 507 RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKey
frame::create(); |
510 endKeyframe->setPropertyValue(id, to.get()); | 508 endKeyframe->setPropertyValue(id, to.get()); |
511 endKeyframe->setOffset(1); | 509 endKeyframe->setOffset(1); |
512 keyframes.append(endKeyframe); | 510 keyframes.append(endKeyframe); |
513 | 511 |
514 RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> model = AnimatableVal
ueKeyframeEffectModel::create(keyframes); | 512 RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> model = AnimatableVal
ueKeyframeEffectModel::create(keyframes); |
515 update->startTransition(id, from.get(), to.get(), InertEffect::create(model,
timing, false, 0)); | 513 update.startTransition(id, from.get(), to.get(), InertEffect::create(model,
timing, false, 0)); |
516 ASSERT(!element->elementAnimations() || !element->elementAnimations()->isAni
mationStyleChange()); | 514 ASSERT(!element->elementAnimations() || !element->elementAnimations()->isAni
mationStyleChange()); |
517 } | 515 } |
518 | 516 |
519 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
Element* animatingElement, const ComputedStyle& style) | 517 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate& update, const
Element* animatingElement, const ComputedStyle& style) |
520 { | 518 { |
521 if (!animatingElement) | 519 if (!animatingElement) |
522 return; | 520 return; |
523 | 521 |
524 ElementAnimations* elementAnimations = animatingElement->elementAnimations()
; | 522 ElementAnimations* elementAnimations = animatingElement->elementAnimations()
; |
525 const TransitionMap* activeTransitions = elementAnimations ? &elementAnimati
ons->cssAnimations().m_transitions : nullptr; | 523 const TransitionMap* activeTransitions = elementAnimations ? &elementAnimati
ons->cssAnimations().m_transitions : nullptr; |
526 const CSSTransitionData* transitionData = style.transitions(); | 524 const CSSTransitionData* transitionData = style.transitions(); |
527 | 525 |
528 #if ENABLE(ASSERT) | 526 #if ENABLE(ASSERT) |
529 // 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. | 527 // 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. |
(...skipping 28 matching lines...) Expand all Loading... |
558 if (!animateAll) { | 556 if (!animateAll) { |
559 if (CSSPropertyMetadata::isInterpolableProperty(id)) | 557 if (CSSPropertyMetadata::isInterpolableProperty(id)) |
560 listedProperties.set(id); | 558 listedProperties.set(id); |
561 else | 559 else |
562 continue; | 560 continue; |
563 } | 561 } |
564 | 562 |
565 // FIXME: We should transition if an !important property changes
even when an animation is running, | 563 // FIXME: We should transition if an !important property changes
even when an animation is running, |
566 // but this is a bit hard to do with the current applyMatchedPro
perties system. | 564 // but this is a bit hard to do with the current applyMatchedPro
perties system. |
567 PropertyHandle property = PropertyHandle(id); | 565 PropertyHandle property = PropertyHandle(id); |
568 if (!update->activeInterpolationsForAnimations().contains(proper
ty) | 566 if (!update.activeInterpolationsForAnimations().contains(propert
y) |
569 && (!elementAnimations || !elementAnimations->cssAnimations(
).m_previousActiveInterpolationsForAnimations.contains(property))) { | 567 && (!elementAnimations || !elementAnimations->cssAnimations(
).m_previousActiveInterpolationsForAnimations.contains(property))) { |
570 calculateTransitionUpdateForProperty(id, *transitionData, i,
oldStyle, style, activeTransitions, update, animatingElement); | 568 calculateTransitionUpdateForProperty(id, *transitionData, i,
oldStyle, style, activeTransitions, update, animatingElement); |
571 } | 569 } |
572 } | 570 } |
573 } | 571 } |
574 } | 572 } |
575 | 573 |
576 if (activeTransitions) { | 574 if (activeTransitions) { |
577 for (const auto& entry : *activeTransitions) { | 575 for (const auto& entry : *activeTransitions) { |
578 CSSPropertyID id = entry.key; | 576 CSSPropertyID id = entry.key; |
579 if (!anyTransitionHadTransitionAll && !animationStyleRecalc && !list
edProperties.get(id)) { | 577 if (!anyTransitionHadTransitionAll && !animationStyleRecalc && !list
edProperties.get(id)) { |
580 // TODO: Figure out why this fails on Chrome OS login page. crbu
g.com/365507 | 578 // TODO: Figure out why this fails on Chrome OS login page. crbu
g.com/365507 |
581 // ASSERT(animation.playStateInternal() == Animation::Finished |
| !(elementAnimations && elementAnimations->isAnimationStyleChange())); | 579 // ASSERT(animation.playStateInternal() == Animation::Finished |
| !(elementAnimations && elementAnimations->isAnimationStyleChange())); |
582 update->cancelTransition(id); | 580 update.cancelTransition(id); |
583 } else if (entry.value.animation->finishedInternal()) { | 581 } else if (entry.value.animation->finishedInternal()) { |
584 update->finishTransition(id); | 582 update.finishTransition(id); |
585 } | 583 } |
586 } | 584 } |
587 } | 585 } |
588 } | 586 } |
589 | 587 |
590 void CSSAnimations::cancel() | 588 void CSSAnimations::cancel() |
591 { | 589 { |
592 for (const auto& entry : m_animations) { | 590 for (const auto& entry : m_animations) { |
593 entry.value->animation->cancel(); | 591 entry.value->animation->cancel(); |
594 entry.value->animation->update(TimingUpdateOnDemand); | 592 entry.value->animation->update(TimingUpdateOnDemand); |
595 } | 593 } |
596 | 594 |
597 for (const auto& entry : m_transitions) { | 595 for (const auto& entry : m_transitions) { |
598 entry.value.animation->cancel(); | 596 entry.value.animation->cancel(); |
599 entry.value.animation->update(TimingUpdateOnDemand); | 597 entry.value.animation->update(TimingUpdateOnDemand); |
600 } | 598 } |
601 | 599 |
602 m_animations.clear(); | 600 m_animations.clear(); |
603 m_transitions.clear(); | 601 clearPendingUpdate(); |
604 m_pendingUpdate = nullptr; | |
605 } | 602 } |
606 | 603 |
607 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u
pdate, const Element* animatingElement, double timelineCurrentTime) | 604 void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate& u
pdate, const Element* animatingElement, double timelineCurrentTime) |
608 { | 605 { |
609 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; | 606 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; |
610 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; | 607 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; |
611 | 608 |
612 if (update->newAnimations().isEmpty() && update->suppressedAnimations().isEm
pty()) { | 609 if (update.newAnimations().isEmpty() && update.suppressedAnimations().isEmpt
y()) { |
613 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack:
:activeInterpolations(animationStack, 0, 0, KeyframeEffect::DefaultPriority, tim
elineCurrentTime)); | 610 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack:
:activeInterpolations(animationStack, 0, 0, KeyframeEffect::DefaultPriority, tim
elineCurrentTime)); |
614 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAn
imations); | 611 update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAni
mations); |
615 return; | 612 return; |
616 } | 613 } |
617 | 614 |
618 WillBeHeapVector<RawPtrWillBeMember<InertEffect>> newEffects; | 615 WillBeHeapVector<RawPtrWillBeMember<InertEffect>> newEffects; |
619 for (const auto& newAnimation : update->newAnimations()) | 616 for (const auto& newAnimation : update.newAnimations()) |
620 newEffects.append(newAnimation.effect.get()); | 617 newEffects.append(newAnimation.effect.get()); |
621 for (const auto& updatedAnimation : update->animationsWithUpdates()) | 618 for (const auto& updatedAnimation : update.animationsWithUpdates()) |
622 newEffects.append(updatedAnimation.effect.get()); // Animations with upd
ates use a temporary InertEffect for the current frame. | 619 newEffects.append(updatedAnimation.effect.get()); // Animations with upd
ates use a temporary InertEffect for the current frame. |
623 | 620 |
624 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack::act
iveInterpolations(animationStack, &newEffects, &update->suppressedAnimations(),
KeyframeEffect::DefaultPriority, timelineCurrentTime)); | 621 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack::act
iveInterpolations(animationStack, &newEffects, &update.suppressedAnimations(), K
eyframeEffect::DefaultPriority, timelineCurrentTime)); |
625 update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimat
ions); | 622 update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimati
ons); |
626 } | 623 } |
627 | 624 |
628 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
update, const Element* animatingElement, double timelineCurrentTime) | 625 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate&
update, const Element* animatingElement, double timelineCurrentTime) |
629 { | 626 { |
630 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; | 627 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; |
631 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; | 628 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; |
632 | 629 |
633 ActiveInterpolationMap activeInterpolationsForTransitions; | 630 ActiveInterpolationMap activeInterpolationsForTransitions; |
634 if (update->newTransitions().isEmpty() && update->cancelledTransitions().isE
mpty()) { | 631 if (update.newTransitions().isEmpty() && update.cancelledTransitions().isEmp
ty()) { |
635 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, 0, 0, KeyframeEffect::TransitionPriority, timelineCurrentTime)
; | 632 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, 0, 0, KeyframeEffect::TransitionPriority, timelineCurrentTime)
; |
636 } else { | 633 } else { |
637 WillBeHeapVector<RawPtrWillBeMember<InertEffect>> newTransitions; | 634 WillBeHeapVector<RawPtrWillBeMember<InertEffect>> newTransitions; |
638 for (const auto& entry : update->newTransitions()) | 635 for (const auto& entry : update.newTransitions()) |
639 newTransitions.append(entry.value.effect.get()); | 636 newTransitions.append(entry.value.effect.get()); |
640 | 637 |
641 WillBeHeapHashSet<RawPtrWillBeMember<const Animation>> cancelledAnimatio
ns; | 638 WillBeHeapHashSet<RawPtrWillBeMember<const Animation>> cancelledAnimatio
ns; |
642 if (!update->cancelledTransitions().isEmpty()) { | 639 if (!update.cancelledTransitions().isEmpty()) { |
643 ASSERT(elementAnimations); | 640 ASSERT(elementAnimations); |
644 const TransitionMap& transitionMap = elementAnimations->cssAnimation
s().m_transitions; | 641 const TransitionMap& transitionMap = elementAnimations->cssAnimation
s().m_transitions; |
645 for (CSSPropertyID id : update->cancelledTransitions()) { | 642 for (CSSPropertyID id : update.cancelledTransitions()) { |
646 ASSERT(transitionMap.contains(id)); | 643 ASSERT(transitionMap.contains(id)); |
647 cancelledAnimations.add(transitionMap.get(id).animation.get()); | 644 cancelledAnimations.add(transitionMap.get(id).animation.get()); |
648 } | 645 } |
649 } | 646 } |
650 | 647 |
651 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, &newTransitions, &cancelledAnimations, KeyframeEffect::Transit
ionPriority, timelineCurrentTime); | 648 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, &newTransitions, &cancelledAnimations, KeyframeEffect::Transit
ionPriority, timelineCurrentTime); |
652 } | 649 } |
653 | 650 |
654 // Properties being animated by animations don't get values from transitions
applied. | 651 // Properties being animated by animations don't get values from transitions
applied. |
655 if (!update->activeInterpolationsForAnimations().isEmpty() && !activeInterpo
lationsForTransitions.isEmpty()) { | 652 if (!update.activeInterpolationsForAnimations().isEmpty() && !activeInterpol
ationsForTransitions.isEmpty()) { |
656 for (const auto& entry : update->activeInterpolationsForAnimations()) | 653 for (const auto& entry : update.activeInterpolationsForAnimations()) |
657 activeInterpolationsForTransitions.remove(entry.key); | 654 activeInterpolationsForTransitions.remove(entry.key); |
658 } | 655 } |
659 update->adoptActiveInterpolationsForTransitions(activeInterpolationsForTrans
itions); | 656 update.adoptActiveInterpolationsForTransitions(activeInterpolationsForTransi
tions); |
660 } | 657 } |
661 | 658 |
662 EventTarget* CSSAnimations::AnimationEventDelegate::eventTarget() const | 659 EventTarget* CSSAnimations::AnimationEventDelegate::eventTarget() const |
663 { | 660 { |
664 return EventPath::eventTargetRespectingTargetRules(*m_animationTarget); | 661 return EventPath::eventTargetRespectingTargetRules(*m_animationTarget); |
665 } | 662 } |
666 | 663 |
667 void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType
listenerType, const AtomicString& eventName, double elapsedTime) | 664 void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType
listenerType, const AtomicString& eventName, double elapsedTime) |
668 { | 665 { |
669 if (m_animationTarget->document().hasListenerType(listenerType)) { | 666 if (m_animationTarget->document().hasListenerType(listenerType)) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 DEFINE_TRACE(CSSAnimations) | 790 DEFINE_TRACE(CSSAnimations) |
794 { | 791 { |
795 #if ENABLE(OILPAN) | 792 #if ENABLE(OILPAN) |
796 visitor->trace(m_transitions); | 793 visitor->trace(m_transitions); |
797 visitor->trace(m_pendingUpdate); | 794 visitor->trace(m_pendingUpdate); |
798 visitor->trace(m_animations); | 795 visitor->trace(m_animations); |
799 visitor->trace(m_previousActiveInterpolationsForAnimations); | 796 visitor->trace(m_previousActiveInterpolationsForAnimations); |
800 #endif | 797 #endif |
801 } | 798 } |
802 | 799 |
803 DEFINE_TRACE(CSSAnimationUpdate) | |
804 { | |
805 #if ENABLE(OILPAN) | |
806 visitor->trace(m_newTransitions); | |
807 visitor->trace(m_activeInterpolationsForAnimations); | |
808 visitor->trace(m_activeInterpolationsForTransitions); | |
809 visitor->trace(m_newAnimations); | |
810 visitor->trace(m_suppressedAnimations); | |
811 visitor->trace(m_animationsWithUpdates); | |
812 visitor->trace(m_animationsWithStyleUpdates); | |
813 #endif | |
814 } | |
815 | |
816 } // namespace blink | 800 } // namespace blink |
OLD | NEW |