[PSON] Flash on back navigation on Mac
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2019 17:43:02 +0000 (17:43 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2019 17:43:02 +0000 (17:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193716
<rdar://problem/47148458>

Reviewed by Chris Dumez.

We close the page immediately if we fail to suspend. Layers disappear and we get a flash.

* UIProcess/SuspendedPageProxy.cpp:
(WebKit::SuspendedPageProxy::didProcessRequestToSuspend):

Remove the suspended page (so closing it on web process side) if the suspension fails.
Skip this if we are using web process side compositing on Mac.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::enterAcceleratedCompositingMode):

On Mac, remove failed SuspendedPageProxy when entering compositing mode. At this point we don't need it to keep layers alive.

* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::removeFailedSuspendedPagesForPage):
* UIProcess/WebProcessPool.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::suspendForProcessSwap):

Don't close the page on suspension failure.

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/SuspendedPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebProcessPool.cpp
Source/WebKit/UIProcess/WebProcessPool.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp

index ea380fb..1a3609b 100644 (file)
@@ -1,3 +1,32 @@
+2019-01-23  Antti Koivisto  <antti@apple.com>
+
+        [PSON] Flash on back navigation on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=193716
+        <rdar://problem/47148458>
+
+        Reviewed by Chris Dumez.
+
+        We close the page immediately if we fail to suspend. Layers disappear and we get a flash.
+
+        * UIProcess/SuspendedPageProxy.cpp:
+        (WebKit::SuspendedPageProxy::didProcessRequestToSuspend):
+
+        Remove the suspended page (so closing it on web process side) if the suspension fails.
+        Skip this if we are using web process side compositing on Mac.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::enterAcceleratedCompositingMode):
+
+        On Mac, remove failed SuspendedPageProxy when entering compositing mode. At this point we don't need it to keep layers alive.
+
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::removeFailedSuspendedPagesForPage):
+        * UIProcess/WebProcessPool.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::suspendForProcessSwap):
+
+        Don't close the page on suspension failure.
+
 2019-01-23  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Introduce UndoStep::label() and adopt it in WebKitLegacy and WebKit
index ff76d9f..ce3109e 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "SuspendedPageProxy.h"
 
+#include "DrawingAreaProxy.h"
 #include "Logging.h"
 #include "WebPageMessages.h"
 #include "WebPageProxy.h"
@@ -154,6 +155,19 @@ void SuspendedPageProxy::didProcessRequestToSuspend(SuspensionState newSuspensio
 
     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
 
+    bool shouldKeepOnFailure = false;
+#if PLATFORM(MAC)
+    // With web process side tiles, we need to keep the suspended page around on failure to avoid flashing.
+    // It is removed by WebPageProxy::enterAcceleratedCompositingMode when the target page is ready.
+    shouldKeepOnFailure = m_page.drawingArea() && m_page.drawingArea()->type() == DrawingAreaTypeTiledCoreAnimation;
+#endif
+    if (newSuspensionState == SuspensionState::FailedToSuspend && !shouldKeepOnFailure) {
+        RunLoop::main().dispatch([weakProcessPool = makeWeakPtr(m_process->processPool()), weakThis = makeWeakPtr(*this)] {
+            if (weakProcessPool && weakThis)
+                weakProcessPool->removeSuspendedPage(*weakThis);
+        });
+    }
+
     if (m_readyToUnsuspendHandler)
         m_readyToUnsuspendHandler(this);
 }
index e4449f8..cd15f88 100644 (file)
@@ -6847,7 +6847,12 @@ void WebPageProxy::isJITEnabled(CompletionHandler<void(bool)>&& completionHandle
 
 void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
 {
+#if PLATFORM(MAC)
+    ASSERT(m_drawingArea->type() == DrawingAreaTypeTiledCoreAnimation);
+#endif
     pageClient().enterAcceleratedCompositingMode(layerTreeContext);
+    // We needed the failed suspended page to stay alive to avoid flashing. Now we can get rid of it.
+    m_process->processPool().removeFailedSuspendedPagesForPage(*this);
 }
 
 void WebPageProxy::exitAcceleratedCompositingMode()
index 2ca7638..e0d5bb1 100644 (file)
@@ -2270,6 +2270,13 @@ void WebProcessPool::removeAllSuspendedPagesForPage(WebPageProxy& page)
     });
 }
 
+void WebProcessPool::removeFailedSuspendedPagesForPage(WebPageProxy& page)
+{
+    m_suspendedPages.removeAllMatching([&page](auto& suspendedPage) {
+        return &suspendedPage->page() == &page && suspendedPage->failedToSuspend();
+    });
+}
+
 std::unique_ptr<SuspendedPageProxy> WebProcessPool::takeSuspendedPage(SuspendedPageProxy& suspendedPage)
 {
     return m_suspendedPages.takeFirst([&suspendedPage](auto& item) {
index 1a161ac..dfc0c04 100644 (file)
@@ -450,6 +450,7 @@ public:
     // SuspendedPageProxy management.
     void addSuspendedPage(std::unique_ptr<SuspendedPageProxy>&&);
     void removeAllSuspendedPagesForPage(WebPageProxy&);
+    void removeFailedSuspendedPagesForPage(WebPageProxy&);
     std::unique_ptr<SuspendedPageProxy> takeSuspendedPage(SuspendedPageProxy&);
     void removeSuspendedPage(SuspendedPageProxy&);
     bool hasSuspendedPageFor(WebProcessProxy&) const;
index 9f8bb91..3b0b509 100644 (file)
@@ -1340,7 +1340,6 @@ void WebPage::sendClose()
 void WebPage::suspendForProcessSwap()
 {
     auto failedToSuspend = [this, protectedThis = makeRef(*this)] {
-        close();
         send(Messages::WebPageProxy::DidFailToSuspendAfterProcessSwap());
     };