Title: [185123] trunk/Source/WebKit2
Revision
185123
Author
cdu...@apple.com
Date
2015-06-02 14:30:27 -0700 (Tue, 02 Jun 2015)

Log Message

[iOS][WK2] Always mark layers as volatile for background pages
https://bugs.webkit.org/show_bug.cgi?id=145547
<rdar://problem/20663184>

Reviewed by Simon Fraser.

We previously marked layers as volatile when the WebProcess was about
to be suspended. Most of the time the WebProcess gets suspended when a
page goes into the background. However, it is not always true (see
radar), in which case the layers won't be marked as volatile and use
memory even though they are not visible.

We now mark layers as volatile as soon as the page goes into the
background, instead of relying on the WebProcess suspension mechanism
to do so.

A new ApplicationDidEnterBackground IPC message from the UIProcess to
the WebProcess is added (in addition to the pre-existing
ApplicationWillEnterForeground one). When the WebProcess receives this
message, it will freeze the layer tree state and mark the layers as
volatile (with a timer to keep retrying if needed), similarly to what
is already done in WebProcess::actualPrepareToSuspend().
When the ApplicationWillEnterForeground is received, we unfreeze the
layer tree state. The layers' volatile state will be automatically
updated when they are displayed (see setBufferVolatility() call in
RemoteLayerBackingStore::display()).

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _applicationDidEnterBackground:]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::applicationDidEnterBackground):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage):
(WebKit::WebPage::setLayerTreeStateIsFrozen):
(WebKit::WebPage::markLayersVolatileImmediatelyIfPossible):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::volatilityTimerFired):
(WebKit::WebPage::applicationDidEnterBackground):
(WebKit::WebPage::applicationWillEnterForeground):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::markAllLayersVolatileIfPossible):
(WebKit::WebProcess::setAllLayerTreeStatesFrozen):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (185122 => 185123)


--- trunk/Source/WebKit2/ChangeLog	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/ChangeLog	2015-06-02 21:30:27 UTC (rev 185123)
@@ -1,3 +1,51 @@
+2015-06-02  Chris Dumez  <cdu...@apple.com>
+
+        [iOS][WK2] Always mark layers as volatile for background pages
+        https://bugs.webkit.org/show_bug.cgi?id=145547
+        <rdar://problem/20663184>
+
+        Reviewed by Simon Fraser.
+
+        We previously marked layers as volatile when the WebProcess was about
+        to be suspended. Most of the time the WebProcess gets suspended when a
+        page goes into the background. However, it is not always true (see
+        radar), in which case the layers won't be marked as volatile and use
+        memory even though they are not visible.
+
+        We now mark layers as volatile as soon as the page goes into the
+        background, instead of relying on the WebProcess suspension mechanism
+        to do so.
+
+        A new ApplicationDidEnterBackground IPC message from the UIProcess to
+        the WebProcess is added (in addition to the pre-existing
+        ApplicationWillEnterForeground one). When the WebProcess receives this
+        message, it will freeze the layer tree state and mark the layers as
+        volatile (with a timer to keep retrying if needed), similarly to what
+        is already done in WebProcess::actualPrepareToSuspend().
+        When the ApplicationWillEnterForeground is received, we unfreeze the
+        layer tree state. The layers' volatile state will be automatically
+        updated when they are displayed (see setBufferVolatility() call in
+        RemoteLayerBackingStore::display()).
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView _applicationDidEnterBackground:]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::applicationDidEnterBackground):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage):
+        (WebKit::WebPage::setLayerTreeStateIsFrozen):
+        (WebKit::WebPage::markLayersVolatileImmediatelyIfPossible):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::volatilityTimerFired):
+        (WebKit::WebPage::applicationDidEnterBackground):
+        (WebKit::WebPage::applicationWillEnterForeground):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::markAllLayersVolatileIfPossible):
+        (WebKit::WebProcess::setAllLayerTreeStatesFrozen):
+
 2015-06-02  Brady Eidson  <beid...@apple.com>
 
         WebKit policy delegate should suggest if a navigation should be allowed to open URLs externally.

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (185122 => 185123)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2015-06-02 21:30:27 UTC (rev 185123)
@@ -498,6 +498,7 @@
     void setAssistedNodeValue(const String&);
     void setAssistedNodeValueAsNumber(double);
     void setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection = false);
+    void applicationDidEnterBackground();
     void applicationWillEnterForeground();
     void applicationWillResignActive();
     void applicationDidBecomeActive();

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (185122 => 185123)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2015-06-02 21:30:27 UTC (rev 185123)
@@ -549,6 +549,7 @@
 - (void)_applicationDidEnterBackground:(NSNotification*)notification
 {
     _isBackground = YES;
+    _page->applicationDidEnterBackground();
     _page->viewStateDidChange(ViewState::AllFlags & ~ViewState::IsInWindow);
 }
 

Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (185122 => 185123)


--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm	2015-06-02 21:30:27 UTC (rev 185123)
@@ -593,6 +593,11 @@
     m_pageClient.didUpdateBlockSelectionWithTouch(touch, flags, growThreshold, shrinkThreshold);
 }
 
+void WebPageProxy::applicationDidEnterBackground()
+{
+    m_process->send(Messages::WebPage::ApplicationDidEnterBackground(), m_pageID);
+}
+
 void WebPageProxy::applicationWillEnterForeground()
 {
     m_process->send(Messages::WebPage::ApplicationWillEnterForeground(), m_pageID);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (185122 => 185123)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2015-06-02 21:30:27 UTC (rev 185123)
@@ -328,6 +328,7 @@
     , m_availableScreenSize(parameters.availableScreenSize)
     , m_deviceOrientation(0)
     , m_inDynamicSizeUpdate(false)
+    , m_volatilityTimer(*this, &WebPage::volatilityTimerFired)
 #endif
     , m_inspectorClient(0)
     , m_backgroundColor(Color::white)
@@ -1860,6 +1861,24 @@
     return g_currentEvent;
 }
 
+void WebPage::setLayerTreeStateIsFrozen(bool frozen)
+{
+    auto* drawingArea = this->drawingArea();
+    if (!drawingArea)
+        return;
+
+    drawingArea->setLayerTreeStateIsFrozen(frozen);
+}
+
+bool WebPage::markLayersVolatileImmediatelyIfPossible()
+{
+    auto* drawingArea = this->drawingArea();
+    if (!drawingArea)
+        return true;
+
+    return drawingArea->markLayersVolatileImmediatelyIfPossible();
+}
+
 class CurrentEvent {
 public:
     explicit CurrentEvent(const WebEvent& event)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (185122 => 185123)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2015-06-02 21:30:27 UTC (rev 185123)
@@ -553,6 +553,9 @@
     void disableInspectorNodeSearch();
 #endif
 
+    void setLayerTreeStateIsFrozen(bool);
+    bool markLayersVolatileImmediatelyIfPossible();
+
     NotificationPermissionRequestManager* notificationPermissionRequestManager();
 
     void pageDidScroll();
@@ -789,6 +792,7 @@
     bool scaleWasSetByUIProcess() const { return m_scaleWasSetByUIProcess; }
     void willStartUserTriggeredZooming();
     void applicationWillResignActive();
+    void applicationDidEnterBackground();
     void applicationWillEnterForeground();
     void applicationDidBecomeActive();
     void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale);
@@ -918,6 +922,7 @@
     void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*);
     void resetTextAutosizingBeforeLayoutIfNeeded(const WebCore::FloatSize& oldSize, const WebCore::FloatSize& newSize);
     WebCore::VisiblePosition visiblePositionInFocusedNodeForPoint(WebCore::Frame&, const WebCore::IntPoint&);
+    void volatilityTimerFired();
 #endif
 #if !PLATFORM(COCOA)
     static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
@@ -1340,6 +1345,7 @@
     RefPtr<WebCore::Node> m_pendingSyntheticClickNode;
     WebCore::FloatPoint m_pendingSyntheticClickLocation;
     WebCore::FloatRect m_previousExposedContentRect;
+    WebCore::Timer m_volatilityTimer;
 #endif
 
     WebInspectorClient* m_inspectorClient;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (185122 => 185123)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2015-06-02 21:30:27 UTC (rev 185123)
@@ -88,6 +88,7 @@
     SetAssistedNodeValueAsNumber(double value)
     SetAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection)
     ApplicationWillResignActive()
+    ApplicationDidEnterBackground()
     ApplicationWillEnterForeground()
     ApplicationDidBecomeActive()
     ContentSizeCategoryDidChange(String contentSizeCategory)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (185122 => 185123)


--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2015-06-02 21:30:27 UTC (rev 185123)
@@ -2718,8 +2718,28 @@
     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationWillResignActiveNotification object:nil];
 }
 
+void WebPage::volatilityTimerFired()
+{
+    if (!markLayersVolatileImmediatelyIfPossible())
+        return;
+
+    m_volatilityTimer.stop();
+}
+
+void WebPage::applicationDidEnterBackground()
+{
+    setLayerTreeStateIsFrozen(true);
+    if (markLayersVolatileImmediatelyIfPossible())
+        return;
+
+    m_volatilityTimer.startRepeating(std::chrono::milliseconds(200));
+}
+
 void WebPage::applicationWillEnterForeground()
 {
+    m_volatilityTimer.stop();
+    setLayerTreeStateIsFrozen(false);
+
     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationWillEnterForegroundNotification object:nil];
 }
 

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (185122 => 185123)


--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2015-06-02 21:24:10 UTC (rev 185122)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2015-06-02 21:30:27 UTC (rev 185123)
@@ -1266,20 +1266,16 @@
 bool WebProcess::markAllLayersVolatileIfPossible()
 {
     bool successfullyMarkedAllLayersVolatile = true;
-    for (auto& page : m_pageMap.values()) {
-        if (auto drawingArea = page->drawingArea())
-            successfullyMarkedAllLayersVolatile &= drawingArea->markLayersVolatileImmediatelyIfPossible();
-    }
+    for (auto& page : m_pageMap.values())
+        successfullyMarkedAllLayersVolatile &= page->markLayersVolatileImmediatelyIfPossible();
 
     return successfullyMarkedAllLayersVolatile;
 }
 
 void WebProcess::setAllLayerTreeStatesFrozen(bool frozen)
 {
-    for (auto& page : m_pageMap.values()) {
-        if (auto drawingArea = page->drawingArea())
-            drawingArea->setLayerTreeStateIsFrozen(frozen);
-    }
+    for (auto& page : m_pageMap.values())
+        page->setLayerTreeStateIsFrozen(frozen);
 }
 
 void WebProcess::processSuspensionCleanupTimerFired()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to