Title: [128473] trunk/Source/WebKit2
Revision
128473
Author
kbal...@webkit.org
Date
2012-09-13 09:18:21 -0700 (Thu, 13 Sep 2012)

Log Message

[WK2] LayerTreeCoordinator should release unused UpdatedAtlases
https://bugs.webkit.org/show_bug.cgi?id=95072

Reviewed by Jocelyn Turcotte.

Release graphic buffers that haven't been used for a while in order to save memory.
This way we can give back memory to the system when no user interaction happens
after a period of time, for example when we are in the background.

* Shared/ShareableBitmap.h:
* WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp:
(WebKit::LayerTreeCoordinator::LayerTreeCoordinator):
(WebKit::LayerTreeCoordinator::beginContentUpdate):
(WebKit):
(WebKit::LayerTreeCoordinator::scheduleReleaseInactiveAtlases):
(WebKit::LayerTreeCoordinator::releaseInactiveAtlasesTimerFired):
* WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h:
(LayerTreeCoordinator):
* WebProcess/WebPage/UpdateAtlas.cpp:
(WebKit::UpdateAtlas::UpdateAtlas):
(WebKit::UpdateAtlas::didSwapBuffers):
Don't call buildLayoutIfNeeded here. It's enought to call it in beginPaintingOnAvailableBuffer
and this way we can track whether this atlas is used with m_areaAllocator.
(WebKit::UpdateAtlas::beginPaintingOnAvailableBuffer):
* WebProcess/WebPage/UpdateAtlas.h:
(WebKit::UpdateAtlas::addTimeInactive):
(WebKit::UpdateAtlas::isInactive):
(WebKit::UpdateAtlas::isInUse):
(UpdateAtlas):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (128472 => 128473)


--- trunk/Source/WebKit2/ChangeLog	2012-09-13 16:07:53 UTC (rev 128472)
+++ trunk/Source/WebKit2/ChangeLog	2012-09-13 16:18:21 UTC (rev 128473)
@@ -1,3 +1,35 @@
+2012-09-13  Balazs Kelemen  <kbal...@webkit.org>
+
+        [WK2] LayerTreeCoordinator should release unused UpdatedAtlases
+        https://bugs.webkit.org/show_bug.cgi?id=95072
+
+        Reviewed by Jocelyn Turcotte.
+
+        Release graphic buffers that haven't been used for a while in order to save memory.
+        This way we can give back memory to the system when no user interaction happens
+        after a period of time, for example when we are in the background.
+
+        * Shared/ShareableBitmap.h:
+        * WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp:
+        (WebKit::LayerTreeCoordinator::LayerTreeCoordinator):
+        (WebKit::LayerTreeCoordinator::beginContentUpdate):
+        (WebKit):
+        (WebKit::LayerTreeCoordinator::scheduleReleaseInactiveAtlases):
+        (WebKit::LayerTreeCoordinator::releaseInactiveAtlasesTimerFired):
+        * WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h:
+        (LayerTreeCoordinator):
+        * WebProcess/WebPage/UpdateAtlas.cpp:
+        (WebKit::UpdateAtlas::UpdateAtlas):
+        (WebKit::UpdateAtlas::didSwapBuffers):
+        Don't call buildLayoutIfNeeded here. It's enought to call it in beginPaintingOnAvailableBuffer
+        and this way we can track whether this atlas is used with m_areaAllocator.
+        (WebKit::UpdateAtlas::beginPaintingOnAvailableBuffer):
+        * WebProcess/WebPage/UpdateAtlas.h:
+        (WebKit::UpdateAtlas::addTimeInactive):
+        (WebKit::UpdateAtlas::isInactive):
+        (WebKit::UpdateAtlas::isInUse):
+        (UpdateAtlas):
+
 2012-09-13  Lauro Neto  <lauro.n...@openbossa.org>
 
         [Qt][WK2] fast/forms/access-key-for-all-elements.html fails

Modified: trunk/Source/WebKit2/Shared/ShareableBitmap.h (128472 => 128473)


--- trunk/Source/WebKit2/Shared/ShareableBitmap.h	2012-09-13 16:07:53 UTC (rev 128472)
+++ trunk/Source/WebKit2/Shared/ShareableBitmap.h	2012-09-13 16:18:21 UTC (rev 128473)
@@ -60,6 +60,7 @@
 class ShareableBitmap : public RefCounted<ShareableBitmap> {
 public:
     enum Flag {
+        NoFlags = 0,
         SupportsAlpha = 1 << 0,
     };
     typedef unsigned Flags;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp (128472 => 128473)


--- trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp	2012-09-13 16:07:53 UTC (rev 128472)
+++ trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp	2012-09-13 16:18:21 UTC (rev 128473)
@@ -78,6 +78,7 @@
     , m_shouldSyncFrame(false)
     , m_shouldSyncRootLayer(true)
     , m_layerFlushTimer(this, &LayerTreeCoordinator::layerFlushTimerFired)
+    , m_releaseInactiveAtlasesTimer(this, &LayerTreeCoordinator::releaseInactiveAtlasesTimerFired)
     , m_layerFlushSchedulingEnabled(true)
     , m_forceRepaintAsyncCallbackID(0)
 {
@@ -634,8 +635,42 @@
 
     static const int ScratchBufferDimension = 1024; // Should be a power of two.
     m_updateAtlases.append(adoptPtr(new UpdateAtlas(ScratchBufferDimension, flags)));
+    scheduleReleaseInactiveAtlases();
     return m_updateAtlases.last()->beginPaintingOnAvailableBuffer(handle, size, offset);
 }
 
+const double ReleaseInactiveAtlasesTimerInterval = 0.5;
+
+void LayerTreeCoordinator::scheduleReleaseInactiveAtlases()
+{
+    if (!m_releaseInactiveAtlasesTimer.isActive())
+        m_releaseInactiveAtlasesTimer.startRepeating(ReleaseInactiveAtlasesTimerInterval);
+}
+
+void LayerTreeCoordinator::releaseInactiveAtlasesTimerFired(Timer<LayerTreeCoordinator>*)
+{
+    // We always want to keep one atlas for non-composited content.
+    OwnPtr<UpdateAtlas> atlasToKeepAnyway;
+    bool foundActiveAtlasForNonCompositedContent = false;
+    for (int i = m_updateAtlases.size() - 1;  i >= 0; --i) {
+        UpdateAtlas* atlas = m_updateAtlases[i].get();
+        if (!atlas->isInUse())
+            atlas->addTimeInactive(ReleaseInactiveAtlasesTimerInterval);
+        bool usableForNonCompositedContent = atlas->flags() == ShareableBitmap::NoFlags;
+        if (atlas->isInactive()) {
+            if (!foundActiveAtlasForNonCompositedContent && !atlasToKeepAnyway && usableForNonCompositedContent)
+                atlasToKeepAnyway = m_updateAtlases[i].release();
+            m_updateAtlases.remove(i);
+        } else if (usableForNonCompositedContent)
+            foundActiveAtlasForNonCompositedContent = true;
+    }
+
+    if (!foundActiveAtlasForNonCompositedContent && atlasToKeepAnyway)
+        m_updateAtlases.append(atlasToKeepAnyway.release());
+
+    if (m_updateAtlases.size() <= 1)
+        m_releaseInactiveAtlasesTimer.stop();
+}
+
 } // namespace WebKit
 #endif // USE(COORDINATED_GRAPHICS)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h (128472 => 128473)


--- trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h	2012-09-13 16:07:53 UTC (rev 128472)
+++ trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h	2012-09-13 16:18:21 UTC (rev 128473)
@@ -113,6 +113,11 @@
     void didPerformScheduledLayerFlush();
     void syncDisplayState();
 
+    void layerFlushTimerFired(WebCore::Timer<LayerTreeCoordinator>*);
+
+    void scheduleReleaseInactiveAtlases();
+    void releaseInactiveAtlasesTimerFired(WebCore::Timer<LayerTreeCoordinator>*);
+
     OwnPtr<WebCore::GraphicsLayer> m_rootLayer;
 
     // The layer which contains all non-composited content.
@@ -137,8 +142,8 @@
     LayerTreeContext m_layerTreeContext;
     bool m_shouldSyncFrame;
     bool m_shouldSyncRootLayer;
-    void layerFlushTimerFired(WebCore::Timer<LayerTreeCoordinator>*);
     WebCore::Timer<LayerTreeCoordinator> m_layerFlushTimer;
+    WebCore::Timer<LayerTreeCoordinator> m_releaseInactiveAtlasesTimer;
     bool m_layerFlushSchedulingEnabled;
     uint64_t m_forceRepaintAsyncCallbackID;
 };

Modified: trunk/Source/WebKit2/WebProcess/WebPage/UpdateAtlas.cpp (128472 => 128473)


--- trunk/Source/WebKit2/WebProcess/WebPage/UpdateAtlas.cpp	2012-09-13 16:07:53 UTC (rev 128472)
+++ trunk/Source/WebKit2/WebProcess/WebPage/UpdateAtlas.cpp	2012-09-13 16:18:21 UTC (rev 128473)
@@ -32,6 +32,7 @@
 
 UpdateAtlas::UpdateAtlas(int dimension, ShareableBitmap::Flags flags)
     : m_flags(flags)
+    , m_inactivityInSeconds(0)
 {
     IntSize size = nextPowerOfTwo(IntSize(dimension, dimension));
     m_surface = ShareableSurface::create(size, flags, ShareableSurface::SupportsGraphicsSurface);
@@ -48,11 +49,11 @@
 void UpdateAtlas::didSwapBuffers()
 {
     m_areaAllocator.clear();
-    buildLayoutIfNeeded();
 }
 
 PassOwnPtr<GraphicsContext> UpdateAtlas::beginPaintingOnAvailableBuffer(ShareableSurface::Handle& handle, const WebCore::IntSize& size, IntPoint& offset)
 {
+    m_inactivityInSeconds = 0;
     buildLayoutIfNeeded();
     IntRect rect = m_areaAllocator->allocate(size);
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/UpdateAtlas.h (128472 => 128473)


--- trunk/Source/WebKit2/WebProcess/WebPage/UpdateAtlas.h	2012-09-13 16:07:53 UTC (rev 128472)
+++ trunk/Source/WebKit2/WebProcess/WebPage/UpdateAtlas.h	2012-09-13 16:18:21 UTC (rev 128473)
@@ -44,6 +44,18 @@
     void didSwapBuffers();
     ShareableBitmap::Flags flags() const { return m_flags; }
 
+    void addTimeInactive(double seconds)
+    {
+        ASSERT(!isInUse());
+        m_inactivityInSeconds += seconds;
+    }
+    bool isInactive() const
+    {
+        const double inactiveSecondsTolerance = 3;
+        return m_inactivityInSeconds > inactiveSecondsTolerance;
+    }
+    bool isInUse() const { return m_areaAllocator; }
+
 private:
     void buildLayoutIfNeeded();
 
@@ -51,6 +63,7 @@
     OwnPtr<GeneralAreaAllocator> m_areaAllocator;
     ShareableBitmap::Flags m_flags;
     RefPtr<ShareableSurface> m_surface;
+    double m_inactivityInSeconds;
 };
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to