Changeset 269914 in webkit


Ignore:
Timestamp:
Nov 17, 2020 11:04:10 AM (3 years ago)
Author:
graouts@webkit.org
Message:

[Web Animations] Move all effect-specific parts of WebAnimation::timeToNextTick() to effect classes
https://bugs.webkit.org/show_bug.cgi?id=219028

Reviewed by Antti Koivisto.

Most of WebAnimation::timeToNextTick() is code that is specific to effects. We move this code out to
KeyframeEffect and a virtual method with a default implementation on AnimationEffect. This is the first
step towards adding more smarts to this method such as avoiding style recalcs if there are no keyframes
set up on a KeyframeEffect or running fewer style recalcs when animating a discrete property.

No new tests since this we are just moving code around.

  • animation/AnimationEffect.h:

(WebCore::AnimationEffect::timeToNextTick const):

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::timeToNextTick const):

  • animation/KeyframeEffect.h:

(WebCore::KeyframeEffect::isCompletelyAccelerated const): Make this method private since it is now only
called by KeyframeEffect.

  • animation/WebAnimation.cpp:

(WebCore::WebAnimation::timeToNextTick const):
(WebCore::WebAnimation::isCompletelyAccelerated const): Deleted. This method no longer has any call sites.

  • animation/WebAnimation.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r269913 r269914  
     12020-11-17  Antoine Quint  <graouts@webkit.org>
     2
     3        [Web Animations] Move all effect-specific parts of WebAnimation::timeToNextTick() to effect classes
     4        https://bugs.webkit.org/show_bug.cgi?id=219028
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Most of WebAnimation::timeToNextTick() is code that is specific to effects. We move this code out to
     9        KeyframeEffect and a virtual method with a default implementation on AnimationEffect. This is the first
     10        step towards adding more smarts to this method such as avoiding style recalcs if there are no keyframes
     11        set up on a KeyframeEffect or running fewer style recalcs when animating a discrete property.
     12
     13        No new tests since this we are just moving code around.
     14
     15        * animation/AnimationEffect.h:
     16        (WebCore::AnimationEffect::timeToNextTick const):
     17        * animation/KeyframeEffect.cpp:
     18        (WebCore::KeyframeEffect::timeToNextTick const):
     19        * animation/KeyframeEffect.h:
     20        (WebCore::KeyframeEffect::isCompletelyAccelerated const): Make this method private since it is now only
     21        called by KeyframeEffect.
     22        * animation/WebAnimation.cpp:
     23        (WebCore::WebAnimation::timeToNextTick const):
     24        (WebCore::WebAnimation::isCompletelyAccelerated const): Deleted. This method no longer has any call sites.
     25        * animation/WebAnimation.h:
     26
    1272020-11-17  Aditya Keerthi  <akeerthi@apple.com>
    228
  • trunk/Source/WebCore/animation/AnimationEffect.h

    r263464 r269914  
    103103    void updateStaticTimingProperties();
    104104
    105     virtual Optional<double> progressUntilNextStep(double) const;
     105    virtual Seconds timeToNextTick() const { return Seconds::infinity(); }
    106106
    107107protected:
    108108    explicit AnimationEffect();
     109
     110    virtual Optional<double> progressUntilNextStep(double) const;
    109111
    110112private:
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r269813 r269914  
    19731973}
    19741974
     1975Seconds KeyframeEffect::timeToNextTick() const
     1976{
     1977    auto timing = getBasicTiming();
     1978    switch (timing.phase) {
     1979    case AnimationEffectPhase::Before:
     1980        // The effect is in its "before" phase, in this case we can wait until it enters its "active" phase.
     1981        return delay() - *timing.localTime;
     1982    case AnimationEffectPhase::Active:
     1983        if (isCompletelyAccelerated() && isRunningAccelerated()) {
     1984            // Fully-accelerated running CSS Animations need to trigger "animationiteration" events, in this case we must wait until the next iteration.
     1985            if (is<CSSAnimation>(animation())) {
     1986                if (auto iterationProgress = getComputedTiming().simpleIterationProgress)
     1987                    return iterationDuration() * (1 - *iterationProgress);
     1988            }
     1989            // Fully-accelerated running effects in the "active" phase can wait until they ended.
     1990            return endTime() - *timing.localTime;
     1991        }
     1992        if (auto iterationProgress = getComputedTiming().simpleIterationProgress) {
     1993            // In case we're in a range that uses a steps() timing function, we can compute the time until the next step starts.
     1994            if (auto progressUntilNextStep = this->progressUntilNextStep(*iterationProgress))
     1995                return iterationDuration() * *progressUntilNextStep;
     1996        }
     1997        // Other effects in the "active" phase will need to update their animated value at the immediate next opportunity.
     1998        return 0_s;
     1999    case AnimationEffectPhase::After:
     2000        // The effect is in its after phase, which means it will no longer update its value, so it doens't need a tick.
     2001        return Seconds::infinity();
     2002    case AnimationEffectPhase::Idle:
     2003        ASSERT_NOT_REACHED();
     2004        return Seconds::infinity();
     2005    }
     2006
     2007    ASSERT_NOT_REACHED();
     2008    return Seconds::infinity();
     2009}
     2010
    19752011} // namespace WebCore
  • trunk/Source/WebCore/animation/KeyframeEffect.h

    r268932 r269914  
    147147    // FIXME: These ignore the fact that some timing functions can prevent acceleration.
    148148    bool isAboutToRunAccelerated() const { return m_acceleratedPropertiesState != AcceleratedProperties::None && m_lastRecordedAcceleratedAction != AcceleratedAction::Stop; }
    149     bool isCompletelyAccelerated() const { return m_acceleratedPropertiesState == AcceleratedProperties::All; }
    150149
    151150    bool filterFunctionListsMatch() const override { return m_filterFunctionListsMatch; }
     
    188187    void addPendingAcceleratedAction(AcceleratedAction);
    189188    bool canBeAccelerated() const;
     189    bool isCompletelyAccelerated() const { return m_acceleratedPropertiesState == AcceleratedProperties::All; }
    190190    void updateAcceleratedActions();
    191191    void setAnimatedPropertiesInStyle(RenderStyle&, double);
     
    201201    void computeAcceleratedPropertiesState();
    202202    void setBlendingKeyframes(KeyframeList&);
     203    Seconds timeToNextTick() const final;
    203204    Optional<double> progressUntilNextStep(double) const final;
    204205    void checkForMatchingTransformFunctionLists();
  • trunk/Source/WebCore/animation/WebAnimation.cpp

    r267571 r269914  
    12061206}
    12071207
    1208 bool WebAnimation::isCompletelyAccelerated() const
    1209 {
    1210     return is<KeyframeEffect>(m_effect) && downcast<KeyframeEffect>(*m_effect).isCompletelyAccelerated();
    1211 }
    1212 
    12131208bool WebAnimation::needsTick() const
    12141209{
     
    14541449Seconds WebAnimation::timeToNextTick() const
    14551450{
    1456     ASSERT(effect());
    1457 
    14581451    if (pending())
    14591452        return 0_s;
     
    14641457        return Seconds::infinity();
    14651458
    1466     auto& effect = *this->effect();
    1467     auto timing = effect.getBasicTiming();
    1468     switch (timing.phase) {
    1469     case AnimationEffectPhase::Before:
    1470         // The animation is in its "before" phase, in this case we can wait until it enters its "active" phase.
    1471         return (effect.delay() - timing.localTime.value()) / playbackRate;
    1472     case AnimationEffectPhase::Active:
    1473         if (isCompletelyAccelerated() && isRunningAccelerated()) {
    1474             // Fully-accelerated running CSS Animations need to trigger "animationiteration" events, in this case we must wait until the next iteration.
    1475             if (isCSSAnimation()) {
    1476                 if (auto iterationProgress = effect.getComputedTiming().simpleIterationProgress)
    1477                     return effect.iterationDuration() * (1 - *iterationProgress);
    1478             }
    1479             // Fully-accelerated running animations in the "active" phase can wait until they ended.
    1480             return (effect.endTime() - timing.localTime.value()) / playbackRate;
    1481         }
    1482         if (auto iterationProgress = effect.getComputedTiming().simpleIterationProgress) {
    1483             // In case we're in a range that uses a steps() timing function, we can compute the time until the next step starts.
    1484             if (auto progressUntilNextStep = effect.progressUntilNextStep(*iterationProgress))
    1485                 return effect.iterationDuration() * *progressUntilNextStep / playbackRate;
    1486         }
    1487         // Other animations in the "active" phase will need to update their animated value at the immediate next opportunity.
    1488         return 0_s;
    1489     case AnimationEffectPhase::After:
    1490         // The animation is in its after phase, which means it will no longer update its value, so it doens't need a tick.
    1491         return Seconds::infinity();
    1492     case AnimationEffectPhase::Idle:
    1493         ASSERT_NOT_REACHED();
    1494         return Seconds::infinity();
    1495     }
    1496 
    1497     ASSERT_NOT_REACHED();
    1498     return Seconds::infinity();
     1459    ASSERT(effect());
     1460    return effect()->timeToNextTick() / playbackRate;
    14991461}
    15001462
  • trunk/Source/WebCore/animation/WebAnimation.h

    r267571 r269914  
    129129
    130130    bool isRunningAccelerated() const;
    131     bool isCompletelyAccelerated() const;
    132131    bool isRelevant() const { return m_isRelevant; }
    133132    void updateRelevance();
Note: See TracChangeset for help on using the changeset viewer.