Title: [169370] trunk/Source
Revision
169370
Author
timothy_hor...@apple.com
Date
2014-05-26 23:14:15 -0700 (Mon, 26 May 2014)

Log Message

[wk2] RemoteLayerBackingStore front buffers should be purgeable when unparented
https://bugs.webkit.org/show_bug.cgi?id=133020
<rdar://problem/16521736>

Reviewed by Simon Fraser.

* Shared/mac/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::display):
Let the context know whenever a RemoteLayerBackingStore is displayed, so that
RemoteLayerBackingStoreCollection can (if needed) note that the backing store
is active once again (because we only display parented backing store).

(WebKit::RemoteLayerBackingStore::setBufferVolatility):
Ensure that we never have live contexts attached to any buffers when
marking them volatile, because checking isInUse() with live contexts is futile.

* Shared/mac/RemoteLayerBackingStoreCollection.h:
* Shared/mac/RemoteLayerBackingStoreCollection.mm:
(WebKit::RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection):
(WebKit::RemoteLayerBackingStoreCollection::willFlushLayers):
(WebKit::RemoteLayerBackingStoreCollection::willCommitLayerTree):
(WebKit::RemoteLayerBackingStoreCollection::didFlushLayers):
(WebKit::RemoteLayerBackingStoreCollection::backingStoreWillBeDestroyed):
(WebKit::RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed):
(WebKit::RemoteLayerBackingStoreCollection::markBackingStoreVolatileImmediately):
(WebKit::RemoteLayerBackingStoreCollection::markBackingStoreVolatile):
(WebKit::RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable):
(WebKit::RemoteLayerBackingStoreCollection::volatilityTimerFired):
(WebKit::RemoteLayerBackingStoreCollection::scheduleVolatilityTimer):
(WebKit::RemoteLayerBackingStoreCollection::purgeabilityTimerFired): Deleted.
(WebKit::RemoteLayerBackingStoreCollection::schedulePurgeabilityTimer): Deleted.
Rename purgeable->volatile for accuracy.
Keep track of two sets of backing store: those which are active/parented, and
those which are not. Backing store is moved to the inactive set after building
the transaction in which its owning layer is unparented.
When backing store is unparented, try to mark it volatile immediately. Also,
mark the backing store property as dirty on the owning layer so that when
said layer is reparented, we encode the backing store in the commit that reparents it,
as the UI process will throw away its reference to the backing store when
the layer is unparented. Mark the front buffers of unparented layers as volatile,
in addition to the others.

* Shared/mac/RemoteLayerTreeTransaction.h:
(WebKit::RemoteLayerTreeTransaction::layerIDsWithNewlyUnreachableBackingStore):
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::encode):
(WebKit::RemoteLayerTreeTransaction::decode):
(WebKit::RemoteLayerTreeTransaction::setLayerIDsWithNewlyUnreachableBackingStore):
Include the list of layers (by ID) with backing store which just became unreachable in the transaction.

* UIProcess/mac/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::updateLayerTree):
Clear the contents of layers which now have unreachable backing store.
Otherwise, the UI process would hold a 'use' on the IOSurface, and prevent
the Web process from marking it volatile.

* WebProcess/WebPage/mac/RemoteLayerTreeContext.h:
* WebProcess/WebPage/mac/RemoteLayerTreeContext.mm:
(WebKit::RemoteLayerTreeContext::backingStoreWillBeDisplayed):
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::flushLayers):
Give RemoteLayerBackingStoreCollection a shot at the RemoteLayerTreeTransaction,
so that it can fill in layerIDsWithNewlyUnreachableBackingStore.
Also, let it know when the flush begins and ends, so that it can keep track
of which layers were reached in the flush.

* WebCore.exp.in:
* platform/graphics/cg/IOSurfacePool.cpp:
(WebCore::IOSurfacePool::willAddSurface):
* platform/graphics/cocoa/IOSurface.h:
* platform/graphics/cocoa/IOSurface.mm:
(IOSurface::releaseGraphicsContext):
Rename clearGraphicsContext to releaseGraphicsContext for clarity.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (169369 => 169370)


--- trunk/Source/WebCore/ChangeLog	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebCore/ChangeLog	2014-05-27 06:14:15 UTC (rev 169370)
@@ -1,3 +1,19 @@
+2014-05-26  Tim Horton  <timothy_hor...@apple.com>
+
+        [wk2] RemoteLayerBackingStore front buffers should be purgeable when unparented
+        https://bugs.webkit.org/show_bug.cgi?id=133020
+        <rdar://problem/16521736>
+
+        Reviewed by Simon Fraser.
+
+        * WebCore.exp.in:
+        * platform/graphics/cg/IOSurfacePool.cpp:
+        (WebCore::IOSurfacePool::willAddSurface):
+        * platform/graphics/cocoa/IOSurface.h:
+        * platform/graphics/cocoa/IOSurface.mm:
+        (IOSurface::releaseGraphicsContext):
+        Rename clearGraphicsContext to releaseGraphicsContext for clarity.
+
 2014-05-26  Philip Rogers  <p...@google.com>
 
         Remove special case for transparent SVG root layers

Modified: trunk/Source/WebCore/WebCore.exp.in (169369 => 169370)


--- trunk/Source/WebCore/WebCore.exp.in	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebCore/WebCore.exp.in	2014-05-27 06:14:15 UTC (rev 169370)
@@ -3143,9 +3143,9 @@
 __ZN7WebCore9IOSurface11createImageEv
 __ZN7WebCore9IOSurface13setIsVolatileEb
 __ZN7WebCore9IOSurface18createFromMachPortEjNS_10ColorSpaceE
-__ZN7WebCore9IOSurface20clearGraphicsContextEv
 __ZN7WebCore9IOSurface21ensureGraphicsContextEv
 __ZN7WebCore9IOSurface21ensurePlatformContextEv
+__ZN7WebCore9IOSurface22releaseGraphicsContextEv
 __ZN7WebCore9IOSurface6createENS_7IntSizeENS_10ColorSpaceE
 __ZNK7WebCore9IOSurface14createMachPortEv
 __ZNK7WebCore9IOSurface7isInUseEv

Modified: trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp (169369 => 169370)


--- trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp	2014-05-27 06:14:15 UTC (rev 169370)
@@ -80,7 +80,7 @@
     CachedSurfaceDetails& details = m_surfaceDetails.add(surface, CachedSurfaceDetails()).iterator->value;
     details.resetLastUseTime();
 
-    surface->clearGraphicsContext();
+    surface->releaseGraphicsContext();
 
     size_t surfaceBytes = surface->totalBytes();
 

Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h (169369 => 169370)


--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h	2014-05-27 06:14:15 UTC (rev 169370)
@@ -75,7 +75,7 @@
 
     // The graphics context cached on the surface counts as a "user", so to get
     // an accurate result from isInUse(), it needs to be released.
-    void clearGraphicsContext();
+    void releaseGraphicsContext();
 
 private:
     IOSurface(IntSize, ColorSpace);

Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm (169369 => 169370)


--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -191,7 +191,7 @@
     return IOSurfaceIsInUse(m_surface.get());
 }
 
-void IOSurface::clearGraphicsContext()
+void IOSurface::releaseGraphicsContext()
 {
     m_graphicsContext = nullptr;
     m_cgContext = nullptr;

Modified: trunk/Source/WebKit2/ChangeLog (169369 => 169370)


--- trunk/Source/WebKit2/ChangeLog	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/ChangeLog	2014-05-27 06:14:15 UTC (rev 169370)
@@ -1,3 +1,71 @@
+2014-05-26  Tim Horton  <timothy_hor...@apple.com>
+
+        [wk2] RemoteLayerBackingStore front buffers should be purgeable when unparented
+        https://bugs.webkit.org/show_bug.cgi?id=133020
+        <rdar://problem/16521736>
+
+        Reviewed by Simon Fraser.
+
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        (WebKit::RemoteLayerBackingStore::display):
+        Let the context know whenever a RemoteLayerBackingStore is displayed, so that
+        RemoteLayerBackingStoreCollection can (if needed) note that the backing store
+        is active once again (because we only display parented backing store).
+
+        (WebKit::RemoteLayerBackingStore::setBufferVolatility):
+        Ensure that we never have live contexts attached to any buffers when
+        marking them volatile, because checking isInUse() with live contexts is futile.
+
+        * Shared/mac/RemoteLayerBackingStoreCollection.h:
+        * Shared/mac/RemoteLayerBackingStoreCollection.mm:
+        (WebKit::RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection):
+        (WebKit::RemoteLayerBackingStoreCollection::willFlushLayers):
+        (WebKit::RemoteLayerBackingStoreCollection::willCommitLayerTree):
+        (WebKit::RemoteLayerBackingStoreCollection::didFlushLayers):
+        (WebKit::RemoteLayerBackingStoreCollection::backingStoreWillBeDestroyed):
+        (WebKit::RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed):
+        (WebKit::RemoteLayerBackingStoreCollection::markBackingStoreVolatileImmediately):
+        (WebKit::RemoteLayerBackingStoreCollection::markBackingStoreVolatile):
+        (WebKit::RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable):
+        (WebKit::RemoteLayerBackingStoreCollection::volatilityTimerFired):
+        (WebKit::RemoteLayerBackingStoreCollection::scheduleVolatilityTimer):
+        (WebKit::RemoteLayerBackingStoreCollection::purgeabilityTimerFired): Deleted.
+        (WebKit::RemoteLayerBackingStoreCollection::schedulePurgeabilityTimer): Deleted.
+        Rename purgeable->volatile for accuracy.
+        Keep track of two sets of backing store: those which are active/parented, and
+        those which are not. Backing store is moved to the inactive set after building
+        the transaction in which its owning layer is unparented.
+        When backing store is unparented, try to mark it volatile immediately. Also,
+        mark the backing store property as dirty on the owning layer so that when
+        said layer is reparented, we encode the backing store in the commit that reparents it,
+        as the UI process will throw away its reference to the backing store when
+        the layer is unparented. Mark the front buffers of unparented layers as volatile,
+        in addition to the others.
+
+        * Shared/mac/RemoteLayerTreeTransaction.h:
+        (WebKit::RemoteLayerTreeTransaction::layerIDsWithNewlyUnreachableBackingStore):
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::encode):
+        (WebKit::RemoteLayerTreeTransaction::decode):
+        (WebKit::RemoteLayerTreeTransaction::setLayerIDsWithNewlyUnreachableBackingStore):
+        Include the list of layers (by ID) with backing store which just became unreachable in the transaction.
+
+        * UIProcess/mac/RemoteLayerTreeHost.mm:
+        (WebKit::RemoteLayerTreeHost::updateLayerTree):
+        Clear the contents of layers which now have unreachable backing store.
+        Otherwise, the UI process would hold a 'use' on the IOSurface, and prevent
+        the Web process from marking it volatile.
+
+        * WebProcess/WebPage/mac/RemoteLayerTreeContext.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeContext.mm:
+        (WebKit::RemoteLayerTreeContext::backingStoreWillBeDisplayed):
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::flushLayers):
+        Give RemoteLayerBackingStoreCollection a shot at the RemoteLayerTreeTransaction,
+        so that it can fill in layerIDsWithNewlyUnreachableBackingStore.
+        Also, let it know when the flush begins and ends, so that it can keep track
+        of which layers were reached in the flush.
+
 2014-05-26  Shivakumar JM  <shiva...@samsung.com>
 
         [EFL][WK2] Fix EWK2BackForwardListTest test fails.

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm (169369 => 169370)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -201,6 +201,9 @@
 
     m_lastDisplayTime = std::chrono::steady_clock::now();
 
+    if (m_context)
+        m_context->backingStoreWillBeDisplayed(this);
+
     // Make the previous front buffer non-volatile early, so that we can dirty the whole layer if it comes back empty.
     setBufferVolatility(BufferType::Front, false);
 
@@ -236,7 +239,7 @@
         context.translate(0, -expandedScaledSize.height());
         drawInContext(context, backImage.get());
 
-        m_frontBuffer.surface->clearGraphicsContext();
+        m_frontBuffer.surface->releaseGraphicsContext();
 
         return true;
     }
@@ -382,6 +385,8 @@
     switch(type) {
     case BufferType::Front:
         if (m_frontBuffer.surface && m_frontBuffer.isVolatile != isVolatile) {
+            if (isVolatile)
+                m_frontBuffer.surface->releaseGraphicsContext();
             if (!isVolatile || !m_frontBuffer.surface->isInUse()) {
                 IOSurface::SurfaceState previousState = m_frontBuffer.surface->setIsVolatile(isVolatile);
                 m_frontBuffer.isVolatile = isVolatile;
@@ -395,6 +400,8 @@
         break;
     case BufferType::Back:
         if (m_backBuffer.surface && m_backBuffer.isVolatile != isVolatile) {
+            if (isVolatile)
+                m_backBuffer.surface->releaseGraphicsContext();
             if (!isVolatile || !m_backBuffer.surface->isInUse()) {
                 m_backBuffer.surface->setIsVolatile(isVolatile);
                 m_backBuffer.isVolatile = isVolatile;
@@ -404,6 +411,8 @@
         break;
     case BufferType::SecondaryBack:
         if (m_secondaryBackBuffer.surface && m_secondaryBackBuffer.isVolatile != isVolatile) {
+            if (isVolatile)
+                m_secondaryBackBuffer.surface->releaseGraphicsContext();
             if (!isVolatile || !m_secondaryBackBuffer.surface->isInUse()) {
                 m_secondaryBackBuffer.surface->setIsVolatile(isVolatile);
                 m_secondaryBackBuffer.isVolatile = isVolatile;

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.h (169369 => 169370)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.h	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.h	2014-05-27 06:14:15 UTC (rev 169370)
@@ -34,6 +34,7 @@
 
 class RemoteLayerBackingStore;
 class RemoteLayerTreeContext;
+class RemoteLayerTreeTransaction;
 
 class RemoteLayerBackingStoreCollection {
     WTF_MAKE_NONCOPYABLE(RemoteLayerBackingStoreCollection);
@@ -45,17 +46,29 @@
     void backingStoreWasCreated(RemoteLayerBackingStore*);
     void backingStoreWillBeDestroyed(RemoteLayerBackingStore*);
 
-    void purgeabilityTimerFired(WebCore::Timer<RemoteLayerBackingStoreCollection>&);
+    void backingStoreWillBeDisplayed(RemoteLayerBackingStore*);
+    void backingStoreBecameUnreachable(RemoteLayerBackingStore*);
 
-    void schedulePurgeabilityTimer();
+    void willFlushLayers();
+    void willCommitLayerTree(RemoteLayerTreeTransaction&);
+    void didFlushLayers();
 
+    void volatilityTimerFired(WebCore::Timer<RemoteLayerBackingStoreCollection>&);
+
+    void scheduleVolatilityTimer();
+
 private:
+    bool markBackingStoreVolatileImmediately(RemoteLayerBackingStore&);
+    bool markBackingStoreVolatile(RemoteLayerBackingStore&, std::chrono::steady_clock::time_point now);
+
     HashSet<RemoteLayerBackingStore*> m_liveBackingStore;
+    HashSet<RemoteLayerBackingStore*> m_unparentedBackingStore;
+    HashSet<RemoteLayerBackingStore*> m_reachableBackingStoreInLatestFlush;
 
-    void markInactiveBackingStorePurgeable();
+    RemoteLayerTreeContext* m_context;
+    WebCore::Timer<RemoteLayerBackingStoreCollection> m_volatilityTimer;
 
-    RemoteLayerTreeContext* m_context;
-    WebCore::Timer<RemoteLayerBackingStoreCollection> m_purgeabilityTimer;
+    bool m_inLayerFlush;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.mm (169369 => 169370)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -30,18 +30,54 @@
 #import "RemoteLayerBackingStore.h"
 #import "RemoteLayerTreeContext.h"
 
-const std::chrono::seconds purgeableBackingStoreAgeThreshold = 1_s;
-const std::chrono::milliseconds purgeableSecondaryBackingStoreAgeThreshold = 200_ms;
-const std::chrono::milliseconds purgeabilityTimerInterval = 200_ms;
+const std::chrono::seconds volatileBackingStoreAgeThreshold = 1_s;
+const std::chrono::milliseconds volatileSecondaryBackingStoreAgeThreshold = 200_ms;
+const std::chrono::milliseconds volatilityTimerInterval = 200_ms;
 
 namespace WebKit {
 
 RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection(RemoteLayerTreeContext* context)
     : m_context(context)
-    , m_purgeabilityTimer(this, &RemoteLayerBackingStoreCollection::purgeabilityTimerFired)
+    , m_volatilityTimer(this, &RemoteLayerBackingStoreCollection::volatilityTimerFired)
+    , m_inLayerFlush(false)
 {
 }
 
+void RemoteLayerBackingStoreCollection::willFlushLayers()
+{
+    m_inLayerFlush = true;
+    m_reachableBackingStoreInLatestFlush.clear();
+}
+
+void RemoteLayerBackingStoreCollection::willCommitLayerTree(RemoteLayerTreeTransaction& transaction)
+{
+    ASSERT(m_inLayerFlush);
+    Vector<WebCore::GraphicsLayer::PlatformLayerID> newlyUnreachableLayerIDs;
+    for (auto& backingStore : m_liveBackingStore) {
+        if (!m_reachableBackingStoreInLatestFlush.contains(backingStore))
+            newlyUnreachableLayerIDs.append(backingStore->layer()->layerID());
+    }
+
+    transaction.setLayerIDsWithNewlyUnreachableBackingStore(newlyUnreachableLayerIDs);
+}
+
+void RemoteLayerBackingStoreCollection::didFlushLayers()
+{
+    m_inLayerFlush = false;
+
+    Vector<RemoteLayerBackingStore*> newlyUnreachableBackingStore;
+    for (auto& backingStore : m_liveBackingStore) {
+        if (!m_reachableBackingStoreInLatestFlush.contains(backingStore))
+            newlyUnreachableBackingStore.append(backingStore);
+    }
+
+    for (auto& backingStore : newlyUnreachableBackingStore)
+        backingStoreBecameUnreachable(backingStore);
+
+    if (!newlyUnreachableBackingStore.isEmpty())
+        scheduleVolatilityTimer();
+}
+
 void RemoteLayerBackingStoreCollection::backingStoreWasCreated(RemoteLayerBackingStore* backingStore)
 {
     m_liveBackingStore.add(backingStore);
@@ -50,41 +86,92 @@
 void RemoteLayerBackingStoreCollection::backingStoreWillBeDestroyed(RemoteLayerBackingStore* backingStore)
 {
     m_liveBackingStore.remove(backingStore);
+    m_unparentedBackingStore.remove(backingStore);
 }
 
-void RemoteLayerBackingStoreCollection::purgeabilityTimerFired(WebCore::Timer<RemoteLayerBackingStoreCollection>&)
+void RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed(RemoteLayerBackingStore* backingStore)
 {
-    auto now = std::chrono::steady_clock::now();
-    bool hadRecentlyPaintedBackingStore = false;
-    bool successfullyMadeBackingStorePurgeable = true;
+    ASSERT(m_inLayerFlush);
+    m_reachableBackingStoreInLatestFlush.add(backingStore);
 
-    for (const auto& backingStore : m_liveBackingStore) {
-        if (now - backingStore->lastDisplayTime() < purgeableBackingStoreAgeThreshold) {
-            hadRecentlyPaintedBackingStore = true;
+    auto backingStoreIter = m_unparentedBackingStore.find(backingStore);
+    if (backingStoreIter == m_unparentedBackingStore.end())
+        return;
+    m_liveBackingStore.add(backingStore);
+    m_unparentedBackingStore.remove(backingStoreIter);
+}
 
-            if (now - backingStore->lastDisplayTime() >= purgeableSecondaryBackingStoreAgeThreshold)
-                backingStore->setBufferVolatility(RemoteLayerBackingStore::BufferType::SecondaryBack, true);
+bool RemoteLayerBackingStoreCollection::markBackingStoreVolatileImmediately(RemoteLayerBackingStore& backingStore)
+{
+    ASSERT(!m_inLayerFlush);
+    bool successfullyMadeBackingStoreVolatile = true;
 
-            continue;
-        }
+    if (!backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::SecondaryBack, true))
+        successfullyMadeBackingStoreVolatile = false;
 
-        // FIXME: If the layer is unparented, we should make all buffers volatile.
-        if (!backingStore->setBufferVolatility(RemoteLayerBackingStore::BufferType::SecondaryBack, true))
-            successfullyMadeBackingStorePurgeable = false;
-        if (!backingStore->setBufferVolatility(RemoteLayerBackingStore::BufferType::Back, true))
-            successfullyMadeBackingStorePurgeable = false;
+    if (!backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::Back, true))
+        successfullyMadeBackingStoreVolatile = false;
+
+    if (!m_reachableBackingStoreInLatestFlush.contains(&backingStore)) {
+        if (!backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::Front, true))
+            successfullyMadeBackingStoreVolatile = false;
     }
 
-    if (!hadRecentlyPaintedBackingStore && successfullyMadeBackingStorePurgeable)
-        m_purgeabilityTimer.stop();
+    return successfullyMadeBackingStoreVolatile;
 }
 
-void RemoteLayerBackingStoreCollection::schedulePurgeabilityTimer()
+bool RemoteLayerBackingStoreCollection::markBackingStoreVolatile(RemoteLayerBackingStore& backingStore, std::chrono::steady_clock::time_point now)
 {
-    if (m_purgeabilityTimer.isActive())
+    if (now - backingStore.lastDisplayTime() < volatileBackingStoreAgeThreshold) {
+        if (now - backingStore.lastDisplayTime() >= volatileSecondaryBackingStoreAgeThreshold)
+            backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::SecondaryBack, true);
+
+        return false;
+    }
+    
+    return markBackingStoreVolatileImmediately(backingStore);
+}
+
+void RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable(RemoteLayerBackingStore* backingStore)
+{
+    ASSERT(backingStore->layer());
+
+    auto backingStoreIter = m_liveBackingStore.find(backingStore);
+    if (backingStoreIter == m_liveBackingStore.end())
         return;
+    m_unparentedBackingStore.add(backingStore);
+    m_liveBackingStore.remove(backingStoreIter);
 
-    m_purgeabilityTimer.startRepeating(purgeabilityTimerInterval);
+    // If a layer with backing store is removed from the tree, mark it as having changed backing store, so that
+    // on the commit which returns it to the tree, we serialize the backing store (despite possibly not painting).
+    backingStore->layer()->properties().notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreChanged);
+
+    // This will not succeed in marking all buffers as volatile, because the commit unparenting the layer hasn't
+    // made it to the UI process yet. The volatility timer will finish marking the remaining buffers later.
+    markBackingStoreVolatileImmediately(*backingStore);
 }
 
+void RemoteLayerBackingStoreCollection::volatilityTimerFired(WebCore::Timer<RemoteLayerBackingStoreCollection>&)
+{
+    bool successfullyMadeBackingStoreVolatile = true;
+
+    auto now = std::chrono::steady_clock::now();
+    for (const auto& backingStore : m_liveBackingStore)
+        successfullyMadeBackingStoreVolatile &= markBackingStoreVolatile(*backingStore, now);
+
+    for (const auto& backingStore : m_unparentedBackingStore)
+        successfullyMadeBackingStoreVolatile &= markBackingStoreVolatileImmediately(*backingStore);
+
+    if (successfullyMadeBackingStoreVolatile)
+        m_volatilityTimer.stop();
+}
+
+void RemoteLayerBackingStoreCollection::scheduleVolatilityTimer()
+{
+    if (m_volatilityTimer.isActive())
+        return;
+
+    m_volatilityTimer.startRepeating(volatilityTimerInterval);
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h (169369 => 169370)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h	2014-05-27 06:14:15 UTC (rev 169370)
@@ -163,6 +163,7 @@
     void layerPropertiesChanged(PlatformCALayerRemote*, LayerProperties&);
     void setCreatedLayers(Vector<LayerCreationProperties>);
     void setDestroyedLayerIDs(Vector<WebCore::GraphicsLayer::PlatformLayerID>);
+    void setLayerIDsWithNewlyUnreachableBackingStore(Vector<WebCore::GraphicsLayer::PlatformLayerID>);
 
 #if !defined(NDEBUG) || !LOG_DISABLED
     WTF::CString description() const;
@@ -173,6 +174,7 @@
 
     Vector<LayerCreationProperties> createdLayers() const { return m_createdLayers; }
     Vector<WebCore::GraphicsLayer::PlatformLayerID> destroyedLayers() const { return m_destroyedLayerIDs; }
+    Vector<WebCore::GraphicsLayer::PlatformLayerID> layerIDsWithNewlyUnreachableBackingStore() const { return m_layerIDsWithNewlyUnreachableBackingStore; }
 
     Vector<RefPtr<PlatformCALayerRemote>>& changedLayers() { return m_changedLayers; }
 
@@ -214,6 +216,7 @@
     Vector<LayerCreationProperties> m_createdLayers;
     Vector<WebCore::GraphicsLayer::PlatformLayerID> m_destroyedLayerIDs;
     Vector<WebCore::GraphicsLayer::PlatformLayerID> m_videoLayerIDsPendingFullscreen;
+    Vector<WebCore::GraphicsLayer::PlatformLayerID> m_layerIDsWithNewlyUnreachableBackingStore;
 
     WebCore::IntSize m_contentsSize;
     WebCore::Color m_pageExtendedBackgroundColor;

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm (169369 => 169370)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -452,6 +452,7 @@
     
     encoder << m_destroyedLayerIDs;
     encoder << m_videoLayerIDsPendingFullscreen;
+    encoder << m_layerIDsWithNewlyUnreachableBackingStore;
 
     encoder << m_contentsSize;
     encoder << m_pageExtendedBackgroundColor;
@@ -503,6 +504,14 @@
     if (!decoder.decode(result.m_videoLayerIDsPendingFullscreen))
         return false;
 
+    if (!decoder.decode(result.m_layerIDsWithNewlyUnreachableBackingStore))
+        return false;
+
+    for (auto& layerID : result.m_layerIDsWithNewlyUnreachableBackingStore) {
+        if (!layerID)
+            return false;
+    }
+
     if (!decoder.decode(result.m_contentsSize))
         return false;
     
@@ -555,6 +564,11 @@
     m_destroyedLayerIDs = std::move(destroyedLayerIDs);
 }
 
+void RemoteLayerTreeTransaction::setLayerIDsWithNewlyUnreachableBackingStore(Vector<GraphicsLayer::PlatformLayerID> layerIDsWithNewlyUnreachableBackingStore)
+{
+    m_layerIDsWithNewlyUnreachableBackingStore = std::move(layerIDsWithNewlyUnreachableBackingStore);
+}
+
 #if !defined(NDEBUG) || !LOG_DISABLED
 
 class RemoteLayerTreeTextStream : public TextStream

Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm (169369 => 169370)


--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -96,6 +96,11 @@
     for (auto& destroyedLayer : transaction.destroyedLayers())
         layerWillBeRemoved(destroyedLayer);
 
+    // Drop the contents of any layers which were unparented; the Web process will re-send
+    // the backing store in the commit that reparents them.
+    for (auto& newlyUnreachableLayerID : transaction.layerIDsWithNewlyUnreachableBackingStore())
+        asLayer(getLayer(newlyUnreachableLayerID)).contents = nullptr;
+
     return rootLayerChanged;
 }
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.h (169369 => 169370)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.h	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.h	2014-05-27 06:14:15 UTC (rev 169370)
@@ -50,6 +50,7 @@
 
     void backingStoreWasCreated(RemoteLayerBackingStore*);
     void backingStoreWillBeDestroyed(RemoteLayerBackingStore*);
+    void backingStoreWillBeDisplayed(RemoteLayerBackingStore*);
 
     LayerHostingMode layerHostingMode() const { return m_webPage->layerHostingMode(); }
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.mm (169369 => 169370)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -86,6 +86,11 @@
     m_backingStoreCollection.backingStoreWillBeDestroyed(backingStore);
 }
 
+void RemoteLayerTreeContext::backingStoreWillBeDisplayed(RemoteLayerBackingStore* backingStore)
+{
+    m_backingStoreCollection.backingStoreWillBeDisplayed(backingStore);
+}
+
 std::unique_ptr<GraphicsLayer> RemoteLayerTreeContext::createGraphicsLayer(GraphicsLayerClient& client)
 {
     return std::make_unique<GraphicsLayerCARemote>(client, this);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (169369 => 169370)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-05-27 05:38:27 UTC (rev 169369)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-05-27 06:14:15 UTC (rev 169370)
@@ -257,6 +257,9 @@
 
     RELEASE_ASSERT(!m_pendingBackingStoreFlusher || m_pendingBackingStoreFlusher->hasFlushed());
 
+    RemoteLayerBackingStoreCollection& backingStoreCollection = m_remoteLayerTreeContext->backingStoreCollection();
+    backingStoreCollection.willFlushLayers();
+
     m_webPage->layoutIfNeeded();
 
     FloatRect visibleRect(FloatPoint(), m_viewSize);
@@ -265,9 +268,10 @@
     m_webPage->corePage()->mainFrame().view()->flushCompositingStateIncludingSubframes();
     m_rootLayer->flushCompositingStateForThisLayerOnly();
 
-    // FIXME: minize these transactions if nothing changed.
+    // FIXME: Minimize these transactions if nothing changed.
     RemoteLayerTreeTransaction layerTransaction;
     m_remoteLayerTreeContext->buildTransaction(layerTransaction, *toGraphicsLayerCARemote(m_rootLayer.get())->platformCALayer());
+    backingStoreCollection.willCommitLayerTree(layerTransaction);
     m_webPage->willCommitLayerTree(layerTransaction);
 
     RemoteScrollingCoordinatorTransaction scrollingTransaction;
@@ -282,6 +286,7 @@
     auto commitEncoder = std::make_unique<IPC::MessageEncoder>(Messages::RemoteLayerTreeDrawingAreaProxy::CommitLayerTree::receiverName(), Messages::RemoteLayerTreeDrawingAreaProxy::CommitLayerTree::name(), m_webPage->pageID());
     commitEncoder->encode(message.arguments());
 
+    // FIXME: Move all backing store flushing management to RemoteLayerBackingStoreCollection.
     bool hadAnyChangedBackingStore = false;
     Vector<RetainPtr<CGContextRef>> contextsToFlush;
     for (auto& layer : layerTransaction.changedLayers()) {
@@ -296,8 +301,10 @@
         layer->didCommit();
     }
 
+    backingStoreCollection.didFlushLayers();
+
     if (hadAnyChangedBackingStore)
-        m_remoteLayerTreeContext->backingStoreCollection().schedulePurgeabilityTimer();
+        backingStoreCollection.scheduleVolatilityTimer();
 
     RefPtr<BackingStoreFlusher> backingStoreFlusher = BackingStoreFlusher::create(WebProcess::shared().parentProcessConnection(), std::move(commitEncoder), std::move(contextsToFlush));
     m_pendingBackingStoreFlusher = backingStoreFlusher;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to