Changeset 263506 in webkit


Ignore:
Timestamp:
Jun 25, 2020 6:42:02 AM (4 years ago)
Author:
graouts@webkit.org
Message:

REGRESSION (r260360): easing curves are broken on JS-originated animations
https://bugs.webkit.org/show_bug.cgi?id=213495
<rdar://problem/64649747>

Reviewed by Darin Adler.

Source/WebCore:

Prior to Web Animations, there was no way for an animation to set an animation-wide timing function while
also setting a per-keyframe timing function. As such GraphicsLayerCA would sometimes decide to set the
timing function on keyframes or on the entire CAAnimation. However, we can no longer do this with Web
Animations where an animation can set an animation-wide timing function and also keyframe-specific
timing functions.

In this patch we create CAKeyframeAnimation objects for any animation that has at least two keyframes
if Web Animations are enabled, whereas the legacy code path requires at least three keyframes. We allow
PlatformCAAnimation::setTimingFunction() to be called in the Web Animations code path only under
GraphicsLayerCA::setupAnimation() while leaving the only call sites in place only for the legacy code
path.

Finally, we modify GraphicsLayerCA::timingFunctionForAnimationValue() to only ever return a keyframe-
specific timing function or fall back to a default linear timing function in the Web Animations code
path, leaving the function to behave the same way as it used to in the legacy code path.

Test: webanimations/accelerated-animation-with-easing.html

  • platform/animation/TimingFunction.h:
  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::isKeyframe):
(WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
(WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
(WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes):

LayoutTests:

Add a new test that checks that various ways of setting the easing timing function on a JS-originated
animation always yield the same visible animation behavior.

  • webanimations/accelerated-animation-with-easing-expected.html: Added.
  • webanimations/accelerated-animation-with-easing.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r263502 r263506  
     12020-06-25  Antoine Quint  <graouts@webkit.org>
     2
     3        REGRESSION (r260360): easing curves are broken on JS-originated animations
     4        https://bugs.webkit.org/show_bug.cgi?id=213495
     5        <rdar://problem/64649747>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add a new test that checks that various ways of setting the easing timing function on a JS-originated
     10        animation always yield the same visible animation behavior.
     11
     12        * webanimations/accelerated-animation-with-easing-expected.html: Added.
     13        * webanimations/accelerated-animation-with-easing.html: Added.
     14
    1152020-06-24  Sergio Villar Senin  <svillar@igalia.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r263505 r263506  
     12020-06-25  Antoine Quint  <graouts@webkit.org>
     2
     3        REGRESSION (r260360): easing curves are broken on JS-originated animations
     4        https://bugs.webkit.org/show_bug.cgi?id=213495
     5        <rdar://problem/64649747>
     6
     7        Reviewed by Darin Adler.
     8
     9        Prior to Web Animations, there was no way for an animation to set an animation-wide timing function while
     10        also setting a per-keyframe timing function. As such GraphicsLayerCA would sometimes decide to set the
     11        timing function on keyframes or on the entire CAAnimation. However, we can no longer do this with Web
     12        Animations where an animation can set an animation-wide timing function and also keyframe-specific
     13        timing functions.
     14
     15        In this patch we create CAKeyframeAnimation objects for any animation that has at least two keyframes
     16        if Web Animations are enabled, whereas the legacy code path requires at least three keyframes. We allow
     17        PlatformCAAnimation::setTimingFunction() to be called in the Web Animations code path only under
     18        GraphicsLayerCA::setupAnimation() while leaving the only call sites in place only for the legacy code
     19        path.
     20
     21        Finally, we modify GraphicsLayerCA::timingFunctionForAnimationValue() to only ever return a keyframe-
     22        specific timing function or fall back to a default linear timing function in the Web Animations code
     23        path, leaving the function to behave the same way as it used to in the legacy code path.
     24
     25        Test: webanimations/accelerated-animation-with-easing.html
     26
     27        * platform/animation/TimingFunction.h:
     28        * platform/graphics/ca/GraphicsLayerCA.cpp:
     29        (WebCore::isKeyframe):
     30        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
     31        (WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
     32        (WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes):
     33
    1342020-06-25  Sergio Villar Senin  <svillar@igalia.com>
    235
  • trunk/Source/WebCore/platform/animation/TimingFunction.h

    r262933 r263506  
    8181    }
    8282
     83    static const LinearTimingFunction& sharedLinearTimingFunction()
     84    {
     85        static const LinearTimingFunction& function = create().leakRef();
     86        return function;
     87    }
     88
    8389private:
    8490    LinearTimingFunction()
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r263481 r263506  
    4242#include "Region.h"
    4343#include "RotateTransformOperation.h"
     44#include "RuntimeEnabledFeatures.h"
    4445#include "ScaleTransformOperation.h"
    4546#include "TiledBacking.h"
     
    30743075}
    30753076
     3077static bool isKeyframe(const KeyframeValueList& list)
     3078{
     3079    if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
     3080        return list.size() > 1;
     3081    return list.size() > 2;
     3082}
     3083
    30763084bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset)
    30773085{
    30783086    ASSERT(valueList.property() != AnimatedPropertyTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyFilter));
    30793087
    3080     bool isKeyframe = valueList.size() > 2;
    30813088    bool valuesOK;
    30823089   
     
    30863093    RefPtr<PlatformCAAnimation> caAnimation;
    30873094
    3088     if (isKeyframe) {
     3095    if (isKeyframe(valueList)) {
    30893096        caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
    30903097        valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
     
    31143121    bool additive = animationIndex < numAnimations - 1;
    31153122#endif
    3116     bool isKeyframe = valueList.size() > 2;
    31173123
    31183124    RefPtr<PlatformCAAnimation> caAnimation;
    31193125    bool validMatrices = true;
    3120     if (isKeyframe) {
     3126    if (isKeyframe(valueList)) {
    31213127        caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
    31223128        validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
     
    31673173bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, Seconds timeOffset)
    31683174{
    3169     bool isKeyframe = valueList.size() > 2;
    3170    
    31713175    FilterOperation::OperationType filterOp = operation->type();
    31723176    int numAnimatedProperties = PlatformCAFilters::numAnimatedFilterProperties(filterOp);
     
    31843188        String keyPath = makeString("filters.filter_", animationIndex, '.', PlatformCAFilters::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
    31853189       
    3186         if (isKeyframe) {
     3190        if (isKeyframe(valueList)) {
    31873191            caAnimation = createKeyframeAnimation(animation, keyPath, false);
    31883192            valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
     
    33253329    propertyAnim->setAdditive(additive);
    33263330    propertyAnim->setFillMode(fillMode);
     3331
     3332    if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
     3333        propertyAnim->setTimingFunction(anim->timingFunction());
    33273334}
    33283335
    33293336const TimingFunction& GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue& animValue, const Animation& anim)
    33303337{
     3338    if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
     3339        if (animValue.timingFunction())
     3340            return *animValue.timingFunction();
     3341        return LinearTimingFunction::sharedLinearTimingFunction();
     3342    }
     3343
    33313344    if (animValue.timingFunction())
    33323345        return *animValue.timingFunction();
     
    33563369    // This codepath is used for 2-keyframe animations, so we still need to look in the start
    33573370    // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
    3358     basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
     3371    if (!RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
     3372        basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
    33593373
    33603374    return true;
     
    34493463    // This codepath is used for 2-keyframe animations, so we still need to look in the start
    34503464    // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
    3451     basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
     3465    if (!RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
     3466        basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
    34523467
    34533468    auto valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
     
    35593574    // This codepath is used for 2-keyframe animations, so we still need to look in the start
    35603575    // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
    3561     basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
     3576    if (!RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
     3577        basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
    35623578
    35633579    return true;
Note: See TracChangeset for help on using the changeset viewer.