<!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>[202291] trunk/Source/WebKit2</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/202291">202291</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-06-21 13:53:45 -0700 (Tue, 21 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS][WK2] When an animation frame is missed, the UI process should immediately notify the Web process once a frame is committed
https://bugs.webkit.org/show_bug.cgi?id=158933

Patch by Said Abou-Hallawa &lt;sabouhallawa@apple,com&gt; on 2016-06-21
Reviewed by Simon Fraser.

When a frame is committed, the UI process schedules a CADisplayLink and waits until
the next didRefreshDisplay event is fired. This causes more delay in the scenario
where there are frames are dropped. didRefreshDisplay() should be called immediately
when commitLayerTree message is received and the last frame was dropped.

The fix is to have the CADisplayLink active all the times. It should be paused
only when we detect at least one frame is dropped. In this case we should not
send a message to the UI process since it has not sent the last requested LayerTree.
Also we should not waste the CPU time by scheduling a new CADisplayLink since we
have not processed the last event. We should resume CADisplayLink timer once a
commitLayerTree message is received.

* UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h:
* UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
(-[WKOneShotDisplayLinkHandler pause]):
(WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree):
(WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay):
(-[WKOneShotDisplayLinkHandler displayLinkFired:]):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxyh">trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxymm">trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (202290 => 202291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-06-21 20:47:17 UTC (rev 202290)
+++ trunk/Source/WebKit2/ChangeLog        2016-06-21 20:53:45 UTC (rev 202291)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2016-06-21  Said Abou-Hallawa  &lt;sabouhallawa@apple,com&gt;
+
+        [iOS][WK2] When an animation frame is missed, the UI process should immediately notify the Web process once a frame is committed
+        https://bugs.webkit.org/show_bug.cgi?id=158933
+
+        Reviewed by Simon Fraser.
+
+        When a frame is committed, the UI process schedules a CADisplayLink and waits until
+        the next didRefreshDisplay event is fired. This causes more delay in the scenario
+        where there are frames are dropped. didRefreshDisplay() should be called immediately
+        when commitLayerTree message is received and the last frame was dropped.
+
+        The fix is to have the CADisplayLink active all the times. It should be paused
+        only when we detect at least one frame is dropped. In this case we should not
+        send a message to the UI process since it has not sent the last requested LayerTree.
+        Also we should not waste the CPU time by scheduling a new CADisplayLink since we
+        have not processed the last event. We should resume CADisplayLink timer once a
+        commitLayerTree message is received.
+
+        * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h:
+        * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
+        (-[WKOneShotDisplayLinkHandler pause]):
+        (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree):
+        (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay):
+        (-[WKOneShotDisplayLinkHandler displayLinkFired:]):
+
</ins><span class="cx"> 2016-06-21  Amir Alavi  &lt;aalavi@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Upstream WKHTTPCookiesForURL from WebKitSystemInterface to OpenSource
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h (202290 => 202291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h        2016-06-21 20:47:17 UTC (rev 202290)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h        2016-06-21 20:53:45 UTC (rev 202291)
</span><span class="lines">@@ -91,7 +91,8 @@
</span><span class="cx"> 
</span><span class="cx">     RemoteLayerTreeHost m_remoteLayerTreeHost;
</span><span class="cx">     bool m_isWaitingForDidUpdateGeometry { false };
</span><del>-    bool m_haveSentDidUpdateSinceLastCommit { false };
</del><ins>+    enum DidUpdateMessageState { NotSent, Sent, MissedCommit };
+    DidUpdateMessageState m_didUpdateMessageState { NotSent };
</ins><span class="cx"> 
</span><span class="cx">     WebCore::IntSize m_lastSentSize;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm (202290 => 202291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm        2016-06-21 20:47:17 UTC (rev 202290)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm        2016-06-21 20:53:45 UTC (rev 202291)
</span><span class="lines">@@ -81,7 +81,6 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isUIThread());
</span><span class="cx">     _drawingAreaProxy-&gt;didRefreshDisplay(sender.timestamp);
</span><del>-    _displayLink.paused = YES;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)invalidate
</span><span class="lines">@@ -95,6 +94,11 @@
</span><span class="cx">     _displayLink.paused = NO;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)pause
+{
+    _displayLink.paused = YES;
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -219,11 +223,12 @@
</span><span class="cx"> 
</span><span class="cx">     m_webPageProxy.layerTreeCommitComplete();
</span><span class="cx"> 
</span><del>-    m_haveSentDidUpdateSinceLastCommit = false;
-
</del><span class="cx"> #if PLATFORM(IOS)
</span><ins>+    if (std::exchange(m_didUpdateMessageState, NotSent) == MissedCommit)
+        didRefreshDisplay(monotonicallyIncreasingTime());
</ins><span class="cx">     [m_displayLinkHandler schedule];
</span><span class="cx"> #else
</span><ins>+    m_didUpdateMessageState = NotSent;
</ins><span class="cx">     didRefreshDisplay(monotonicallyIncreasingTime());
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -391,10 +396,15 @@
</span><span class="cx">     if (!m_webPageProxy.isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (m_haveSentDidUpdateSinceLastCommit)
</del><ins>+    if (m_didUpdateMessageState != NotSent) {
+        m_didUpdateMessageState = MissedCommit;
+#if PLATFORM(IOS)
+        [m_displayLinkHandler pause];
+#endif
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">     
</span><del>-    m_haveSentDidUpdateSinceLastCommit = true;
</del><ins>+    m_didUpdateMessageState = Sent;
</ins><span class="cx"> 
</span><span class="cx">     // Waiting for CA to commit is insufficient, because the render server can still be
</span><span class="cx">     // using our backing store. We can improve this by waiting for the render server to commit
</span></span></pre>
</div>
</div>

</body>
</html>