Title: [136151] trunk/Source/WebCore
Revision
136151
Author
[email protected]
Date
2012-11-29 12:34:41 -0800 (Thu, 29 Nov 2012)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=103577
TiledDrawingArea should recycle tiles
-and corresponding-
<rdar://problem/12714586>

Reviewed by Simon Fraser.

New class LayerPool will keep a list of layers to reuse so that 
we can avoid creating and destroying so many layer.

When removing layers, add them to the LayerPool
* platform/graphics/ca/mac/TileCache.mm:
(WebCore::TileCache::revalidateTiles):

Before creating a new layer, try to get one of the appropriate size 
from the LayerPool.
(WebCore::TileCache::createTileLayer):

New class.
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/ca/mac/LayerPool.h: Added.
(WebCore):
(LayerPool):
(WebCore::LayerPool::capacity):
(WebCore::LayerPool::canReuseLayerWithSize):
* platform/graphics/ca/mac/LayerPool.mm: Added.
(WebCore):
(WebCore::LayerPool:: LayerPool):
(WebCore::LayerPool::sharedPool):
(WebCore::LayerPool::bytesBackingLayerWithPixelSize):
(WebCore::LayerPool::listOfLayersWithSize):
(WebCore::LayerPool::addLayer):
(WebCore::LayerPool::takeLayerWithSize):
(WebCore::LayerPool::decayedCapacity):
(WebCore::LayerPool::schedulePrune):
(WebCore::LayerPool::prune):
(WebCore::LayerPool::drain):

If we're under memory pressure, drain the LayerPool
* platform/mac/MemoryPressureHandlerMac.mm:
(WebCore::MemoryPressureHandler::releaseMemory):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (136150 => 136151)


--- trunk/Source/WebCore/ChangeLog	2012-11-29 20:26:29 UTC (rev 136150)
+++ trunk/Source/WebCore/ChangeLog	2012-11-29 20:34:41 UTC (rev 136151)
@@ -1,3 +1,47 @@
+2012-11-29  Beth Dakin  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=103577
+        TiledDrawingArea should recycle tiles
+        -and corresponding-
+        <rdar://problem/12714586>
+
+        Reviewed by Simon Fraser.
+
+        New class LayerPool will keep a list of layers to reuse so that 
+        we can avoid creating and destroying so many layer.
+
+        When removing layers, add them to the LayerPool
+        * platform/graphics/ca/mac/TileCache.mm:
+        (WebCore::TileCache::revalidateTiles):
+
+        Before creating a new layer, try to get one of the appropriate size 
+        from the LayerPool.
+        (WebCore::TileCache::createTileLayer):
+
+        New class.
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/ca/mac/LayerPool.h: Added.
+        (WebCore):
+        (LayerPool):
+        (WebCore::LayerPool::capacity):
+        (WebCore::LayerPool::canReuseLayerWithSize):
+        * platform/graphics/ca/mac/LayerPool.mm: Added.
+        (WebCore):
+        (WebCore::LayerPool:: LayerPool):
+        (WebCore::LayerPool::sharedPool):
+        (WebCore::LayerPool::bytesBackingLayerWithPixelSize):
+        (WebCore::LayerPool::listOfLayersWithSize):
+        (WebCore::LayerPool::addLayer):
+        (WebCore::LayerPool::takeLayerWithSize):
+        (WebCore::LayerPool::decayedCapacity):
+        (WebCore::LayerPool::schedulePrune):
+        (WebCore::LayerPool::prune):
+        (WebCore::LayerPool::drain):
+
+        If we're under memory pressure, drain the LayerPool
+        * platform/mac/MemoryPressureHandlerMac.mm:
+        (WebCore::MemoryPressureHandler::releaseMemory):
+
 2012-11-29  Julien Chaffraix  <[email protected]>
 
         [CSS Grid Layout] track sizing functions should have their own type

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (136150 => 136151)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-11-29 20:26:29 UTC (rev 136150)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-11-29 20:34:41 UTC (rev 136151)
@@ -3430,6 +3430,8 @@
 		93F1D5C112D5335600832BEC /* JSWebGLLoseContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F1D5BF12D5335600832BEC /* JSWebGLLoseContext.h */; };
 		93F6F1ED127F70B10055CB06 /* WebGLContextEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F6F1EA127F70B10055CB06 /* WebGLContextEvent.cpp */; };
 		93F6F1EE127F70B10055CB06 /* WebGLContextEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F6F1EB127F70B10055CB06 /* WebGLContextEvent.h */; };
+		93F72AF31666EDFC002A02BD /* LayerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F72AF11666EDFC002A02BD /* LayerPool.h */; };
+		93F72AF41666EDFC002A02BD /* LayerPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F72AF21666EDFC002A02BD /* LayerPool.mm */; };
 		93F925430F7EF5B8007E37C9 /* CheckedRadioButtons.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F925410F7EF5B8007E37C9 /* CheckedRadioButtons.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		93F925440F7EF5B8007E37C9 /* CheckedRadioButtons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F925420F7EF5B8007E37C9 /* CheckedRadioButtons.cpp */; };
 		93F9B6570BA0F35E00854064 /* DOMHTMLCanvasElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F9B6540BA0F35E00854064 /* DOMHTMLCanvasElement.mm */; };
@@ -5929,10 +5931,10 @@
 		CDB859F7160D48A400E5B07F /* MediaKeyEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB859F4160D489900E5B07F /* MediaKeyEvent.cpp */; };
 		CDB859FA160D494900E5B07F /* JSMediaKeyEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB859F8160D493E00E5B07F /* JSMediaKeyEvent.cpp */; };
 		CDB859FB160D494F00E5B07F /* JSMediaKeyError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB859F0160D42DD00E5B07F /* JSMediaKeyError.cpp */; };
+		CDC69DD61632026C007C38DF /* WebCoreFullScreenWarningView.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		CDC69DD71632026C007C38DF /* WebCoreFullScreenWarningView.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC69DD51632026C007C38DF /* WebCoreFullScreenWarningView.mm */; };
 		CDC69DDA16371FD4007C38DF /* WebCoreFullScreenPlaceholderView.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC69DD816371FD3007C38DF /* WebCoreFullScreenPlaceholderView.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CDC69DDB16371FD4007C38DF /* WebCoreFullScreenPlaceholderView.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC69DD916371FD3007C38DF /* WebCoreFullScreenPlaceholderView.mm */; };
-		CDC69DD61632026C007C38DF /* WebCoreFullScreenWarningView.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		CDC69DD71632026C007C38DF /* WebCoreFullScreenWarningView.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC69DD51632026C007C38DF /* WebCoreFullScreenWarningView.mm */; };
 		CDD525D7145B6DD0008D204D /* JSHTMLMediaElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */; };
 		CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */; };
 		CDEA76341460B56F008B31F1 /* ClockGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA76321460AE29008B31F1 /* ClockGeneric.cpp */; };
@@ -10685,6 +10687,8 @@
 		93F6F1EA127F70B10055CB06 /* WebGLContextEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLContextEvent.cpp; path = canvas/WebGLContextEvent.cpp; sourceTree = "<group>"; };
 		93F6F1EB127F70B10055CB06 /* WebGLContextEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLContextEvent.h; path = canvas/WebGLContextEvent.h; sourceTree = "<group>"; };
 		93F6F1EC127F70B10055CB06 /* WebGLContextEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebGLContextEvent.idl; path = canvas/WebGLContextEvent.idl; sourceTree = "<group>"; };
+		93F72AF11666EDFC002A02BD /* LayerPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LayerPool.h; path = ca/mac/LayerPool.h; sourceTree = "<group>"; };
+		93F72AF21666EDFC002A02BD /* LayerPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = LayerPool.mm; path = ca/mac/LayerPool.mm; sourceTree = "<group>"; };
 		93F8B3050A300FE100F61AB8 /* CodeGenerator.pm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = CodeGenerator.pm; path = scripts/CodeGenerator.pm; sourceTree = "<group>"; };
 		93F8B3060A300FEA00F61AB8 /* CodeGeneratorJS.pm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = CodeGeneratorJS.pm; path = ../scripts/CodeGeneratorJS.pm; sourceTree = "<group>"; wrapsLines = 0; };
 		93F8B3070A300FEA00F61AB8 /* generate-bindings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = "generate-bindings.pl"; path = "scripts/generate-bindings.pl"; sourceTree = "<group>"; };
@@ -13358,10 +13362,10 @@
 		CDB859F8160D493E00E5B07F /* JSMediaKeyEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaKeyEvent.cpp; sourceTree = "<group>"; };
 		CDB859F9160D493E00E5B07F /* JSMediaKeyEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaKeyEvent.h; sourceTree = "<group>"; };
 		CDBD93BA1333BD4B002570E3 /* fullscreenQuickTime.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreenQuickTime.css; sourceTree = "<group>"; };
+		CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreFullScreenWarningView.h; sourceTree = "<group>"; };
+		CDC69DD51632026C007C38DF /* WebCoreFullScreenWarningView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFullScreenWarningView.mm; sourceTree = "<group>"; };
 		CDC69DD816371FD3007C38DF /* WebCoreFullScreenPlaceholderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreFullScreenPlaceholderView.h; sourceTree = "<group>"; };
 		CDC69DD916371FD3007C38DF /* WebCoreFullScreenPlaceholderView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFullScreenPlaceholderView.mm; sourceTree = "<group>"; };
-		CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreFullScreenWarningView.h; sourceTree = "<group>"; };
-		CDC69DD51632026C007C38DF /* WebCoreFullScreenWarningView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFullScreenWarningView.mm; sourceTree = "<group>"; };
 		CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetFactory.in; sourceTree = "<group>"; };
 		CDEA762C14608224008B31F1 /* Clock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clock.h; sourceTree = "<group>"; };
 		CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformClockCA.cpp; sourceTree = "<group>"; };
@@ -15398,6 +15402,8 @@
 				4958782012A57DDF007238AC /* PlatformCALayerMac.mm */,
 				1AA71609149BC4DB0016EC19 /* TileCache.h */,
 				1AA71608149BC4DA0016EC19 /* TileCache.mm */,
+				93F72AF11666EDFC002A02BD /* LayerPool.h */,
+				93F72AF21666EDFC002A02BD /* LayerPool.mm */,
 				0F580FA11496939100FB5BD8 /* WebTileCacheLayer.h */,
 				0F580FA21496939100FB5BD8 /* WebTileCacheLayer.mm */,
 				1AA71625149BFFB20016EC19 /* WebTileLayer.h */,
@@ -25840,6 +25846,7 @@
 				FB2C15C3165D649D0039C9F8 /* CachedSVGDocumentReference.h in Headers */,
 				31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
 				15B8B7C91652C5220036EF55 /* JSWebKitCSSMixFunctionValue.h in Headers */,
+				93F72AF31666EDFC002A02BD /* LayerPool.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -28943,6 +28950,7 @@
 				447958051643B4B2001E0A7F /* ParsedContentType.cpp in Sources */,
 				15B8B7C81652C5220036EF55 /* JSWebKitCSSMixFunctionValue.cpp in Sources */,
 				86BA766E166427A8005BE5D1 /* FrameLoadRequest.cpp in Sources */,
+				93F72AF41666EDFC002A02BD /* LayerPool.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Added: trunk/Source/WebCore/platform/graphics/ca/mac/LayerPool.h (0 => 136151)


--- trunk/Source/WebCore/platform/graphics/ca/mac/LayerPool.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/LayerPool.h	2012-11-29 20:34:41 UTC (rev 136151)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LayerPool_h
+#define LayerPool_h
+
+#include "IntSize.h"
+#include "IntSizeHash.h"
+#include "Timer.h"
+#include <wtf/Deque.h>
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+
+@class WebTileLayer;
+
+namespace WebCore {
+    
+class LayerPool {
+    WTF_MAKE_NONCOPYABLE(LayerPool);
+public:
+    static LayerPool* sharedPool();
+    
+    void addLayer(const RetainPtr<WebTileLayer>&);
+    RetainPtr<WebTileLayer> takeLayerWithSize(const IntSize&);
+
+    void drain();
+
+    // The maximum size of all queued layers in bytes.
+    unsigned capacity() const { return m_maxBytesForPool; }
+
+private:
+    LayerPool();
+
+    typedef Deque<RetainPtr<WebTileLayer> > LayerList;
+
+    unsigned decayedCapacity() const;
+
+    bool canReuseLayerWithSize(const IntSize& size) const { return m_maxBytesForPool && !size.isEmpty(); }
+    void schedulePrune();
+    void pruneTimerFired(Timer<LayerPool>*);
+
+    typedef enum { LeaveUnchanged, MarkAsUsed } AccessType;
+    LayerList& listOfLayersWithSize(const IntSize&, AccessType = LeaveUnchanged);
+
+    static unsigned backingStoreBytesForSize(const IntSize&);
+
+    HashMap<IntSize, LayerList> m_reuseLists;
+    // Ordered by recent use. The last size is the most recently used.
+    Vector<IntSize> m_sizesInPruneOrder;
+    unsigned m_totalBytes;
+    unsigned m_maxBytesForPool;
+
+    Timer<LayerPool> m_pruneTimer;
+
+    double m_lastAddTime;
+};
+
+}
+
+#endif

Added: trunk/Source/WebCore/platform/graphics/ca/mac/LayerPool.mm (0 => 136151)


--- trunk/Source/WebCore/platform/graphics/ca/mac/LayerPool.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/LayerPool.mm	2012-11-29 20:34:41 UTC (rev 136151)
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "LayerPool.h"
+
+#include "Logging.h"
+#include "WebTileLayer.h"
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+    
+static const double capacityDecayTime = 5;
+    
+LayerPool::LayerPool()
+    : m_totalBytes(0)
+    , m_maxBytesForPool(48 * 1024 * 1024)
+    , m_pruneTimer(this, &LayerPool::pruneTimerFired)
+    , m_lastAddTime(0)
+{
+}
+
+LayerPool* LayerPool::sharedPool()
+{
+    static LayerPool* sharedPool = new LayerPool;
+    return sharedPool;
+}
+
+unsigned LayerPool::backingStoreBytesForSize(const IntSize& size)
+{
+    return size.width() * size.height() * 4;
+}
+
+LayerPool::LayerList& LayerPool::listOfLayersWithSize(const IntSize& size, AccessType accessType)
+{
+    HashMap<IntSize, LayerList>::iterator it = m_reuseLists.find(size);
+    if (it == m_reuseLists.end()) {
+        it = m_reuseLists.add(size, LayerList()).iterator;
+        m_sizesInPruneOrder.append(size);
+    } else if (accessType == MarkAsUsed) {
+        m_sizesInPruneOrder.remove(m_sizesInPruneOrder.reverseFind(size));
+        m_sizesInPruneOrder.append(size);
+    }
+    return it->value;
+}
+
+void LayerPool::addLayer(const RetainPtr<WebTileLayer>& layer)
+{
+    IntSize layerSize([layer.get() bounds].size);
+    if (!canReuseLayerWithSize(layerSize))
+        return;
+
+    listOfLayersWithSize(layerSize).prepend(layer);
+    m_totalBytes += backingStoreBytesForSize(layerSize);
+    
+    m_lastAddTime = currentTime();
+    schedulePrune();
+}
+
+RetainPtr<WebTileLayer> LayerPool::takeLayerWithSize(const IntSize& size)
+{
+    if (!canReuseLayerWithSize(size))
+        return nil;
+    LayerList& reuseList = listOfLayersWithSize(size, MarkAsUsed);
+    if (reuseList.isEmpty())
+        return nil;
+    m_totalBytes -= backingStoreBytesForSize(size);
+    return reuseList.takeFirst();
+}
+    
+unsigned LayerPool::decayedCapacity() const
+{
+    // Decay to one quarter over capacityDecayTime
+    double timeSinceLastAdd = currentTime() - m_lastAddTime;
+    if (timeSinceLastAdd > capacityDecayTime)
+        return m_maxBytesForPool / 4;
+    float decayProgess = float(timeSinceLastAdd / capacityDecayTime);
+    return m_maxBytesForPool / 4 + m_maxBytesForPool * 3 / 4 * (1 - decayProgess);
+}
+
+void LayerPool::schedulePrune()
+{
+    if (m_pruneTimer.isActive())
+        return;
+    m_pruneTimer.startOneShot(0);
+}
+
+void LayerPool::pruneTimerFired(Timer<LayerPool>*)
+{
+    unsigned shrinkTo = decayedCapacity();
+    while (m_totalBytes > shrinkTo) {
+        ASSERT(!m_sizesInPruneOrder.isEmpty());
+        IntSize sizeToDrop = m_sizesInPruneOrder.first();
+        LayerList& oldestReuseList = m_reuseLists.find(sizeToDrop)->value;
+        if (oldestReuseList.isEmpty()) {
+            m_reuseLists.remove(sizeToDrop);
+            m_sizesInPruneOrder.remove(0);
+            continue;
+        }
+
+        m_totalBytes -= backingStoreBytesForSize(sizeToDrop);
+        // The last element in the list is the oldest, hence most likely not to
+        // still have a backing store.
+        oldestReuseList.remove(--oldestReuseList.end());
+    }
+    if (currentTime() - m_lastAddTime <= capacityDecayTime)
+        schedulePrune();
+}
+
+void LayerPool::drain()
+{
+    m_reuseLists.clear();
+    m_sizesInPruneOrder.clear();
+    m_totalBytes = 0;
+}
+
+}

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm (136150 => 136151)


--- trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm	2012-11-29 20:26:29 UTC (rev 136150)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm	2012-11-29 20:34:41 UTC (rev 136151)
@@ -29,6 +29,7 @@
 #import "IntRect.h"
 #import "PlatformCALayer.h"
 #import "Region.h"
+#import "LayerPool.h"
 #import "WebLayer.h"
 #import "WebTileCacheLayer.h"
 #import "WebTileLayer.h"
@@ -419,7 +420,7 @@
     // the tiles that are outside the coverage rect. When we know that we're going to be scrolling up,
     // we might want to remove the ones below the coverage rect but keep the ones above.
     for (size_t i = 0; i < tilesToRemove.size(); ++i)
-        m_tiles.remove(tilesToRemove[i]);
+        LayerPool::sharedPool()->addLayer(m_tiles.take(tilesToRemove[i]));
 
     TileIndex topLeft;
     TileIndex bottomRight;
@@ -487,7 +488,13 @@
 
 RetainPtr<WebTileLayer> TileCache::createTileLayer(const IntRect& tileRect)
 {
-    RetainPtr<WebTileLayer> layer = adoptNS([[WebTileLayer alloc] init]);
+    RetainPtr<WebTileLayer> layer = LayerPool::sharedPool()->takeLayerWithSize(tileRect.size());
+    if (layer) {
+        // If we were able to restore a layer from the LayerPool, we should call setNeedsDisplay to
+        // ensure we avoid stale content.
+        [layer setNeedsDisplay];
+    } else
+        layer = adoptNS([[WebTileLayer alloc] init]);
     [layer.get() setAnchorPoint:CGPointZero];
     [layer.get() setFrame:tileRect];
     [layer.get() setTileCache:this];

Modified: trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm (136150 => 136151)


--- trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm	2012-11-29 20:26:29 UTC (rev 136150)
+++ trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm	2012-11-29 20:34:41 UTC (rev 136151)
@@ -30,6 +30,7 @@
 #import <WebCore/FontCache.h>
 #import <WebCore/MemoryCache.h>
 #import <WebCore/PageCache.h>
+#import <WebCore/LayerPool.h>
 #import <wtf/CurrentTime.h>
 #import <wtf/FastMalloc.h>
 
@@ -148,6 +149,8 @@
 
     memoryCache()->pruneToPercentage(critical ? 0 : 0.5f);
 
+    LayerPool::sharedPool()->drain();
+
     gcController().discardAllCompiledCode();
 
     WTF::releaseFastMallocFreeMemory();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to