Title: [230574] trunk
Revision
230574
Author
grao...@webkit.org
Date
2018-04-12 08:14:31 -0700 (Thu, 12 Apr 2018)

Log Message

[Web Animations] Enable seeking for hardware animations
https://bugs.webkit.org/show_bug.cgi?id=184518

Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

Track a small regression in the Web Animations WPT tests.

* web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt:

Source/WebCore:

Hardware animations had lagged behind software animations in support and this patch bring their respective level
of support closer to one another. Importantly, we add the ability to seek an animation added to a GraphicsLayerCA
since many tests pause and seek animations to test their state. Animations may also have their playback state changed
along with their current time in the same run loop, so we now maintain a list of pending processing actions for
hardware animations.

* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::updateAnimationSchedule): If we have animations queued up for updates to their accelerated
state we can schedule animation resolution immediately since we've already established we'll have work to do.
(WebCore::DocumentTimeline::updateAnimations): Factor the updates of pending accelerated animations out in a dedicated
method.
(WebCore::DocumentTimeline::applyPendingAcceleratedAnimations): Go through all pending accelerated animations and update
their state.
* animation/KeyframeEffectReadOnly.cpp:
(WebCore::KeyframeEffectReadOnly::setBlendingKeyframes): Update the m_shouldRunAccelerated flag when setting blending keyframes.
(WebCore::KeyframeEffectReadOnly::apply): Ensure we finish accelerated animations if the progress is 1 or null (no longer active).
start accelerated animations if the animation is starting and always resolve styles in software as well to ensure that
hit testing will work as expected.
(WebCore::KeyframeEffectReadOnly::computeShouldRunAccelerated):
(WebCore::KeyframeEffectReadOnly::animationPlayStateDidChange): Called by WebAnimation when play() or pause() is called
with the appropriate flag.
(WebCore::KeyframeEffectReadOnly::animationDidSeek): Called by WebAnimation when the currentTime property is set.
(WebCore::KeyframeEffectReadOnly::addPendingAcceleratedAction): Add the provided action to the list of pending accelerated
actions and notify the animation that the accelerated state needs changing.
(WebCore::KeyframeEffectReadOnly::applyPendingAcceleratedActions): Called by DocumentTimeline, through WebAnimation, to apply
all pending accelerated actions.
(WebCore::KeyframeEffectReadOnly::backingAnimationForCompositedRenderer const): If we're dealing with a declarative animation,
we already have a backing Animation object, so use it directly. Otherwise, create one and ensure it reflects all timing properties
for the animation.
(WebCore::KeyframeEffectReadOnly::shouldRunAccelerated): Deleted.
(WebCore::KeyframeEffectReadOnly::startOrStopAccelerated): Deleted.
* animation/WebAnimation.cpp:
(WebCore::WebAnimation::setCurrentTime): Call animationDidSeek() on the effect to ensure its accelerated animation gets seeked.
(WebCore::WebAnimation::play): Call animationPlayStateDidChange() on the effect to ensure its accelerated animation is started or resumed.
(WebCore::WebAnimation::pause): Call animationPlayStateDidChange() on the effect to ensure its accelerated animation gets paused.
(WebCore::WebAnimation::acceleratedStateDidChange):
(WebCore::WebAnimation::applyPendingAcceleratedActions):
(WebCore::WebAnimation::acceleratedRunningStateDidChange): Deleted.
(WebCore::WebAnimation::startOrStopAccelerated): Deleted.
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::seekAnimation):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::addProcessingActionForAnimation): Add an AnimationProcessingAction to the list of such actions for a
given animation name. In case we already have a Remove action, we ignore the action since the hardware animation will have been
removed by the time we try to apply this processing action.
(WebCore::GraphicsLayerCA::pauseAnimation): Add a Pause processing action.
(WebCore::GraphicsLayerCA::seekAnimation): Add a Seek processing action.
(WebCore::GraphicsLayerCA::removeAnimation): Add a Remove processing action.
(WebCore::GraphicsLayerCA::updateAnimations): First ensure that all animations pending commit are committed and then update
all animations based on the actions added through addProcessingActionForAnimation().
(WebCore::GraphicsLayerCA::seekCAAnimationOnLayer): Generate a new animation based on the new seek time provided.
* platform/graphics/ca/GraphicsLayerCA.h:
(WebCore::GraphicsLayerCA::AnimationProcessingAction::AnimationProcessingAction):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::animationSeeked):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::animationSeeked):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingForAnimation const): Fix an issue where we would run the CSSAnimationController
logic even when the legacy animation engine was disabled.

LayoutTests:

Update current test expectations, some tests have regressed because they weren't probably running their hardware
animations. Followup patches will make them opt into CSS Animations and CSS Transitions as Web Animations again.

* animations/3d/transform-origin-vs-functions.html:
* animations/change-completed-animation-transform.html:
* animations/missing-values-first-keyframe.html:
* animations/missing-values-last-keyframe.html:
* animations/play-state-start-paused.html:
* compositing/contents-scale/animating.html:
* compositing/layer-creation/animation-overlap-with-children.html:
* compositing/overflow/overflow-positioning.html:
* compositing/visible-rect/animated.html:
* css3/filters/filter-animation-from-none-hw.html:
* css3/filters/filter-animation-from-none-multi-hw.html:
* css3/filters/filter-animation-from-none-multi.html:
* css3/filters/filter-animation-from-none.html:
* platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (230573 => 230574)


--- trunk/LayoutTests/ChangeLog	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/ChangeLog	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,3 +1,28 @@
+2018-04-11  Antoine Quint  <grao...@apple.com>
+
+        [Web Animations] Enable seeking for hardware animations
+        https://bugs.webkit.org/show_bug.cgi?id=184518
+
+        Reviewed by Dean Jackson.
+
+        Update current test expectations, some tests have regressed because they weren't probably running their hardware
+        animations. Followup patches will make them opt into CSS Animations and CSS Transitions as Web Animations again.
+
+        * animations/3d/transform-origin-vs-functions.html:
+        * animations/change-completed-animation-transform.html:
+        * animations/missing-values-first-keyframe.html:
+        * animations/missing-values-last-keyframe.html:
+        * animations/play-state-start-paused.html:
+        * compositing/contents-scale/animating.html:
+        * compositing/layer-creation/animation-overlap-with-children.html:
+        * compositing/overflow/overflow-positioning.html:
+        * compositing/visible-rect/animated.html:
+        * css3/filters/filter-animation-from-none-hw.html:
+        * css3/filters/filter-animation-from-none-multi-hw.html:
+        * css3/filters/filter-animation-from-none-multi.html:
+        * css3/filters/filter-animation-from-none.html:
+        * platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt:
+
 2018-04-12  Per Arne Vollan  <pvol...@apple.com>
 
         Skip the test fast/forms/file/entries-api/webkitEntries-nonascii-folder-name.html on Windows.

Modified: trunk/LayoutTests/animations/3d/transform-origin-vs-functions.html (230573 => 230574)


--- trunk/LayoutTests/animations/3d/transform-origin-vs-functions.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/animations/3d/transform-origin-vs-functions.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,5 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-  "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 <html>
   <head>
     <meta http-equiv="Content-type" content="text/html; charset=utf-8">

Modified: trunk/LayoutTests/animations/change-completed-animation-transform.html (230573 => 230574)


--- trunk/LayoutTests/animations/change-completed-animation-transform.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/animations/change-completed-animation-transform.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 <html>
 <head>
     <style>

Modified: trunk/LayoutTests/animations/missing-values-first-keyframe.html (230573 => 230574)


--- trunk/LayoutTests/animations/missing-values-first-keyframe.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/animations/missing-values-first-keyframe.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
   <style type="text/css" media="screen">

Modified: trunk/LayoutTests/animations/missing-values-last-keyframe.html (230573 => 230574)


--- trunk/LayoutTests/animations/missing-values-last-keyframe.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/animations/missing-values-last-keyframe.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
   <style type="text/css" media="screen">

Modified: trunk/LayoutTests/animations/play-state-start-paused.html (230573 => 230574)


--- trunk/LayoutTests/animations/play-state-start-paused.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/animations/play-state-start-paused.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 <html>
 <head>
     <style>

Modified: trunk/LayoutTests/compositing/contents-scale/animating.html (230573 => 230574)


--- trunk/LayoutTests/compositing/contents-scale/animating.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/compositing/contents-scale/animating.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 
 <html>
 <head>

Modified: trunk/LayoutTests/compositing/layer-creation/animation-overlap-with-children.html (230573 => 230574)


--- trunk/LayoutTests/compositing/layer-creation/animation-overlap-with-children.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/compositing/layer-creation/animation-overlap-with-children.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 
 <html>
 <head>

Modified: trunk/LayoutTests/compositing/overflow/overflow-positioning.html (230573 => 230574)


--- trunk/LayoutTests/compositing/overflow/overflow-positioning.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/compositing/overflow/overflow-positioning.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,5 +1,4 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-   "http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 
 <html lang="en">
 <head>

Modified: trunk/LayoutTests/compositing/visible-rect/animated.html (230573 => 230574)


--- trunk/LayoutTests/compositing/visible-rect/animated.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/compositing/visible-rect/animated.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
 
 <html>
 <head>

Modified: trunk/LayoutTests/css3/filters/filter-animation-from-none-hw.html (230573 => 230574)


--- trunk/LayoutTests/css3/filters/filter-animation-from-none-hw.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/css3/filters/filter-animation-from-none-hw.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
+<!DOCTYPE html>
 
 <html>
 <head>

Modified: trunk/LayoutTests/css3/filters/filter-animation-from-none-multi-hw.html (230573 => 230574)


--- trunk/LayoutTests/css3/filters/filter-animation-from-none-multi-hw.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/css3/filters/filter-animation-from-none-multi-hw.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
+<!DOCTYPE html>
 
 <html>
 <head>

Modified: trunk/LayoutTests/css3/filters/filter-animation-from-none-multi.html (230573 => 230574)


--- trunk/LayoutTests/css3/filters/filter-animation-from-none-multi.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/css3/filters/filter-animation-from-none-multi.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
+<!DOCTYPE html>
 
 <html>
 <head>

Modified: trunk/LayoutTests/css3/filters/filter-animation-from-none.html (230573 => 230574)


--- trunk/LayoutTests/css3/filters/filter-animation-from-none.html	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/css3/filters/filter-animation-from-none.html	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,4 +1,4 @@
-<!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] -->
+<!DOCTYPE html>
 
 <html>
 <head>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (230573 => 230574)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,3 +1,14 @@
+2018-04-11  Antoine Quint  <grao...@apple.com>
+
+        [Web Animations] Enable seeking for hardware animations
+        https://bugs.webkit.org/show_bug.cgi?id=184518
+
+        Reviewed by Dean Jackson.
+
+        Track a small regression in the Web Animations WPT tests.
+
+        * web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt:
+
 2018-04-11  Jianjun Zhu  <jianjun....@intel.com>
 
         Fix a WebRTC data channel issue for non-ASCII characters.

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt (230573 => 230574)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt	2018-04-12 15:14:31 UTC (rev 230574)
@@ -140,7 +140,7 @@
 FAIL filter: percentage or numeric-specifiable functions (number value) assert_equals: The value should be brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3) at 500ms expected "brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3)" but got "brightness(0.30000000000000004) contrast(0.30000000000000004) grayscale(0.30000000000000004) invert(0.30000000000000004) opacity(0.30000000000000004) saturate(0.30000000000000004) sepia(0.30000000000000004)"
 FAIL filter: percentage or numeric-specifiable functions (percentage value) assert_equals: The value should be brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3) at 500ms expected "brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3)" but got "brightness(0.30000000000000004) contrast(0.30000000000000004) grayscale(0.30000000000000004) invert(0.30000000000000004) opacity(0.30000000000000004) saturate(0.30000000000000004) sepia(0.30000000000000004)"
 FAIL filter: interpolate different length of filter-function-list with function which lacuna value is 1 assert_equals: The value should be grayscale(0.5) brightness(0.5) contrast(0.5) opacity(0.5) saturate(0.5) at 500ms expected "grayscale(0.5) brightness(0.5) contrast(0.5) opacity(0.5) saturate(0.5)" but got "grayscale(1) brightness(0) contrast(0) opacity(0) saturate(0)"
-PASS filter: interpolate different length of filter-function-list with function which lacuna value is 0 
+FAIL filter: interpolate different length of filter-function-list with function which lacuna value is 0 assert_equals: The value should be opacity(0.5) grayscale(0.5) invert(0.5) sepia(0.5) blur(5px) at 500ms expected "opacity(0.5) grayscale(0.5) invert(0.5) sepia(0.5) blur(5px)" but got "opacity(0.25) grayscale(0.75) invert(0.75) sepia(0.75) blur(7.5px)"
 FAIL filter: interpolate different length of filter-function-list with drop-shadow function assert_equals: The value should be blur(5px) drop-shadow(rgba(85, 0, 170, 0.6) 5px 5px 5px at 500ms expected "blur(5px) drop-shadow(rgba(85, 0, 170, 0.6) 5px 5px 5px" but got "blur(10px) drop-shadow(rgba(0, 0, 255, 0.8) 10px 10px 10px)"
 PASS filter: interpolate from none 
 FAIL filter: url function (interpoalte as discrete) assert_equals: The value should be blur(0px) url("#f1") at 499ms expected "blur(0px) url(\"#f1\")" but got "blur(4.989999771118164px) url(#f1)"

Modified: trunk/LayoutTests/platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt (230573 => 230574)


--- trunk/LayoutTests/platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/LayoutTests/platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt	2018-04-12 15:14:31 UTC (rev 230574)
@@ -140,7 +140,7 @@
 FAIL filter: percentage or numeric-specifiable functions (number value) assert_equals: The value should be brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3) at 500ms expected "brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3)" but got "brightness(0.30000000000000004) contrast(0.30000000000000004) grayscale(0.30000000000000004) invert(0.30000000000000004) opacity(0.30000000000000004) saturate(0.30000000000000004) sepia(0.30000000000000004)"
 FAIL filter: percentage or numeric-specifiable functions (percentage value) assert_equals: The value should be brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3) at 500ms expected "brightness(0.3) contrast(0.3) grayscale(0.3) invert(0.3) opacity(0.3) saturate(0.3) sepia(0.3)" but got "brightness(0.30000000000000004) contrast(0.30000000000000004) grayscale(0.30000000000000004) invert(0.30000000000000004) opacity(0.30000000000000004) saturate(0.30000000000000004) sepia(0.30000000000000004)"
 FAIL filter: interpolate different length of filter-function-list with function which lacuna value is 1 assert_equals: The value should be grayscale(0.5) brightness(0.5) contrast(0.5) opacity(0.5) saturate(0.5) at 500ms expected "grayscale(0.5) brightness(0.5) contrast(0.5) opacity(0.5) saturate(0.5)" but got "grayscale(1) brightness(0) contrast(0) opacity(0) saturate(0)"
-PASS filter: interpolate different length of filter-function-list with function which lacuna value is 0 
+FAIL filter: interpolate different length of filter-function-list with function which lacuna value is 0 assert_equals: The value should be opacity(0.5) grayscale(0.5) invert(0.5) sepia(0.5) blur(5px) at 500ms expected "opacity(0.5) grayscale(0.5) invert(0.5) sepia(0.5) blur(5px)" but got "opacity(0.25) grayscale(0.75) invert(0.75) sepia(0.75) blur(7.5px)"
 FAIL filter: interpolate different length of filter-function-list with drop-shadow function assert_equals: The value should be blur(5px) drop-shadow(rgba(85, 0, 170, 0.6) 5px 5px 5px at 500ms expected "blur(5px) drop-shadow(rgba(85, 0, 170, 0.6) 5px 5px 5px" but got "blur(10px) drop-shadow(rgba(0, 0, 255, 0.8) 10px 10px 10px)"
 PASS filter: interpolate from none 
 FAIL filter: url function (interpoalte as discrete) assert_equals: The value should be blur(0px) url("#f1") at 499ms expected "blur(0px) url(\"#f1\")" but got "blur(4.989999771118164px) url(#f1)"

Modified: trunk/Source/WebCore/ChangeLog (230573 => 230574)


--- trunk/Source/WebCore/ChangeLog	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/ChangeLog	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1,3 +1,71 @@
+2018-04-11  Antoine Quint  <grao...@apple.com>
+
+        [Web Animations] Enable seeking for hardware animations
+        https://bugs.webkit.org/show_bug.cgi?id=184518
+
+        Reviewed by Dean Jackson.
+
+        Hardware animations had lagged behind software animations in support and this patch bring their respective level
+        of support closer to one another. Importantly, we add the ability to seek an animation added to a GraphicsLayerCA
+        since many tests pause and seek animations to test their state. Animations may also have their playback state changed
+        along with their current time in the same run loop, so we now maintain a list of pending processing actions for
+        hardware animations.
+
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::updateAnimationSchedule): If we have animations queued up for updates to their accelerated
+        state we can schedule animation resolution immediately since we've already established we'll have work to do.
+        (WebCore::DocumentTimeline::updateAnimations): Factor the updates of pending accelerated animations out in a dedicated
+        method.
+        (WebCore::DocumentTimeline::applyPendingAcceleratedAnimations): Go through all pending accelerated animations and update
+        their state.
+        * animation/KeyframeEffectReadOnly.cpp:
+        (WebCore::KeyframeEffectReadOnly::setBlendingKeyframes): Update the m_shouldRunAccelerated flag when setting blending keyframes.
+        (WebCore::KeyframeEffectReadOnly::apply): Ensure we finish accelerated animations if the progress is 1 or null (no longer active).
+        start accelerated animations if the animation is starting and always resolve styles in software as well to ensure that
+        hit testing will work as expected.
+        (WebCore::KeyframeEffectReadOnly::computeShouldRunAccelerated):
+        (WebCore::KeyframeEffectReadOnly::animationPlayStateDidChange): Called by WebAnimation when play() or pause() is called
+        with the appropriate flag.
+        (WebCore::KeyframeEffectReadOnly::animationDidSeek): Called by WebAnimation when the currentTime property is set.
+        (WebCore::KeyframeEffectReadOnly::addPendingAcceleratedAction): Add the provided action to the list of pending accelerated
+        actions and notify the animation that the accelerated state needs changing.
+        (WebCore::KeyframeEffectReadOnly::applyPendingAcceleratedActions): Called by DocumentTimeline, through WebAnimation, to apply
+        all pending accelerated actions.
+        (WebCore::KeyframeEffectReadOnly::backingAnimationForCompositedRenderer const): If we're dealing with a declarative animation,
+        we already have a backing Animation object, so use it directly. Otherwise, create one and ensure it reflects all timing properties
+        for the animation.
+        (WebCore::KeyframeEffectReadOnly::shouldRunAccelerated): Deleted.
+        (WebCore::KeyframeEffectReadOnly::startOrStopAccelerated): Deleted.
+        * animation/WebAnimation.cpp:
+        (WebCore::WebAnimation::setCurrentTime): Call animationDidSeek() on the effect to ensure its accelerated animation gets seeked.
+        (WebCore::WebAnimation::play): Call animationPlayStateDidChange() on the effect to ensure its accelerated animation is started or resumed.
+        (WebCore::WebAnimation::pause): Call animationPlayStateDidChange() on the effect to ensure its accelerated animation gets paused.
+        (WebCore::WebAnimation::acceleratedStateDidChange): 
+        (WebCore::WebAnimation::applyPendingAcceleratedActions):
+        (WebCore::WebAnimation::acceleratedRunningStateDidChange): Deleted.
+        (WebCore::WebAnimation::startOrStopAccelerated): Deleted.
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::seekAnimation):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::addProcessingActionForAnimation): Add an AnimationProcessingAction to the list of such actions for a
+        given animation name. In case we already have a Remove action, we ignore the action since the hardware animation will have been
+        removed by the time we try to apply this processing action.
+        (WebCore::GraphicsLayerCA::pauseAnimation): Add a Pause processing action.
+        (WebCore::GraphicsLayerCA::seekAnimation): Add a Seek processing action.
+        (WebCore::GraphicsLayerCA::removeAnimation): Add a Remove processing action.
+        (WebCore::GraphicsLayerCA::updateAnimations): First ensure that all animations pending commit are committed and then update
+        all animations based on the actions added through addProcessingActionForAnimation().
+        (WebCore::GraphicsLayerCA::seekCAAnimationOnLayer): Generate a new animation based on the new seek time provided.
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        (WebCore::GraphicsLayerCA::AnimationProcessingAction::AnimationProcessingAction):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::animationSeeked):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::animationSeeked):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::requiresCompositingForAnimation const): Fix an issue where we would run the CSSAnimationController
+        logic even when the legacy animation engine was disabled.
+
 2018-04-12  Xabier Rodriguez Calvar  <calva...@igalia.com>
 
         Unreviewed, fix GStreamer builds

Modified: trunk/Source/WebCore/animation/AnimationEffectReadOnly.h (230573 => 230574)


--- trunk/Source/WebCore/animation/AnimationEffectReadOnly.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/AnimationEffectReadOnly.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -46,6 +46,8 @@
     ComputedTimingProperties getComputedTiming();
     virtual void apply(RenderStyle&) = 0;
     virtual void invalidate() = 0;
+    virtual void animationPlayStateDidChange(WebAnimation::PlayState) = 0;
+    virtual void animationDidSeek() = 0;
 
     WebAnimation* animation() const { return m_animation.get(); }
     void setAnimation(RefPtr<WebAnimation>&& animation) { m_animation = animation; }

Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (230573 => 230574)


--- trunk/Source/WebCore/animation/DocumentTimeline.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -127,6 +127,11 @@
 
     m_needsUpdateAnimationSchedule = false;
 
+    if (!m_acceleratedAnimationsPendingRunningStateChange.isEmpty()) {
+        scheduleAnimationResolution();
+        return;
+    }
+
     Seconds scheduleDelay = Seconds::infinity();
 
     for (const auto& animation : animations()) {
@@ -179,9 +184,7 @@
         m_document->updateStyleIfNeeded();
     }
 
-    for (auto& animation : m_acceleratedAnimationsPendingRunningStateChange)
-        animation->startOrStopAccelerated();
-    m_acceleratedAnimationsPendingRunningStateChange.clear();
+    applyPendingAcceleratedAnimations();
 
     // Time has advanced, the timing model requires invalidation now.
     timingModelDidChange();
@@ -209,6 +212,13 @@
     m_acceleratedAnimationsPendingRunningStateChange.add(&animation);
 }
 
+void DocumentTimeline::applyPendingAcceleratedAnimations()
+{
+    for (auto& animation : m_acceleratedAnimationsPendingRunningStateChange)
+        animation->applyPendingAcceleratedActions();
+    m_acceleratedAnimationsPendingRunningStateChange.clear();
+}
+
 bool DocumentTimeline::runningAnimationsForElementAreAllAccelerated(Element& element)
 {
     // FIXME: This will let animations run using hardware compositing even if later in the active

Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (230573 => 230574)


--- trunk/Source/WebCore/animation/DocumentTimeline.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -59,6 +59,7 @@
 
     std::unique_ptr<RenderStyle> animatedStyleForRenderer(RenderElement& renderer);
     void animationAcceleratedRunningStateDidChange(WebAnimation&);
+    void applyPendingAcceleratedAnimations();
     bool runningAnimationsForElementAreAllAccelerated(Element&);
     void detachFromDocument();
 

Modified: trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp (230573 => 230574)


--- trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -695,6 +695,7 @@
     m_blendingKeyframes = WTFMove(blendingKeyframes);
 
     computeStackingContextImpact();
+    computeShouldRunAccelerated();
 
     checkForMatchingTransformFunctionLists();
     checkForMatchingFilterFunctionLists();
@@ -924,26 +925,21 @@
         return;
 
     auto progress = iterationProgress();
-    if (!progress)
-        return;
-
-    if (m_startedAccelerated && progress.value() >= 1) {
+    if (m_startedAccelerated && (!progress || progress.value() >= 1)) {
         m_startedAccelerated = false;
-        animation()->acceleratedRunningStateDidChange();
+        animation()->acceleratedStateDidChange();
     }
 
-    bool needsToStartAccelerated = false;
+    if (!progress)
+        return;
 
-    if (!m_started && !m_startedAccelerated) {
-        needsToStartAccelerated = shouldRunAccelerated();
-        m_startedAccelerated = needsToStartAccelerated;
-        if (needsToStartAccelerated)
-            animation()->acceleratedRunningStateDidChange();
+    if (!m_started && !m_startedAccelerated && m_shouldRunAccelerated) {
+        m_startedAccelerated = true;
+        animation()->acceleratedStateDidChange();
     }
     m_started = true;
 
-    if (!needsToStartAccelerated && !m_startedAccelerated)
-        setAnimatedPropertiesInStyle(targetStyle, progress.value());
+    setAnimatedPropertiesInStyle(targetStyle, progress.value());
 
     // https://w3c.github.io/web-animations/#side-effects-section
     // For every property targeted by at least one animation effect that is current or in effect, the user agent
@@ -957,13 +953,15 @@
     invalidateElement(m_target.get());
 }
 
-bool KeyframeEffectReadOnly::shouldRunAccelerated()
+void KeyframeEffectReadOnly::computeShouldRunAccelerated()
 {
+    m_shouldRunAccelerated = hasBlendingKeyframes();
     for (auto cssPropertyId : m_blendingKeyframes.properties()) {
-        if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(cssPropertyId))
-            return false;
+        if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(cssPropertyId)) {
+            m_shouldRunAccelerated = false;
+            return;
+        }
     }
-    return hasBlendingKeyframes();
 }
 
 void KeyframeEffectReadOnly::getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle)
@@ -1143,8 +1141,30 @@
     return downcast<DeclarativeAnimation>(effectAnimation)->backingAnimation().timingFunction();
 }
 
-void KeyframeEffectReadOnly::startOrStopAccelerated()
+void KeyframeEffectReadOnly::animationPlayStateDidChange(WebAnimation::PlayState playState)
 {
+    if (playState == WebAnimation::PlayState::Running)
+        addPendingAcceleratedAction(AcceleratedAction::Play);
+    else if (playState == WebAnimation::PlayState::Paused)
+        addPendingAcceleratedAction(AcceleratedAction::Pause);
+};
+
+void KeyframeEffectReadOnly::animationDidSeek()
+{
+    addPendingAcceleratedAction(AcceleratedAction::Seek);
+}
+
+void KeyframeEffectReadOnly::addPendingAcceleratedAction(AcceleratedAction action)
+{
+    if (!m_shouldRunAccelerated)
+        return;
+
+    m_pendingAcceleratedActions.append(action);
+    animation()->acceleratedStateDidChange();
+}
+
+void KeyframeEffectReadOnly::applyPendingAcceleratedActions()
+{
     auto* renderer = this->renderer();
     if (!renderer || !renderer->isComposited())
         return;
@@ -1151,9 +1171,24 @@
 
     auto* compositedRenderer = downcast<RenderBoxModelObject>(renderer);
     if (m_startedAccelerated) {
-        auto animation = Animation::create();
-        animation->setDuration(timing()->iterationDuration().seconds());
-        compositedRenderer->startAnimation(0, animation.ptr(), m_blendingKeyframes);
+        auto timeOffset = animation()->currentTime().value().seconds();
+        if (timing()->delay() < 0_s)
+            timeOffset = -timing()->delay().seconds();
+
+        for (const auto& action : m_pendingAcceleratedActions) {
+            switch (action) {
+            case AcceleratedAction::Play:
+                compositedRenderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer().ptr(), m_blendingKeyframes);
+                break;
+            case AcceleratedAction::Pause:
+                compositedRenderer->animationPaused(timeOffset, m_blendingKeyframes.animationName());
+                break;
+            case AcceleratedAction::Seek:
+                compositedRenderer->animationSeeked(timeOffset, m_blendingKeyframes.animationName());
+                break;
+            }
+        }
+        m_pendingAcceleratedActions.clear();
     } else {
         compositedRenderer->animationFinished(m_blendingKeyframes.animationName());
         if (!m_target->document().renderTreeBeingDestroyed())
@@ -1161,6 +1196,55 @@
     }
 }
 
+Ref<const Animation> KeyframeEffectReadOnly::backingAnimationForCompositedRenderer() const
+{
+    auto effectAnimation = animation();
+    if (is<DeclarativeAnimation>(effectAnimation))
+        return downcast<DeclarativeAnimation>(effectAnimation)->backingAnimation();
+
+    // FIXME: The iterationStart and endDelay AnimationEffectTimingReadOnly properties do not have
+    // corresponding Animation properties.
+    auto effectTiming = timing();
+    auto animation = Animation::create();
+    animation->setDuration(effectTiming->iterationDuration().seconds());
+    animation->setDelay(effectTiming->delay().seconds());
+    animation->setIterationCount(effectTiming->iterations());
+    animation->setTimingFunction(effectTiming->timingFunction()->clone());
+
+    switch (effectTiming->fill()) {
+    case FillMode::None:
+    case FillMode::Auto:
+        animation->setFillMode(AnimationFillModeNone);
+        break;
+    case FillMode::Backwards:
+        animation->setFillMode(AnimationFillModeBackwards);
+        break;
+    case FillMode::Forwards:
+        animation->setFillMode(AnimationFillModeForwards);
+        break;
+    case FillMode::Both:
+        animation->setFillMode(AnimationFillModeBoth);
+        break;
+    }
+
+    switch (effectTiming->direction()) {
+    case PlaybackDirection::Normal:
+        animation->setDirection(Animation::AnimationDirectionNormal);
+        break;
+    case PlaybackDirection::Alternate:
+        animation->setDirection(Animation::AnimationDirectionAlternate);
+        break;
+    case PlaybackDirection::Reverse:
+        animation->setDirection(Animation::AnimationDirectionReverse);
+        break;
+    case PlaybackDirection::AlternateReverse:
+        animation->setDirection(Animation::AnimationDirectionAlternateReverse);
+        break;
+    }
+
+    return WTFMove(animation);
+}
+
 RenderElement* KeyframeEffectReadOnly::renderer() const
 {
     return m_target ? m_target->renderer() : nullptr;

Modified: trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h (230573 => 230574)


--- trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -98,12 +98,14 @@
     void getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle);
     void apply(RenderStyle&) override;
     void invalidate() override;
-    void startOrStopAccelerated();
+    void animationPlayStateDidChange(WebAnimation::PlayState) final;
+    void animationDidSeek() final;
+    void applyPendingAcceleratedActions();
     bool isRunningAccelerated() const { return m_startedAccelerated; }
 
     RenderElement* renderer() const override;
     const RenderStyle& currentStyle() const override;
-    bool isAccelerated() const override { return false; }
+    bool isAccelerated() const override { return m_startedAccelerated; }
     bool filterFunctionListsMatch() const override { return m_filterFunctionListsMatch; }
     bool transformFunctionListsMatch() const override { return m_transformFunctionListsMatch; }
 #if ENABLE(FILTERS_LEVEL_2)
@@ -125,11 +127,14 @@
     KeyframeEffectReadOnly(ClassType, Ref<AnimationEffectTimingReadOnly>&&, Element*);
 
 private:
+    enum class AcceleratedAction { Play, Pause, Seek };
+    void addPendingAcceleratedAction(AcceleratedAction);
     void setAnimatedPropertiesInStyle(RenderStyle&, double);
     TimingFunction* timingFunctionForKeyframeAtIndex(size_t);
+    Ref<const Animation> backingAnimationForCompositedRenderer() const;
     void computeStackingContextImpact();
     void updateBlendingKeyframes();
-    bool shouldRunAccelerated();
+    void computeShouldRunAccelerated();
     void setBlendingKeyframes(KeyframeList&);
     void checkForMatchingTransformFunctionLists();
     void checkForMatchingFilterFunctionLists();
@@ -137,6 +142,7 @@
     void checkForMatchingBackdropFilterFunctionLists();
 #endif
 
+    bool m_shouldRunAccelerated { false };
     bool m_triggersStackingContext { false };
     bool m_started { false };
     bool m_startedAccelerated { false };
@@ -149,6 +155,8 @@
     RefPtr<Element> m_target;
     KeyframeList m_blendingKeyframes;
     Vector<ParsedKeyframe> m_parsedKeyframes;
+
+    Vector<AcceleratedAction> m_pendingAcceleratedActions;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (230573 => 230574)


--- trunk/Source/WebCore/animation/WebAnimation.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -383,6 +383,9 @@
     // 3. Run the procedure to update an animation's finished state for animation with the did seek flag set to true, and the synchronously notify flag set to false.
     updateFinishedState(DidSeek::Yes, SynchronouslyNotify::No);
 
+    if (m_effect)
+        m_effect->animationDidSeek();
+
     return { };
 }
 
@@ -779,6 +782,9 @@
     // 9. Run the procedure to update an animation's finished state for animation with the did seek flag set to false, and the synchronously notify flag set to false.
     updateFinishedState(DidSeek::No, SynchronouslyNotify::No);
 
+    if (m_effect)
+        m_effect->animationPlayStateDidChange(PlayState::Running);
+
     return { };
 }
 
@@ -875,6 +881,9 @@
     // 8. Run the procedure to update an animation's finished state for animation with the did seek flag set to false, and the synchronously notify flag set to false.
     updateFinishedState(DidSeek::No, SynchronouslyNotify::No);
 
+    if (m_effect)
+        m_effect->animationPlayStateDidChange(PlayState::Paused);
+
     return { };
 }
 
@@ -1008,16 +1017,16 @@
         m_effect->apply(targetStyle);
 }
 
-void WebAnimation::acceleratedRunningStateDidChange()
+void WebAnimation::acceleratedStateDidChange()
 {
     if (is<DocumentTimeline>(m_timeline))
         downcast<DocumentTimeline>(*m_timeline).animationAcceleratedRunningStateDidChange(*this);
 }
 
-void WebAnimation::startOrStopAccelerated()
+void WebAnimation::applyPendingAcceleratedActions()
 {
     if (is<KeyframeEffectReadOnly>(m_effect))
-        downcast<KeyframeEffectReadOnly>(*m_effect).startOrStopAccelerated();
+        downcast<KeyframeEffectReadOnly>(*m_effect).applyPendingAcceleratedActions();
 }
 
 WebAnimation& WebAnimation::readyPromiseResolve()

Modified: trunk/Source/WebCore/animation/WebAnimation.h (230573 => 230574)


--- trunk/Source/WebCore/animation/WebAnimation.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/animation/WebAnimation.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -100,8 +100,8 @@
     Seconds timeToNextRequiredTick() const;
     void resolve(RenderStyle&);
     void effectTargetDidChange(Element* previousTarget, Element* newTarget);
-    void acceleratedRunningStateDidChange();
-    void startOrStopAccelerated();
+    void acceleratedStateDidChange();
+    void applyPendingAcceleratedActions();
 
     void timingModelDidChange();
     void suspendEffectInvalidation();

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (230573 => 230574)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -452,6 +452,7 @@
     // 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 (230573 => 230574)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -1006,6 +1006,18 @@
     return true;
 }
 
+void GraphicsLayerCA::addProcessingActionForAnimation(const String& animationName, AnimationProcessingAction processingAction)
+{
+    auto& processingActions = m_animationsToProcess.ensure(animationName, [] {
+        return Vector<AnimationProcessingAction> { };
+    }).iterator->value;
+
+    if (!processingActions.isEmpty() && processingActions.last().action == Remove)
+        return;
+
+    processingActions.append(processingAction);
+}
+
 bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const FloatSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
 {
     LOG(Animations, "GraphicsLayerCA %p addAnimation %s (can be accelerated %d)", this, animationName.utf8().data(), animationCanBeAccelerated(valueList, anim));
@@ -1041,11 +1053,18 @@
 {
     LOG(Animations, "GraphicsLayerCA %p pauseAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
 
-    if (!animationIsRunning(animationName))
-        return;
+    // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
+    addProcessingActionForAnimation(animationName, AnimationProcessingAction { Pause, Seconds { timeOffset } });
 
+    noteLayerPropertyChanged(AnimationChanged);
+}
+
+void GraphicsLayerCA::seekAnimation(const String& animationName, double timeOffset)
+{
+    LOG(Animations, "GraphicsLayerCA %p seekAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
+
     // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
-    m_animationsToProcess.add(animationName, AnimationProcessingAction { Pause, Seconds { timeOffset } });
+    addProcessingActionForAnimation(animationName, AnimationProcessingAction { Seek, Seconds { timeOffset } });
 
     noteLayerPropertyChanged(AnimationChanged);
 }
@@ -1057,7 +1076,7 @@
     if (!animationIsRunning(animationName))
         return;
 
-    m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
+    addProcessingActionForAnimation(animationName, AnimationProcessingAction(Remove));
     noteLayerPropertyChanged(AnimationChanged);
 }
 
@@ -2761,41 +2780,12 @@
 
 void GraphicsLayerCA::updateAnimations()
 {
-    if (m_animationsToProcess.size()) {
-        AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
-        for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
-            const String& currAnimationName = it->key;
-            AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
-            if (animationIt == m_runningAnimations.end())
-                continue;
-
-            const AnimationProcessingAction& processingInfo = it->value;
-            const Vector<LayerPropertyAnimation>& animations = animationIt->value;
-            for (size_t i = 0; i < animations.size(); ++i) {
-                const LayerPropertyAnimation& currAnimation = animations[i];
-                switch (processingInfo.action) {
-                case Remove:
-                    removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, currAnimation.m_subIndex);
-                    break;
-                case Pause:
-                    pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, currAnimation.m_subIndex, processingInfo.timeOffset);
-                    break;
-                }
-            }
-
-            if (processingInfo.action == Remove)
-                m_runningAnimations.remove(currAnimationName);
-        }
-    
-        m_animationsToProcess.clear();
-    }
-    
     size_t numAnimations;
     if ((numAnimations = m_uncomittedAnimations.size())) {
         for (size_t i = 0; i < numAnimations; ++i) {
             const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
             setAnimationOnLayer(*pendingAnimation.m_animation, pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_subIndex, pendingAnimation.m_timeOffset);
-            
+
             AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
             if (it == m_runningAnimations.end()) {
                 Vector<LayerPropertyAnimation> animations;
@@ -2808,6 +2798,39 @@
         }
         m_uncomittedAnimations.clear();
     }
+
+    if (m_animationsToProcess.size()) {
+        AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
+        for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
+            const String& currentAnimationName = it->key;
+            auto animationIterator = m_runningAnimations.find(currentAnimationName);
+            if (animationIterator == m_runningAnimations.end())
+                continue;
+
+            for (const auto& processingInfo : it->value) {
+                const Vector<LayerPropertyAnimation>& animations = animationIterator->value;
+                for (const auto& currentAnimation : animations) {
+                    switch (processingInfo.action) {
+                    case Remove:
+                        removeCAAnimationFromLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex);
+                        break;
+                    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;
+                    }
+                }
+
+                if (processingInfo.action == Remove)
+                    m_runningAnimations.remove(currentAnimationName);
+            }
+
+        }
+
+        m_animationsToProcess.clear();
+    }
 }
 
 bool GraphicsLayerCA::isRunningTransformAnimation() const
@@ -2916,6 +2939,35 @@
     }
 }
 
+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->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::repaintLayerDirtyRects()
 {
     if (m_needsFullRepaint) {

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


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -130,6 +130,7 @@
 
     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;
@@ -443,6 +444,7 @@
     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);
@@ -518,6 +520,18 @@
 
     void repaintLayerDirtyRects();
 
+    enum Action { Remove, Pause, Seek };
+    struct AnimationProcessingAction {
+        AnimationProcessingAction(Action action = "" Seconds timeOffset = 0_s)
+            : action(action)
+            , timeOffset(timeOffset)
+        {
+        }
+        Action action;
+        Seconds timeOffset; // Only used for pause.
+    };
+    void addProcessingActionForAnimation(const String&, AnimationProcessingAction);
+
     RefPtr<PlatformCALayer> m_layer; // The main layer
     RefPtr<PlatformCALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer.
     RefPtr<PlatformCALayer> m_contentsClippingLayer; // A layer used to clip inner content
@@ -581,17 +595,7 @@
     // Uncommitted transitions and animations.
     Vector<LayerPropertyAnimation> m_uncomittedAnimations;
     
-    enum Action { Remove, Pause };
-    struct AnimationProcessingAction {
-        AnimationProcessingAction(Action action = "" Seconds timeOffset = 0_s)
-            : action(action)
-            , timeOffset(timeOffset)
-        {
-        }
-        Action action;
-        Seconds timeOffset; // only used for pause
-    };
-    typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
+    typedef HashMap<String, Vector<AnimationProcessingAction>> AnimationsToProcessMap;
     AnimationsToProcessMap m_animationsToProcess;
 
     // Map of animation names to their associated lists of property animations, so we can remove/pause them.

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (230573 => 230574)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -194,6 +194,13 @@
     layer()->backing()->animationPaused(timeOffset, name);
 }
 
+void RenderBoxModelObject::animationSeeked(double timeOffset, const String& name)
+{
+    ASSERT(hasLayer());
+    ASSERT(isComposited());
+    layer()->backing()->animationSeeked(timeOffset, name);
+}
+
 void RenderBoxModelObject::animationFinished(const String& name)
 {
     ASSERT(hasLayer());

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (230573 => 230574)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -229,6 +229,7 @@
 
     bool startAnimation(double timeOffset, const Animation*, const KeyframeList& keyframes);
     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/RenderLayerBacking.cpp (230573 => 230574)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -2778,6 +2778,11 @@
     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 (230573 => 230574)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2018-04-12 15:14:31 UTC (rev 230574)
@@ -167,6 +167,7 @@
 
     bool startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes);
     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/RenderLayerCompositor.cpp (230573 => 230574)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2018-04-12 14:51:35 UTC (rev 230573)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2018-04-12 15:14:31 UTC (rev 230574)
@@ -54,6 +54,7 @@
 #include "RenderReplica.h"
 #include "RenderVideo.h"
 #include "RenderView.h"
+#include "RuntimeEnabledFeatures.h"
 #include "ScrollingConstraints.h"
 #include "ScrollingCoordinator.h"
 #include "Settings.h"
@@ -2477,6 +2478,9 @@
         }
     }
 
+    if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled())
+        return false;
+
     const AnimationBase::RunningState activeAnimationState = AnimationBase::Running | AnimationBase::Paused;
     auto& animController = renderer.animation();
     return (animController.isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity, activeAnimationState)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to