<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[166682] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/166682">166682</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2014-04-02 17:33:02 -0700 (Wed, 02 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Pool IOSurfaces to help with allocation cost
https://bugs.webkit.org/show_bug.cgi?id=131096
&lt;rdar://problem/15373942&gt;

Reviewed by Simon Fraser.

* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:

* platform/Timer.h:
(WebCore::TimerBase::startRepeating): Add a std::chrono startRepeating.

* platform/graphics/cg/IOSurfacePool.h: Added.
(WebCore::IOSurfacePool::CachedSurfaceDetails::CachedSurfaceDetails):
(WebCore::IOSurfacePool::CachedSurfaceDetails::resetLastUseTime):
* platform/graphics/cg/ImageBufferBackingStoreCache.cpp: Removed.
* platform/graphics/cg/ImageBufferBackingStoreCache.h: Removed.
* platform/graphics/cg/IOSurfacePool.cpp: Added.
(WebCore::IOSurfacePool::IOSurfacePool):
(WebCore::IOSurfacePool::sharedPool):
(WebCore::surfaceMatchesParameters):
(WebCore::IOSurfacePool::willAddSurface):
(WebCore::IOSurfacePool::didRemoveSurface):
(WebCore::IOSurfacePool::didUseSurfaceOfSize):
(WebCore::IOSurfacePool::takeSurface):
(WebCore::IOSurfacePool::addSurface):
(WebCore::IOSurfacePool::insertSurfaceIntoPool):
(WebCore::IOSurfacePool::setPoolSize):
(WebCore::IOSurfacePool::tryEvictInUseSurface):
(WebCore::IOSurfacePool::tryEvictOldestCachedSurface):
(WebCore::IOSurfacePool::evict):
(WebCore::IOSurfacePool::collectInUseSurfaces):
(WebCore::IOSurfacePool::markOlderSurfacesPurgeable):
(WebCore::IOSurfacePool::collectionTimerFired):
(WebCore::IOSurfacePool::scheduleCollectionTimer):
(WebCore::IOSurfacePool::discardAllSurfaces):
(WebCore::IOSurfacePool::showPoolStatistics):
Add a pool of IOSurfaces. It behaves as such:

    - Keeps up to 64MB of surfaces.
    - Keeps unused and in-use surfaces (but never gets more than 1/2 full with the latter)
    - Marks surfaces purgeable after they've been unused for 2 seconds.
    - Tries to move surfaces from the in-use pool to the unused pool every 500ms.
    - Evicts in an LRU-ish fashion, interleaving eviction of the oldest
      surfaces and the in-use surfaces (since in-use surfaces are not immediately
      useful for the pool, but they are desirous because they were recently used).
    - Throws everything away under memory pressure.

* platform/graphics/cocoa/IOSurface.mm:
(IOSurface::create):
Try to grab a surface from the IOSurfacePool.

* platform/ios/MemoryPressureHandlerIOS.mm:
(WebCore::MemoryPressureHandler::platformReleaseMemory):
* platform/mac/MemoryPressureHandlerMac.mm:
(WebCore::MemoryPressureHandler::install):
(WebCore::MemoryPressureHandler::platformReleaseMemory):
* platform/MemoryPressureHandler.cpp:
(WebCore::MemoryPressureHandler::platformReleaseMemory):
Fix some includes, and throw away all surfaces when we're under memory pressure.

* Shared/mac/RemoteLayerBackingStore.h:
* Shared/mac/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::~RemoteLayerBackingStore):
(WebKit::RemoteLayerBackingStore::clearBackingStore):
(WebKit::RemoteLayerBackingStore::display):
When RemoteLayerBackingStore discards a layer, throw it into the pool.

* UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
(WebKit::RemoteLayerTreeDrawingAreaProxy::RemoteLayerTreeDrawingAreaProxy):
Disable the pool in the UI process.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformMemoryPressureHandlercpp">trunk/Source/WebCore/platform/MemoryPressureHandler.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformTimerh">trunk/Source/WebCore/platform/Timer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscocoaIOSurfacemm">trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformiosMemoryPressureHandlerIOSmm">trunk/Source/WebCore/platform/ios/MemoryPressureHandlerIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmacMemoryPressureHandlerMacmm">trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedmacRemoteLayerBackingStoreh">trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h</a></li>
<li><a href="#trunkSourceWebKit2SharedmacRemoteLayerBackingStoremm">trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxymm">trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicscgIOSurfacePoolcpp">trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgIOSurfacePoolh">trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageBufferBackingStoreCachecpp">trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageBufferBackingStoreCacheh">trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/ChangeLog        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -1,3 +1,66 @@
</span><ins>+2014-04-02  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Pool IOSurfaces to help with allocation cost
+        https://bugs.webkit.org/show_bug.cgi?id=131096
+        &lt;rdar://problem/15373942&gt;
+
+        Reviewed by Simon Fraser.
+
+        * WebCore.exp.in:
+        * WebCore.xcodeproj/project.pbxproj:
+        
+        * platform/Timer.h:
+        (WebCore::TimerBase::startRepeating): Add a std::chrono startRepeating.
+
+        * platform/graphics/cg/IOSurfacePool.h: Added.
+        (WebCore::IOSurfacePool::CachedSurfaceDetails::CachedSurfaceDetails):
+        (WebCore::IOSurfacePool::CachedSurfaceDetails::resetLastUseTime):
+        * platform/graphics/cg/ImageBufferBackingStoreCache.cpp: Removed.
+        * platform/graphics/cg/ImageBufferBackingStoreCache.h: Removed.
+        * platform/graphics/cg/IOSurfacePool.cpp: Added.
+        (WebCore::IOSurfacePool::IOSurfacePool):
+        (WebCore::IOSurfacePool::sharedPool):
+        (WebCore::surfaceMatchesParameters):
+        (WebCore::IOSurfacePool::willAddSurface):
+        (WebCore::IOSurfacePool::didRemoveSurface):
+        (WebCore::IOSurfacePool::didUseSurfaceOfSize):
+        (WebCore::IOSurfacePool::takeSurface):
+        (WebCore::IOSurfacePool::addSurface):
+        (WebCore::IOSurfacePool::insertSurfaceIntoPool):
+        (WebCore::IOSurfacePool::setPoolSize):
+        (WebCore::IOSurfacePool::tryEvictInUseSurface):
+        (WebCore::IOSurfacePool::tryEvictOldestCachedSurface):
+        (WebCore::IOSurfacePool::evict):
+        (WebCore::IOSurfacePool::collectInUseSurfaces):
+        (WebCore::IOSurfacePool::markOlderSurfacesPurgeable):
+        (WebCore::IOSurfacePool::collectionTimerFired):
+        (WebCore::IOSurfacePool::scheduleCollectionTimer):
+        (WebCore::IOSurfacePool::discardAllSurfaces):
+        (WebCore::IOSurfacePool::showPoolStatistics):
+        Add a pool of IOSurfaces. It behaves as such:
+
+            - Keeps up to 64MB of surfaces.
+            - Keeps unused and in-use surfaces (but never gets more than 1/2 full with the latter)
+            - Marks surfaces purgeable after they've been unused for 2 seconds.
+            - Tries to move surfaces from the in-use pool to the unused pool every 500ms.
+            - Evicts in an LRU-ish fashion, interleaving eviction of the oldest
+              surfaces and the in-use surfaces (since in-use surfaces are not immediately
+              useful for the pool, but they are desirous because they were recently used).
+            - Throws everything away under memory pressure.
+
+        * platform/graphics/cocoa/IOSurface.mm:
+        (IOSurface::create):
+        Try to grab a surface from the IOSurfacePool.
+
+        * platform/ios/MemoryPressureHandlerIOS.mm:
+        (WebCore::MemoryPressureHandler::platformReleaseMemory):
+        * platform/mac/MemoryPressureHandlerMac.mm:
+        (WebCore::MemoryPressureHandler::install):
+        (WebCore::MemoryPressureHandler::platformReleaseMemory):
+        * platform/MemoryPressureHandler.cpp:
+        (WebCore::MemoryPressureHandler::platformReleaseMemory):
+        Fix some includes, and throw away all surfaces when we're under memory pressure.
+
</ins><span class="cx"> 2014-04-02  Stephanie Lewis  &lt;slewis@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Roll out http://trac.webkit.org/changeset/166144
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -3077,6 +3077,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if USE(IOSURFACE)
</span><ins>+__ZN7WebCore13IOSurfacePool10addSurfaceEPNS_9IOSurfaceE
+__ZN7WebCore13IOSurfacePool10sharedPoolEv
+__ZN7WebCore13IOSurfacePool11setPoolSizeEm
</ins><span class="cx"> __ZN7WebCore9IOSurface11createImageEv
</span><span class="cx"> __ZN7WebCore9IOSurface14setIsPurgeableEb
</span><span class="cx"> __ZN7WebCore9IOSurface18createFromMachPortEjNS_10ColorSpaceE
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -913,8 +913,8 @@
</span><span class="cx">                 1C11CCC80AA6093700DADB20 /* DOMHTMLElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85DF2EEB0AA387CB00AD64C5 /* DOMHTMLElement.h */; };
</span><span class="cx">                 1C18DA58181AF6A500C4EF22 /* TextPainter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C18DA56181AF6A500C4EF22 /* TextPainter.cpp */; };
</span><span class="cx">                 1C18DA59181AF6A500C4EF22 /* TextPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C18DA57181AF6A500C4EF22 /* TextPainter.h */; };
</span><del>-                1C21E57C183ED1FF001C289D /* ImageBufferBackingStoreCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C21E57A183ED1FF001C289D /* ImageBufferBackingStoreCache.cpp */; };
-                1C21E57D183ED1FF001C289D /* ImageBufferBackingStoreCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C21E57B183ED1FF001C289D /* ImageBufferBackingStoreCache.h */; };
</del><ins>+                1C21E57C183ED1FF001C289D /* IOSurfacePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C21E57A183ED1FF001C289D /* IOSurfacePool.cpp */; };
+                1C21E57D183ED1FF001C289D /* IOSurfacePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C21E57B183ED1FF001C289D /* IOSurfacePool.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 1C26497A0D7E248A00BD10F2 /* DocumentLoaderMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C2649790D7E248A00BD10F2 /* DocumentLoaderMac.cpp */; };
</span><span class="cx">                 1C26497C0D7E24EC00BD10F2 /* PageMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C26497B0D7E24EC00BD10F2 /* PageMac.cpp */; };
</span><span class="cx">                 1C4C8F020AD85D87009475CE /* DeleteButtonController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C4C8F000AD85D87009475CE /* DeleteButtonController.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -7773,8 +7773,8 @@
</span><span class="cx">                 1AFE11980CBFFCC4003017FA /* JSSQLResultSetRowList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLResultSetRowList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C18DA56181AF6A500C4EF22 /* TextPainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextPainter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C18DA57181AF6A500C4EF22 /* TextPainter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextPainter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                1C21E57A183ED1FF001C289D /* ImageBufferBackingStoreCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferBackingStoreCache.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                1C21E57B183ED1FF001C289D /* ImageBufferBackingStoreCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferBackingStoreCache.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                1C21E57A183ED1FF001C289D /* IOSurfacePool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IOSurfacePool.cpp; path = ../cg/IOSurfacePool.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                1C21E57B183ED1FF001C289D /* IOSurfacePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOSurfacePool.h; path = ../cg/IOSurfacePool.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 1C2649790D7E248A00BD10F2 /* DocumentLoaderMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentLoaderMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C26497B0D7E24EC00BD10F2 /* PageMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C4C8EFF0AD85D87009475CE /* DeleteButtonController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeleteButtonController.cpp; sourceTree = &quot;&lt;group&gt;&quot;; tabWidth = 8; usesTabs = 0; };
</span><span class="lines">@@ -19933,8 +19933,6 @@
</span><span class="cx">                                 B2ED97700B1F55CE00257D0F /* GraphicsContextCG.cpp */,
</span><span class="cx">                                 934907E3125BBBC8007F23A0 /* GraphicsContextCG.h */,
</span><span class="cx">                                 A80D67070E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h */,
</span><del>-                                1C21E57A183ED1FF001C289D /* ImageBufferBackingStoreCache.cpp */,
-                                1C21E57B183ED1FF001C289D /* ImageBufferBackingStoreCache.h */,
</del><span class="cx">                                 B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */,
</span><span class="cx">                                 2292B27B1356669400CF11EF /* ImageBufferDataCG.cpp */,
</span><span class="cx">                                 22BD9F80135364FE009BD102 /* ImageBufferDataCG.h */,
</span><span class="lines">@@ -20320,6 +20318,8 @@
</span><span class="cx">                         children = (
</span><span class="cx">                                 2D0B4AA918DA1CCD00434DE1 /* IOSurface.h */,
</span><span class="cx">                                 2D0B4AAA18DA1CCD00434DE1 /* IOSurface.mm */,
</span><ins>+                                1C21E57A183ED1FF001C289D /* IOSurfacePool.cpp */,
+                                1C21E57B183ED1FF001C289D /* IOSurfacePool.h */,
</ins><span class="cx">                                 B5320D6A122A24E9002D1440 /* FontPlatformDataCocoa.mm */,
</span><span class="cx">                         );
</span><span class="cx">                         path = cocoa;
</span><span class="lines">@@ -24144,7 +24144,7 @@
</span><span class="cx">                                 8AB4BC77126FDB7100DEB727 /* IgnoreDestructiveWriteCountIncrementer.h in Headers */,
</span><span class="cx">                                 B27535700B053814002CE64F /* Image.h in Headers */,
</span><span class="cx">                                 B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */,
</span><del>-                                1C21E57D183ED1FF001C289D /* ImageBufferBackingStoreCache.h in Headers */,
</del><ins>+                                1C21E57D183ED1FF001C289D /* IOSurfacePool.h in Headers */,
</ins><span class="cx">                                 22BD9F7F1353625C009BD102 /* ImageBufferData.h in Headers */,
</span><span class="cx">                                 22BD9F81135364FE009BD102 /* ImageBufferDataCG.h in Headers */,
</span><span class="cx">                                 510192D618B6B9B7007FC7A1 /* ImageControlsRootElement.h in Headers */,
</span><span class="lines">@@ -27544,7 +27544,7 @@
</span><span class="cx">                                 C3CF17A615B0063F00276D39 /* IdTargetObserverRegistry.cpp in Sources */,
</span><span class="cx">                                 B275356F0B053814002CE64F /* Image.cpp in Sources */,
</span><span class="cx">                                 43D2597713C816F400608559 /* ImageBuffer.cpp in Sources */,
</span><del>-                                1C21E57C183ED1FF001C289D /* ImageBufferBackingStoreCache.cpp in Sources */,
</del><ins>+                                1C21E57C183ED1FF001C289D /* IOSurfacePool.cpp in Sources */,
</ins><span class="cx">                                 B2A10B940B3818D700099AA4 /* ImageBufferCG.cpp in Sources */,
</span><span class="cx">                                 2292B27C1356669400CF11EF /* ImageBufferDataCG.cpp in Sources */,
</span><span class="cx">                                 B275355E0B053814002CE64F /* ImageCG.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformMemoryPressureHandlercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.cpp (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/MemoryPressureHandler.cpp        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/MemoryPressureHandler.cpp        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -96,13 +96,14 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(MAC)
</span><del>-
</del><span class="cx"> void MemoryPressureHandler::install() { }
</span><span class="cx"> void MemoryPressureHandler::uninstall() { }
</span><span class="cx"> void MemoryPressureHandler::holdOff(unsigned) { }
</span><span class="cx"> void MemoryPressureHandler::respondToMemoryPressure() { }
</span><ins>+#endif
+
+#if !PLATFORM(COCOA)
</ins><span class="cx"> void MemoryPressureHandler::platformReleaseMemory(bool) { }
</span><del>-
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformTimerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/Timer.h (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/Timer.h        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/Timer.h        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx">     void start(double nextFireInterval, double repeatInterval);
</span><span class="cx"> 
</span><span class="cx">     void startRepeating(double repeatInterval) { start(repeatInterval, repeatInterval); }
</span><ins>+    void startRepeating(std::chrono::milliseconds repeatInterval) { startRepeating(repeatInterval.count() * 0.001); }
</ins><span class="cx">     void startOneShot(double interval) { start(interval, 0); }
</span><span class="cx">     void startOneShot(std::chrono::milliseconds interval) { startOneShot(interval.count() * 0.001); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgIOSurfacePoolcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp (0 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -0,0 +1,357 @@
</span><ins>+/*
+ * Copyright (C) 2013, 2014 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;IOSurfacePool.h&quot;
+
+#if USE(IOSURFACE)
+
+#include &quot;GraphicsContextCG.h&quot;
+#include &quot;IOSurface.h&quot;
+#include &lt;CoreGraphics/CoreGraphics.h&gt;
+#include &lt;chrono&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
+
+const std::chrono::milliseconds collectionInterval = 500_ms;
+const std::chrono::seconds surfaceAgeBeforeMarkingPurgeable = 2_s;
+const size_t defaultMaximumBytesCached = 1024 * 1024 * 64;
+
+// We'll never allow more than 1/2 of the cache to be filled with in-use surfaces, because
+// they can't be immediately returned when requested (but will be freed up in the future).
+const size_t maximumInUseBytes = defaultMaximumBytesCached / 2;
+
+#define ENABLE_IOSURFACE_POOL_STATISTICS false
+#if ENABLE_IOSURFACE_POOL_STATISTICS
+#define DUMP_POOL_STATISTICS() do { showPoolStatistics(); } while (0);
+#else
+#define DUMP_POOL_STATISTICS() ((void)0)
+#endif
+
+namespace WebCore {
+
+IOSurfacePool::IOSurfacePool()
+    : m_collectionTimer(this, &amp;IOSurfacePool::collectionTimerFired)
+    , m_bytesCached(0)
+    , m_inUseBytesCached(0)
+    , m_maximumBytesCached(defaultMaximumBytesCached)
+{
+}
+
+IOSurfacePool&amp; IOSurfacePool::sharedPool()
+{
+    static NeverDestroyed&lt;IOSurfacePool&gt; pool;
+    return pool;
+}
+
+static bool surfaceMatchesParameters(IOSurface&amp; surface, const IntSize&amp; requestedSize, ColorSpace colorSpace)
+{
+    IntSize surfaceSize = surface.size();
+    if (colorSpace != surface.colorSpace())
+        return false;
+    if (surfaceSize != requestedSize)
+        return false;
+    return true;
+}
+
+void IOSurfacePool::willAddSurface(IOSurface* surface, bool inUse)
+{
+    CachedSurfaceDetails&amp; details = m_surfaceDetails.add(surface, CachedSurfaceDetails()).iterator-&gt;value;
+    details.resetLastUseTime();
+
+    surface-&gt;clearGraphicsContext();
+
+    size_t surfaceBytes = surface-&gt;totalBytes();
+    m_bytesCached += surfaceBytes;
+    if (inUse)
+        m_inUseBytesCached += surfaceBytes;
+    evict(surface-&gt;totalBytes());
+}
+
+void IOSurfacePool::didRemoveSurface(IOSurface* surface, bool inUse)
+{
+    size_t surfaceBytes = surface-&gt;totalBytes();
+    m_bytesCached -= surfaceBytes;
+    if (inUse)
+        m_inUseBytesCached -= surfaceBytes;
+
+    m_surfaceDetails.remove(surface);
+}
+
+void IOSurfacePool::didUseSurfaceOfSize(IntSize size)
+{
+    m_sizesInPruneOrder.remove(m_sizesInPruneOrder.reverseFind(size));
+    m_sizesInPruneOrder.append(size);
+}
+
+PassRefPtr&lt;IOSurface&gt; IOSurfacePool::takeSurface(IntSize size, ColorSpace colorSpace)
+{
+    CachedSurfaceMap::iterator mapIter = m_cachedSurfaces.find(size);
+
+    if (mapIter == m_cachedSurfaces.end()) {
+        DUMP_POOL_STATISTICS();
+        return nullptr;
+    }
+
+    for (auto surfaceIter = mapIter-&gt;value.begin(); surfaceIter != mapIter-&gt;value.end(); ++surfaceIter) {
+        if (!surfaceMatchesParameters(*surfaceIter-&gt;get(), size, colorSpace))
+            continue;
+        
+        RefPtr&lt;IOSurface&gt; surface = surfaceIter-&gt;get();
+        mapIter-&gt;value.remove(surfaceIter);
+
+        didUseSurfaceOfSize(size);
+
+        if (mapIter-&gt;value.isEmpty()) {
+            m_cachedSurfaces.remove(mapIter);
+            m_sizesInPruneOrder.removeLast();
+        }
+
+        didRemoveSurface(surface.get(), false);
+
+        surface-&gt;setIsPurgeable(false);
+
+        DUMP_POOL_STATISTICS();
+        return surface.release();
+    }
+
+    // Some of the in-use surfaces may no longer actually be in-use, but we haven't moved them over yet.
+    for (auto surfaceIter = m_inUseSurfaces.begin(); surfaceIter != m_inUseSurfaces.end(); ++surfaceIter) {
+        if (!surfaceMatchesParameters(*surfaceIter-&gt;get(), size, colorSpace))
+            continue;
+        if (surfaceIter-&gt;get()-&gt;isInUse())
+            continue;
+        
+        RefPtr&lt;IOSurface&gt; surface = surfaceIter-&gt;get();
+        m_inUseSurfaces.remove(surfaceIter);
+        didRemoveSurface(surface.get(), true);
+
+        surface-&gt;setIsPurgeable(false);
+
+        DUMP_POOL_STATISTICS();
+        return surface.release();
+    }
+
+    DUMP_POOL_STATISTICS();
+    return nullptr;
+}
+
+void IOSurfacePool::addSurface(IOSurface* surface)
+{
+    if (surface-&gt;totalBytes() &gt; m_maximumBytesCached)
+        return;
+
+    bool surfaceIsInUse = surface-&gt;isInUse();
+
+    willAddSurface(surface, surfaceIsInUse);
+
+    if (surfaceIsInUse) {
+        m_inUseSurfaces.prepend(surface);
+        scheduleCollectionTimer();
+        DUMP_POOL_STATISTICS();
+        return;
+    }
+
+    insertSurfaceIntoPool(surface);
+    DUMP_POOL_STATISTICS();
+}
+
+void IOSurfacePool::insertSurfaceIntoPool(IOSurface* surface)
+{
+    auto insertedTuple = m_cachedSurfaces.add(surface-&gt;size(), CachedSurfaceQueue());
+    insertedTuple.iterator-&gt;value.prepend(surface);
+    if (!insertedTuple.isNewEntry)
+        m_sizesInPruneOrder.remove(m_sizesInPruneOrder.reverseFind(surface-&gt;size()));
+    m_sizesInPruneOrder.append(surface-&gt;size());
+
+    scheduleCollectionTimer();
+}
+
+void IOSurfacePool::setPoolSize(size_t poolSizeInBytes)
+{
+    m_maximumBytesCached = poolSizeInBytes;
+    evict(0);
+}
+
+void IOSurfacePool::tryEvictInUseSurface()
+{
+    if (m_inUseSurfaces.isEmpty())
+        return;
+
+    RefPtr&lt;IOSurface&gt; surface = m_inUseSurfaces.takeLast();
+    didRemoveSurface(surface.get(), true);
+}
+
+void IOSurfacePool::tryEvictOldestCachedSurface()
+{
+    if (m_cachedSurfaces.isEmpty())
+        return;
+
+    if (m_sizesInPruneOrder.isEmpty())
+        return;
+
+    CachedSurfaceMap::iterator surfaceQueueIter = m_cachedSurfaces.find(m_sizesInPruneOrder.first());
+    ASSERT(!surfaceQueueIter-&gt;value.isEmpty());
+    RefPtr&lt;IOSurface&gt; surface = surfaceQueueIter-&gt;value.takeLast();
+    didRemoveSurface(surface.get(), false);
+
+    if (surfaceQueueIter-&gt;value.isEmpty()) {
+        m_cachedSurfaces.remove(surfaceQueueIter);
+        m_sizesInPruneOrder.remove(0);
+    }
+}
+
+void IOSurfacePool::evict(size_t additionalSize)
+{
+    // FIXME: Perhaps purgeable surfaces should count less against the cap?
+    // We don't want to end up with a ton of empty (purged) surfaces, though, as that would defeat the purpose of the pool.
+    size_t targetSize = m_maximumBytesCached - additionalSize;
+
+    // Interleave eviction of old cached surfaces and more recent in-use surfaces.
+    // In-use surfaces are more recently used, but less useful in the pool, as they aren't
+    // immediately available when requested.
+    while (m_bytesCached &gt; targetSize) {
+        tryEvictOldestCachedSurface();
+
+        if (m_inUseBytesCached &gt; maximumInUseBytes)
+            tryEvictInUseSurface();
+    }
+
+    while (m_inUseBytesCached &gt; maximumInUseBytes)
+        tryEvictInUseSurface();
+}
+
+void IOSurfacePool::collectInUseSurfaces()
+{
+    CachedSurfaceQueue newInUseSurfaces;
+    for (CachedSurfaceQueue::iterator surfaceIter = m_inUseSurfaces.begin(); surfaceIter != m_inUseSurfaces.end(); ++surfaceIter) {
+        IOSurface* surface = surfaceIter-&gt;get();
+        if (surface-&gt;isInUse()) {
+            newInUseSurfaces.append(*surfaceIter);
+            continue;
+        }
+
+        m_inUseBytesCached -= surface-&gt;totalBytes();
+        insertSurfaceIntoPool(surface);
+    }
+
+    m_inUseSurfaces = newInUseSurfaces;
+}
+
+bool IOSurfacePool::markOlderSurfacesPurgeable()
+{
+    bool markedAllSurfaces = true;
+    auto markTime = std::chrono::steady_clock::now();
+
+    for (auto&amp; surfaceAndDetails : m_surfaceDetails) {
+        if (surfaceAndDetails.value.hasMarkedPurgeable)
+            continue;
+
+        if (markTime - surfaceAndDetails.value.lastUseTime &lt; surfaceAgeBeforeMarkingPurgeable) {
+            markedAllSurfaces = false;
+            continue;
+        }
+
+        surfaceAndDetails.key-&gt;setIsPurgeable(true);
+        surfaceAndDetails.value.hasMarkedPurgeable = true;
+    }
+
+    return markedAllSurfaces;
+}
+
+void IOSurfacePool::collectionTimerFired(Timer&lt;IOSurfacePool&gt;&amp;)
+{
+    collectInUseSurfaces();
+    bool markedAllSurfaces = markOlderSurfacesPurgeable();
+
+    if (!m_inUseSurfaces.size() &amp;&amp; markedAllSurfaces)
+        m_collectionTimer.stop();
+
+    DUMP_POOL_STATISTICS();
+}
+
+void IOSurfacePool::scheduleCollectionTimer()
+{
+    if (!m_collectionTimer.isActive())
+        m_collectionTimer.startRepeating(collectionInterval);
+}
+
+void IOSurfacePool::discardAllSurfaces()
+{
+    m_bytesCached = 0;
+    m_inUseBytesCached = 0;
+    m_surfaceDetails.clear();
+    m_cachedSurfaces.clear();
+    m_inUseSurfaces.clear();
+    m_sizesInPruneOrder.clear();
+    m_collectionTimer.stop();
+}
+
+void IOSurfacePool::showPoolStatistics()
+{
+#if ENABLE_IOSURFACE_POOL_STATISTICS
+    WTFLogAlways(&quot;IOSurfacePool Statistics\n&quot;);
+    unsigned totalSurfaces = 0;
+    size_t totalSize = 0;
+    size_t totalPurgeableSize = 0;
+
+    for (const auto&amp; keyAndSurfaces : m_cachedSurfaces) {
+        ASSERT(!keyAndSurfaces.value.isEmpty());
+        size_t queueSize = 0;
+        size_t queuePurgeableSize = 0;
+        for (const auto&amp; surface : keyAndSurfaces.value) {
+            size_t surfaceBytes = surface-&gt;totalBytes();
+
+            totalSurfaces++;
+            queueSize += surfaceBytes;
+
+            if (surface-&gt;isPurgeable())
+                queuePurgeableSize += surfaceBytes;
+        }
+
+        totalSize += queueSize;
+        totalPurgeableSize += queuePurgeableSize;
+
+        WTFLogAlways(&quot;   %d x %d: %zu surfaces for %zd KB (%zd KB purgeable)&quot;, keyAndSurfaces.key.width(), keyAndSurfaces.key.height(), keyAndSurfaces.value.size(), queueSize / 1024, queuePurgeableSize / 1024);
+    }
+
+    size_t inUseSize = 0;
+    for (const auto&amp; surface : m_inUseSurfaces) {
+        totalSurfaces++;
+        inUseSize += surface-&gt;totalBytes();
+    }
+
+    totalSize += inUseSize;
+    WTFLogAlways(&quot;   IN USE: %zu surfaces for %zd KB&quot;, m_inUseSurfaces.size(), inUseSize / 1024);
+
+    // FIXME: Should move consistency checks elsewhere, and always perform them in debug builds.
+    ASSERT(m_bytesCached == totalSize);
+    ASSERT(m_bytesCached &lt;= m_maximumBytesCached);
+
+    WTFLogAlways(&quot;   TOTAL: %d surfaces for %zd KB (%zd KB purgeable)\n&quot;, totalSurfaces, totalSize / 1024, totalPurgeableSize / 1024);
+#endif
+}
+
+}
+#endif // USE(IOSURFACE)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgIOSurfacePoolh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.h (0 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.h        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+/*
+ * Copyright (C) 2013, 2014 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 IOSurfacePool_h
+#define IOSurfacePool_h
+
+#include &quot;ColorSpace.h&quot;
+#include &quot;IntSize.h&quot;
+#include &quot;IntSizeHash.h&quot;
+#include &quot;Timer.h&quot;
+#include &lt;wtf/Deque.h&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
+#include &lt;wtf/RetainPtr.h&gt;
+
+#if USE(IOSURFACE)
+
+namespace WebCore {
+
+class IOSurface;
+
+class IOSurfacePool {
+    WTF_MAKE_NONCOPYABLE(IOSurfacePool);
+    WTF_MAKE_FAST_ALLOCATED;
+    friend class NeverDestroyed&lt;IOSurfacePool&gt;;
+
+public:
+    static IOSurfacePool&amp; sharedPool();
+
+    PassRefPtr&lt;IOSurface&gt; takeSurface(IntSize size, ColorSpace colorSpace);
+    void addSurface(IOSurface*);
+
+    void discardAllSurfaces();
+
+    void setPoolSize(size_t);
+
+    void showPoolStatistics();
+
+private:
+    IOSurfacePool();
+
+    struct CachedSurfaceDetails {
+        CachedSurfaceDetails()
+            : hasMarkedPurgeable(false)
+        { }
+
+        void resetLastUseTime() { lastUseTime = std::chrono::steady_clock::now(); }
+
+        std::chrono::steady_clock::time_point lastUseTime;
+        bool hasMarkedPurgeable;
+    };
+
+    typedef Deque&lt;RefPtr&lt;IOSurface&gt;&gt; CachedSurfaceQueue;
+    typedef HashMap&lt;IntSize, CachedSurfaceQueue&gt; CachedSurfaceMap;
+    typedef HashMap&lt;IOSurface*, CachedSurfaceDetails&gt; CachedSurfaceDetailsMap;
+
+    void willAddSurface(IOSurface*, bool inUse);
+    void didRemoveSurface(IOSurface*, bool inUse);
+    void didUseSurfaceOfSize(IntSize);
+
+    void insertSurfaceIntoPool(IOSurface*);
+
+    void evict(size_t additionalSize);
+    void tryEvictInUseSurface();
+    void tryEvictOldestCachedSurface();
+
+    void scheduleCollectionTimer();
+    void collectionTimerFired(Timer&lt;IOSurfacePool&gt;&amp;);
+    void collectInUseSurfaces();
+    bool markOlderSurfacesPurgeable();
+
+    Timer&lt;IOSurfacePool&gt; m_collectionTimer;
+    CachedSurfaceMap m_cachedSurfaces;
+    CachedSurfaceQueue m_inUseSurfaces;
+    CachedSurfaceDetailsMap m_surfaceDetails;
+    Vector&lt;IntSize&gt; m_sizesInPruneOrder;
+
+    size_t m_bytesCached;
+    size_t m_inUseBytesCached;
+    size_t m_maximumBytesCached;
+};
+
+}
+#endif // USE(IOSURFACE)
+
+#endif // IOSurfacePool_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageBufferBackingStoreCachecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.cpp (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.cpp        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.cpp        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -1,227 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 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.
- */
-
-#include &quot;config.h&quot;
-#include &quot;ImageBufferBackingStoreCache.h&quot;
-
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
-#include &lt;CoreGraphics/CoreGraphics.h&gt;
-#include &lt;IOSurface/IOSurface.h&gt;
-
-static const double purgeInterval = 5;
-
-namespace WebCore {
-
-// FIXME: Adopt WebCore::IOSurface.
-static RetainPtr&lt;IOSurfaceRef&gt; createIOSurface(const IntSize&amp; size)
-{
-    unsigned pixelFormat = 'BGRA';
-    unsigned bytesPerElement = 4;
-    int width = size.width();
-    int height = size.height();
-
-    unsigned long bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, size.width() * bytesPerElement);
-    if (!bytesPerRow)
-        return 0;
-
-    unsigned long allocSize = IOSurfaceAlignProperty(kIOSurfaceAllocSize, size.height() * bytesPerRow);
-    if (!allocSize)
-        return 0;
-
-    const int kNumCreationParameters = 6;
-    const void* keys[kNumCreationParameters];
-    const void* values[kNumCreationParameters];
-    keys[0] = kIOSurfaceWidth;
-    values[0] = CFNumberCreate(0, kCFNumberIntType, &amp;width);
-    keys[1] = kIOSurfaceHeight;
-    values[1] = CFNumberCreate(0, kCFNumberIntType, &amp;height);
-    keys[2] = kIOSurfacePixelFormat;
-    values[2] = CFNumberCreate(0, kCFNumberIntType, &amp;pixelFormat);
-    keys[3] = kIOSurfaceBytesPerElement;
-    values[3] = CFNumberCreate(0, kCFNumberIntType, &amp;bytesPerElement);
-    keys[4] = kIOSurfaceBytesPerRow;
-    values[4] = CFNumberCreate(0, kCFNumberLongType, &amp;bytesPerRow);
-    keys[5] = kIOSurfaceAllocSize;
-    values[5] = CFNumberCreate(0, kCFNumberLongType, &amp;allocSize);
-
-    RetainPtr&lt;CFDictionaryRef&gt; dict = adoptCF(CFDictionaryCreate(0, keys, values, kNumCreationParameters, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
-    for (unsigned i = 0; i &lt; kNumCreationParameters; i++)
-        CFRelease(values[i]);
-
-    return adoptCF(IOSurfaceCreate(dict.get()));
-}
-
-ImageBufferBackingStoreCache::ImageBufferBackingStoreCache()
-    : m_purgeTimer(this, &amp;ImageBufferBackingStoreCache::timerFired, purgeInterval)
-    , m_pixelsCached(0)
-    {
-    }
-
-ImageBufferBackingStoreCache&amp; ImageBufferBackingStoreCache::get()
-{
-    DEPRECATED_DEFINE_STATIC_LOCAL(ImageBufferBackingStoreCache, cache, ());
-    return cache;
-}
-
-bool ImageBufferBackingStoreCache::isAcceptableSurface(const IOSurfaceAndContextWithCreationParams&amp; info, const IntSize&amp; requestedSize, CGColorSpaceRef colorSpace, bool needExactSize) const
-{
-    IOSurfaceRef surface = info.surface.get();
-    IntSize actualSize(IOSurfaceGetWidth(surface), IOSurfaceGetHeight(surface));
-    if (!CFEqual(info.colorSpace.get(), colorSpace))
-        return false;
-    if (needExactSize &amp;&amp; actualSize != requestedSize)
-        return false;
-    if (actualSize.width() &lt; requestedSize.width() || actualSize.height() &lt; requestedSize.height())
-        return false;
-    return true;
-}
-
-void ImageBufferBackingStoreCache::insertIntoCache(IOSurfaceAndContextWithCreationParams&amp;&amp; info)
-{
-    IOSurfaceRef surface = info.surface.get();
-    IntSize surfaceSize(IOSurfaceGetWidth(surface), IOSurfaceGetHeight(surface));
-
-    auto toAdd = new IOSurfaceAndContextWithCreationParams(info);
-    auto insertedTuple = m_cachedSurfaces.add(convertSizeToKey(surfaceSize), InfoLinkedList());
-    insertedTuple.iterator-&gt;value.append(toAdd);
-    
-    m_pixelsCached += surfaceSize.area();
-}
-
-auto ImageBufferBackingStoreCache::takeFromCache(CachedSurfaceMap::iterator iter, IOSurfaceAndContextWithCreationParams* info) -&gt; IOSurfaceAndContextWithCreationParams
-{
-    ASSERT(info);
-    ASSERT(iter != m_cachedSurfaces.end());
-
-    IOSurfaceRef surface = info-&gt;surface.get();
-    m_pixelsCached -= IOSurfaceGetWidth(surface) * IOSurfaceGetHeight(surface);
-
-    iter-&gt;value.remove(info);
-    if (iter-&gt;value.isEmpty())
-        m_cachedSurfaces.remove(iter);
-    IOSurfaceAndContextWithCreationParams result = std::move(*info);
-    delete info;
-    return result;
-}
-
-bool ImageBufferBackingStoreCache::tryTakeFromCache(const IntSize&amp; size, CGColorSpaceRef colorSpace, bool needExactSize, IOSurfaceAndContextWithCreationParams&amp; outInfo)
-{
-    CachedSurfaceMap::iterator i = m_cachedSurfaces.find(convertSizeToKey(size));
-    if (i == m_cachedSurfaces.end())
-        return nullptr;
-    InfoLinkedList&amp; ll = i-&gt;value;
-    for (auto info = ll.head(); info; info = info-&gt;next()) {
-        if (isAcceptableSurface(*info, size, colorSpace, needExactSize)) {
-            outInfo = takeFromCache(i, info);
-            return true;
-        }
-    }
-    return false;
-}
-
-ImageBufferBackingStoreCache::IOSurfaceAndContext ImageBufferBackingStoreCache::getOrAllocate(IntSize size, CGColorSpaceRef colorSpace, bool needExactSize)
-{
-    IOSurfaceAndContextWithCreationParams foundInfo;
-    if (tryTakeFromCache(size, colorSpace, needExactSize, foundInfo)) {
-        IOSurfaceRef surface = foundInfo.surface.get();
-        CGContextRef context = foundInfo.context.get();
-        CGContextSaveGState(context);
-        auto activeInserted = m_activeSurfaces.add(surface, std::move(foundInfo));
-        ASSERT(activeInserted.isNewEntry);
-        return activeInserted.iterator-&gt;value;
-    }
-
-    RetainPtr&lt;IOSurfaceRef&gt; surface = createIOSurface(size);
-    if (!surface.get())
-        return IOSurfaceAndContext();
-
-    RetainPtr&lt;CGContextRef&gt; context = adoptCF(wkIOSurfaceContextCreate(surface.get(), size.width(), size.height(), colorSpace));
-    if (!context.get())
-        return IOSurfaceAndContext();
-    CGContextSaveGState(context.get());
-
-    auto insertedTuple = m_activeSurfaces.add(surface, IOSurfaceAndContextWithCreationParams(surface.get(), context.get(), colorSpace));
-    ASSERT(insertedTuple.isNewEntry);
-
-    return insertedTuple.iterator-&gt;value;
-}
-
-void ImageBufferBackingStoreCache::deallocate(IOSurfaceRef surface)
-{
-    ActiveSurfaceMap::iterator lookup = m_activeSurfaces.find(surface);
-    ASSERT(lookup != m_activeSurfaces.end());
-    
-    auto info = std::move(lookup-&gt;value);
-    m_activeSurfaces.remove(lookup);
-    
-    IOSurfaceRef ioSurface = info.surface.get();
-    CGContextRef context = info.context.get();
-    IntSize surfaceSize(IOSurfaceGetWidth(ioSurface), IOSurfaceGetHeight(ioSurface));
-    int surfaceArea = surfaceSize.area();
-
-    static const int kMaxPixelsCached = 1024 * 1024 * 64; // 256MB
-    if (surfaceArea &gt; kMaxPixelsCached)
-        return;
-
-    // Evict
-    auto bucket = m_cachedSurfaces.find(convertSizeToKey(surfaceSize));
-    if (bucket != m_cachedSurfaces.end()) {
-        for (int itemsInBucket = bucket-&gt;value.size();
-            itemsInBucket &gt; 0 &amp;&amp; m_pixelsCached + surfaceArea &gt; kMaxPixelsCached;
-            --itemsInBucket)
-            takeFromCache(bucket, bucket-&gt;value.head());
-    }
-    while (m_pixelsCached + surfaceArea &gt; kMaxPixelsCached) {
-        CachedSurfaceMap::iterator iter = m_cachedSurfaces.begin();
-        takeFromCache(iter, iter-&gt;value.head());
-    }
-
-    CGContextRestoreGState(context);
-    // Clear opportunistically so CG has more time to carry it out.
-    CGContextClearRect(context, CGRectMake(0, 0, surfaceSize.width(), surfaceSize.height()));
-#if !PLATFORM(IOS) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &lt; 1090
-    CGContextFlush(context);
-#endif
-
-    insertIntoCache(std::move(info));
-
-    schedulePurgeTimer();
-}
-
-void ImageBufferBackingStoreCache::timerFired(DeferrableOneShotTimer&lt;ImageBufferBackingStoreCache&gt;&amp;)
-{
-    while (!m_cachedSurfaces.isEmpty()) {
-        CachedSurfaceMap::iterator iter = m_cachedSurfaces.begin();
-        takeFromCache(iter, iter-&gt;value.head());
-    }
-}
-
-void ImageBufferBackingStoreCache::schedulePurgeTimer()
-{
-    m_purgeTimer.restart();
-}
-
-}
-#endif // IOSURFACE_CANVAS_BACKING_STORE
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageBufferBackingStoreCacheh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.h (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.h        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferBackingStoreCache.h        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -1,112 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 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 ImageBufferBackingStoreCache_h
-#define ImageBufferBackingStoreCache_h
-
-#include &quot;ImageBuffer.h&quot;
-
-#include &quot;Timer.h&quot;
-
-#include &lt;wtf/DoublyLinkedList.h&gt;
-#include &lt;wtf/HashMap.h&gt;
-
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
-
-namespace WebCore {
-
-class ImageBufferBackingStoreCache {
-    WTF_MAKE_NONCOPYABLE(ImageBufferBackingStoreCache); WTF_MAKE_FAST_ALLOCATED;
-
-public:
-    static ImageBufferBackingStoreCache&amp; get();
-    
-    struct IOSurfaceAndContext {
-        IOSurfaceAndContext()
-        {
-        }
-
-        IOSurfaceAndContext(IOSurfaceRef surface, CGContextRef context)
-            : surface(surface)
-            , context(context)
-        {
-        }
-
-        RetainPtr&lt;IOSurfaceRef&gt; surface;
-        RetainPtr&lt;CGContextRef&gt; context;
-    };
-
-    IOSurfaceAndContext getOrAllocate(IntSize, CGColorSpaceRef, bool needExactSize);
-    void deallocate(IOSurfaceRef);
-
-private:
-    ImageBufferBackingStoreCache();
-
-    struct IOSurfaceAndContextWithCreationParams : public IOSurfaceAndContext, public DoublyLinkedListNode&lt;IOSurfaceAndContextWithCreationParams&gt; {
-        IOSurfaceAndContextWithCreationParams()
-        {
-        }
-
-        IOSurfaceAndContextWithCreationParams(IOSurfaceRef surface, CGContextRef context, CGColorSpaceRef colorSpace)
-            : IOSurfaceAndContext(surface, context)
-            , colorSpace(colorSpace)
-        {
-        }
-
-        IOSurfaceAndContextWithCreationParams* m_prev;
-        IOSurfaceAndContextWithCreationParams* m_next;
-        RetainPtr&lt;CGColorSpaceRef&gt; colorSpace;
-    };
-    typedef HashMap&lt;RetainPtr&lt;IOSurfaceRef&gt;, IOSurfaceAndContextWithCreationParams&gt; ActiveSurfaceMap;
-    typedef std::pair&lt;int, int&gt; CachedSurfaceKey;
-    typedef DoublyLinkedList&lt;IOSurfaceAndContextWithCreationParams&gt; InfoLinkedList;
-    typedef HashMap&lt;CachedSurfaceKey, InfoLinkedList&gt; CachedSurfaceMap;
-
-    static CachedSurfaceKey convertSizeToKey(const IntSize&amp; size)
-    {
-        return std::make_pair(WTF::roundUpToMultipleOf(8, size.width()), WTF::roundUpToMultipleOf(8, size.height()));
-    }
-
-    IOSurfaceAndContextWithCreationParams takeFromCache(CachedSurfaceMap::iterator, IOSurfaceAndContextWithCreationParams*);
-    void insertIntoCache(IOSurfaceAndContextWithCreationParams&amp;&amp;);
-
-    // If we find an acceptable surface, this function removes it from the cache as
-    // well as placing it in the out parameter.
-    bool tryTakeFromCache(const IntSize&amp;, CGColorSpaceRef, bool needExactSize, IOSurfaceAndContextWithCreationParams&amp; outInfo);
-    bool isAcceptableSurface(const IOSurfaceAndContextWithCreationParams&amp;, const IntSize&amp;, CGColorSpaceRef, bool needExactSize) const;
-
-    void timerFired(DeferrableOneShotTimer&lt;ImageBufferBackingStoreCache&gt;&amp;);
-    void schedulePurgeTimer();
-
-    DeferrableOneShotTimer&lt;ImageBufferBackingStoreCache&gt; m_purgeTimer;
-    ActiveSurfaceMap m_activeSurfaces;
-    CachedSurfaceMap m_cachedSurfaces;
-    int m_pixelsCached;
-};
-
-}
-#endif // IOSURFACE_CANVAS_BACKING_STORE
-
-#endif // ImageBufferBackingStoreCache_h
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscocoaIOSurfacemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if USE(IOSURFACE)
</span><span class="cx"> 
</span><span class="cx"> #import &quot;GraphicsContextCG.h&quot;
</span><ins>+#import &quot;IOSurfacePool.h&quot;
</ins><span class="cx"> #import &lt;IOSurface/IOSurface.h&gt;
</span><span class="cx"> #import &lt;wtf/Assertions.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -53,6 +54,8 @@
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;IOSurface&gt; IOSurface::create(IntSize size, ColorSpace colorSpace)
</span><span class="cx"> {
</span><ins>+    if (RefPtr&lt;IOSurface&gt; cachedSurface = IOSurfacePool::sharedPool().takeSurface(size, colorSpace))
+        return cachedSurface.release();
</ins><span class="cx">     return adoptRef(new IOSurface(size, colorSpace));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosMemoryPressureHandlerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/MemoryPressureHandlerIOS.mm (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/MemoryPressureHandlerIOS.mm        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/ios/MemoryPressureHandlerIOS.mm        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #import &quot;config.h&quot;
</span><span class="cx"> #import &quot;MemoryPressureHandler.h&quot;
</span><span class="cx"> 
</span><ins>+#import &quot;IOSurfacePool.h&quot;
</ins><span class="cx"> #import &quot;Logging.h&quot;
</span><span class="cx"> #import &quot;SystemMemory.h&quot;
</span><span class="cx"> #import &quot;WebCoreThread.h&quot;
</span><span class="lines">@@ -104,4 +105,9 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MemoryPressureHandler::platformReleaseMemory(bool)
+{
+    IOSurfacePool::sharedPool().discardAllSurfaces();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacMemoryPressureHandlerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -26,18 +26,17 @@
</span><span class="cx"> #import &quot;config.h&quot;
</span><span class="cx"> #import &quot;MemoryPressureHandler.h&quot;
</span><span class="cx"> 
</span><del>-#import &lt;WebCore/LayerPool.h&gt;
-#import &lt;wtf/CurrentTime.h&gt;
-#import &lt;malloc/malloc.h&gt;
</del><ins>+#if !PLATFORM(IOS)
</ins><span class="cx"> 
</span><del>-#if !PLATFORM(IOS)
</del><ins>+#import &quot;IOSurfacePool.h&quot;
+#import &quot;LayerPool.h&quot;
</ins><span class="cx"> #import &quot;WebCoreSystemInterface.h&quot;
</span><ins>+#import &lt;malloc/malloc.h&gt;
</ins><span class="cx"> #import &lt;notify.h&gt;
</span><del>-#endif
</del><ins>+#import &lt;wtf/CurrentTime.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-#if !PLATFORM(IOS)
</del><span class="cx"> static dispatch_source_t _cache_event_source = 0;
</span><span class="cx"> static dispatch_source_t _timer_event_source = 0;
</span><span class="cx"> static int _notifyToken;
</span><span class="lines">@@ -57,7 +56,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     dispatch_async(dispatch_get_main_queue(), ^{
</span><del>-#if !PLATFORM(IOS) &amp;&amp; MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 1090
</del><ins>+#if MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 1090
</ins><span class="cx">         _cache_event_source = wkCreateMemoryStatusPressureCriticalDispatchOnMainQueue();
</span><span class="cx"> #else
</span><span class="cx">         _cache_event_source = wkCreateVMPressureDispatchOnMainQueue();
</span><span class="lines">@@ -138,8 +137,9 @@
</span><span class="cx"> void MemoryPressureHandler::platformReleaseMemory(bool)
</span><span class="cx"> {
</span><span class="cx">     LayerPool::sharedPool()-&gt;drain();
</span><ins>+    IOSurfacePool::sharedPool().discardAllSurfaces();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+} // namespace WebCore
+
</ins><span class="cx"> #endif // !PLATFORM(IOS)
</span><del>-
-} // namespace WebCore
</del></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebKit2/ChangeLog        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2014-04-02  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Pool IOSurfaces to help with allocation cost
+        https://bugs.webkit.org/show_bug.cgi?id=131096
+        &lt;rdar://problem/15373942&gt;
+
+        Reviewed by Simon Fraser.
+
+        * Shared/mac/RemoteLayerBackingStore.h:
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        (WebKit::RemoteLayerBackingStore::~RemoteLayerBackingStore):
+        (WebKit::RemoteLayerBackingStore::clearBackingStore):
+        (WebKit::RemoteLayerBackingStore::display):
+        When RemoteLayerBackingStore discards a layer, throw it into the pool.
+
+        * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
+        (WebKit::RemoteLayerTreeDrawingAreaProxy::RemoteLayerTreeDrawingAreaProxy):
+        Disable the pool in the UI process.
+
</ins><span class="cx"> 2014-04-02  Alice Barraclough  &lt;alice.barraclough@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix a typo causing TestWebKitAPI to timeout when testing Find.
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedmacRemoteLayerBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     RemoteLayerBackingStore();
</span><ins>+    ~RemoteLayerBackingStore();
</ins><span class="cx"> 
</span><span class="cx">     void ensureBackingStore(PlatformCALayerRemote*, WebCore::IntSize, float scale, bool acceleratesDrawing, bool isOpaque);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedmacRemoteLayerBackingStoremm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #import &lt;QuartzCore/QuartzCore.h&gt;
</span><span class="cx"> #import &lt;WebCore/GraphicsContextCG.h&gt;
</span><span class="cx"> #import &lt;WebCore/IOSurface.h&gt;
</span><ins>+#import &lt;WebCore/IOSurfacePool.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WebLayer.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if USE(IOSURFACE)
</span><span class="lines">@@ -58,6 +59,11 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RemoteLayerBackingStore::~RemoteLayerBackingStore()
+{
+    clearBackingStore();
+}
+
</ins><span class="cx"> void RemoteLayerBackingStore::ensureBackingStore(PlatformCALayerRemote* layer, IntSize size, float scale, bool acceleratesDrawing, bool isOpaque)
</span><span class="cx"> {
</span><span class="cx">     if (m_layer == layer &amp;&amp; m_size == size &amp;&amp; m_scale == scale &amp;&amp; m_acceleratesDrawing == acceleratesDrawing &amp;&amp; m_isOpaque == isOpaque)
</span><span class="lines">@@ -75,6 +81,11 @@
</span><span class="cx"> void RemoteLayerBackingStore::clearBackingStore()
</span><span class="cx"> {
</span><span class="cx"> #if USE(IOSURFACE)
</span><ins>+    if (m_frontSurface)
+        IOSurfacePool::sharedPool().addSurface(m_frontSurface.get());
+    if (m_backSurface)
+        IOSurfacePool::sharedPool().addSurface(m_backSurface.get());
+
</ins><span class="cx">     m_frontSurface = nullptr;
</span><span class="cx">     m_backSurface = nullptr;
</span><span class="cx"> #endif
</span><span class="lines">@@ -188,6 +199,8 @@
</span><span class="cx"> 
</span><span class="cx">         if (!m_frontSurface || m_frontSurface-&gt;isInUse()) {
</span><span class="cx">             // FIXME: Instead of discarding it, put the unusable in-use surface into a pool for future use.
</span><ins>+            if (m_frontSurface)
+                IOSurfacePool::sharedPool().addSurface(m_frontSurface.get());
</ins><span class="cx">             m_frontSurface = IOSurface::create(expandedScaledSize, ColorSpaceDeviceRGB);
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm (166681 => 166682)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm        2014-04-03 00:07:03 UTC (rev 166681)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm        2014-04-03 00:33:02 UTC (rev 166682)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #import &quot;RemoteScrollingCoordinatorProxy.h&quot;
</span><span class="cx"> #import &quot;WebPageProxy.h&quot;
</span><span class="cx"> #import &quot;WebProcessProxy.h&quot;
</span><ins>+#import &lt;WebCore/IOSurfacePool.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WebCoreCALayerExtras.h&gt;
</span><span class="cx"> 
</span><span class="cx"> static const CFIndex CoreAnimationCommitRunLoopOrder = 2000000;
</span><span class="lines">@@ -46,6 +47,10 @@
</span><span class="cx">     , m_remoteLayerTreeHost(*this)
</span><span class="cx">     , m_isWaitingForDidUpdateGeometry(false)
</span><span class="cx"> {
</span><ins>+    // We don't want to pool surfaces in the UI process.
+    // FIXME: We should do this somewhere else.
+    IOSurfacePool::sharedPool().setPoolSize(0);
+
</ins><span class="cx">     m_webPageProxy-&gt;process().addMessageReceiver(Messages::RemoteLayerTreeDrawingAreaProxy::messageReceiverName(), m_webPageProxy-&gt;pageID(), *this);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>