<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[285728] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/285728">285728</a></dd>
<dt>Author</dt> <dd>graouts@webkit.org</dd>
<dt>Date</dt> <dd>2021-11-12 09:40:47 -0800 (Fri, 12 Nov 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Web Animations] Accelerated animations with a single keyframe don't account for prior forward-filling animations
https://bugs.webkit.org/show_bug.cgi?id=233041
<rdar://problem/85236241>

Reviewed by Dean Jackson.

Source/WebCore:

Test: webanimations/accelerated-animation-after-forward-filling-animation.html

When starting an accelerated animation, we would fill any implicit keyframes based on the unanimated style.
We now also apply all animations below this animation in the target's effect stack such that a previous
forward-filling animation is accounted for.

* animation/KeyframeEffect.cpp:
(WebCore::KeyframeEffect::applyPendingAcceleratedActions):

LayoutTests:

Add a new test that runs a forward-filling animation for `transform`, waits for its completion,
then runs another `transform` animation with an implicit initial keyframe, ensuring that the
result of the first forward-filling animation is accounted for when computing the initial
keyframe.

This test would fail prior to this patch.

* webanimations/accelerated-animation-after-forward-filling-animation-expected.html: Added.
* webanimations/accelerated-animation-after-forward-filling-animation.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreanimationKeyframeEffectcpp">trunk/Source/WebCore/animation/KeyframeEffect.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestswebanimationsacceleratedanimationafterforwardfillinganimationexpectedhtml">trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation-expected.html</a></li>
<li><a href="#trunkLayoutTestswebanimationsacceleratedanimationafterforwardfillinganimationhtml">trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (285727 => 285728)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-11-12 17:37:01 UTC (rev 285727)
+++ trunk/LayoutTests/ChangeLog 2021-11-12 17:40:47 UTC (rev 285728)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2021-11-12  Antoine Quint  <graouts@webkit.org>
+
+        [Web Animations] Accelerated animations with a single keyframe don't account for prior forward-filling animations
+        https://bugs.webkit.org/show_bug.cgi?id=233041
+        <rdar://problem/85236241>
+
+        Reviewed by Dean Jackson.
+
+        Add a new test that runs a forward-filling animation for `transform`, waits for its completion,
+        then runs another `transform` animation with an implicit initial keyframe, ensuring that the
+        result of the first forward-filling animation is accounted for when computing the initial
+        keyframe.
+
+        This test would fail prior to this patch.
+
+        * webanimations/accelerated-animation-after-forward-filling-animation-expected.html: Added.
+        * webanimations/accelerated-animation-after-forward-filling-animation.html: Added.
+
</ins><span class="cx"> 2021-11-12  Patrick Angle  <pangle@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Mark inspector/page/setShowPaintRects.html as flakey in test expectations for Mac
</span></span></pre></div>
<a id="trunkLayoutTestswebanimationsacceleratedanimationafterforwardfillinganimationexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation-expected.html (0 => 285728)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation-expected.html                              (rev 0)
+++ trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation-expected.html 2021-11-12 17:40:47 UTC (rev 285728)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+<!DOCTYPE html>
+<body>
+<style>
+
+    #target {
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 100px;
+        height: 100px;
+        background-color: black;
+        transform: translateX(100px);
+    }
+
+</style>
+<div id="target"></div>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestswebanimationsacceleratedanimationafterforwardfillinganimationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation.html (0 => 285728)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation.html                               (rev 0)
+++ trunk/LayoutTests/webanimations/accelerated-animation-after-forward-filling-animation.html  2021-11-12 17:40:47 UTC (rev 285728)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+<!DOCTYPE html>
+<body>
+<style>
+
+    #target {
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 100px;
+        height: 100px;
+        background-color: black;
+    }
+
+</style>
+<div id="target"></div>
+<script>
+
+(async () => {
+    if (window.testRunner)
+        window.testRunner.waitUntilDone();
+
+    const target = document.getElementById("target");
+
+    // Start a forward-filling accelerated animation.
+    const fillingAnimation = target.animate({ transform: "translateX(100px)" }, { duration: 1, fill: "forwards" });
+    await fillingAnimation.finished;
+
+    // Start another animation with an implicit from keyframe.
+    const animation = target.animate({ transform: "translateY(1px)" }, { duration: 1000 * 1000 });
+
+    // Wait two frames for the accelerated animation to be committed.
+    await animation.ready;
+    await new Promise(requestAnimationFrame);
+    await new Promise(requestAnimationFrame);
+
+    if (window.testRunner)
+        window.testRunner.notifyDone();
+})();
+
+</script>
+</body>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (285727 => 285728)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-11-12 17:37:01 UTC (rev 285727)
+++ trunk/Source/WebCore/ChangeLog      2021-11-12 17:40:47 UTC (rev 285728)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2021-11-12  Antoine Quint  <graouts@webkit.org>
+
+        [Web Animations] Accelerated animations with a single keyframe don't account for prior forward-filling animations
+        https://bugs.webkit.org/show_bug.cgi?id=233041
+        <rdar://problem/85236241>
+
+        Reviewed by Dean Jackson.
+
+        Test: webanimations/accelerated-animation-after-forward-filling-animation.html
+
+        When starting an accelerated animation, we would fill any implicit keyframes based on the unanimated style.
+        We now also apply all animations below this animation in the target's effect stack such that a previous
+        forward-filling animation is accounted for.
+
+        * animation/KeyframeEffect.cpp:
+        (WebCore::KeyframeEffect::applyPendingAcceleratedActions):
+
</ins><span class="cx"> 2021-11-12  Wenson Hsieh  <wenson_hsieh@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Move subtree update logic in ImageOverlay::updateWithTextRecognitionResult() into a separate helper
</span></span></pre></div>
<a id="trunkSourceWebCoreanimationKeyframeEffectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (285727 => 285728)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/animation/KeyframeEffect.cpp        2021-11-12 17:37:01 UTC (rev 285727)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp   2021-11-12 17:40:47 UTC (rev 285728)
</span><span class="lines">@@ -1788,9 +1788,22 @@
</span><span class="cx">         auto* lastStyleChangeEventStyle = m_target->lastStyleChangeEventStyle(m_pseudoId);
</span><span class="cx">         ASSERT(lastStyleChangeEventStyle);
</span><span class="cx"> 
</span><ins>+        // We need to resolve all animations up to this point to ensure any forward-filling
+        // effect is accounted for when computing the "from" value for the accelerated animation.
+        auto underlyingStyle = RenderStyle::clonePtr(*lastStyleChangeEventStyle);
+        auto* effectStack = m_target->keyframeEffectStack(m_pseudoId);
+        ASSERT(effectStack);
+
+        for (const auto& effect : effectStack->sortedEffects()) {
+            if (this == effect.get())
+                break;
+            if (auto progress = effect->getComputedTiming().progress)
+                effect->setAnimatedPropertiesInStyle(*underlyingStyle, *progress);
+        }
+
</ins><span class="cx">         KeyframeList explicitKeyframes(m_blendingKeyframes.animationName());
</span><span class="cx">         explicitKeyframes.copyKeyframes(m_blendingKeyframes);
</span><del>-        explicitKeyframes.fillImplicitKeyframes(*m_target, m_target->styleResolver(), lastStyleChangeEventStyle, nullptr);
</del><ins>+        explicitKeyframes.fillImplicitKeyframes(*m_target, m_target->styleResolver(), underlyingStyle.get(), nullptr);
</ins><span class="cx">         return renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), explicitKeyframes) ? RunningAccelerated::Yes : RunningAccelerated::No;
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>