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