| 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 | 
|---|