First in-window viewStateChange synchronously blocks despite not previously being...
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Jul 2015 00:43:04 +0000 (00:43 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Jul 2015 00:43:04 +0000 (00:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147344
<rdar://problem/22021772>

Reviewed by Simon Fraser.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::updateViewState):
(WebKit::WebPageProxy::dispatchViewStateChange):
The whole point of m_viewWasEverInWindow was so that we would not
synchronously wait when a view was added to a window for the first time,
only all subsequent times.

However, since m_viewWasEverInWindow was being set *before* being
checked in dispatchViewStateChange, we were always blocking. This is
a huge waste of main-thread time, because there's no reason to wait
for the first paint if you've never seen the view before (and shouldn't
expect it to have content).

Instead, set the flag after dispatching a view state change, so it becomes
"have we ever sent a view state with IsInWindow set" instead.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187471 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/WebPageProxy.cpp

index 291c60f..e383d69 100644 (file)
@@ -1,5 +1,29 @@
 2015-07-27  Tim Horton  <timothy_horton@apple.com>
 
+        First in-window viewStateChange synchronously blocks despite not previously being in-window
+        https://bugs.webkit.org/show_bug.cgi?id=147344
+        <rdar://problem/22021772>
+
+        Reviewed by Simon Fraser.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::updateViewState):
+        (WebKit::WebPageProxy::dispatchViewStateChange):
+        The whole point of m_viewWasEverInWindow was so that we would not
+        synchronously wait when a view was added to a window for the first time,
+        only all subsequent times.
+
+        However, since m_viewWasEverInWindow was being set *before* being
+        checked in dispatchViewStateChange, we were always blocking. This is
+        a huge waste of main-thread time, because there's no reason to wait
+        for the first paint if you've never seen the view before (and shouldn't
+        expect it to have content).
+
+        Instead, set the flag after dispatching a view state change, so it becomes
+        "have we ever sent a view state with IsInWindow set" instead.
+
+2015-07-27  Tim Horton  <timothy_horton@apple.com>
+
         [iOS] Long press or link click can sometimes trigger during/after a preview
         https://bugs.webkit.org/show_bug.cgi?id=147338
         <rdar://problem/22020770>
index d7ebfc8..577027a 100644 (file)
@@ -1330,10 +1330,8 @@ void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
         m_viewState |= ViewState::IsVisible;
     if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
         m_viewState |= ViewState::IsVisibleOrOccluded;
-    if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) {
+    if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow())
         m_viewState |= ViewState::IsInWindow;
-        m_viewWasEverInWindow = true;
-    }
     if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
         m_viewState |= ViewState::IsVisuallyIdle;
 }
@@ -1401,8 +1399,9 @@ void WebPageProxy::dispatchViewStateChange()
     updateViewState(m_potentiallyChangedViewStateFlags);
     ViewState::Flags changed = m_viewState ^ previousViewState;
 
+    bool isNowInWindow = (changed & ViewState::IsInWindow) && isInWindow();
     // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
-    if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow() && m_drawingArea->hasVisibleContent())
+    if (m_viewWasEverInWindow && isNowInWindow && m_drawingArea->hasVisibleContent())
         m_viewStateChangeWantsSynchronousReply = true;
 
     // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.)
@@ -1437,6 +1436,7 @@ void WebPageProxy::dispatchViewStateChange()
 
     m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
     m_viewStateChangeWantsSynchronousReply = false;
+    m_viewWasEverInWindow |= isNowInWindow;
 }
 
 void WebPageProxy::updateActivityToken()