Clean up layer tree freezing logic in WebPage
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Nov 2018 09:40:49 +0000 (09:40 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Nov 2018 09:40:49 +0000 (09:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191826

Reviewed by Dean Jackson.

Use OptionSet<LayerTreeFreezeReason> to track various reasons that can cause layer tree to get frozen.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::reinitializeWebPage):
(WebKit::WebPage::freezeLayerTree):
(WebKit::WebPage::unfreezeLayerTree):
(WebKit::WebPage::updateDrawingAreaLayerTreeFreezeState):

Layer tree is unfrozen when there there are no reasons to freeze it.

(WebKit::WebPage::didStartPageTransition):
(WebKit::WebPage::didCompletePageTransition):
(WebKit::WebPage::beginPrinting):
(WebKit::WebPage::endPrinting):
(WebKit::WebPage::setIsSuspended):
(WebKit::WebPage::setLayerTreeStateIsFrozen): Deleted.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::applicationDidEnterBackground):
(WebKit::WebPage::applicationWillEnterForeground):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::actualPrepareToSuspend):
(WebKit::WebProcess::cancelPrepareToSuspend):
(WebKit::WebProcess::freezeAllLayerTrees):
(WebKit::WebProcess::unfreezeAllLayerTrees):
(WebKit::WebProcess::processDidResume):
(WebKit::WebProcess::setAllLayerTreeStatesFrozen): Deleted.
* WebProcess/WebProcess.h:

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

Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Source/WebKit/WebProcess/WebProcess.cpp
Source/WebKit/WebProcess/WebProcess.h

index ec9d5c0..071448d 100644 (file)
@@ -1,3 +1,39 @@
+2018-11-26  Antti Koivisto  <antti@apple.com>
+
+        Clean up layer tree freezing logic in WebPage
+        https://bugs.webkit.org/show_bug.cgi?id=191826
+
+        Reviewed by Dean Jackson.
+
+        Use OptionSet<LayerTreeFreezeReason> to track various reasons that can cause layer tree to get frozen.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::reinitializeWebPage):
+        (WebKit::WebPage::freezeLayerTree):
+        (WebKit::WebPage::unfreezeLayerTree):
+        (WebKit::WebPage::updateDrawingAreaLayerTreeFreezeState):
+
+        Layer tree is unfrozen when there there are no reasons to freeze it.
+
+        (WebKit::WebPage::didStartPageTransition):
+        (WebKit::WebPage::didCompletePageTransition):
+        (WebKit::WebPage::beginPrinting):
+        (WebKit::WebPage::endPrinting):
+        (WebKit::WebPage::setIsSuspended):
+        (WebKit::WebPage::setLayerTreeStateIsFrozen): Deleted.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::applicationDidEnterBackground):
+        (WebKit::WebPage::applicationWillEnterForeground):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::actualPrepareToSuspend):
+        (WebKit::WebProcess::cancelPrepareToSuspend):
+        (WebKit::WebProcess::freezeAllLayerTrees):
+        (WebKit::WebProcess::unfreezeAllLayerTrees):
+        (WebKit::WebProcess::processDidResume):
+        (WebKit::WebProcess::setAllLayerTreeStatesFrozen): Deleted.
+        * WebProcess/WebProcess.h:
+
 2018-11-25  Antti Koivisto  <antti@apple.com>
 
         RemoteLayerTreeNode construction cleanups
index 10a7c94..8235c53 100644 (file)
@@ -659,11 +659,11 @@ void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters)
 
     setSize(parameters.viewSize);
 
-    if (m_shouldResetDrawingArea) {
+    if (m_shouldResetDrawingAreaAfterSuspend) {
         // Make sure we destroy the previous drawing area before constructing the new one as DrawingArea registers / unregisters
         // itself as an IPC::MesssageReceiver in its constructor / destructor.
         m_drawingArea = nullptr;
-        m_shouldResetDrawingArea = false;
+        m_shouldResetDrawingAreaAfterSuspend = false;
 
         m_drawingArea = DrawingArea::create(*this, parameters);
         m_drawingArea->setPaintingEnabled(false);
@@ -673,6 +673,7 @@ void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters)
 #if PLATFORM(MAC)
         m_shouldAttachDrawingAreaOnPageTransition = parameters.shouldDelayAttachingDrawingArea;
 #endif
+        unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended);
     }
 
     setViewLayoutSize(parameters.viewLayoutSize);
@@ -2327,13 +2328,23 @@ const WebEvent* WebPage::currentEvent()
     return g_currentEvent;
 }
 
-void WebPage::setLayerTreeStateIsFrozen(bool frozen)
+void WebPage::freezeLayerTree(LayerTreeFreezeReason reason)
 {
-    auto* drawingArea = this->drawingArea();
-    if (!drawingArea)
-        return;
+    m_LayerTreeFreezeReasons.add(reason);
+    updateDrawingAreaLayerTreeFreezeState();
+}
+
+void WebPage::unfreezeLayerTree(LayerTreeFreezeReason reason)
+{
+    m_LayerTreeFreezeReasons.remove(reason);
+    updateDrawingAreaLayerTreeFreezeState();
+}
 
-    drawingArea->setLayerTreeStateIsFrozen(frozen || m_isSuspended || m_shouldResetDrawingArea);
+void WebPage::updateDrawingAreaLayerTreeFreezeState()
+{
+    if (!m_drawingArea)
+        return;
+    m_drawingArea->setLayerTreeStateIsFrozen(!!m_LayerTreeFreezeReasons);
 }
 
 void WebPage::callVolatilityCompletionHandlers(bool succeeded)
@@ -3006,7 +3017,7 @@ void WebPage::continueWillSubmitForm(uint64_t frameID, uint64_t listenerID)
 
 void WebPage::didStartPageTransition()
 {
-    setLayerTreeStateIsFrozen(true);
+    freezeLayerTree(LayerTreeFreezeReason::PageTransition);
 
 #if PLATFORM(MAC)
     bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
@@ -3030,8 +3041,7 @@ void WebPage::didStartPageTransition()
 
 void WebPage::didCompletePageTransition()
 {
-    // FIXME: Layer tree freezing should be managed entirely in the UI process side.
-    setLayerTreeStateIsFrozen(false);
+    unfreezeLayerTree(LayerTreeFreezeReason::PageTransition);
 
 #if PLATFORM(MAC)
     bool isInitialEmptyDocument = !m_mainFrame;
@@ -4461,7 +4471,8 @@ void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
     if (!m_printContext)
         m_printContext = std::make_unique<PrintContext>(coreFrame);
 
-    drawingArea()->setLayerTreeStateIsFrozen(true);
+    freezeLayerTree(LayerTreeFreezeReason::Printing);
+
     m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
 
     float fullPageHeight;
@@ -4475,7 +4486,8 @@ void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
 
 void WebPage::endPrinting()
 {
-    drawingArea()->setLayerTreeStateIsFrozen(false);
+    unfreezeLayerTree(LayerTreeFreezeReason::Printing);
+
     m_printContext = nullptr;
 }
 
@@ -6222,10 +6234,11 @@ void WebPage::setIsSuspended(bool suspended)
 
     m_isSuspended = suspended;
 
-    if (!m_isSuspended)
-        m_shouldResetDrawingArea = true;
-
-    setLayerTreeStateIsFrozen(true);
+    if (m_isSuspended) {
+        // Unfrozen on drawing area reset.
+        freezeLayerTree(LayerTreeFreezeReason::PageSuspended);
+    } else
+        m_shouldResetDrawingAreaAfterSuspend = true;
 }
 
 void WebPage::frameBecameRemote(uint64_t frameID, GlobalFrameIdentifier&& remoteFrameIdentifier, GlobalWindowIdentifier&& remoteWindowIdentifier)
index d1a82d6..8881d6d 100644 (file)
@@ -683,7 +683,16 @@ public:
 
     bool hasRichlyEditableSelection() const;
 
-    void setLayerTreeStateIsFrozen(bool);
+    enum class LayerTreeFreezeReason {
+        PageTransition          = 1 << 0,
+        BackgroundApplication   = 1 << 1,
+        ProcessSuspended        = 1 << 2,
+        PageSuspended           = 1 << 3,
+        Printing                = 1 << 4,
+    };
+    void freezeLayerTree(LayerTreeFreezeReason);
+    void unfreezeLayerTree(LayerTreeFreezeReason);
+
     void markLayersVolatile(WTF::Function<void (bool)>&& completionHandler = { });
     void cancelMarkLayersVolatile();
 
@@ -1175,6 +1184,7 @@ private:
     bool executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>&, WebCore::KeyboardEvent*);
 #endif
 
+    void updateDrawingAreaLayerTreeFreezeState();
     bool markLayersVolatileImmediatelyIfPossible();
     void layerVolatilityTimerFired();
     void callVolatilityCompletionHandlers(bool succeeded);
@@ -1471,7 +1481,7 @@ private:
 
     WebCore::IntSize m_viewSize;
     std::unique_ptr<DrawingArea> m_drawingArea;
-    bool m_shouldResetDrawingArea { false };
+    bool m_shouldResetDrawingAreaAfterSuspend { false };
 
     HashSet<PluginView*> m_pluginViews;
     bool m_hasSeenPlugin { false };
@@ -1769,6 +1779,7 @@ private:
     HashMap<uint64_t, uint64_t> m_applicationManifestFetchCallbackMap;
 #endif
 
+    OptionSet<LayerTreeFreezeReason> m_LayerTreeFreezeReasons;
     bool m_isSuspended { false };
     bool m_needsFontAttributes { false };
 #if PLATFORM(MAC)
index fb1c0c6..35fe9f5 100644 (file)
@@ -2882,7 +2882,7 @@ void WebPage::applicationDidEnterBackground(bool isSuspendedUnderLock)
     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationDidEnterBackgroundNotification object:nil userInfo:@{@"isSuspendedUnderLock": [NSNumber numberWithBool:isSuspendedUnderLock]}];
 
     m_isSuspendedUnderLock = isSuspendedUnderLock;
-    setLayerTreeStateIsFrozen(true);
+    freezeLayerTree(LayerTreeFreezeReason::BackgroundApplication);
 
     if (m_page)
         m_page->applicationDidEnterBackground();
@@ -2897,7 +2897,7 @@ void WebPage::applicationWillEnterForeground(bool isSuspendedUnderLock)
 {
     m_isSuspendedUnderLock = false;
     cancelMarkLayersVolatile();
-    setLayerTreeStateIsFrozen(false);
+    unfreezeLayerTree(LayerTreeFreezeReason::BackgroundApplication);
 
     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationWillEnterForegroundNotification object:nil userInfo:@{@"isSuspendedUnderLock": @(isSuspendedUnderLock)}];
 
index c1e018f..f44e653 100644 (file)
@@ -1378,7 +1378,7 @@ void WebProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shou
     if (!m_suppressMemoryPressureHandler)
         MemoryPressureHandler::singleton().releaseMemory(Critical::Yes, Synchronous::Yes);
 
-    setAllLayerTreeStatesFrozen(true);
+    freezeAllLayerTrees();
     
 #if PLATFORM(COCOA)
     destroyRenderingResources();
@@ -1426,7 +1426,7 @@ void WebProcess::prepareToSuspend()
 void WebProcess::cancelPrepareToSuspend()
 {
     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::cancelPrepareToSuspend()", this);
-    setAllLayerTreeStatesFrozen(false);
+    unfreezeAllLayerTrees();
 
 #if PLATFORM(IOS_FAMILY)
     accessibilityProcessSuspendedNotification(false);
@@ -1474,18 +1474,24 @@ void WebProcess::cancelMarkAllLayersVolatile()
         page->cancelMarkLayersVolatile();
 }
 
-void WebProcess::setAllLayerTreeStatesFrozen(bool frozen)
+void WebProcess::freezeAllLayerTrees()
 {
     for (auto& page : m_pageMap.values())
-        page->setLayerTreeStateIsFrozen(frozen);
+        page->freezeLayerTree(WebPage::LayerTreeFreezeReason::ProcessSuspended);
 }
-    
+
+void WebProcess::unfreezeAllLayerTrees()
+{
+    for (auto& page : m_pageMap.values())
+        page->unfreezeLayerTree(WebPage::LayerTreeFreezeReason::ProcessSuspended);
+}
+
 void WebProcess::processDidResume()
 {
     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processDidResume()", this);
 
     cancelMarkAllLayersVolatile();
-    setAllLayerTreeStatesFrozen(false);
+    unfreezeAllLayerTrees();
     
 #if PLATFORM(IOS_FAMILY)
     accessibilityProcessSuspendedNotification(false);
index cde0b55..ebb848a 100644 (file)
@@ -260,7 +260,10 @@ private:
 
     void markAllLayersVolatile(WTF::Function<void(bool)>&& completionHandler);
     void cancelMarkAllLayersVolatile();
-    void setAllLayerTreeStatesFrozen(bool);
+
+    void freezeAllLayerTrees();
+    void unfreezeAllLayerTrees();
+
     void processSuspensionCleanupTimerFired();
 
     void clearCachedCredentials();