Title: [261637] trunk
Revision
261637
Author
[email protected]
Date
2020-05-13 12:26:58 -0700 (Wed, 13 May 2020)

Log Message

[Web Animations] Calling reverse() on an accelerated animation has no effect
https://bugs.webkit.org/show_bug.cgi?id=204717
<rdar://problem/62503582>

Patch by Antoine Quint <[email protected]> on 2020-05-13
Reviewed by Dean Jackson.

Source/WebCore:

Test: webanimations/accelerated-animation-playback-rate.html

We completely ignored the playbackRate set on a WebAnimation object when considering whether we could run an accelerated animation.
To address this we do several things.

First, we now add a playbackRate() on Animation objects such that we can make GraphicsLayerCA aware of the originating WebAnimation's
playback rate and use this data to opt out of running CA animations for animations with a playbackRate other than 1 in
GraphicsLayerCA::animationCanBeAccelerated(). We'll be looking to add support for variable playback rates for CA animations in
https://bugs.webkit.org/show_bug.cgi?id=211839.

Then, we make sure to completely replace an accelerated animation whenever one of the properties affected timing would change. Up until
now we would onyl do this for a change in the effective currentTime, but this needs to also happen when the current time doesn't change
but the animation may have changed playback rate or any of its timing properties that could change the duration of the animation. So we
remove the "Seek" command and instead use an "UpdateTiming" command that will remove the existing animation and add a new one.

This allows us to remove any notion of seeking in GraphicsLayer since now we'll just create a new animation when its timing attributes
changed.

This revealed an issue where if we called animationFinished() and startAnimation() on a RenderLayerModelObject in succession, theanimation
removal would not occur on the GraphicsLayerCA because we disregarded any pending accelerated action for an animation we knew would be
replaced. We now ensure we honor the removal in GraphicsLayerCA::appendToUncommittedAnimations().

* animation/AnimationEffect.cpp:
(WebCore::AnimationEffect::updateTiming):
* animation/AnimationEffect.h:
* animation/CSSAnimation.cpp:
(WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):
* animation/KeyframeEffect.cpp:
(WebCore::KeyframeEffect::addPendingAcceleratedAction):
(WebCore::KeyframeEffect::animationDidChangeTimingProperties):
(WebCore::KeyframeEffect::applyPendingAcceleratedActions):
(WebCore::KeyframeEffect::backingAnimationForCompositedRenderer const):
(WebCore::KeyframeEffect::animationDidSeek): Deleted.
* animation/KeyframeEffect.h:
* animation/WebAnimation.cpp:
(WebCore::WebAnimation::effectTimingDidChange):
(WebCore::WebAnimation::setCurrentTime):
(WebCore::WebAnimation::setPlaybackRate):
(WebCore::WebAnimation::updatePlaybackRate):
(WebCore::WebAnimation::reverse):
* animation/WebAnimation.h:
* platform/animation/Animation.h:
(WebCore::Animation::playbackRate const):
(WebCore::Animation::setPlaybackRate):
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::pauseAnimation):
(WebCore::GraphicsLayer::seekAnimation): Deleted.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::animationCanBeAccelerated const):
(WebCore::GraphicsLayerCA::updateAnimations):
(WebCore::GraphicsLayerCA::pauseCAAnimationOnLayer):
(WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes):
(WebCore::GraphicsLayerCA::seekAnimation): Deleted.
(WebCore::GraphicsLayerCA::seekCAAnimationOnLayer): Deleted.
* platform/graphics/ca/GraphicsLayerCA.h:
* rendering/RenderElement.h:
(WebCore::RenderElement::animationPaused):
(WebCore::RenderElement::animationSeeked): Deleted.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::animationSeeked): Deleted.
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerModelObject.cpp:
(WebCore::RenderLayerModelObject::animationSeeked): Deleted.
* rendering/RenderLayerModelObject.h:

LayoutTests:

Add a test where we play an animation for an accelerated property in reverse.

* webanimations/accelerated-animation-playback-rate-expected.html: Added.
* webanimations/accelerated-animation-playback-rate.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (261636 => 261637)


--- trunk/LayoutTests/ChangeLog	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/LayoutTests/ChangeLog	2020-05-13 19:26:58 UTC (rev 261637)
@@ -1,3 +1,16 @@
+2020-05-13  Antoine Quint  <[email protected]>
+
+        [Web Animations] Calling reverse() on an accelerated animation has no effect
+        https://bugs.webkit.org/show_bug.cgi?id=204717
+        <rdar://problem/62503582>
+
+        Reviewed by Dean Jackson.
+
+        Add a test where we play an animation for an accelerated property in reverse.
+
+        * webanimations/accelerated-animation-playback-rate-expected.html: Added.
+        * webanimations/accelerated-animation-playback-rate.html: Added.
+
 2020-05-13  Simon Fraser  <[email protected]>
 
         composited scrolling interferes with the propagation of perspective

Added: trunk/LayoutTests/webanimations/accelerated-animation-playback-rate-expected.html (0 => 261637)


--- trunk/LayoutTests/webanimations/accelerated-animation-playback-rate-expected.html	                        (rev 0)
+++ trunk/LayoutTests/webanimations/accelerated-animation-playback-rate-expected.html	2020-05-13 19:26:58 UTC (rev 261637)
@@ -0,0 +1 @@
+<body style="background-color: green"></body>

Added: trunk/LayoutTests/webanimations/accelerated-animation-playback-rate.html (0 => 261637)


--- trunk/LayoutTests/webanimations/accelerated-animation-playback-rate.html	                        (rev 0)
+++ trunk/LayoutTests/webanimations/accelerated-animation-playback-rate.html	2020-05-13 19:26:58 UTC (rev 261637)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<body>
+<style>
+    body, #cover {
+        background-color: green;
+    }
+
+    #target, #cover {
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100px;
+    }
+
+    #target {
+        width: 100px;
+        background-color: red;
+    }
+
+    /* This element covers the first half of the area traveled by the animated target. If the animation did not
+       respect the playbackRate, then red would appear since the animated target would travel to the right of
+       the cover element. */
+    #cover {
+        left: 100px;
+        width: 200px;
+    }
+
+</style>
+<div id="target"></div>
+<div id="cover"></div>
+<script>
+
+(async () => {
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    // Start an animation.
+    const animation = document.getElementById("target").animate({ transform: ["translateX(100px)", "translateX(300px)"] }, { duration: 1000, fill: "both" });
+
+    // Seek it to its halfway point, the target should align with the right edge of the cover.
+    animation.currentTime = animation.effect.getTiming().duration / 2;
+
+    // Make it play backwards.
+    animation.playbackRate = -1;
+
+    // Wait a few frames.
+    await animation.ready;
+    await new Promise(requestAnimationFrame);
+    await new Promise(requestAnimationFrame);
+    await new Promise(requestAnimationFrame);
+
+    // At this point, if the target were ignoring the playbackRate, it would peek a little to the right of the cover.
+    if (window.testRunner)
+        testRunner.notifyDone();
+})();
+
+</script>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (261636 => 261637)


--- trunk/Source/WebCore/ChangeLog	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/ChangeLog	2020-05-13 19:26:58 UTC (rev 261637)
@@ -1,3 +1,76 @@
+2020-05-13  Antoine Quint  <[email protected]>
+
+        [Web Animations] Calling reverse() on an accelerated animation has no effect
+        https://bugs.webkit.org/show_bug.cgi?id=204717
+        <rdar://problem/62503582>
+
+        Reviewed by Dean Jackson.
+
+        Test: webanimations/accelerated-animation-playback-rate.html
+
+        We completely ignored the playbackRate set on a WebAnimation object when considering whether we could run an accelerated animation.
+        To address this we do several things.
+
+        First, we now add a playbackRate() on Animation objects such that we can make GraphicsLayerCA aware of the originating WebAnimation's
+        playback rate and use this data to opt out of running CA animations for animations with a playbackRate other than 1 in
+        GraphicsLayerCA::animationCanBeAccelerated(). We'll be looking to add support for variable playback rates for CA animations in
+        https://bugs.webkit.org/show_bug.cgi?id=211839.
+
+        Then, we make sure to completely replace an accelerated animation whenever one of the properties affected timing would change. Up until
+        now we would onyl do this for a change in the effective currentTime, but this needs to also happen when the current time doesn't change
+        but the animation may have changed playback rate or any of its timing properties that could change the duration of the animation. So we
+        remove the "Seek" command and instead use an "UpdateTiming" command that will remove the existing animation and add a new one.
+
+        This allows us to remove any notion of seeking in GraphicsLayer since now we'll just create a new animation when its timing attributes
+        changed.
+
+        This revealed an issue where if we called animationFinished() and startAnimation() on a RenderLayerModelObject in succession, theanimation
+        removal would not occur on the GraphicsLayerCA because we disregarded any pending accelerated action for an animation we knew would be
+        replaced. We now ensure we honor the removal in GraphicsLayerCA::appendToUncommittedAnimations().
+
+        * animation/AnimationEffect.cpp:
+        (WebCore::AnimationEffect::updateTiming):
+        * animation/AnimationEffect.h:
+        * animation/CSSAnimation.cpp:
+        (WebCore::CSSAnimation::syncPropertiesWithBackingAnimation):
+        * animation/KeyframeEffect.cpp:
+        (WebCore::KeyframeEffect::addPendingAcceleratedAction):
+        (WebCore::KeyframeEffect::animationDidChangeTimingProperties):
+        (WebCore::KeyframeEffect::applyPendingAcceleratedActions):
+        (WebCore::KeyframeEffect::backingAnimationForCompositedRenderer const):
+        (WebCore::KeyframeEffect::animationDidSeek): Deleted.
+        * animation/KeyframeEffect.h:
+        * animation/WebAnimation.cpp:
+        (WebCore::WebAnimation::effectTimingDidChange):
+        (WebCore::WebAnimation::setCurrentTime):
+        (WebCore::WebAnimation::setPlaybackRate):
+        (WebCore::WebAnimation::updatePlaybackRate):
+        (WebCore::WebAnimation::reverse):
+        * animation/WebAnimation.h:
+        * platform/animation/Animation.h:
+        (WebCore::Animation::playbackRate const):
+        (WebCore::Animation::setPlaybackRate):
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::pauseAnimation):
+        (WebCore::GraphicsLayer::seekAnimation): Deleted.
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::animationCanBeAccelerated const):
+        (WebCore::GraphicsLayerCA::updateAnimations):
+        (WebCore::GraphicsLayerCA::pauseCAAnimationOnLayer):
+        (WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes):
+        (WebCore::GraphicsLayerCA::seekAnimation): Deleted.
+        (WebCore::GraphicsLayerCA::seekCAAnimationOnLayer): Deleted.
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        * rendering/RenderElement.h:
+        (WebCore::RenderElement::animationPaused):
+        (WebCore::RenderElement::animationSeeked): Deleted.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::animationSeeked): Deleted.
+        * rendering/RenderLayerBacking.h:
+        * rendering/RenderLayerModelObject.cpp:
+        (WebCore::RenderLayerModelObject::animationSeeked): Deleted.
+        * rendering/RenderLayerModelObject.h:
+
 2020-05-13  Antti Koivisto  <[email protected]>
 
         [Wheel event region] Debug overlay

Modified: trunk/Source/WebCore/animation/AnimationEffect.cpp (261636 => 261637)


--- trunk/Source/WebCore/animation/AnimationEffect.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/AnimationEffect.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -369,10 +369,6 @@
     if (!timing)
         return { };
 
-    Optional<ComputedEffectTiming> previousTiming;
-    if (m_animation)
-        previousTiming = getComputedTiming();
-
     // 1. If the iterationStart member of input is present and less than zero, throw a TypeError and abort this procedure.
     if (timing->iterationStart) {
         if (timing->iterationStart.value() < 0)
@@ -441,7 +437,7 @@
     updateStaticTimingProperties();
 
     if (m_animation)
-        m_animation->effectTimingDidChange(previousTiming);
+        m_animation->effectTimingDidChange();
 
     return { };
 }

Modified: trunk/Source/WebCore/animation/AnimationEffect.h (261636 => 261637)


--- trunk/Source/WebCore/animation/AnimationEffect.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/AnimationEffect.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -65,7 +65,7 @@
     virtual void invalidate() = 0;
     virtual void animationDidTick() = 0;
     virtual void animationDidPlay() = 0;
-    virtual void animationDidSeek() = 0;
+    virtual void animationDidChangeTimingProperties() = 0;
     virtual void animationWasCanceled() = 0;
     virtual void animationSuspensionStateDidChange(bool) = 0;
     virtual void animationTimelineDidChange(AnimationTimeline*) = 0;

Modified: trunk/Source/WebCore/animation/CSSAnimation.cpp (261636 => 261637)


--- trunk/Source/WebCore/animation/CSSAnimation.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/CSSAnimation.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -65,8 +65,6 @@
     auto& animation = backingAnimation();
     auto* animationEffect = effect();
 
-    auto previousTiming = animationEffect->getComputedTiming();
-
     if (!m_overriddenProperties.contains(Property::FillMode)) {
         switch (animation.fillMode()) {
         case AnimationFillMode::None:
@@ -113,7 +111,7 @@
         animationEffect->setIterationDuration(Seconds(animation.duration()));
 
     animationEffect->updateStaticTimingProperties();
-    effectTimingDidChange(previousTiming);
+    effectTimingDidChange();
 
     // Synchronize the play state
     if (!m_overriddenProperties.contains(Property::PlayState)) {

Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (261636 => 261637)


--- trunk/Source/WebCore/animation/KeyframeEffect.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -1508,7 +1508,7 @@
     if (action == AcceleratedAction::Stop)
         m_pendingAcceleratedActions.clear();
     m_pendingAcceleratedActions.append(action);
-    if (action != AcceleratedAction::Seek)
+    if (action != AcceleratedAction::UpdateTiming)
         m_lastRecordedAcceleratedAction = action;
     animation()->acceleratedStateDidChange();
 }
@@ -1525,12 +1525,12 @@
         addPendingAcceleratedAction(AcceleratedAction::Play);
 }
 
-void KeyframeEffect::animationDidSeek()
+void KeyframeEffect::animationDidChangeTimingProperties()
 {
-    // There is no need to seek if we're not playing an animation already. If seeking
+    // There is no need to update the animation if we're not playing already. If updating timing
     // means we're moving into an active lexicalGlobalObject, we'll pick this up in apply().
     if (m_isRunningAccelerated || isAboutToRunAccelerated())
-        addPendingAcceleratedAction(AcceleratedAction::Seek);
+        addPendingAcceleratedAction(AcceleratedAction::UpdateTiming);
 }
 
 void KeyframeEffect::animationWasCanceled()
@@ -1581,6 +1581,7 @@
     for (const auto& action : pendingAcceleratedActions) {
         switch (action) {
         case AcceleratedAction::Play:
+            renderer->animationFinished(m_blendingKeyframes.animationName());
             m_isRunningAccelerated = renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), m_blendingKeyframes);
             if (!m_isRunningAccelerated) {
                 m_lastRecordedAcceleratedAction = AcceleratedAction::Stop;
@@ -1590,8 +1591,11 @@
         case AcceleratedAction::Pause:
             renderer->animationPaused(timeOffset, m_blendingKeyframes.animationName());
             break;
-        case AcceleratedAction::Seek:
-            renderer->animationSeeked(timeOffset, m_blendingKeyframes.animationName());
+        case AcceleratedAction::UpdateTiming:
+            renderer->animationFinished(m_blendingKeyframes.animationName());
+            renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), m_blendingKeyframes);
+            if (animation()->playState() == WebAnimation::PlayState::Paused)
+                renderer->animationPaused(timeOffset, m_blendingKeyframes.animationName());
             break;
         case AcceleratedAction::Stop:
             ASSERT(document());
@@ -1617,6 +1621,7 @@
     animation->setDelay(delay().seconds());
     animation->setIterationCount(iterations());
     animation->setTimingFunction(timingFunction()->clone());
+    animation->setPlaybackRate(effectAnimation->playbackRate());
 
     switch (fill()) {
     case FillMode::None:

Modified: trunk/Source/WebCore/animation/KeyframeEffect.h (261636 => 261637)


--- trunk/Source/WebCore/animation/KeyframeEffect.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/KeyframeEffect.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -124,7 +124,7 @@
     void invalidate() override;
     void animationDidTick() final;
     void animationDidPlay() final;
-    void animationDidSeek() final;
+    void animationDidChangeTimingProperties() final;
     void animationWasCanceled() final;
     void animationSuspensionStateDidChange(bool) final;
     void animationTimelineDidChange(AnimationTimeline*) final;
@@ -169,7 +169,7 @@
 private:
     KeyframeEffect(Element*, PseudoId);
 
-    enum class AcceleratedAction : uint8_t { Play, Pause, Seek, Stop };
+    enum class AcceleratedAction : uint8_t { Play, Pause, UpdateTiming, Stop };
     enum class BlendingKeyframesSource : uint8_t { CSSAnimation, CSSTransition, WebAnimation };
     enum class AcceleratedProperties : uint8_t { None, Some, All };
 

Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (261636 => 261637)


--- trunk/Source/WebCore/animation/WebAnimation.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -134,16 +134,12 @@
     --m_suspendCount;
 }
 
-void WebAnimation::effectTimingDidChange(Optional<ComputedEffectTiming> previousTiming)
+void WebAnimation::effectTimingDidChange()
 {
     timingDidChange(DidSeek::No, SynchronouslyNotify::Yes);
 
-    if (previousTiming) {
-        auto* effect = this->effect();
-        ASSERT(effect);
-        if (previousTiming->progress != effect->getComputedTiming().progress)
-            effect->animationDidSeek();
-    }
+    if (m_effect)
+        m_effect->animationDidChangeTimingProperties();
 
     InspectorInstrumentation::didChangeWebAnimationEffectTiming(*this);
 }
@@ -477,7 +473,7 @@
     timingDidChange(DidSeek::Yes, SynchronouslyNotify::No);
 
     if (m_effect)
-        m_effect->animationDidSeek();
+        m_effect->animationDidChangeTimingProperties();
 
     invalidateEffect();
 
@@ -508,6 +504,9 @@
     // 4. If previous time is resolved, set the current time of animation to previous time.
     if (previousTime)
         setCurrentTime(previousTime);
+
+    if (m_effect)
+        m_effect->animationDidChangeTimingProperties();
 }
 
 void WebAnimation::updatePlaybackRate(double newPlaybackRate)
@@ -560,6 +559,9 @@
         // Run the procedure to play an animation for animation with the auto-rewind flag set to false.
         play(AutoRewind::No);
     }
+
+    if (m_effect)
+        m_effect->animationDidChangeTimingProperties();
 }
 
 void WebAnimation::applyPendingPlaybackRate()
@@ -1152,6 +1154,9 @@
         return playResult.releaseException();
     }
 
+    if (m_effect)
+        m_effect->animationDidChangeTimingProperties();
+
     return { };
 }
 

Modified: trunk/Source/WebCore/animation/WebAnimation.h (261636 => 261637)


--- trunk/Source/WebCore/animation/WebAnimation.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/animation/WebAnimation.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -26,7 +26,6 @@
 #pragma once
 
 #include "ActiveDOMObject.h"
-#include "ComputedEffectTiming.h"
 #include "EventTarget.h"
 #include "ExceptionOr.h"
 #include "IDLTypes.h"
@@ -132,7 +131,7 @@
     bool isCompletelyAccelerated() const;
     bool isRelevant() const { return m_isRelevant; }
     void updateRelevance();
-    void effectTimingDidChange(Optional<ComputedEffectTiming> = WTF::nullopt);
+    void effectTimingDidChange();
     void suspendEffectInvalidation();
     void unsuspendEffectInvalidation();
     void setSuspended(bool);

Modified: trunk/Source/WebCore/platform/animation/Animation.h (261636 => 261637)


--- trunk/Source/WebCore/platform/animation/Animation.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/platform/animation/Animation.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -117,6 +117,7 @@
     AnimationFillMode fillMode() const { return static_cast<AnimationFillMode>(m_fillMode); }
 
     double duration() const { return m_duration; }
+    double playbackRate() const { return m_playbackRate; }
 
     enum { IterationCountInfinite = -1 };
     double iterationCount() const { return m_iterationCount; }
@@ -130,6 +131,7 @@
     void setDelay(double c) { m_delay = c; m_delaySet = true; }
     void setDirection(AnimationDirection d) { m_direction = d; m_directionSet = true; }
     void setDuration(double d) { ASSERT(d >= 0); m_duration = d; m_durationSet = true; }
+    void setPlaybackRate(double d) { m_playbackRate = d; }
     void setFillMode(AnimationFillMode f) { m_fillMode = static_cast<unsigned>(f); m_fillModeSet = true; }
     void setIterationCount(double c) { m_iterationCount = c; m_iterationCountSet = true; }
     void setName(const String& name, Style::ScopeOrdinal scope = Style::ScopeOrdinal::Element)
@@ -169,6 +171,7 @@
     double m_iterationCount;
     double m_delay;
     double m_duration;
+    double m_playbackRate { 1 };
     RefPtr<TimingFunction> m_timingFunction;
 
     Style::ScopeOrdinal m_nameStyleScopeOrdinal { Style::ScopeOrdinal::Element };

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (261636 => 261637)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -478,7 +478,6 @@
     // These methods handle both transitions and keyframe animations.
     virtual bool addAnimation(const KeyframeValueList&, const FloatSize& /*boxSize*/, const Animation*, const String& /*animationName*/, double /*timeOffset*/)  { return false; }
     virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { }
-    virtual void seekAnimation(const String& /*animationName*/, double /*timeOffset*/) { }
     virtual void removeAnimation(const String& /*animationName*/) { }
 
     WEBCORE_EXPORT virtual void suspendAnimations(MonotonicTime);

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (261636 => 261637)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -1029,6 +1029,9 @@
 
 bool GraphicsLayerCA::animationCanBeAccelerated(const KeyframeValueList& valueList, const Animation* anim) const
 {
+    if (anim->playbackRate() != 1)
+        return false;
+
     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
         return false;
 
@@ -1093,16 +1096,6 @@
     noteLayerPropertyChanged(AnimationChanged);
 }
 
-void GraphicsLayerCA::seekAnimation(const String& animationName, double timeOffset)
-{
-    LOG_WITH_STREAM(Animations, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " seekAnimation " << animationName << " to " << timeOffset << " (is running " << animationIsRunning(animationName) << ")");
-
-    // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
-    addProcessingActionForAnimation(animationName, AnimationProcessingAction { Seek, Seconds { timeOffset } });
-
-    noteLayerPropertyChanged(AnimationChanged);
-}
-
 void GraphicsLayerCA::removeAnimation(const String& animationName)
 {
     LOG_WITH_STREAM(Animations, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " removeAnimation " << animationName << " (is running " << animationIsRunning(animationName) << ")");
@@ -2921,9 +2914,6 @@
                     case Pause:
                         pauseCAAnimationOnLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex, processingInfo.timeOffset);
                         break;
-                    case Seek:
-                        seekCAAnimationOnLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex, processingInfo.timeOffset);
-                        break;
                     }
                 }
 
@@ -3036,37 +3026,7 @@
 
     newAnim->setSpeed(0);
     newAnim->setTimeOffset(timeOffset.seconds());
-    
-    layer->addAnimationForKey(animationID, *newAnim); // This will replace the running animation.
 
-    // Pause the animations on the clones too.
-    if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
-        for (auto& clone : *layerCloneMap) {
-            // Skip immediate replicas, since they move with the original.
-            if (m_replicaLayer && isReplicatedRootClone(clone.key))
-                continue;
-            clone.value->addAnimationForKey(animationID, *newAnim);
-        }
-    }
-}
-
-void GraphicsLayerCA::seekCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
-{
-    // FIXME: this can be refactored a fair bit or merged with pauseCAAnimationOnLayer() with an operation flag.
-    PlatformCALayer* layer = animatedLayer(property);
-
-    String animationID = animationIdentifier(animationName, property, index, subIndex);
-
-    RefPtr<PlatformCAAnimation> currentAnimation = layer->animationForKey(animationID);
-    if (!currentAnimation)
-        return;
-
-    // Animations on the layer are immutable, so we have to clone and modify.
-    RefPtr<PlatformCAAnimation> newAnim = currentAnimation->copy();
-
-    newAnim->setBeginTime(CACurrentMediaTime());
-    newAnim->setTimeOffset(timeOffset.seconds());
-
     layer->addAnimationForKey(animationID, *newAnim); // This will replace the running animation.
 
     // Pause the animations on the clones too.
@@ -3232,8 +3192,24 @@
     ensureLayerAnimations();
 
     // Since we're adding a new animation, make sure we clear any pending AnimationProcessingAction for this animation
-    // as these are applied after we've committed new animations.
-    m_animations->animationsToProcess.remove(animation.m_name);
+    // as these are applied after we've committed new animations. However, we want to check if we had a pending removal
+    // such that removing an animation prior to adding a new one for the same name works.
+    auto processingInfoIterator = m_animations->animationsToProcess.find(animation.m_name);
+    if (processingInfoIterator != m_animations->animationsToProcess.end()) {
+        auto animationIterator = m_animations->runningAnimations.find(animation.m_name);
+        if (animationIterator != m_animations->runningAnimations.end()) {
+            auto& animations = animationIterator->value;
+            for (const auto& processingInfo : processingInfoIterator->value) {
+                if (processingInfo.action == Remove) {
+                    for (const auto& currentAnimation : animations)
+                        removeCAAnimationFromLayer(currentAnimation.m_property, animation.m_name, currentAnimation.m_index, currentAnimation.m_subIndex);
+                    m_animations->runningAnimations.remove(animationIterator);
+                    break;
+                }
+            }
+        }
+        m_animations->animationsToProcess.remove(processingInfoIterator);
+    }
 
     m_animations->uncomittedAnimations.append(WTFMove(animation));
 }

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (261636 => 261637)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -136,7 +136,6 @@
 
     WEBCORE_EXPORT bool addAnimation(const KeyframeValueList&, const FloatSize& boxSize, const Animation*, const String& animationName, double timeOffset) override;
     WEBCORE_EXPORT void pauseAnimation(const String& animationName, double timeOffset) override;
-    WEBCORE_EXPORT void seekAnimation(const String& animationName, double timeOffset) override;
     WEBCORE_EXPORT void removeAnimation(const String& animationName) override;
 
     WEBCORE_EXPORT void setContentsToImage(Image*) override;
@@ -461,7 +460,6 @@
     void setAnimationOnLayer(PlatformCAAnimation&, AnimatedPropertyID, const String& animationName, int index, int subIndex, Seconds timeOffset);
     bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index, int subINdex);
     void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, int subIndex, Seconds timeOffset);
-    void seekCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, int subIndex, Seconds timeOffset);
 
     enum MoveOrCopy { Move, Copy };
     static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer);
@@ -563,7 +561,7 @@
 
     void repaintLayerDirtyRects();
 
-    enum Action { Remove, Pause, Seek };
+    enum Action { Remove, Pause };
     struct AnimationProcessingAction {
         AnimationProcessingAction(Action action = "" Seconds timeOffset = 0_s)
             : action(action)

Modified: trunk/Source/WebCore/rendering/RenderElement.h (261636 => 261637)


--- trunk/Source/WebCore/rendering/RenderElement.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/rendering/RenderElement.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -232,7 +232,6 @@
 
     virtual bool startAnimation(double /* timeOffset */, const Animation&, const KeyframeList&) { return false; }
     virtual void animationPaused(double /* timeOffset */, const String& /* name */) { }
-    virtual void animationSeeked(double /* timeOffset */, const String& /* name */) { }
     virtual void animationFinished(const String& /* name */) { }
 
     virtual void suspendAnimations(MonotonicTime = MonotonicTime()) { }

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (261636 => 261637)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -3497,11 +3497,6 @@
     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
 }
 
-void RenderLayerBacking::animationSeeked(double timeOffset, const String& animationName)
-{
-    m_graphicsLayer->seekAnimation(animationName, timeOffset);
-}
-
 void RenderLayerBacking::animationFinished(const String& animationName)
 {
     m_graphicsLayer->removeAnimation(animationName);

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (261636 => 261637)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -188,7 +188,6 @@
 
     bool startAnimation(double timeOffset, const Animation&, const KeyframeList&);
     void animationPaused(double timeOffset, const String& name);
-    void animationSeeked(double timeOffset, const String& name);
     void animationFinished(const String& name);
 
     void suspendAnimations(MonotonicTime = MonotonicTime());

Modified: trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp (261636 => 261637)


--- trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp	2020-05-13 19:26:58 UTC (rev 261637)
@@ -318,13 +318,6 @@
     layer()->backing()->animationPaused(timeOffset, name);
 }
 
-void RenderLayerModelObject::animationSeeked(double timeOffset, const String& name)
-{
-    if (!layer() || !layer()->backing())
-        return;
-    layer()->backing()->animationSeeked(timeOffset, name);
-}
-
 void RenderLayerModelObject::animationFinished(const String& name)
 {
     if (!layer() || !layer()->backing())

Modified: trunk/Source/WebCore/rendering/RenderLayerModelObject.h (261636 => 261637)


--- trunk/Source/WebCore/rendering/RenderLayerModelObject.h	2020-05-13 19:24:01 UTC (rev 261636)
+++ trunk/Source/WebCore/rendering/RenderLayerModelObject.h	2020-05-13 19:26:58 UTC (rev 261637)
@@ -75,7 +75,6 @@
 
     bool startAnimation(double timeOffset, const Animation&, const KeyframeList&) override;
     void animationPaused(double timeOffset, const String& name) override;
-    void animationSeeked(double timeOffset, const String& name) override;
     void animationFinished(const String& name) override;
 
     void suspendAnimations(MonotonicTime = MonotonicTime()) override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to