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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 #include "public/platform/Platform.h" | 58 #include "public/platform/Platform.h" |
59 #include "wtf/BitArray.h" | 59 #include "wtf/BitArray.h" |
60 #include "wtf/HashSet.h" | 60 #include "wtf/HashSet.h" |
61 | 61 |
62 namespace blink { | 62 namespace blink { |
63 | 63 |
64 using PropertySet = HashSet<CSSPropertyID>; | 64 using PropertySet = HashSet<CSSPropertyID>; |
65 | 65 |
66 namespace { | 66 namespace { |
67 | 67 |
68 static PassRefPtrWillBeRawPtr<StringKeyframeEffectModel> createKeyframeEffectMod
el(StyleResolver* resolver, const Element* animatingElement, Element& element, c
onst ComputedStyle* style, const ComputedStyle* parentStyle, const AtomicString&
name, TimingFunction* defaultTimingFunction, size_t animationIndex) | 68 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) |
69 { | 69 { |
70 // When the animating element is null, use its parent for scoping purposes. | 70 // When the animating element is null, use its parent for scoping purposes. |
71 const Element* elementForScoping = animatingElement ? animatingElement : &el
ement; | 71 const Element* elementForScoping = animatingElement ? animatingElement : &el
ement; |
72 const StyleRuleKeyframes* keyframesRule = resolver->findKeyframesRule(elemen
tForScoping, name); | 72 const StyleRuleKeyframes* keyframesRule = resolver->findKeyframesRule(elemen
tForScoping, name); |
73 ASSERT(keyframesRule); | 73 ASSERT(keyframesRule); |
74 | 74 |
75 StringKeyframeVector keyframes; | 75 StringKeyframeVector keyframes; |
76 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleKeyframe>>& styleKeyframe
s = keyframesRule->keyframes(); | 76 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleKeyframe>>& styleKeyframe
s = keyframesRule->keyframes(); |
77 | 77 |
78 // Construct and populate the style for each keyframe | 78 // Construct and populate the style for each keyframe |
79 PropertySet specifiedPropertiesForUseCounter; | 79 PropertySet specifiedPropertiesForUseCounter; |
80 for (size_t i = 0; i < styleKeyframes.size(); ++i) { | 80 for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
81 const StyleRuleKeyframe* styleKeyframe = styleKeyframes[i].get(); | 81 const StyleRuleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
82 RefPtrWillBeRawPtr<StringKeyframe> keyframe = StringKeyframe::create(); | 82 StringKeyframe* keyframe = StringKeyframe::create(); |
83 const Vector<double>& offsets = styleKeyframe->keys(); | 83 const Vector<double>& offsets = styleKeyframe->keys(); |
84 ASSERT(!offsets.isEmpty()); | 84 ASSERT(!offsets.isEmpty()); |
85 keyframe->setOffset(offsets[0]); | 85 keyframe->setOffset(offsets[0]); |
86 keyframe->setEasing(defaultTimingFunction); | 86 keyframe->setEasing(defaultTimingFunction); |
87 const StylePropertySet& properties = styleKeyframe->properties(); | 87 const StylePropertySet& properties = styleKeyframe->properties(); |
88 for (unsigned j = 0; j < properties.propertyCount(); j++) { | 88 for (unsigned j = 0; j < properties.propertyCount(); j++) { |
89 CSSPropertyID property = properties.propertyAt(j).id(); | 89 CSSPropertyID property = properties.propertyAt(j).id(); |
90 specifiedPropertiesForUseCounter.add(property); | 90 specifiedPropertiesForUseCounter.add(property); |
91 if (property == CSSPropertyAnimationTimingFunction) { | 91 if (property == CSSPropertyAnimationTimingFunction) { |
92 CSSValue* value = properties.propertyAt(j).value(); | 92 CSSValue* value = properties.propertyAt(j).value(); |
93 RefPtr<TimingFunction> timingFunction; | 93 RefPtr<TimingFunction> timingFunction; |
94 if (value->isInheritedValue() && parentStyle->animations()) { | 94 if (value->isInheritedValue() && parentStyle->animations()) { |
95 timingFunction = parentStyle->animations()->timingFunctionLi
st()[0]; | 95 timingFunction = parentStyle->animations()->timingFunctionLi
st()[0]; |
96 } else if (value->isValueList()) { | 96 } else if (value->isValueList()) { |
97 timingFunction = CSSToStyleMap::mapAnimationTimingFunction(t
oCSSValueList(value)->item(0)); | 97 timingFunction = CSSToStyleMap::mapAnimationTimingFunction(t
oCSSValueList(value)->item(0)); |
98 } else { | 98 } else { |
99 ASSERT(value->isCSSWideKeyword()); | 99 ASSERT(value->isCSSWideKeyword()); |
100 timingFunction = CSSTimingData::initialTimingFunction(); | 100 timingFunction = CSSTimingData::initialTimingFunction(); |
101 } | 101 } |
102 keyframe->setEasing(timingFunction.release()); | 102 keyframe->setEasing(timingFunction.release()); |
103 } else if (CSSAnimations::isAnimatableProperty(property)) { | 103 } else if (CSSAnimations::isAnimatableProperty(property)) { |
104 keyframe->setPropertyValue(property, properties.propertyAt(j).va
lue()); | 104 keyframe->setPropertyValue(property, properties.propertyAt(j).va
lue()); |
105 } | 105 } |
106 } | 106 } |
107 keyframes.append(keyframe); | 107 keyframes.append(keyframe); |
108 // The last keyframe specified at a given offset is used. | 108 // The last keyframe specified at a given offset is used. |
109 for (size_t j = 1; j < offsets.size(); ++j) { | 109 for (size_t j = 1; j < offsets.size(); ++j) { |
110 keyframes.append(toStringKeyframe(keyframe->cloneWithOffset(offsets[
j]).get())); | 110 keyframes.append(toStringKeyframe(keyframe->cloneWithOffset(offsets[
j]))); |
111 } | 111 } |
112 } | 112 } |
113 | 113 |
114 for (CSSPropertyID property : specifiedPropertiesForUseCounter) { | 114 for (CSSPropertyID property : specifiedPropertiesForUseCounter) { |
115 ASSERT(property != CSSPropertyInvalid); | 115 ASSERT(property != CSSPropertyInvalid); |
116 Platform::current()->histogramSparse("WebCore.Animation.CSSProperties",
UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property)); | 116 Platform::current()->histogramSparse("WebCore.Animation.CSSProperties",
UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property)); |
117 } | 117 } |
118 | 118 |
119 // Merge duplicate keyframes. | 119 // Merge duplicate keyframes. |
120 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset
s); | 120 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset
s); |
121 size_t targetIndex = 0; | 121 size_t targetIndex = 0; |
122 for (size_t i = 1; i < keyframes.size(); i++) { | 122 for (size_t i = 1; i < keyframes.size(); i++) { |
123 if (keyframes[i]->offset() == keyframes[targetIndex]->offset()) { | 123 if (keyframes[i]->offset() == keyframes[targetIndex]->offset()) { |
124 for (const auto& property : keyframes[i]->properties()) | 124 for (const auto& property : keyframes[i]->properties()) |
125 keyframes[targetIndex]->setPropertyValue(property.cssProperty(),
keyframes[i]->cssPropertyValue(property.cssProperty())); | 125 keyframes[targetIndex]->setPropertyValue(property.cssProperty(),
keyframes[i]->cssPropertyValue(property.cssProperty())); |
126 } else { | 126 } else { |
127 targetIndex++; | 127 targetIndex++; |
128 keyframes[targetIndex] = keyframes[i]; | 128 keyframes[targetIndex] = keyframes[i]; |
129 } | 129 } |
130 } | 130 } |
131 if (!keyframes.isEmpty()) | 131 if (!keyframes.isEmpty()) |
132 keyframes.shrink(targetIndex + 1); | 132 keyframes.shrink(targetIndex + 1); |
133 | 133 |
134 // Add 0% and 100% keyframes if absent. | 134 // Add 0% and 100% keyframes if absent. |
135 RefPtrWillBeRawPtr<StringKeyframe> startKeyframe = keyframes.isEmpty() ? nul
lptr : keyframes[0]; | 135 StringKeyframe* startKeyframe = keyframes.isEmpty() ? nullptr : keyframes[0]
; |
136 if (!startKeyframe || keyframes[0]->offset() != 0) { | 136 if (!startKeyframe || keyframes[0]->offset() != 0) { |
137 startKeyframe = StringKeyframe::create(); | 137 startKeyframe = StringKeyframe::create(); |
138 startKeyframe->setOffset(0); | 138 startKeyframe->setOffset(0); |
139 startKeyframe->setEasing(defaultTimingFunction); | 139 startKeyframe->setEasing(defaultTimingFunction); |
140 keyframes.prepend(startKeyframe); | 140 keyframes.prepend(startKeyframe); |
141 } | 141 } |
142 RefPtrWillBeRawPtr<StringKeyframe> endKeyframe = keyframes[keyframes.size()
- 1]; | 142 StringKeyframe* endKeyframe = keyframes[keyframes.size() - 1]; |
143 if (endKeyframe->offset() != 1) { | 143 if (endKeyframe->offset() != 1) { |
144 endKeyframe = StringKeyframe::create(); | 144 endKeyframe = StringKeyframe::create(); |
145 endKeyframe->setOffset(1); | 145 endKeyframe->setOffset(1); |
146 endKeyframe->setEasing(defaultTimingFunction); | 146 endKeyframe->setEasing(defaultTimingFunction); |
147 keyframes.append(endKeyframe); | 147 keyframes.append(endKeyframe); |
148 } | 148 } |
149 ASSERT(keyframes.size() >= 2); | 149 ASSERT(keyframes.size() >= 2); |
150 ASSERT(!keyframes.first()->offset()); | 150 ASSERT(!keyframes.first()->offset()); |
151 ASSERT(keyframes.last()->offset() == 1); | 151 ASSERT(keyframes.last()->offset() == 1); |
152 | 152 |
(...skipping 11 matching lines...) Expand all Loading... |
164 for (CSSPropertyID property : allProperties) { | 164 for (CSSPropertyID property : allProperties) { |
165 bool startNeedsValue = missingStartValues && !startKeyframePropertie
s.contains(PropertyHandle(property)); | 165 bool startNeedsValue = missingStartValues && !startKeyframePropertie
s.contains(PropertyHandle(property)); |
166 bool endNeedsValue = missingEndValues && !endKeyframeProperties.cont
ains(PropertyHandle(property)); | 166 bool endNeedsValue = missingEndValues && !endKeyframeProperties.cont
ains(PropertyHandle(property)); |
167 if (!startNeedsValue && !endNeedsValue) | 167 if (!startNeedsValue && !endNeedsValue) |
168 continue; | 168 continue; |
169 if (CompositorAnimations::isCompositableProperty(property)) | 169 if (CompositorAnimations::isCompositableProperty(property)) |
170 UseCounter::count(elementForScoping->document(), UseCounter::Syn
theticKeyframesInCompositedCSSAnimation); | 170 UseCounter::count(elementForScoping->document(), UseCounter::Syn
theticKeyframesInCompositedCSSAnimation); |
171 } | 171 } |
172 } | 172 } |
173 | 173 |
174 RefPtrWillBeRawPtr<StringKeyframeEffectModel> model = StringKeyframeEffectMo
del::create(keyframes, &keyframes[0]->easing()); | 174 StringKeyframeEffectModel* model = StringKeyframeEffectModel::create(keyfram
es, &keyframes[0]->easing()); |
175 model->forceConversionsToAnimatableValues(element, style); | 175 model->forceConversionsToAnimatableValues(element, style); |
176 if (animationIndex > 0 && model->hasSyntheticKeyframes()) | 176 if (animationIndex > 0 && model->hasSyntheticKeyframes()) |
177 UseCounter::count(elementForScoping->document(), UseCounter::CSSAnimatio
nsStackedNeutralKeyframe); | 177 UseCounter::count(elementForScoping->document(), UseCounter::CSSAnimatio
nsStackedNeutralKeyframe); |
178 return model; | 178 return model; |
179 } | 179 } |
180 | 180 |
181 } // namespace | 181 } // namespace |
182 | 182 |
183 CSSAnimations::CSSAnimations() | 183 CSSAnimations::CSSAnimations() |
184 { | 184 { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 return; | 302 return; |
303 | 303 |
304 m_previousActiveInterpolationsForAnimations.swap(m_pendingUpdate.activeInter
polationsForAnimations()); | 304 m_previousActiveInterpolationsForAnimations.swap(m_pendingUpdate.activeInter
polationsForAnimations()); |
305 | 305 |
306 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here | 306 // FIXME: cancelling, pausing, unpausing animations all query compositingSta
te, which is not necessarily up to date here |
307 // since we call this from recalc style. | 307 // since we call this from recalc style. |
308 // https://code.google.com/p/chromium/issues/detail?id=339847 | 308 // https://code.google.com/p/chromium/issues/detail?id=339847 |
309 DisableCompositingQueryAsserts disabler; | 309 DisableCompositingQueryAsserts disabler; |
310 | 310 |
311 for (const AtomicString& animationName : m_pendingUpdate.cancelledAnimationN
ames()) { | 311 for (const AtomicString& animationName : m_pendingUpdate.cancelledAnimationN
ames()) { |
312 RefPtrWillBeRawPtr<Animation> animation = m_animations.take(animationNam
e)->animation; | 312 Animation* animation = m_animations.take(animationName)->animation; |
313 animation->cancel(); | 313 animation->cancel(); |
314 animation->update(TimingUpdateOnDemand); | 314 animation->update(TimingUpdateOnDemand); |
315 } | 315 } |
316 | 316 |
317 for (const AtomicString& animationName : m_pendingUpdate.animationsWithPause
Toggled()) { | 317 for (const AtomicString& animationName : m_pendingUpdate.animationsWithPause
Toggled()) { |
318 Animation* animation = m_animations.get(animationName)->animation.get(); | 318 Animation* animation = m_animations.get(animationName)->animation.get(); |
319 if (animation->paused()) | 319 if (animation->paused()) |
320 animation->unpause(); | 320 animation->unpause(); |
321 else | 321 else |
322 animation->pause(); | 322 animation->pause(); |
(...skipping 24 matching lines...) Expand all Loading... |
347 KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect()); | 347 KeyframeEffect* effect = toKeyframeEffect(entry.animation->effect()); |
348 | 348 |
349 effect->setModel(entry.effect->model()); | 349 effect->setModel(entry.effect->model()); |
350 effect->updateSpecifiedTiming(entry.effect->specifiedTiming()); | 350 effect->updateSpecifiedTiming(entry.effect->specifiedTiming()); |
351 | 351 |
352 m_animations.find(entry.name)->value->update(entry); | 352 m_animations.find(entry.name)->value->update(entry); |
353 } | 353 } |
354 | 354 |
355 for (const auto& entry : m_pendingUpdate.newAnimations()) { | 355 for (const auto& entry : m_pendingUpdate.newAnimations()) { |
356 const InertEffect* inertAnimation = entry.effect.get(); | 356 const InertEffect* inertAnimation = entry.effect.get(); |
357 OwnPtrWillBeRawPtr<AnimationEventDelegate> eventDelegate = adoptPtrWillB
eNoop(new AnimationEventDelegate(element, entry.name)); | 357 AnimationEventDelegate* eventDelegate = new AnimationEventDelegate(eleme
nt, entry.name); |
358 RefPtrWillBeRawPtr<KeyframeEffect> effect = KeyframeEffect::create(eleme
nt, inertAnimation->model(), inertAnimation->specifiedTiming(), KeyframeEffect::
DefaultPriority, eventDelegate.release()); | 358 KeyframeEffect* effect = KeyframeEffect::create(element, inertAnimation-
>model(), inertAnimation->specifiedTiming(), KeyframeEffect::DefaultPriority, ev
entDelegate); |
359 effect->setName(inertAnimation->name()); | 359 effect->setName(inertAnimation->name()); |
360 RefPtrWillBeRawPtr<Animation> animation = element->document().timeline()
.play(effect.get()); | 360 Animation* animation = element->document().timeline().play(effect); |
361 if (inertAnimation->paused()) | 361 if (inertAnimation->paused()) |
362 animation->pause(); | 362 animation->pause(); |
363 animation->update(TimingUpdateOnDemand); | 363 animation->update(TimingUpdateOnDemand); |
364 | 364 |
365 m_animations.set(entry.name, adoptRefWillBeNoop(new RunningAnimation(ani
mation, entry))); | 365 m_animations.set(entry.name, new RunningAnimation(animation, entry)); |
366 } | 366 } |
367 | 367 |
368 // Transitions that are run on the compositor only update main-thread state | 368 // Transitions that are run on the compositor only update main-thread state |
369 // lazily. However, we need the new state to know what the from state shoud | 369 // lazily. However, we need the new state to know what the from state shoud |
370 // be when transitions are retargeted. Instead of triggering complete style | 370 // be when transitions are retargeted. Instead of triggering complete style |
371 // recalculation, we find these cases by searching for new transitions that | 371 // recalculation, we find these cases by searching for new transitions that |
372 // have matching cancelled animation property IDs on the compositor. | 372 // have matching cancelled animation property IDs on the compositor. |
373 WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<KeyframeEffect
>, double>> retargetedCompositorTransitions; | 373 HeapHashMap<CSSPropertyID, std::pair<Member<KeyframeEffect>, double>> retarg
etedCompositorTransitions; |
374 for (CSSPropertyID id : m_pendingUpdate.cancelledTransitions()) { | 374 for (CSSPropertyID id : m_pendingUpdate.cancelledTransitions()) { |
375 ASSERT(m_transitions.contains(id)); | 375 ASSERT(m_transitions.contains(id)); |
376 | 376 |
377 RefPtrWillBeRawPtr<Animation> animation = m_transitions.take(id).animati
on; | 377 Animation* animation = m_transitions.take(id).animation; |
378 KeyframeEffect* effect = toKeyframeEffect(animation->effect()); | 378 KeyframeEffect* effect = toKeyframeEffect(animation->effect()); |
379 if (effect->hasActiveAnimationsOnCompositor(id) && m_pendingUpdate.newTr
ansitions().find(id) != m_pendingUpdate.newTransitions().end() && !animation->li
mited()) | 379 if (effect->hasActiveAnimationsOnCompositor(id) && m_pendingUpdate.newTr
ansitions().find(id) != m_pendingUpdate.newTransitions().end() && !animation->li
mited()) |
380 retargetedCompositorTransitions.add(id, std::pair<RefPtrWillBeMember
<KeyframeEffect>, double>(effect, animation->startTimeInternal())); | 380 retargetedCompositorTransitions.add(id, std::pair<Member<KeyframeEff
ect>, double>(effect, animation->startTimeInternal())); |
381 animation->cancel(); | 381 animation->cancel(); |
382 // after cancelation, transitions must be downgraded or they'll fail | 382 // after cancelation, transitions must be downgraded or they'll fail |
383 // to be considered when retriggering themselves. This can happen if | 383 // to be considered when retriggering themselves. This can happen if |
384 // the transition is captured through getAnimations then played. | 384 // the transition is captured through getAnimations then played. |
385 if (animation->effect() && animation->effect()->isAnimation()) | 385 if (animation->effect() && animation->effect()->isAnimation()) |
386 toKeyframeEffect(animation->effect())->downgradeToNormal(); | 386 toKeyframeEffect(animation->effect())->downgradeToNormal(); |
387 animation->update(TimingUpdateOnDemand); | 387 animation->update(TimingUpdateOnDemand); |
388 } | 388 } |
389 | 389 |
390 for (CSSPropertyID id : m_pendingUpdate.finishedTransitions()) { | 390 for (CSSPropertyID id : m_pendingUpdate.finishedTransitions()) { |
391 // This transition can also be cancelled and finished at the same time | 391 // This transition can also be cancelled and finished at the same time |
392 if (m_transitions.contains(id)) { | 392 if (m_transitions.contains(id)) { |
393 RefPtrWillBeRawPtr<Animation> animation = m_transitions.take(id).ani
mation; | 393 Animation* animation = m_transitions.take(id).animation; |
394 // Transition must be downgraded | 394 // Transition must be downgraded |
395 if (animation->effect() && animation->effect()->isAnimation()) | 395 if (animation->effect() && animation->effect()->isAnimation()) |
396 toKeyframeEffect(animation->effect())->downgradeToNormal(); | 396 toKeyframeEffect(animation->effect())->downgradeToNormal(); |
397 } | 397 } |
398 } | 398 } |
399 | 399 |
400 for (const auto& entry : m_pendingUpdate.newTransitions()) { | 400 for (const auto& entry : m_pendingUpdate.newTransitions()) { |
401 const CSSAnimationUpdate::NewTransition& newTransition = entry.value; | 401 const CSSAnimationUpdate::NewTransition& newTransition = entry.value; |
402 | 402 |
403 RunningTransition runningTransition; | 403 RunningTransition runningTransition; |
404 runningTransition.from = newTransition.from; | 404 runningTransition.from = newTransition.from; |
405 runningTransition.to = newTransition.to; | 405 runningTransition.to = newTransition.to; |
406 | 406 |
407 CSSPropertyID id = newTransition.id; | 407 CSSPropertyID id = newTransition.id; |
408 InertEffect* inertAnimation = newTransition.effect.get(); | 408 InertEffect* inertAnimation = newTransition.effect.get(); |
409 OwnPtrWillBeRawPtr<TransitionEventDelegate> eventDelegate = adoptPtrWill
BeNoop(new TransitionEventDelegate(element, id)); | 409 TransitionEventDelegate* eventDelegate = new TransitionEventDelegate(ele
ment, id); |
410 | 410 |
411 RefPtrWillBeRawPtr<EffectModel> model = inertAnimation->model(); | 411 EffectModel* model = inertAnimation->model(); |
412 | 412 |
413 if (retargetedCompositorTransitions.contains(id)) { | 413 if (retargetedCompositorTransitions.contains(id)) { |
414 const std::pair<RefPtrWillBeMember<KeyframeEffect>, double>& oldTran
sition = retargetedCompositorTransitions.get(id); | 414 const std::pair<Member<KeyframeEffect>, double>& oldTransition = ret
argetedCompositorTransitions.get(id); |
415 RefPtrWillBeRawPtr<KeyframeEffect> oldAnimation = oldTransition.firs
t; | 415 KeyframeEffect* oldAnimation = oldTransition.first; |
416 double oldStartTime = oldTransition.second; | 416 double oldStartTime = oldTransition.second; |
417 double inheritedTime = isNull(oldStartTime) ? 0 : element->document(
).timeline().currentTimeInternal() - oldStartTime; | 417 double inheritedTime = isNull(oldStartTime) ? 0 : element->document(
).timeline().currentTimeInternal() - oldStartTime; |
418 | 418 |
419 AnimatableValueKeyframeEffectModel* oldEffect = toAnimatableValueKey
frameEffectModel(inertAnimation->model()); | 419 AnimatableValueKeyframeEffectModel* oldEffect = toAnimatableValueKey
frameEffectModel(inertAnimation->model()); |
420 const KeyframeVector& frames = oldEffect->getFrames(); | 420 const KeyframeVector& frames = oldEffect->getFrames(); |
421 | 421 |
422 AnimatableValueKeyframeVector newFrames; | 422 AnimatableValueKeyframeVector newFrames; |
423 newFrames.append(toAnimatableValueKeyframe(frames[0]->clone().get())
); | 423 newFrames.append(toAnimatableValueKeyframe(frames[0]->clone())); |
424 newFrames.append(toAnimatableValueKeyframe(frames[1]->clone().get())
); | 424 newFrames.append(toAnimatableValueKeyframe(frames[1]->clone())); |
425 newFrames.append(toAnimatableValueKeyframe(frames[2]->clone().get())
); | 425 newFrames.append(toAnimatableValueKeyframe(frames[2]->clone())); |
426 newFrames[0]->clearPropertyValue(id); | 426 newFrames[0]->clearPropertyValue(id); |
427 newFrames[1]->clearPropertyValue(id); | 427 newFrames[1]->clearPropertyValue(id); |
428 | 428 |
429 RefPtrWillBeRawPtr<InertEffect> inertAnimationForSampling = InertEff
ect::create(oldAnimation->model(), oldAnimation->specifiedTiming(), false, inher
itedTime); | 429 InertEffect* inertAnimationForSampling = InertEffect::create(oldAnim
ation->model(), oldAnimation->specifiedTiming(), false, inheritedTime); |
430 OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation
>>> sample = nullptr; | 430 HeapVector<Member<Interpolation>>* sample = nullptr; |
431 inertAnimationForSampling->sample(sample); | 431 inertAnimationForSampling->sample(sample); |
432 if (sample && sample->size() == 1) { | 432 if (sample && sample->size() == 1) { |
433 newFrames[0]->setPropertyValue(id, toLegacyStyleInterpolation(sa
mple->at(0).get())->currentValue()); | 433 newFrames[0]->setPropertyValue(id, toLegacyStyleInterpolation(sa
mple->at(0).get())->currentValue()); |
434 newFrames[1]->setPropertyValue(id, toLegacyStyleInterpolation(sa
mple->at(0).get())->currentValue()); | 434 newFrames[1]->setPropertyValue(id, toLegacyStyleInterpolation(sa
mple->at(0).get())->currentValue()); |
435 model = AnimatableValueKeyframeEffectModel::create(newFrames); | 435 model = AnimatableValueKeyframeEffectModel::create(newFrames); |
436 } | 436 } |
437 } | 437 } |
438 | 438 |
439 RefPtrWillBeRawPtr<KeyframeEffect> transition = KeyframeEffect::create(e
lement, model, inertAnimation->specifiedTiming(), KeyframeEffect::TransitionPrio
rity, eventDelegate.release()); | 439 KeyframeEffect* transition = KeyframeEffect::create(element, model, iner
tAnimation->specifiedTiming(), KeyframeEffect::TransitionPriority, eventDelegate
); |
440 transition->setName(inertAnimation->name()); | 440 transition->setName(inertAnimation->name()); |
441 RefPtrWillBeRawPtr<Animation> animation = element->document().timeline()
.play(transition.get()); | 441 Animation* animation = element->document().timeline().play(transition); |
442 // Set the current time as the start time for retargeted transitions | 442 // Set the current time as the start time for retargeted transitions |
443 if (retargetedCompositorTransitions.contains(id)) | 443 if (retargetedCompositorTransitions.contains(id)) |
444 animation->setStartTime(element->document().timeline().currentTime()
); | 444 animation->setStartTime(element->document().timeline().currentTime()
); |
445 animation->update(TimingUpdateOnDemand); | 445 animation->update(TimingUpdateOnDemand); |
446 runningTransition.animation = animation; | 446 runningTransition.animation = animation; |
447 m_transitions.set(id, runningTransition); | 447 m_transitions.set(id, runningTransition); |
448 ASSERT(id != CSSPropertyInvalid); | 448 ASSERT(id != CSSPropertyInvalid); |
449 Platform::current()->histogramSparse("WebCore.Animation.CSSProperties",
UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); | 449 Platform::current()->histogramSparse("WebCore.Animation.CSSProperties",
UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id)); |
450 } | 450 } |
451 | 451 |
452 clearPendingUpdate(); | 452 clearPendingUpdate(); |
453 } | 453 } |
454 | 454 |
455 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) | 455 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 { | 456 { |
457 RefPtrWillBeRawPtr<AnimatableValue> to = nullptr; | 457 AnimatableValue* to = nullptr; |
458 if (activeTransitions) { | 458 if (activeTransitions) { |
459 TransitionMap::const_iterator activeTransitionIter = activeTransitions->
find(id); | 459 TransitionMap::const_iterator activeTransitionIter = activeTransitions->
find(id); |
460 if (activeTransitionIter != activeTransitions->end()) { | 460 if (activeTransitionIter != activeTransitions->end()) { |
461 to = CSSAnimatableValueFactory::create(id, style); | 461 to = CSSAnimatableValueFactory::create(id, style); |
462 const AnimatableValue* activeTo = activeTransitionIter->value.to; | 462 const AnimatableValue* activeTo = activeTransitionIter->value.to; |
463 if (to->equals(activeTo)) | 463 if (to->equals(activeTo)) |
464 return; | 464 return; |
465 update.cancelTransition(id); | 465 update.cancelTransition(id); |
466 ASSERT(!element->elementAnimations() || !element->elementAnimations(
)->isAnimationStyleChange()); | 466 ASSERT(!element->elementAnimations() || !element->elementAnimations(
)->isAnimationStyleChange()); |
467 } | 467 } |
468 } | 468 } |
469 | 469 |
470 if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style)) | 470 if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style)) |
471 return; | 471 return; |
472 if (!to) | 472 if (!to) |
473 to = CSSAnimatableValueFactory::create(id, style); | 473 to = CSSAnimatableValueFactory::create(id, style); |
474 | 474 |
475 RefPtrWillBeRawPtr<AnimatableValue> from = CSSAnimatableValueFactory::create
(id, oldStyle); | 475 AnimatableValue* from = CSSAnimatableValueFactory::create(id, oldStyle); |
476 // If we have multiple transitions on the same property, we will use the | 476 // If we have multiple transitions on the same property, we will use the |
477 // last one since we iterate over them in order. | 477 // last one since we iterate over them in order. |
478 if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get())) | 478 if (AnimatableValue::usesDefaultInterpolation(to, from)) |
479 return; | 479 return; |
480 | 480 |
481 Timing timing = transitionData.convertToTiming(transitionIndex); | 481 Timing timing = transitionData.convertToTiming(transitionIndex); |
482 if (timing.startDelay + timing.iterationDuration <= 0) | 482 if (timing.startDelay + timing.iterationDuration <= 0) |
483 return; | 483 return; |
484 | 484 |
485 AnimatableValueKeyframeVector keyframes; | 485 AnimatableValueKeyframeVector keyframes; |
486 double startKeyframeOffset = 0; | 486 double startKeyframeOffset = 0; |
487 | 487 |
488 if (timing.startDelay > 0) { | 488 if (timing.startDelay > 0) { |
489 timing.iterationDuration += timing.startDelay; | 489 timing.iterationDuration += timing.startDelay; |
490 startKeyframeOffset = timing.startDelay / timing.iterationDuration; | 490 startKeyframeOffset = timing.startDelay / timing.iterationDuration; |
491 timing.startDelay = 0; | 491 timing.startDelay = 0; |
492 } | 492 } |
493 | 493 |
494 RefPtrWillBeRawPtr<AnimatableValueKeyframe> delayKeyframe = AnimatableValueK
eyframe::create(); | 494 AnimatableValueKeyframe* delayKeyframe = AnimatableValueKeyframe::create(); |
495 delayKeyframe->setPropertyValue(id, from.get()); | 495 delayKeyframe->setPropertyValue(id, from); |
496 delayKeyframe->setOffset(0); | 496 delayKeyframe->setOffset(0); |
497 keyframes.append(delayKeyframe); | 497 keyframes.append(delayKeyframe); |
498 | 498 |
499 RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = AnimatableValueK
eyframe::create(); | 499 AnimatableValueKeyframe* startKeyframe = AnimatableValueKeyframe::create(); |
500 startKeyframe->setPropertyValue(id, from.get()); | 500 startKeyframe->setPropertyValue(id, from); |
501 startKeyframe->setOffset(startKeyframeOffset); | 501 startKeyframe->setOffset(startKeyframeOffset); |
502 startKeyframe->setEasing(timing.timingFunction.release()); | 502 startKeyframe->setEasing(timing.timingFunction.release()); |
503 timing.timingFunction = LinearTimingFunction::shared(); | 503 timing.timingFunction = LinearTimingFunction::shared(); |
504 keyframes.append(startKeyframe); | 504 keyframes.append(startKeyframe); |
505 | 505 |
506 RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKey
frame::create(); | 506 AnimatableValueKeyframe* endKeyframe = AnimatableValueKeyframe::create(); |
507 endKeyframe->setPropertyValue(id, to.get()); | 507 endKeyframe->setPropertyValue(id, to); |
508 endKeyframe->setOffset(1); | 508 endKeyframe->setOffset(1); |
509 keyframes.append(endKeyframe); | 509 keyframes.append(endKeyframe); |
510 | 510 |
511 RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> model = AnimatableVal
ueKeyframeEffectModel::create(keyframes); | 511 AnimatableValueKeyframeEffectModel* model = AnimatableValueKeyframeEffectMod
el::create(keyframes); |
512 update.startTransition(id, from.get(), to.get(), InertEffect::create(model,
timing, false, 0)); | 512 update.startTransition(id, from, to, InertEffect::create(model, timing, fals
e, 0)); |
513 ASSERT(!element->elementAnimations() || !element->elementAnimations()->isAni
mationStyleChange()); | 513 ASSERT(!element->elementAnimations() || !element->elementAnimations()->isAni
mationStyleChange()); |
514 } | 514 } |
515 | 515 |
516 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate& update, const
Element* animatingElement, const ComputedStyle& style) | 516 void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate& update, const
Element* animatingElement, const ComputedStyle& style) |
517 { | 517 { |
518 if (!animatingElement) | 518 if (!animatingElement) |
519 return; | 519 return; |
520 | 520 |
521 ElementAnimations* elementAnimations = animatingElement->elementAnimations()
; | 521 ElementAnimations* elementAnimations = animatingElement->elementAnimations()
; |
522 const TransitionMap* activeTransitions = elementAnimations ? &elementAnimati
ons->cssAnimations().m_transitions : nullptr; | 522 const TransitionMap* activeTransitions = elementAnimations ? &elementAnimati
ons->cssAnimations().m_transitions : nullptr; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 { | 605 { |
606 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; | 606 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; |
607 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; | 607 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; |
608 | 608 |
609 if (update.newAnimations().isEmpty() && update.suppressedAnimations().isEmpt
y()) { | 609 if (update.newAnimations().isEmpty() && update.suppressedAnimations().isEmpt
y()) { |
610 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack:
:activeInterpolations(animationStack, 0, 0, KeyframeEffect::DefaultPriority, tim
elineCurrentTime)); | 610 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack:
:activeInterpolations(animationStack, 0, 0, KeyframeEffect::DefaultPriority, tim
elineCurrentTime)); |
611 update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAni
mations); | 611 update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAni
mations); |
612 return; | 612 return; |
613 } | 613 } |
614 | 614 |
615 WillBeHeapVector<RawPtrWillBeMember<InertEffect>> newEffects; | 615 HeapVector<Member<InertEffect>> newEffects; |
616 for (const auto& newAnimation : update.newAnimations()) | 616 for (const auto& newAnimation : update.newAnimations()) |
617 newEffects.append(newAnimation.effect.get()); | 617 newEffects.append(newAnimation.effect.get()); |
618 for (const auto& updatedAnimation : update.animationsWithUpdates()) | 618 for (const auto& updatedAnimation : update.animationsWithUpdates()) |
619 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. |
620 | 620 |
621 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack::act
iveInterpolations(animationStack, &newEffects, &update.suppressedAnimations(), K
eyframeEffect::DefaultPriority, timelineCurrentTime)); | 621 ActiveInterpolationMap activeInterpolationsForAnimations(AnimationStack::act
iveInterpolations(animationStack, &newEffects, &update.suppressedAnimations(), K
eyframeEffect::DefaultPriority, timelineCurrentTime)); |
622 update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimati
ons); | 622 update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimati
ons); |
623 } | 623 } |
624 | 624 |
625 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate&
update, const Element* animatingElement, double timelineCurrentTime) | 625 void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate&
update, const Element* animatingElement, double timelineCurrentTime) |
626 { | 626 { |
627 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; | 627 ElementAnimations* elementAnimations = animatingElement ? animatingElement->
elementAnimations() : nullptr; |
628 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; | 628 AnimationStack* animationStack = elementAnimations ? &elementAnimations->def
aultStack() : nullptr; |
629 | 629 |
630 ActiveInterpolationMap activeInterpolationsForTransitions; | 630 ActiveInterpolationMap activeInterpolationsForTransitions; |
631 if (update.newTransitions().isEmpty() && update.cancelledTransitions().isEmp
ty()) { | 631 if (update.newTransitions().isEmpty() && update.cancelledTransitions().isEmp
ty()) { |
632 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, 0, 0, KeyframeEffect::TransitionPriority, timelineCurrentTime)
; | 632 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, 0, 0, KeyframeEffect::TransitionPriority, timelineCurrentTime)
; |
633 } else { | 633 } else { |
634 WillBeHeapVector<RawPtrWillBeMember<InertEffect>> newTransitions; | 634 HeapVector<Member<InertEffect>> newTransitions; |
635 for (const auto& entry : update.newTransitions()) | 635 for (const auto& entry : update.newTransitions()) |
636 newTransitions.append(entry.value.effect.get()); | 636 newTransitions.append(entry.value.effect.get()); |
637 | 637 |
638 WillBeHeapHashSet<RawPtrWillBeMember<const Animation>> cancelledAnimatio
ns; | 638 HeapHashSet<Member<const Animation>> cancelledAnimations; |
639 if (!update.cancelledTransitions().isEmpty()) { | 639 if (!update.cancelledTransitions().isEmpty()) { |
640 ASSERT(elementAnimations); | 640 ASSERT(elementAnimations); |
641 const TransitionMap& transitionMap = elementAnimations->cssAnimation
s().m_transitions; | 641 const TransitionMap& transitionMap = elementAnimations->cssAnimation
s().m_transitions; |
642 for (CSSPropertyID id : update.cancelledTransitions()) { | 642 for (CSSPropertyID id : update.cancelledTransitions()) { |
643 ASSERT(transitionMap.contains(id)); | 643 ASSERT(transitionMap.contains(id)); |
644 cancelledAnimations.add(transitionMap.get(id).animation.get()); | 644 cancelledAnimations.add(transitionMap.get(id).animation.get()); |
645 } | 645 } |
646 } | 646 } |
647 | 647 |
648 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, &newTransitions, &cancelledAnimations, KeyframeEffect::Transit
ionPriority, timelineCurrentTime); | 648 activeInterpolationsForTransitions = AnimationStack::activeInterpolation
s(animationStack, &newTransitions, &cancelledAnimations, KeyframeEffect::Transit
ionPriority, timelineCurrentTime); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 case CSSPropertyTransitionProperty: | 782 case CSSPropertyTransitionProperty: |
783 case CSSPropertyTransitionTimingFunction: | 783 case CSSPropertyTransitionTimingFunction: |
784 return false; | 784 return false; |
785 default: | 785 default: |
786 return true; | 786 return true; |
787 } | 787 } |
788 } | 788 } |
789 | 789 |
790 DEFINE_TRACE(CSSAnimations) | 790 DEFINE_TRACE(CSSAnimations) |
791 { | 791 { |
792 #if ENABLE(OILPAN) | |
793 visitor->trace(m_transitions); | 792 visitor->trace(m_transitions); |
794 visitor->trace(m_pendingUpdate); | 793 visitor->trace(m_pendingUpdate); |
795 visitor->trace(m_animations); | 794 visitor->trace(m_animations); |
796 visitor->trace(m_previousActiveInterpolationsForAnimations); | 795 visitor->trace(m_previousActiveInterpolationsForAnimations); |
797 #endif | |
798 } | 796 } |
799 | 797 |
800 } // namespace blink | 798 } // namespace blink |
OLD | NEW |