Changeset 251785 in webkit


Ignore:
Timestamp:
Oct 30, 2019 11:29:56 AM (4 years ago)
Author:
graouts@webkit.org
Message:

[Web Animations] Precompute an animation effect's active duration and end time
https://bugs.webkit.org/show_bug.cgi?id=203611

Reviewed by Dean Jackson.

We would compute an animation effect's active duration and end time in AnimationEffect::getBasicTiming()
but these two properties could be computed ahead of time when the other static timing properties of an
animation effect are changed. This allows several calls sites to WebAnimation::effectEndTime() to no
longer require the dynamic computation of all the other timing properties in AnimationEffect::getBasicTiming(),
(local time, active time and phase) which need to be computed dynamically as they rely on the current
timeline time.

  • animation/AnimationEffect.cpp:

(WebCore::AnimationEffect::getBasicTiming const):
(WebCore::AnimationEffect::getComputedTiming const):
(WebCore::AnimationEffect::updateTiming):
(WebCore::AnimationEffect::updateStaticTimingProperties):

  • animation/AnimationEffect.h:

(WebCore::AnimationEffect::activeDuration const):
(WebCore::AnimationEffect::endTime const):

  • animation/CSSAnimation.cpp:

(WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):

  • animation/CSSTransition.cpp:

(WebCore::CSSTransition::setTimingProperties):

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::copyPropertiesFromSource):

  • animation/WebAnimation.cpp:

(WebCore::WebAnimation::effectEndTime const):
(WebCore::WebAnimation::timeToNextTick const):

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r251780 r251785  
     12019-10-30  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Precompute an animation effect's active duration and end time
     4        https://bugs.webkit.org/show_bug.cgi?id=203611
     5
     6        Reviewed by Dean Jackson.
     7
     8        We would compute an animation effect's active duration and end time in AnimationEffect::getBasicTiming()
     9        but these two properties could be computed ahead of time when the other static timing properties of an
     10        animation effect are changed. This allows several calls sites to WebAnimation::effectEndTime() to no
     11        longer require the dynamic computation of all the other timing properties in AnimationEffect::getBasicTiming(),
     12        (local time, active time and phase) which need to be computed dynamically as they rely on the current
     13        timeline time.
     14
     15        * animation/AnimationEffect.cpp:
     16        (WebCore::AnimationEffect::getBasicTiming const):
     17        (WebCore::AnimationEffect::getComputedTiming const):
     18        (WebCore::AnimationEffect::updateTiming):
     19        (WebCore::AnimationEffect::updateStaticTimingProperties):
     20        * animation/AnimationEffect.h:
     21        (WebCore::AnimationEffect::activeDuration const):
     22        (WebCore::AnimationEffect::endTime const):
     23        * animation/CSSAnimation.cpp:
     24        (WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):
     25        * animation/CSSTransition.cpp:
     26        (WebCore::CSSTransition::setTimingProperties):
     27        * animation/KeyframeEffect.cpp:
     28        (WebCore::KeyframeEffect::copyPropertiesFromSource):
     29        * animation/WebAnimation.cpp:
     30        (WebCore::WebAnimation::effectEndTime const):
     31        (WebCore::WebAnimation::timeToNextTick const):
     32
    1332019-10-30  Antti Koivisto  <antti@apple.com>
    234
  • trunk/Source/WebCore/animation/AnimationEffect.cpp

    r239723 r251785  
    6565    // to return them all as a single BasicEffectTiming.
    6666
    67     auto activeDuration = [this]() -> Seconds {
    68         // 3.8.2. Calculating the active duration
    69         // https://drafts.csswg.org/web-animations-1/#calculating-the-active-duration
    70 
    71         // The active duration is calculated as follows:
    72         // active duration = iteration duration × iteration count
    73         // If either the iteration duration or iteration count are zero, the active duration is zero.
    74         if (!m_iterationDuration || !m_iterations)
    75             return 0_s;
    76         return m_iterationDuration * m_iterations;
    77     }();
    78 
    79     auto endTime = [this, activeDuration]() -> Seconds {
    80         // 3.5.3 The active interval
    81         // https://drafts.csswg.org/web-animations-1/#end-time
    82 
    83         // The end time of an animation effect is the result of evaluating max(start delay + active duration + end delay, 0).
    84         auto endTime = m_delay + activeDuration + m_endDelay;
    85         return endTime > 0_s ? endTime : 0_s;
    86     }();
    87 
    8867    auto localTime = [this]() -> Optional<Seconds> {
    8968        // 4.5.4. Local time
     
    9877    }();
    9978
    100     auto phase = [this, endTime, localTime, activeDuration]() -> AnimationEffectPhase {
     79    auto phase = [this, localTime]() -> AnimationEffectPhase {
    10180        // 3.5.5. Animation effect phases and states
    10281        // https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states
    10382
    10483        bool animationIsBackwards = m_animation && m_animation->playbackRate() < 0;
    105         auto beforeActiveBoundaryTime = std::max(std::min(m_delay, endTime), 0_s);
    106         auto activeAfterBoundaryTime = std::max(std::min(m_delay + activeDuration, endTime), 0_s);
     84        auto beforeActiveBoundaryTime = std::max(std::min(m_delay, m_endTime), 0_s);
     85        auto activeAfterBoundaryTime = std::max(std::min(m_delay + m_activeDuration, m_endTime), 0_s);
    10786
    10887        // (This should be the last statement, but it's more efficient to cache the local time and return right away if it's not resolved.)
     
    132111    }();
    133112
    134     auto activeTime = [this, localTime, phase, activeDuration]() -> Optional<Seconds> {
     113    auto activeTime = [this, localTime, phase]() -> Optional<Seconds> {
    135114        // 3.8.3.1. Calculating the active time
    136115        // https://drafts.csswg.org/web-animations-1/#calculating-the-active-time
     
    161140            // max(min(local time - start delay, active duration), 0).
    162141            if (m_fill == FillMode::Forwards || m_fill == FillMode::Both)
    163                 return std::max(std::min(*localTime - m_delay, activeDuration), 0_s);
     142                return std::max(std::min(*localTime - m_delay, m_activeDuration), 0_s);
    164143            // Otherwise, return an unresolved time value.
    165144            return WTF::nullopt;
     
    170149    }();
    171150
    172     return { localTime, activeTime, endTime, activeDuration, phase };
     151    return { localTime, activeTime, m_endTime, m_activeDuration, phase };
    173152}
    174153
     
    181160    auto basicEffectTiming = getBasicTiming();
    182161    auto activeTime = basicEffectTiming.activeTime;
    183     auto activeDuration = basicEffectTiming.activeDuration;
    184162    auto phase = basicEffectTiming.phase;
    185163
     
    211189    }();
    212190
    213     auto simpleIterationProgress = [this, overallProgress, phase, activeTime, activeDuration]() -> Optional<double> {
     191    auto simpleIterationProgress = [this, overallProgress, phase, activeTime]() -> Optional<double> {
    214192        // 3.8.3.3. Calculating the simple iteration progress
    215193        // https://drafts.csswg.org/web-animations-1/#calculating-the-simple-iteration-progress
     
    234212        // the iteration count is not equal to zero.
    235213        // let the simple iteration progress be 1.0.
    236         if (!simpleIterationProgress && (phase == AnimationEffectPhase::Active || phase == AnimationEffectPhase::After) && std::abs(activeTime->microseconds() - activeDuration.microseconds()) < timeEpsilon.microseconds() && m_iterations)
     214        if (!simpleIterationProgress && (phase == AnimationEffectPhase::Active || phase == AnimationEffectPhase::After) && std::abs(activeTime->microseconds() - m_activeDuration.microseconds()) < timeEpsilon.microseconds() && m_iterations)
    237215            return 1;
    238216
     
    348326    computedTiming.direction = m_direction;
    349327    computedTiming.easing = m_timingFunction->cssText();
    350     computedTiming.endTime = secondsToWebAnimationsAPITime(basicEffectTiming.endTime);
    351     computedTiming.activeDuration = secondsToWebAnimationsAPITime(activeDuration);
     328    computedTiming.endTime = secondsToWebAnimationsAPITime(m_endTime);
     329    computedTiming.activeDuration = secondsToWebAnimationsAPITime(m_activeDuration);
    352330    if (basicEffectTiming.localTime)
    353331        computedTiming.localTime = secondsToWebAnimationsAPITime(*basicEffectTiming.localTime);
     
    433411        m_direction = timing->direction.value();
    434412
     413    updateStaticTimingProperties();
     414
    435415    if (m_animation)
    436416        m_animation->effectTimingDidChange();
    437417
    438418    return { };
     419}
     420
     421void AnimationEffect::updateStaticTimingProperties()
     422{
     423    // 3.8.2. Calculating the active duration
     424    // https://drafts.csswg.org/web-animations-1/#calculating-the-active-duration
     425
     426    // The active duration is calculated as follows:
     427    // active duration = iteration duration × iteration count
     428    // If either the iteration duration or iteration count are zero, the active duration is zero.
     429    if (!m_iterationDuration || !m_iterations)
     430        m_activeDuration = 0_s;
     431    else
     432        m_activeDuration = m_iterationDuration * m_iterations;
     433
     434    // 3.5.3 The active interval
     435    // https://drafts.csswg.org/web-animations-1/#end-time
     436
     437    // The end time of an animation effect is the result of evaluating max(start delay + active duration + end delay, 0).
     438    m_endTime = m_delay + m_activeDuration + m_endDelay;
     439    if (m_endTime < 0_s)
     440        m_endTime = 0_s;
    439441}
    440442
  • trunk/Source/WebCore/animation/AnimationEffect.h

    r239820 r251785  
    9191    void setTimingFunction(const RefPtr<TimingFunction>&);
    9292
     93    Seconds activeDuration() const { return m_activeDuration; }
     94    Seconds endTime() const { return m_endTime; }
     95
     96    void updateStaticTimingProperties();
     97
    9398protected:
    9499    explicit AnimationEffect();
     
    109114    Seconds m_endDelay { 0_s };
    110115    Seconds m_iterationDuration { 0_s };
     116    Seconds m_activeDuration { 0_s };
     117    Seconds m_endTime { 0_s };
    111118};
    112119
  • trunk/Source/WebCore/animation/CSSAnimation.cpp

    r244115 r251785  
    9797    animationEffect->setDelay(Seconds(animation.delay()));
    9898    animationEffect->setIterationDuration(Seconds(animation.duration()));
     99    animationEffect->updateStaticTimingProperties();
    99100
    100101    // Synchronize the play state
  • trunk/Source/WebCore/animation/CSSTransition.cpp

    r251657 r251785  
    7474    animationEffect->setIterationDuration(duration);
    7575    animationEffect->setTimingFunction(backingAnimation().timingFunction());
     76    animationEffect->updateStaticTimingProperties();
    7677
    7778    unsuspendEffectInvalidation();
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r251706 r251785  
    543543    setIterationStart(source->iterationStart());
    544544    setIterationDuration(source->iterationDuration());
     545    updateStaticTimingProperties();
    545546
    546547    KeyframeList keyframeList("keyframe-effect-" + createCanonicalUUIDString());
  • trunk/Source/WebCore/animation/WebAnimation.cpp

    r251742 r251785  
    546546    // The target effect end of an animation is equal to the end time of the animation's target effect.
    547547    // If the animation has no target effect, the target effect end is zero.
    548     return m_effect ? m_effect->getBasicTiming().endTime : 0_s;
     548    return m_effect ? m_effect->endTime() : 0_s;
    549549}
    550550
     
    12921292        }
    12931293    } else if (auto animationCurrentTime = currentTime())
    1294         return effect()->getBasicTiming().endTime - *animationCurrentTime;
     1294        return effect()->endTime() - *animationCurrentTime;
    12951295
    12961296    ASSERT_NOT_REACHED();
Note: See TracChangeset for help on using the changeset viewer.