⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 201519 in webkit


Ignore:
Timestamp:
May 31, 2016, 12:35:06 PM (10 years ago)
Author:
Chris Dumez
Message:

[iOS] Better deal with WebProcess suspension due to screen locking
https://bugs.webkit.org/show_bug.cgi?id=158229
<rdar://problem/17665473>
<rdar://problem/26554699>

Reviewed by Tim Horton.

When locking the screen while MobileSafari is front-most, we would try keep
trying to mark IOSurfaces as volatile until the 30 seconds timeout was
reached. This patch deals more cleanly with this situation by only trying
to mark IOSurfaces as volatile once if the suspension is due to screen
locking. In such case, it is apparently expected that some IOSurfaces cannot
be marked as volatile so it is enough to try once and let ourselves get
suspended.

This patch also reduces the timeout from 30 seconds to ~3 seconds in the
other suspension cases (e.g. homing out of MobileSafari). If we fail to mark
them as purgeable for 3 seconds for a reason or another, it is no use in
retrying, it is simply not going to happen and there is no reason to delay
process suspension any further.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::callVolatilityCompletionHandlers):
(WebKit::WebPage::layerVolatilityTimerFired):
(WebKit::WebPage::markLayersVolatileImmediatelyIfPossible):
(WebKit::WebPage::markLayersVolatile):

  • WebProcess/WebPage/WebPage.h:

(WebKit::WebPage::markLayersVolatile):

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::applicationDidEnterBackground):
(WebKit::WebPage::applicationWillEnterForeground):

Location:
trunk/Source/WebKit2
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r201518 r201519  
     12016-05-31  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] Better deal with WebProcess suspension due to screen locking
     4        https://bugs.webkit.org/show_bug.cgi?id=158229
     5        <rdar://problem/17665473>
     6        <rdar://problem/26554699>
     7
     8        Reviewed by Tim Horton.
     9
     10        When locking the screen while MobileSafari is front-most, we would try keep
     11        trying to mark IOSurfaces as volatile until the 30 seconds timeout was
     12        reached. This patch deals more cleanly with this situation by only trying
     13        to mark IOSurfaces as volatile once if the suspension is due to screen
     14        locking. In such case, it is apparently expected that some IOSurfaces cannot
     15        be marked as volatile so it is enough to try once and let ourselves get
     16        suspended.
     17
     18        This patch also reduces the timeout from 30 seconds to ~3 seconds in the
     19        other suspension cases (e.g. homing out of MobileSafari). If we fail to mark
     20        them as purgeable for 3 seconds for a reason or another, it is no use in
     21        retrying, it is simply not going to happen and there is no reason to delay
     22        process suspension any further.
     23
     24        * WebProcess/WebPage/WebPage.cpp:
     25        (WebKit::WebPage::callVolatilityCompletionHandlers):
     26        (WebKit::WebPage::layerVolatilityTimerFired):
     27        (WebKit::WebPage::markLayersVolatileImmediatelyIfPossible):
     28        (WebKit::WebPage::markLayersVolatile):
     29        * WebProcess/WebPage/WebPage.h:
     30        (WebKit::WebPage::markLayersVolatile):
     31        * WebProcess/WebPage/ios/WebPageIOS.mm:
     32        (WebKit::WebPage::applicationDidEnterBackground):
     33        (WebKit::WebPage::applicationWillEnterForeground):
     34
    1352016-05-31  Brady Eidson  <beidson@apple.com>
    236
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r201440 r201519  
    249249static const double pageScrollHysteresisSeconds = 0.3;
    250250static const std::chrono::milliseconds initialLayerVolatilityTimerInterval { 20 };
    251 static const std::chrono::seconds maximumLayerVolatilityTimerInterval { 10 };
     251static const std::chrono::seconds maximumLayerVolatilityTimerInterval { 2 };
    252252
    253253#define WEBPAGE_LOG_ALWAYS(...) LOG_ALWAYS(isAlwaysOnLoggingAllowed(), __VA_ARGS__)
     
    20382038}
    20392039
     2040void WebPage::callVolatilityCompletionHandlers()
     2041{
     2042    auto completionHandlers = WTFMove(m_markLayersAsVolatileCompletionHandlers);
     2043    for (auto& completionHandler : completionHandlers)
     2044        completionHandler();
     2045}
     2046
    20402047void WebPage::layerVolatilityTimerFired()
    20412048{
    2042     if (markLayersVolatileImmediatelyIfPossible()) {
     2049    auto newInterval = 2 * m_layerVolatilityTimer.repeatIntervalMS();
     2050    bool didSucceed = markLayersVolatileImmediatelyIfPossible();
     2051    if (didSucceed || newInterval > maximumLayerVolatilityTimerInterval) {
    20432052        m_layerVolatilityTimer.stop();
    2044         return;
    2045     }
    2046 
    2047     auto newInterval = std::min(2 * m_layerVolatilityTimer.repeatIntervalMS(), std::chrono::duration_cast<std::chrono::milliseconds>(maximumLayerVolatilityTimerInterval));
     2053        WEBPAGE_LOG_ALWAYS("%p - WebPage - Attempted to mark surfaces as volatile, success? %d", this, didSucceed);
     2054        callVolatilityCompletionHandlers();
     2055        return;
     2056    }
     2057
    20482058    WEBPAGE_LOG_ALWAYS_ERROR("%p - WebPage - Failed to mark all layers as volatile, will retry in %lld ms", this, static_cast<long long>(newInterval.count()));
    20492059    m_layerVolatilityTimer.startRepeating(newInterval);
     
    20522062bool WebPage::markLayersVolatileImmediatelyIfPossible()
    20532063{
    2054     bool success = !drawingArea() || drawingArea()->markLayersVolatileImmediatelyIfPossible();
    2055     if (success) {
    2056         WEBPAGE_LOG_ALWAYS("%p - WebPage - Successfully marked layers as volatile", this);
    2057         auto completionHandlers = WTFMove(m_markLayersAsVolatileCompletionHandlers);
    2058         for (auto& completionHandler : completionHandlers)
    2059             completionHandler();
    2060     }
    2061 
    2062     return success;
    2063 }
    2064 
    2065 void WebPage::markLayersVolatile(std::function<void()> completionHandler)
     2064    return !drawingArea() || drawingArea()->markLayersVolatileImmediatelyIfPossible();
     2065}
     2066
     2067void WebPage::markLayersVolatile(std::function<void ()> completionHandler)
    20662068{
    20672069    WEBPAGE_LOG_ALWAYS("%p - WebPage::markLayersVolatile()", this);
     
    20732075        m_markLayersAsVolatileCompletionHandlers.append(WTFMove(completionHandler));
    20742076
    2075     if (markLayersVolatileImmediatelyIfPossible())
    2076         return;
     2077    bool didSucceed = markLayersVolatileImmediatelyIfPossible();
     2078    if (didSucceed || m_isSuspendedUnderLock) {
     2079        if (didSucceed)
     2080            WEBPAGE_LOG_ALWAYS("%p - WebPage - Successfully marked layers as volatile", this);
     2081        else {
     2082            // If we get suspended when locking the screen, it is expected that some IOSurfaces cannot be marked as purgeable so we do not keep retrying.
     2083            WEBPAGE_LOG_ALWAYS("%p - WebPage - Did what we could to mark IOSurfaces as purgeable after locking the screen", this);
     2084        }
     2085        callVolatilityCompletionHandlers();
     2086        return;
     2087    }
    20772088
    20782089    WEBPAGE_LOG_ALWAYS("%p - Failed to mark all layers as volatile, will retry in %lld ms", this, initialLayerVolatilityTimerInterval.count());
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r201298 r201519  
    583583
    584584    void setLayerTreeStateIsFrozen(bool);
    585     void markLayersVolatile(std::function<void()> completionHandler = {});
     585    void markLayersVolatile(std::function<void ()> completionHandler = { });
    586586    void cancelMarkLayersVolatile();
    587587
     
    993993    bool markLayersVolatileImmediatelyIfPossible();
    994994    void layerVolatilityTimerFired();
     995    void callVolatilityCompletionHandlers();
    995996
    996997    String sourceForFrame(WebFrame*);
     
    14271428
    14281429    WebCore::Timer m_layerVolatilityTimer;
    1429     Vector<std::function<void()>> m_markLayersAsVolatileCompletionHandlers;
     1430    Vector<std::function<void ()>> m_markLayersAsVolatileCompletionHandlers;
     1431    bool m_isSuspendedUnderLock { false };
    14301432
    14311433    HashSet<String, ASCIICaseInsensitiveHash> m_mimeTypesWithCustomContentProviders;
  • trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

    r201453 r201519  
    29742974    [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationDidEnterBackgroundNotification object:nil userInfo:@{@"isSuspendedUnderLock": [NSNumber numberWithBool:isSuspendedUnderLock]}];
    29752975
     2976    m_isSuspendedUnderLock = isSuspendedUnderLock;
    29762977    setLayerTreeStateIsFrozen(true);
    29772978    markLayersVolatile();
     
    29802981void WebPage::applicationWillEnterForeground(bool isSuspendedUnderLock)
    29812982{
     2983    m_isSuspendedUnderLock = false;
    29822984    cancelMarkLayersVolatile();
    29832985    setLayerTreeStateIsFrozen(false);
Note: See TracChangeset for help on using the changeset viewer.