Changeset 251706 in webkit


Ignore:
Timestamp:
Oct 29, 2019 9:14:58 AM (4 years ago)
Author:
graouts@webkit.org
Message:

[Web Animations] Optimize blending for CSS Transitions
https://bugs.webkit.org/show_bug.cgi?id=203561

Reviewed by Simon Fraser.

The work performed in KeyframeEffect::setAnimatedPropertiesInStyle() has a level of complexity warranted by the
flexibility of how keyframes can be specified via the Web Animations JS API. However, in the case of CSS Transitions,
we already know that there are only two keyframes, one where offset=0 and one where offset=1, and that only a single
CSS property is specified so we can simplify the process greatly.

To ensure we only perform this quicker blending operation for keyframes computed for a CSS Transition and that no
modification to the keyframes have been applied via the Web Animations JS API after the fact, we now keep track
of whether the blending keyframes (KeyframeList) were generated for a CSS Transition or a CSS Animation and only
use this information to decide whether we're blending for declarative animations.

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::processKeyframes):
(WebCore::KeyframeEffect::clearBlendingKeyframes):
(WebCore::KeyframeEffect::computeCSSAnimationBlendingKeyframes):
(WebCore::KeyframeEffect::computeCSSTransitionBlendingKeyframes):
(WebCore::KeyframeEffect::setTarget):
(WebCore::KeyframeEffect::setAnimatedPropertiesInStyle):

  • animation/KeyframeEffect.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r251698 r251706  
     12019-10-29  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Optimize blending for CSS Transitions
     4        https://bugs.webkit.org/show_bug.cgi?id=203561
     5
     6        Reviewed by Simon Fraser.
     7
     8        The work performed in KeyframeEffect::setAnimatedPropertiesInStyle() has a level of complexity warranted by the
     9        flexibility of how keyframes can be specified via the Web Animations JS API. However, in the case of CSS Transitions,
     10        we already know that there are only two keyframes, one where offset=0 and one where offset=1, and that only a single
     11        CSS property is specified so we can simplify the process greatly.
     12
     13        To ensure we only perform this quicker blending operation for keyframes computed for a CSS Transition and that no
     14        modification to the keyframes have been applied via the Web Animations JS API after the fact, we now keep track
     15        of whether the blending keyframes (KeyframeList) were generated for a CSS Transition or a CSS Animation and only
     16        use this information to decide whether we're blending for declarative animations.
     17
     18        * animation/KeyframeEffect.cpp:
     19        (WebCore::KeyframeEffect::processKeyframes):
     20        (WebCore::KeyframeEffect::clearBlendingKeyframes):
     21        (WebCore::KeyframeEffect::computeCSSAnimationBlendingKeyframes):
     22        (WebCore::KeyframeEffect::computeCSSTransitionBlendingKeyframes):
     23        (WebCore::KeyframeEffect::setTarget):
     24        (WebCore::KeyframeEffect::setAnimatedPropertiesInStyle):
     25        * animation/KeyframeEffect.h:
     26
    1272019-10-29  Adrian Perez de Castro  <aperez@igalia.com>
    228
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r251657 r251706  
    727727    m_parsedKeyframes = WTFMove(parsedKeyframes);
    728728
    729     m_blendingKeyframes.clear();
     729    clearBlendingKeyframes();
    730730
    731731    return { };
     
    771771    frameView->forceLayout();
    772772    return true;
     773}
     774
     775
     776void KeyframeEffect::clearBlendingKeyframes()
     777{
     778    m_blendingKeyframesSource = BlendingKeyframesSource::WebAnimation;
     779    m_blendingKeyframes.clear();
    773780}
    774781
     
    910917    }
    911918
     919    m_blendingKeyframesSource = BlendingKeyframesSource::CSSAnimation;
    912920    setBlendingKeyframes(keyframeList);
    913921}
     
    937945    keyframeList.insert(WTFMove(toKeyframeValue));
    938946
     947    m_blendingKeyframesSource = BlendingKeyframesSource::CSSTransition;
    939948    setBlendingKeyframes(keyframeList);
    940949}
     
    989998        effectAnimation->effectTargetDidChange(previousTarget.get(), m_target.get());
    990999
    991     m_blendingKeyframes.clear();
     1000    clearBlendingKeyframes();
    9921001
    9931002    // We need to invalidate the effect now that the target has changed
     
    10551064void KeyframeEffect::setAnimatedPropertiesInStyle(RenderStyle& targetStyle, double iterationProgress)
    10561065{
     1066    // In the case of CSS Transitions we already know that there are only two keyframes, one where offset=0 and one where offset=1,
     1067    // and only a single CSS property so we can simply blend based on the style available on those keyframes with the provided iteration
     1068    // progress which already accounts for the transition's timing function.
     1069    if (m_blendingKeyframesSource == BlendingKeyframesSource::CSSTransition) {
     1070        ASSERT(is<CSSTransition>(animation()));
     1071        CSSPropertyAnimation::blendProperties(this, downcast<CSSTransition>(animation())->property(), &targetStyle, m_blendingKeyframes[0].style(), m_blendingKeyframes[1].style(), iterationProgress);
     1072        return;
     1073    }
     1074
    10571075    // 4.4.3. The effect value of a keyframe effect
    10581076    // https://drafts.csswg.org/web-animations-1/#the-effect-value-of-a-keyframe-animation-effect
     
    10641082    if (m_blendingKeyframes.isEmpty())
    10651083        return;
    1066 
    1067     bool isCSSAnimation = is<CSSAnimation>(animation());
    1068     bool isCSSTransition = is<CSSTransition>(animation());
    10691084
    10701085    for (auto cssPropertyId : m_blendingKeyframes.properties()) {
     
    10861101                // If we're dealing with a CSS animation, we consider the first and last keyframes to always have the property listed
    10871102                // since the underlying style was provided and should be captured.
    1088                 if (!isCSSAnimation || (offset && offset < 1))
     1103                if (m_blendingKeyframesSource == BlendingKeyframesSource::WebAnimation || (offset && offset < 1))
    10891104                    continue;
    10901105            }
     
    11851200        // 17. Let transformed distance be the result of evaluating the timing function associated with the first keyframe in interval endpoints
    11861201        //     passing interval distance as the input progress.
    1187         // We do not need to do this for CSS Transitions since the timing function is applied to the AnimationEffect as a whole and thus
    1188         // iterationProgress is already transformed.
    11891202        auto transformedDistance = intervalDistance;
    1190         if (!isCSSTransition && startKeyframeIndex) {
     1203        if (startKeyframeIndex) {
    11911204            if (auto duration = iterationDuration()) {
    11921205                auto rangeDuration = (endOffset - startOffset) * duration.seconds();
  • trunk/Source/WebCore/animation/KeyframeEffect.h

    r251425 r251706  
    142142
    143143    enum class AcceleratedAction : uint8_t { Play, Pause, Seek, Stop };
     144    enum class BlendingKeyframesSource : uint8_t { CSSAnimation, CSSTransition, WebAnimation };
    144145
    145146    void copyPropertiesFromSource(Ref<KeyframeEffect>&&);
     
    152153    void computedNeedsForcedLayout();
    153154    void computeStackingContextImpact();
     155    void clearBlendingKeyframes();
    154156    void updateBlendingKeyframes(RenderStyle&);
    155157    void computeCSSAnimationBlendingKeyframes();
     
    171173
    172174    AcceleratedAction m_lastRecordedAcceleratedAction { AcceleratedAction::Stop };
     175    BlendingKeyframesSource m_blendingKeyframesSource { BlendingKeyframesSource::WebAnimation };
    173176    IterationCompositeOperation m_iterationCompositeOperation { IterationCompositeOperation::Replace };
    174177    CompositeOperation m_compositeOperation { CompositeOperation::Replace };
Note: See TracChangeset for help on using the changeset viewer.