<!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>[203842] 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/203842">203842</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2016-07-28 14:19:06 -0700 (Thu, 28 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Frequent animation lags when interacting with Safari (sidebar, tab switching, etc.)
https://bugs.webkit.org/show_bug.cgi?id=160289
&lt;rdar://problem/27553464&gt;

Reviewed by Simon Fraser.

API Tests: WebKit2.AnimatedResizeDoesNotHang, WebKit2.ResizeWithHiddenContentDoesNotHang

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _didCommitLayerTree:]):
Avoid calling _endAnimatedResize when a commit comes in when we haven't yet received
a dynamic viewport update reply (and thus don't have a transaction ID to wait on).
Previously, in this case, _resizeAnimationTransformTransactionID would be 0,
and *any* commit would cause _endAnimatedResize to be called, causing us to always
fall into the worst-case sync wait.

* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::synchronizeDynamicViewportUpdate):
Make use of waitForDidUpdateViewState instead of having a separate waitForAndDispatchImmediately
here, because it knows to do things like dispatch the didUpdate message if it's still
pending. This also shortens the sync wait timeout from 1s to 500ms, which makes it
consistent with e.g. the newly-parented-view timeout duration, and should be nothing
but positive.

* Platform/IPC/Connection.cpp:
(IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting):
(IPC::Connection::waitForMessage):
(IPC::Connection::sendSyncMessageFromSecondaryThread):
(IPC::Connection::waitForSyncReply):
* Platform/IPC/Connection.h:
(IPC::Connection::ignoreTimeoutsForTesting):
* UIProcess/API/APIProcessPoolConfiguration.cpp:
(API::ProcessPoolConfiguration::copy):
* UIProcess/API/APIProcessPoolConfiguration.h:
* UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h:
* UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm:
(-[_WKProcessPoolConfiguration ignoreSynchronousMessagingTimeoutsForTesting]):
(-[_WKProcessPoolConfiguration setIgnoreSynchronousMessagingTimeoutsForTesting:]):
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::processDidFinishLaunching):
Add a mechanism for clients to cause all synchronous message timeouts to be effectively infinite.
The new API tests use this to ensure that the test will time out if they ever enter
the bad state (otherwise, the shorter sync wait timeout could make the test still pass).

* TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/AnimatedResize.mm: Added.
(-[AnimatedResizeNavigationDelegate _webView:renderingProgressDidChange:]):
(-[AnimatedResizeWebView _endAnimatedResize]):
(animatedResizeWebView):
(TEST):
* TestWebKitAPI/Tests/WebKit2Cocoa/blinking-div.html: Added.
Add two tests that ensure that hidden-content and animated resizes
don't cause unnecessary synchronous waits. Only the hidden-content
one fails before my patch, but it seemed reasonable to add both anyway.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2PlatformIPCConnectioncpp">trunk/Source/WebKit2/Platform/IPC/Connection.cpp</a></li>
<li><a href="#trunkSourceWebKit2PlatformIPCConnectionh">trunk/Source/WebKit2/Platform/IPC/Connection.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIProcessPoolConfigurationcpp">trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIProcessPoolConfigurationh">trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoa_WKProcessPoolConfigurationh">trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoa_WKProcessPoolConfigurationmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolcpp">trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIxcconfig">trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaAnimatedResizemm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AnimatedResize.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2Cocoablinkingdivhtml">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/blinking-div.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/ChangeLog        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2016-07-28  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Frequent animation lags when interacting with Safari (sidebar, tab switching, etc.)
+        https://bugs.webkit.org/show_bug.cgi?id=160289
+        &lt;rdar://problem/27553464&gt;
+
+        Reviewed by Simon Fraser.
+
+        API Tests: WebKit2.AnimatedResizeDoesNotHang, WebKit2.ResizeWithHiddenContentDoesNotHang
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _didCommitLayerTree:]):
+        Avoid calling _endAnimatedResize when a commit comes in when we haven't yet received
+        a dynamic viewport update reply (and thus don't have a transaction ID to wait on).
+        Previously, in this case, _resizeAnimationTransformTransactionID would be 0,
+        and *any* commit would cause _endAnimatedResize to be called, causing us to always
+        fall into the worst-case sync wait.
+        
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::synchronizeDynamicViewportUpdate):
+        Make use of waitForDidUpdateViewState instead of having a separate waitForAndDispatchImmediately
+        here, because it knows to do things like dispatch the didUpdate message if it's still
+        pending. This also shortens the sync wait timeout from 1s to 500ms, which makes it
+        consistent with e.g. the newly-parented-view timeout duration, and should be nothing
+        but positive.
+
+        * Platform/IPC/Connection.cpp:
+        (IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting):
+        (IPC::Connection::waitForMessage):
+        (IPC::Connection::sendSyncMessageFromSecondaryThread):
+        (IPC::Connection::waitForSyncReply):
+        * Platform/IPC/Connection.h:
+        (IPC::Connection::ignoreTimeoutsForTesting):
+        * UIProcess/API/APIProcessPoolConfiguration.cpp:
+        (API::ProcessPoolConfiguration::copy):
+        * UIProcess/API/APIProcessPoolConfiguration.h:
+        * UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h:
+        * UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm:
+        (-[_WKProcessPoolConfiguration ignoreSynchronousMessagingTimeoutsForTesting]):
+        (-[_WKProcessPoolConfiguration setIgnoreSynchronousMessagingTimeoutsForTesting:]):
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::processDidFinishLaunching):
+        Add a mechanism for clients to cause all synchronous message timeouts to be effectively infinite.
+        The new API tests use this to ensure that the test will time out if they ever enter
+        the bad state (otherwise, the shorter sync wait timeout could make the test still pass).
+
</ins><span class="cx"> 2016-07-27  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Add WKUIDelegate SPI for specifying that an attachment list is from a managed source
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformIPCConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/IPC/Connection.cpp (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/IPC/Connection.cpp        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/Platform/IPC/Connection.cpp        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -385,10 +385,17 @@
</span><span class="cx">     return sendMessage(WTFMove(encoder));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+std::chrono::milliseconds Connection::timeoutRespectingIgnoreTimeoutsForTesting(std::chrono::milliseconds timeout) const
+{
+    return m_ignoreTimeoutsForTesting ? std::chrono::milliseconds::max() : timeout;
+}
+
</ins><span class="cx"> std::unique_ptr&lt;MessageDecoder&gt; Connection::waitForMessage(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID, std::chrono::milliseconds timeout, unsigned waitForMessageFlags)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    timeout = timeoutRespectingIgnoreTimeoutsForTesting(timeout);
+
</ins><span class="cx">     bool hasIncomingSynchronousMessage = false;
</span><span class="cx"> 
</span><span class="cx">     // First, check if this message is already in the incoming messages queue.
</span><span class="lines">@@ -532,6 +539,7 @@
</span><span class="cx"> 
</span><span class="cx">     sendMessage(WTFMove(encoder), 0, true);
</span><span class="cx"> 
</span><ins>+    timeout = timeoutRespectingIgnoreTimeoutsForTesting(timeout);
</ins><span class="cx">     pendingReply.semaphore.wait(currentTime() + (timeout.count() / 1000.0));
</span><span class="cx"> 
</span><span class="cx">     // Finally, pop the pending sync reply information.
</span><span class="lines">@@ -546,6 +554,7 @@
</span><span class="cx"> 
</span><span class="cx"> std::unique_ptr&lt;MessageDecoder&gt; Connection::waitForSyncReply(uint64_t syncRequestID, std::chrono::milliseconds timeout, unsigned syncSendFlags)
</span><span class="cx"> {
</span><ins>+    timeout = timeoutRespectingIgnoreTimeoutsForTesting(timeout);
</ins><span class="cx">     double absoluteTime = currentTime() + (timeout.count() / 1000.0);
</span><span class="cx"> 
</span><span class="cx">     willSendSyncMessage(syncSendFlags);
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformIPCConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/IPC/Connection.h (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/IPC/Connection.h        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/Platform/IPC/Connection.h        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -205,6 +205,8 @@
</span><span class="cx"> 
</span><span class="cx">     void allowFullySynchronousModeForTesting() { m_fullySynchronousModeIsAllowedForTesting = true; }
</span><span class="cx"> 
</span><ins>+    void ignoreTimeoutsForTesting() { m_ignoreTimeoutsForTesting = true; }
+
</ins><span class="cx"> private:
</span><span class="cx">     Connection(Identifier, bool isServer, Client&amp;);
</span><span class="cx">     void platformInitialize(Identifier);
</span><span class="lines">@@ -239,6 +241,8 @@
</span><span class="cx"> 
</span><span class="cx">     void willSendSyncMessage(unsigned syncSendFlags);
</span><span class="cx">     void didReceiveSyncReply(unsigned syncSendFlags);
</span><ins>+
+    std::chrono::milliseconds timeoutRespectingIgnoreTimeoutsForTesting(std::chrono::milliseconds) const;
</ins><span class="cx">     
</span><span class="cx">     Client* m_client;
</span><span class="cx">     bool m_isServer;
</span><span class="lines">@@ -258,6 +262,7 @@
</span><span class="cx">     unsigned m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount;
</span><span class="cx">     unsigned m_inDispatchMessageMarkedToUseFullySynchronousModeForTesting { 0 };
</span><span class="cx">     bool m_fullySynchronousModeIsAllowedForTesting { false };
</span><ins>+    bool m_ignoreTimeoutsForTesting { false };
</ins><span class="cx">     bool m_didReceiveInvalidMessage;
</span><span class="cx"> 
</span><span class="cx">     // Incoming messages.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIProcessPoolConfigurationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -109,6 +109,7 @@
</span><span class="cx">     copy-&gt;m_cachePartitionedURLSchemes = this-&gt;m_cachePartitionedURLSchemes;
</span><span class="cx">     copy-&gt;m_alwaysRevalidatedURLSchemes = this-&gt;m_alwaysRevalidatedURLSchemes;
</span><span class="cx">     copy-&gt;m_fullySynchronousModeIsAllowedForTesting = this-&gt;m_fullySynchronousModeIsAllowedForTesting;
</span><ins>+    copy-&gt;m_ignoreSynchronousMessagingTimeoutsForTesting = this-&gt;m_ignoreSynchronousMessagingTimeoutsForTesting;
</ins><span class="cx">     copy-&gt;m_overrideLanguages = this-&gt;m_overrideLanguages;
</span><span class="cx">     
</span><span class="cx">     return copy;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIProcessPoolConfigurationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -96,6 +96,9 @@
</span><span class="cx">     bool fullySynchronousModeIsAllowedForTesting() const { return m_fullySynchronousModeIsAllowedForTesting; }
</span><span class="cx">     void setFullySynchronousModeIsAllowedForTesting(bool allowed) { m_fullySynchronousModeIsAllowedForTesting = allowed; }
</span><span class="cx"> 
</span><ins>+    bool ignoreSynchronousMessagingTimeoutsForTesting() const { return m_ignoreSynchronousMessagingTimeoutsForTesting; }
+    void setIgnoreSynchronousMessagingTimeoutsForTesting(bool allowed) { m_ignoreSynchronousMessagingTimeoutsForTesting = allowed; }
+
</ins><span class="cx">     const Vector&lt;WTF::String&gt;&amp; overrideLanguages() const { return m_overrideLanguages; }
</span><span class="cx">     void setOverrideLanguages(Vector&lt;WTF::String&gt;&amp;&amp; languages) { m_overrideLanguages = WTFMove(languages); }
</span><span class="cx"> 
</span><span class="lines">@@ -120,6 +123,7 @@
</span><span class="cx">     Vector&lt;WTF::String&gt; m_cachePartitionedURLSchemes;
</span><span class="cx">     Vector&lt;WTF::String&gt; m_alwaysRevalidatedURLSchemes;
</span><span class="cx">     bool m_fullySynchronousModeIsAllowedForTesting { false };
</span><ins>+    bool m_ignoreSynchronousMessagingTimeoutsForTesting { false };
</ins><span class="cx">     Vector&lt;WTF::String&gt; m_overrideLanguages;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -235,7 +235,7 @@
</span><span class="cx">     uint64_t _firstPaintAfterCommitLoadTransactionID;
</span><span class="cx">     DynamicViewportUpdateMode _dynamicViewportUpdateMode;
</span><span class="cx">     CATransform3D _resizeAnimationTransformAdjustments;
</span><del>-    uint64_t _resizeAnimationTransformTransactionID;
</del><ins>+    Optional&lt;uint64_t&gt; _resizeAnimationTransformTransactionID;
</ins><span class="cx">     RetainPtr&lt;UIView&gt; _resizeAnimationView;
</span><span class="cx">     CGFloat _lastAdjustmentForScroller;
</span><span class="cx">     Optional&lt;CGRect&gt; _frozenVisibleContentRect;
</span><span class="lines">@@ -1236,7 +1236,8 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (_dynamicViewportUpdateMode != DynamicViewportUpdateMode::NotResizing) {
</span><del>-        if (layerTreeTransaction.transactionID() &gt;= _resizeAnimationTransformTransactionID) {
</del><ins>+        if (_resizeAnimationTransformTransactionID &amp;&amp; layerTreeTransaction.transactionID() &gt;= _resizeAnimationTransformTransactionID.value()) {
+            _resizeAnimationTransformTransactionID = Nullopt;
</ins><span class="cx">             [_resizeAnimationView layer].sublayerTransform = _resizeAnimationTransformAdjustments;
</span><span class="cx">             if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::ResizingWithDocumentHidden) {
</span><span class="cx">                 [_contentView setHidden:NO];
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoa_WKProcessPoolConfigurationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> @property (nonatomic, copy) NSArray *cachePartitionedURLSchemes;
</span><span class="cx"> @property (nonatomic, copy) NSArray&lt;NSString *&gt; *alwaysRevalidatedURLSchemes WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
</span><span class="cx"> @property (nonatomic) BOOL diskCacheSpeculativeValidationEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
</span><ins>+@property (nonatomic) BOOL ignoreSynchronousMessagingTimeoutsForTesting WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
</ins><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoa_WKProcessPoolConfigurationmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -92,6 +92,16 @@
</span><span class="cx">     _processPoolConfiguration-&gt;setDiskCacheSpeculativeValidationEnabled(enabled);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (BOOL)ignoreSynchronousMessagingTimeoutsForTesting
+{
+    return _processPoolConfiguration-&gt;ignoreSynchronousMessagingTimeoutsForTesting();
+}
+
+- (void)setIgnoreSynchronousMessagingTimeoutsForTesting:(BOOL)ignoreSynchronousMessagingTimeoutsForTesting
+{
+    _processPoolConfiguration-&gt;setIgnoreSynchronousMessagingTimeoutsForTesting(ignoreSynchronousMessagingTimeoutsForTesting);
+}
+
</ins><span class="cx"> - (NSArray *)cachePartitionedURLSchemes
</span><span class="cx"> {
</span><span class="cx">     auto schemes = _processPoolConfiguration-&gt;cachePartitionedURLSchemes();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -730,6 +730,9 @@
</span><span class="cx">     if (m_configuration-&gt;fullySynchronousModeIsAllowedForTesting())
</span><span class="cx">         process-&gt;connection()-&gt;allowFullySynchronousModeForTesting();
</span><span class="cx"> 
</span><ins>+    if (m_configuration-&gt;ignoreSynchronousMessagingTimeoutsForTesting())
+        process-&gt;connection()-&gt;ignoreTimeoutsForTesting();
+
</ins><span class="cx">     m_connectionClient.didCreateConnection(this, process-&gt;webConnection());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -301,9 +301,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // If m_dynamicViewportSizeUpdateWaitingForTarget is false, we are waiting for the next valid frame with the hope it is the one for the new target.
</span><del>-    // If m_dynamicViewportSizeUpdateWaitingForTarget is still true, this is a desesperate attempt to get the valid frame before finishing the animation.
</del><ins>+    // If m_dynamicViewportSizeUpdateWaitingForTarget is still true, this is a desperate attempt to get the valid frame before finishing the animation.
</ins><span class="cx">     if (m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit)
</span><del>-        m_process-&gt;connection()-&gt;waitForAndDispatchImmediately&lt;Messages::RemoteLayerTreeDrawingAreaProxy::CommitLayerTree&gt;(m_pageID, std::chrono::seconds(1), IPC::InterruptWaitingIfSyncMessageArrives);
</del><ins>+        m_drawingArea-&gt;waitForDidUpdateViewState();
</ins><span class="cx"> 
</span><span class="cx">     m_dynamicViewportSizeUpdateWaitingForTarget = false;
</span><span class="cx">     m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Tools/ChangeLog        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-07-28  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Frequent animation lags when interacting with Safari (sidebar, tab switching, etc.)
+        https://bugs.webkit.org/show_bug.cgi?id=160289
+        &lt;rdar://problem/27553464&gt;
+
+        Reviewed by Simon Fraser.
+
+        * TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/AnimatedResize.mm: Added.
+        (-[AnimatedResizeNavigationDelegate _webView:renderingProgressDidChange:]):
+        (-[AnimatedResizeWebView _endAnimatedResize]):
+        (animatedResizeWebView):
+        (TEST):
+        * TestWebKitAPI/Tests/WebKit2Cocoa/blinking-div.html: Added.
+        Add two tests that ensure that hidden-content and animated resizes
+        don't cause unnecessary synchronous waits. Only the hidden-content
+        one fails before my patch, but it seemed reasonable to add both anyway.
+
</ins><span class="cx"> 2016-07-28  David Kilzer  &lt;ddkilzer@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         webkit-patch upload --suggest-reviewers shouldn't break in the presence of deleted or moved files
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIxcconfig"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -32,6 +32,6 @@
</span><span class="cx"> OTHER_LDFLAGS_PLATFORM[sdk=macosx*] = -framework Cocoa -framework Carbon;
</span><span class="cx"> 
</span><span class="cx"> // FIXME: This should not be built on iOS. Instead we should create and use a TestWebKitAPI application.
</span><del>-OTHER_LDFLAGS_PLATFORM[sdk=iphone*] = -framework WebCore -framework CoreGraphics;
</del><ins>+OTHER_LDFLAGS_PLATFORM[sdk=iphone*] = -framework WebCore -framework CoreGraphics -framework UIKit;
</ins><span class="cx"> 
</span><span class="cx"> LD_RUNPATH_SEARCH_PATHS = &quot;@loader_path&quot;;
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (203841 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-07-28 21:17:58 UTC (rev 203841)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -52,12 +52,14 @@
</span><span class="cx">                 2D51A0C71C8BF00C00765C45 /* DOMHTMLVideoElementWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D51A0C51C8BF00400765C45 /* DOMHTMLVideoElementWrapper.mm */; };
</span><span class="cx">                 2DC4CF771D2D9DD800ECCC94 /* DataDetection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DC4CF761D2D9DD800ECCC94 /* DataDetection.mm */; };
</span><span class="cx">                 2DD7D3AF178227B30026E1E3 /* lots-of-text-vertical-lr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */; };
</span><ins>+                2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */; };
+                2DE71B001D49C3ED00904094 /* blinking-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DE71AFF1D49C2F000904094 /* blinking-div.html */; };
</ins><span class="cx">                 2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */; };
</span><span class="cx">                 2E1B7B001D41ABA7007558B4 /* large-video-seek-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */; };
</span><span class="cx">                 2E1B7B021D41B1B9007558B4 /* large-video-hides-controls-after-seek-to-end.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */; };
</span><del>-                2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
</del><span class="cx">                 2E1DFDED1D42A51100714A00 /* large-videos-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */; };
</span><span class="cx">                 2E1DFDEF1D42A6F200714A00 /* large-videos-with-audio-autoplay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */; };
</span><ins>+                2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
</ins><span class="cx">                 2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */; };
</span><span class="cx">                 2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */; };
</span><span class="cx">                 33BE5AF9137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BE5AF8137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp */; };
</span><span class="lines">@@ -509,6 +511,7 @@
</span><span class="cx">                                 2E1DFDEF1D42A6F200714A00 /* large-videos-with-audio-autoplay.html in Copy Resources */,
</span><span class="cx">                                 2E1DFDED1D42A51100714A00 /* large-videos-with-audio.html in Copy Resources */,
</span><span class="cx">                                 5C9E59411D3EB5AC00E3C62E /* ApplicationCache.db in Copy Resources */,
</span><ins>+                                2DE71B001D49C3ED00904094 /* blinking-div.html in Copy Resources */,
</ins><span class="cx">                                 5C9E59421D3EB5AC00E3C62E /* ApplicationCache.db-shm in Copy Resources */,
</span><span class="cx">                                 5C9E59431D3EB5AC00E3C62E /* ApplicationCache.db-wal in Copy Resources */,
</span><span class="cx">                                 2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */,
</span><span class="lines">@@ -707,12 +710,14 @@
</span><span class="cx">                 2DD355351BD08378005DF4A7 /* AutoLayoutIntegration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoLayoutIntegration.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2DD7D3A9178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResizeReversePaginatedWebView.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = &quot;lots-of-text-vertical-lr.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnimatedResize.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                2DE71AFF1D49C2F000904094 /* blinking-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;blinking-div.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;autoplaying-video-with-audio.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;large-video-seek-after-ending.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;large-video-hides-controls-after-seek-to-end.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;large-video-seek-to-beginning-and-play-after-ending.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;large-videos-with-audio.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;large-videos-with-audio-autoplay.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;large-video-seek-to-beginning-and-play-after-ending.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainIOS.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreventEmptyUserAgent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1226,6 +1231,7 @@
</span><span class="cx">                                 A16F66B81C40E9E100BD4D24 /* Resources */,
</span><span class="cx">                                 7CEFA9641AC0B9E200B910FD /* _WKUserContentExtensionStore.mm */,
</span><span class="cx">                                 A1DF74301C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm */,
</span><ins>+                                2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */,
</ins><span class="cx">                                 2DD355351BD08378005DF4A7 /* AutoLayoutIntegration.mm */,
</span><span class="cx">                                 A13EBBAC1B87436F00097110 /* BundleParameters.mm */,
</span><span class="cx">                                 A13EBBAE1B87436F00097110 /* BundleParametersPlugIn.mm */,
</span><span class="lines">@@ -1358,6 +1364,7 @@
</span><span class="cx">                                 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */,
</span><span class="cx">                                 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */,
</span><span class="cx">                                 93CFA8661CEB9DE1000565A8 /* autofocused-text-input.html */,
</span><ins>+                                2DE71AFF1D49C2F000904094 /* blinking-div.html */,
</ins><span class="cx">                                 A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */,
</span><span class="cx">                                 5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */,
</span><span class="cx">                                 5714ECBC1CA8C21800051AC8 /* DownloadRequestOriginalURL2.html */,
</span><span class="lines">@@ -2218,6 +2225,7 @@
</span><span class="cx">                                 7CCE7F241A411AF600447C4C /* Navigation.mm in Sources */,
</span><span class="cx">                                 A14FC5881B8991BF00D107EB /* ContentFiltering.mm in Sources */,
</span><span class="cx">                                 7CCE7F021A411AE600447C4C /* NewFirstVisuallyNonEmptyLayout.cpp in Sources */,
</span><ins>+                                2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */,
</ins><span class="cx">                                 51A587861D273AA9004BA9AF /* IndexedDBDatabaseProcessKill.mm in Sources */,
</span><span class="cx">                                 7CCE7F031A411AE600447C4C /* NewFirstVisuallyNonEmptyLayoutFails.cpp in Sources */,
</span><span class="cx">                                 7CCE7F041A411AE600447C4C /* NewFirstVisuallyNonEmptyLayoutForImages.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaAnimatedResizemm"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AnimatedResize.mm (0 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AnimatedResize.mm                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AnimatedResize.mm        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#import &quot;PlatformUtilities.h&quot;
+#import &lt;WebKit/WKNavigationDelegatePrivate.h&gt;
+#import &lt;WebKit/WKPreferences.h&gt;
+#import &lt;WebKit/WKProcessPoolPrivate.h&gt;
+#import &lt;WebKit/WKWebView.h&gt;
+#import &lt;WebKit/WKWebViewConfiguration.h&gt;
+#import &lt;WebKit/WKWebViewPrivate.h&gt;
+#import &lt;WebKit/_WKProcessPoolConfiguration.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+#if WK_API_ENABLED &amp;&amp; PLATFORM(IOS)
+
+static bool didLayout;
+static bool didEndAnimatedResize;
+
+@interface AnimatedResizeNavigationDelegate : NSObject &lt;WKNavigationDelegate&gt;
+@end
+
+@implementation AnimatedResizeNavigationDelegate
+
+- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
+{
+    if (progressEvents &amp; _WKRenderingProgressEventFirstVisuallyNonEmptyLayout)
+        didLayout = true;
+}
+
+@end
+
+@interface AnimatedResizeWebView : WKWebView
+
+@end
+
+@implementation AnimatedResizeWebView
+
+- (void)_endAnimatedResize
+{
+    [super _endAnimatedResize];
+
+    didEndAnimatedResize = true;
+}
+
+@end
+
+static RetainPtr&lt;WKWebView&gt; animatedResizeWebView()
+{
+    RetainPtr&lt;_WKProcessPoolConfiguration&gt; processPoolConfiguration = [[_WKProcessPoolConfiguration alloc] init];
+    [processPoolConfiguration setIgnoreSynchronousMessagingTimeoutsForTesting:YES];
+    RetainPtr&lt;WKProcessPool&gt; processPool = [[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()];
+
+    RetainPtr&lt;WKWebViewConfiguration&gt; webViewConfiguration = [[WKWebViewConfiguration alloc] init];
+    [webViewConfiguration setProcessPool:processPool.get()];
+
+    RetainPtr&lt;WKWebView&gt; webView = adoptNS([[AnimatedResizeWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+
+    AnimatedResizeNavigationDelegate *navigationDelegate = [[AnimatedResizeNavigationDelegate alloc] init];
+    [webView setNavigationDelegate:navigationDelegate];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@&quot;blinking-div&quot; withExtension:@&quot;html&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;]];
+    [webView loadRequest:request];
+
+    return webView;
+}
+
+TEST(WebKit2, ResizeWithHiddenContentDoesNotHang)
+{
+    auto webView = animatedResizeWebView();
+    RetainPtr&lt;UIWindow&gt; window = adoptNS([[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]);
+    [window addSubview:webView.get()];
+    [window setHidden:NO];
+
+    TestWebKitAPI::Util::run(&amp;didLayout);
+    didLayout = false;
+
+    for (unsigned i = 0; i &lt; 50; i++) {
+        [webView _resizeWhileHidingContentWithUpdates:^{
+            [webView setFrame:CGRectMake(0, 0, [webView frame].size.width + 100, 400)];
+        }];
+
+        TestWebKitAPI::Util::run(&amp;didEndAnimatedResize);
+        didEndAnimatedResize = false;
+    }
+}
+
+TEST(WebKit2, AnimatedResizeDoesNotHang)
+{
+    auto webView = animatedResizeWebView();
+    RetainPtr&lt;UIWindow&gt; window = adoptNS([[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]);
+    [window addSubview:webView.get()];
+    [window setHidden:NO];
+
+    TestWebKitAPI::Util::run(&amp;didLayout);
+    didLayout = false;
+
+    for (unsigned i = 0; i &lt; 50; i++) {
+        [webView _beginAnimatedResizeWithUpdates:^{
+            [webView setFrame:CGRectMake(0, 0, [webView frame].size.width + 100, 400)];
+        }];
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [webView _endAnimatedResize];
+        });
+
+        TestWebKitAPI::Util::run(&amp;didEndAnimatedResize);
+        didEndAnimatedResize = false;
+    }
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2Cocoablinkingdivhtml"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/blinking-div.html (0 => 203842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/blinking-div.html                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/blinking-div.html        2016-07-28 21:19:06 UTC (rev 203842)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+&lt;html&gt;
+    &lt;script&gt;
+window.onload = function () {
+    setInterval(blink, 0);
+}
+
+var a = 0;
+
+function blink() {
+    document.getElementById(&quot;blink&quot;).style.backgroundColor = a ? &quot;blue&quot; : &quot;green&quot;;
+    a = !a;
+}
+    &lt;/script&gt;
+    &lt;style&gt;
+#blink {
+    width: 200px; height: 200px;
+    display: inline-block;
+}
+    &lt;/style&gt;
+    &lt;body&gt;
+        &lt;div id=&quot;blink&quot;&gt;&lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre>
</div>
</div>

</body>
</html>