<!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>[181301] trunk</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/181301">181301</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2015-03-09 18:24:14 -0700 (Mon, 09 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[CG] Have Canvas use the IOSurfacePool
https://bugs.webkit.org/show_bug.cgi?id=142417
&lt;rdar://problem/20044440&gt;

Reviewed by Darin Adler.

PerformanceTests:

Lower the number of different canvas sizes from 1000 to 100 so that
the test does not require such a huge cache size. With 100, we now
get over 90% cache hit rate with the default IOSurfacePool size.

* Canvas/reuse.html:

Source/WebCore:

Have ImageBufferDataCG use the IOSurfacePool so that Canvas can
benefit from it. I see a ~75% progression on Canvas/reuse.html
performance test on my Macbook Pro with 1000 different canvas
sizes and ~110% progression with 100 different canvas sizes.

I also see a ~65% cache hit rate on the mobile version of
cnn.com.

Note that ImageData calls CGContextClearRect() after calling
IOSurface::create() so recycling IOSurfaces in this case should
be safe.

Performance test: Canvas/reuse.html

* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::baseTransform):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::ImageBuffer):
(WebCore::ImageBuffer::context):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::copyNativeImage):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::clip):
(WebCore::ImageBuffer::putByteArray):
(WebCore::ImageBuffer::toDataURL):
* platform/graphics/cg/ImageBufferDataCG.cpp:
(WebCore::ImageBufferData::~ImageBufferData):
(WebCore::ImageBufferData::getData):
(WebCore::ImageBufferData::putData):
(WebCore::ImageBufferData::ImageBufferData): Deleted.
* platform/graphics/cg/ImageBufferDataCG.h:
* platform/graphics/cocoa/IOSurface.h:
* platform/graphics/cocoa/IOSurface.mm:
(IOSurface::surfaceFromPool):
(IOSurface::create):
(IOSurface::createFromSendRight):
(IOSurface::createFromImage):
(IOSurface::setContextSize):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsCanvasreusehtml">trunk/PerformanceTests/Canvas/reuse.html</a></li>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageBufferh">trunk/Source/WebCore/platform/graphics/ImageBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageBufferCGcpp">trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageBufferDataCGcpp">trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageBufferDataCGh">trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscocoaIOSurfaceh">trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscocoaIOSurfacemm">trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsCanvasreusehtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Canvas/reuse.html (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Canvas/reuse.html        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/PerformanceTests/Canvas/reuse.html        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -4,7 +4,7 @@
</span><span class="cx"> &lt;script src=&quot;../resources/runner.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;script&gt;
</span><span class="cx"> 
</span><del>-var numCreated = 1000;
</del><ins>+var numCreated = 100;
</ins><span class="cx"> 
</span><span class="cx"> function testCreation() {
</span><span class="cx">     (function() {
</span></span></pre></div>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/PerformanceTests/ChangeLog        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-03-09  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [CG] Have Canvas use the IOSurfacePool
+        https://bugs.webkit.org/show_bug.cgi?id=142417
+        &lt;rdar://problem/20044440&gt;
+
+        Reviewed by Darin Adler.
+
+        Lower the number of different canvas sizes from 1000 to 100 so that
+        the test does not require such a huge cache size. With 100, we now
+        get over 90% cache hit rate with the default IOSurfacePool size.
+
+        * Canvas/reuse.html:
+
</ins><span class="cx"> 2015-01-28  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Poor performance on IE's Chalkboard benchmark.
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/ChangeLog        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2015-03-09  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [CG] Have Canvas use the IOSurfacePool
+        https://bugs.webkit.org/show_bug.cgi?id=142417
+        &lt;rdar://problem/20044440&gt;
+
+        Reviewed by Darin Adler.
+
+        Have ImageBufferDataCG use the IOSurfacePool so that Canvas can
+        benefit from it. I see a ~75% progression on Canvas/reuse.html
+        performance test on my Macbook Pro with 1000 different canvas
+        sizes and ~110% progression with 100 different canvas sizes.
+
+        I also see a ~65% cache hit rate on the mobile version of
+        cnn.com.
+
+        Note that ImageData calls CGContextClearRect() after calling
+        IOSurface::create() so recycling IOSurfaces in this case should
+        be safe.
+
+        Performance test: Canvas/reuse.html
+
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::baseTransform):
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        (WebCore::ImageBuffer::context):
+        (WebCore::ImageBuffer::copyImage):
+        (WebCore::ImageBuffer::copyNativeImage):
+        (WebCore::ImageBuffer::draw):
+        (WebCore::ImageBuffer::clip):
+        (WebCore::ImageBuffer::putByteArray):
+        (WebCore::ImageBuffer::toDataURL):
+        * platform/graphics/cg/ImageBufferDataCG.cpp:
+        (WebCore::ImageBufferData::~ImageBufferData):
+        (WebCore::ImageBufferData::getData):
+        (WebCore::ImageBufferData::putData):
+        (WebCore::ImageBufferData::ImageBufferData): Deleted.
+        * platform/graphics/cg/ImageBufferDataCG.h:
+        * platform/graphics/cocoa/IOSurface.h:
+        * platform/graphics/cocoa/IOSurface.mm:
+        (IOSurface::surfaceFromPool):
+        (IOSurface::create):
+        (IOSurface::createFromSendRight):
+        (IOSurface::createFromImage):
+        (IOSurface::setContextSize):
+
</ins><span class="cx"> 2015-03-09  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Assertion in ScrollController::processWheelEventForScrollSnapOnAxis when scrolling with mechanical wheel mouse
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">     void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace);
</span><span class="cx">     void platformTransformColorSpace(const Vector&lt;int&gt;&amp;);
</span><span class="cx"> #else
</span><del>-    AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.m_backingStoreSize.height()); }
</del><ins>+    AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.backingStoreSize.height()); }
</ins><span class="cx"> #endif
</span><span class="cx">     PlatformLayer* platformLayer() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageBufferCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -81,7 +81,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_size = IntSize(scaledWidth, scaledHeight);
</span><del>-    m_data.m_backingStoreSize = m_size;
</del><ins>+    m_data.backingStoreSize = m_size;
</ins><span class="cx"> 
</span><span class="cx">     success = false;  // Make early return mean failure.
</span><span class="cx">     bool accelerateRendering = renderingMode == Accelerated;
</span><span class="lines">@@ -94,8 +94,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Prevent integer overflows
</span><del>-    m_data.m_bytesPerRow = 4 * Checked&lt;unsigned, RecordOverflow&gt;(m_data.m_backingStoreSize.width());
-    Checked&lt;size_t, RecordOverflow&gt; numBytes = Checked&lt;unsigned, RecordOverflow&gt;(m_data.m_backingStoreSize.height()) * m_data.m_bytesPerRow;
</del><ins>+    m_data.bytesPerRow = 4 * Checked&lt;unsigned, RecordOverflow&gt;(m_data.backingStoreSize.width());
+    Checked&lt;size_t, RecordOverflow&gt; numBytes = Checked&lt;unsigned, RecordOverflow&gt;(m_data.backingStoreSize.height()) * m_data.bytesPerRow;
</ins><span class="cx">     if (numBytes.hasOverflowed())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -107,14 +107,14 @@
</span><span class="cx">     ASSERT(renderingMode == Unaccelerated);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    m_data.m_colorSpace = cachedCGColorSpace(imageColorSpace);
</del><ins>+    m_data.colorSpace = cachedCGColorSpace(imageColorSpace);
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;CGContextRef&gt; cgContext;
</span><span class="cx">     if (accelerateRendering) {
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><del>-        FloatSize userBounds = scaleSizeToUserSpace(FloatSize(width.unsafeGet(), height.unsafeGet()), m_data.m_backingStoreSize, m_size);
-        m_data.m_surface = IOSurface::create(m_data.m_backingStoreSize, IntSize(userBounds), imageColorSpace);
-        cgContext = m_data.m_surface-&gt;ensurePlatformContext();
</del><ins>+        FloatSize userBounds = scaleSizeToUserSpace(FloatSize(width.unsafeGet(), height.unsafeGet()), m_data.backingStoreSize, m_size);
+        m_data.surface = IOSurface::create(m_data.backingStoreSize, IntSize(userBounds), imageColorSpace);
+        cgContext = m_data.surface-&gt;ensurePlatformContext();
</ins><span class="cx">         if (cgContext)
</span><span class="cx">             CGContextClearRect(cgContext.get(), FloatRect(FloatPoint(), userBounds));
</span><span class="cx"> #endif
</span><span class="lines">@@ -124,27 +124,27 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!accelerateRendering) {
</span><del>-        if (!tryFastCalloc(m_data.m_backingStoreSize.height(), m_data.m_bytesPerRow.unsafeGet()).getValue(m_data.m_data))
</del><ins>+        if (!tryFastCalloc(m_data.backingStoreSize.height(), m_data.bytesPerRow.unsafeGet()).getValue(m_data.data))
</ins><span class="cx">             return;
</span><del>-        ASSERT(!(reinterpret_cast&lt;intptr_t&gt;(m_data.m_data) &amp; 3));
</del><ins>+        ASSERT(!(reinterpret_cast&lt;intptr_t&gt;(m_data.data) &amp; 3));
</ins><span class="cx"> 
</span><span class="cx"> #if USE_ARGB32
</span><del>-        m_data.m_bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
</del><ins>+        m_data.bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
</ins><span class="cx"> #else
</span><del>-        m_data.m_bitmapInfo = kCGImageAlphaPremultipliedLast;
</del><ins>+        m_data.bitmapInfo = kCGImageAlphaPremultipliedLast;
</ins><span class="cx"> #endif
</span><del>-        cgContext = adoptCF(CGBitmapContextCreate(m_data.m_data, m_data.m_backingStoreSize.width(), m_data.m_backingStoreSize.height(), 8, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo));
</del><ins>+        cgContext = adoptCF(CGBitmapContextCreate(m_data.data, m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo));
</ins><span class="cx">         // Create a live image that wraps the data.
</span><del>-        m_data.m_dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, numBytes.unsafeGet(), releaseImageData));
</del><ins>+        m_data.dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.data, numBytes.unsafeGet(), releaseImageData));
</ins><span class="cx"> 
</span><span class="cx">         if (!cgContext)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        m_data.m_context = adoptPtr(new GraphicsContext(cgContext.get()));
</del><ins>+        m_data.context = adoptPtr(new GraphicsContext(cgContext.get()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     context()-&gt;scale(FloatSize(1, -1));
</span><del>-    context()-&gt;translate(0, -m_data.m_backingStoreSize.height());
</del><ins>+    context()-&gt;translate(0, -m_data.backingStoreSize.height());
</ins><span class="cx">     context()-&gt;applyDeviceScaleFactor(m_resolutionScale);
</span><span class="cx"> 
</span><span class="cx">     success = true;
</span><span class="lines">@@ -157,10 +157,10 @@
</span><span class="cx"> GraphicsContext* ImageBuffer::context() const
</span><span class="cx"> {
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><del>-    if (m_data.m_surface)
-        return &amp;m_data.m_surface-&gt;ensureGraphicsContext();
</del><ins>+    if (m_data.surface)
+        return &amp;m_data.surface-&gt;ensureGraphicsContext();
</ins><span class="cx"> #endif
</span><del>-    return m_data.m_context.get();
</del><ins>+    return m_data.context.get();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImageBuffer::flushContext() const
</span><span class="lines">@@ -188,7 +188,7 @@
</span><span class="cx">         RetainPtr&lt;CGContextRef&gt; context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
</span><span class="cx">         CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
</span><span class="cx">         CGContextClipToRect(context.get(), FloatRect(FloatPoint::zero(), logicalSize()));
</span><del>-        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
</del><ins>+        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.backingStoreSize, internalSize());
</ins><span class="cx">         CGContextDrawImage(context.get(), FloatRect(FloatPoint::zero(), imageSizeInUserSpace), image.get());
</span><span class="cx">         image = adoptCF(CGBitmapContextCreateImage(context.get()));
</span><span class="cx">     }
</span><span class="lines">@@ -213,7 +213,7 @@
</span><span class="cx">     if (!context()-&gt;isAcceleratedContext()) {
</span><span class="cx">         switch (copyBehavior) {
</span><span class="cx">         case DontCopyBackingStore:
</span><del>-            image = adoptCF(CGImageCreate(m_data.m_backingStoreSize.width(), m_data.m_backingStoreSize.height(), 8, 32, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo, m_data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault));
</del><ins>+            image = adoptCF(CGImageCreate(m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, 32, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo, m_data.dataProvider.get(), 0, true, kCGRenderingIntentDefault));
</ins><span class="cx">             break;
</span><span class="cx">         case CopyBackingStore:
</span><span class="cx">             image = adoptCF(CGBitmapContextCreateImage(context()-&gt;platformContext()));
</span><span class="lines">@@ -225,7 +225,7 @@
</span><span class="cx">     }
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><span class="cx">     else
</span><del>-        image = m_data.m_surface-&gt;createImage();
</del><ins>+        image = m_data.surface-&gt;createImage();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     return image;
</span><span class="lines">@@ -244,7 +244,7 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect adjustedSrcRect = srcRect;
</span><span class="cx">     adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale);
</span><del>-    destContext-&gt;drawNativeImage(image.get(), m_data.m_backingStoreSize, colorSpace, destRect, adjustedSrcRect, op, blendMode);
</del><ins>+    destContext-&gt;drawNativeImage(image.get(), m_data.backingStoreSize, colorSpace, destRect, adjustedSrcRect, op, blendMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect&amp; srcRect, const AffineTransform&amp; patternTransform, const FloatPoint&amp; phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect&amp; destRect, BlendMode blendMode)
</span><span class="lines">@@ -268,7 +268,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect&amp; rect) const
</span><span class="cx"> {
</span><del>-    FloatSize backingStoreSizeInUserSpace = scaleSizeToUserSpace(rect.size(), m_data.m_backingStoreSize, internalSize());
</del><ins>+    FloatSize backingStoreSizeInUserSpace = scaleSizeToUserSpace(rect.size(), m_data.backingStoreSize, internalSize());
</ins><span class="cx"> 
</span><span class="cx">     CGContextRef platformContextToClip = contextToClip-&gt;platformContext();
</span><span class="cx">     // FIXME: This image needs to be grayscale to be used as an alpha mask here.
</span><span class="lines">@@ -342,7 +342,7 @@
</span><span class="cx">     CGContextSetShadowWithColor(destContext, CGSizeZero, 0, 0);
</span><span class="cx"> 
</span><span class="cx">     // Draw the image in CG coordinate space
</span><del>-    FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.m_backingStoreSize, internalSize());
</del><ins>+    FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.backingStoreSize, internalSize());
</ins><span class="cx">     IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), scaledDestSize.height() - (destPoint.y() + sourceRect.y()) - sourceRect.height());
</span><span class="cx">     IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize);
</span><span class="cx">     CGContextClipToRect(destContext, destRectInCGCoords);
</span><span class="lines">@@ -461,7 +461,7 @@
</span><span class="cx">         RetainPtr&lt;CGContextRef&gt; context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), deviceRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
</span><span class="cx">         CGContextSetBlendMode(context.get(), kCGBlendModeCopy);
</span><span class="cx">         CGContextClipToRect(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height()));
</span><del>-        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.m_backingStoreSize, internalSize());
</del><ins>+        FloatSize imageSizeInUserSpace = scaleSizeToUserSpace(logicalSize(), m_data.backingStoreSize, internalSize());
</ins><span class="cx">         CGContextDrawImage(context.get(), CGRectMake(0, 0, imageSizeInUserSpace.width(), imageSizeInUserSpace.height()), image.get());
</span><span class="cx">         image = adoptCF(CGBitmapContextCreateImage(context.get()));
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageBufferDataCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><span class="cx"> #include &quot;IOSurface.h&quot;
</span><ins>+#include &quot;IOSurfacePool.h&quot;
</ins><span class="cx"> #include &quot;IOSurfaceSPI.h&quot;
</span><span class="cx"> #include &lt;dispatch/dispatch.h&gt;
</span><span class="cx"> #endif
</span><span class="lines">@@ -56,12 +57,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-ImageBufferData::ImageBufferData()
-    : m_data(nullptr)
</del><ins>+ImageBufferData::~ImageBufferData()
+{
</ins><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><del>-    , m_surface(nullptr)
</del><ins>+    if (surface)
+        IOSurfacePool::sharedPool().addSurface(WTF::move(surface));
</ins><span class="cx"> #endif
</span><del>-{
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if USE(ACCELERATE)
</span><span class="lines">@@ -117,7 +118,7 @@
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;Uint8ClampedArray&gt; result = Uint8ClampedArray::createUninitialized(area.unsafeGet());
</span><del>-    unsigned char* data = result-&gt;data();
</del><ins>+    unsigned char* resultData = result-&gt;data();
</ins><span class="cx">     
</span><span class="cx">     Checked&lt;int&gt; endx = rect.maxX();
</span><span class="cx">     endx *= ceilf(resolutionScale);
</span><span class="lines">@@ -158,14 +159,14 @@
</span><span class="cx">         return result.release();
</span><span class="cx">     
</span><span class="cx">     unsigned destBytesPerRow = 4 * rect.width();
</span><del>-    unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
</del><ins>+    unsigned char* destRows = resultData + desty * destBytesPerRow + destx * 4;
</ins><span class="cx">     
</span><span class="cx">     unsigned srcBytesPerRow;
</span><span class="cx">     unsigned char* srcRows;
</span><span class="cx">     
</span><span class="cx">     if (!accelerateRendering) {
</span><del>-        srcBytesPerRow = m_bytesPerRow.unsafeGet();
-        srcRows = reinterpret_cast&lt;unsigned char*&gt;(m_data) + originy * srcBytesPerRow + originx * 4;
</del><ins>+        srcBytesPerRow = bytesPerRow.unsafeGet();
+        srcRows = reinterpret_cast&lt;unsigned char*&gt;(data) + originy * srcBytesPerRow + originx * 4;
</ins><span class="cx">         
</span><span class="cx"> #if USE(ACCELERATE)
</span><span class="cx">         if (unmultiplied) {
</span><span class="lines">@@ -205,9 +206,9 @@
</span><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="cx">         if (resolutionScale != 1) {
</span><del>-            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             RetainPtr&lt;CGImageRef&gt; sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
</span><del>-            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
</span><span class="cx">             CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
</span><span class="cx">             if (!unmultiplied)
</span><span class="lines">@@ -272,10 +273,10 @@
</span><span class="cx">     } else {
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><span class="cx">         // FIXME: WebCore::IOSurface should have a locking RAII object and base-address getter.
</span><del>-        IOSurfaceRef surface = m_surface-&gt;surface();
-        IOSurfaceLock(surface, kIOSurfaceLockReadOnly, 0);
-        srcBytesPerRow = IOSurfaceGetBytesPerRow(surface);
-        srcRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + originy * srcBytesPerRow + originx * 4;
</del><ins>+        IOSurfaceRef surfaceRef = surface-&gt;surface();
+        IOSurfaceLock(surfaceRef, kIOSurfaceLockReadOnly, nullptr);
+        srcBytesPerRow = IOSurfaceGetBytesPerRow(surfaceRef);
+        srcRows = static_cast&lt;unsigned char*&gt;(IOSurfaceGetBaseAddress(surfaceRef)) + originy * srcBytesPerRow + originx * 4;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(ACCELERATE)
</span><span class="cx">         vImage_Buffer src;
</span><span class="lines">@@ -320,9 +321,9 @@
</span><span class="cx">         }
</span><span class="cx"> #else
</span><span class="cx">         if (resolutionScale != 1) {
</span><del>-            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             RetainPtr&lt;CGImageRef&gt; sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
</span><del>-            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
</span><span class="cx">             CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
</span><span class="cx"> 
</span><span class="lines">@@ -371,7 +372,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> #endif // USE(ACCELERATE)
</span><del>-        IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, 0);
</del><ins>+        IOSurfaceUnlock(surfaceRef, kIOSurfaceLockReadOnly, nullptr);
</ins><span class="cx"> #else
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx"> #endif // USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><span class="lines">@@ -428,8 +429,8 @@
</span><span class="cx">     unsigned char* destRows;
</span><span class="cx">     
</span><span class="cx">     if (!accelerateRendering) {
</span><del>-        destBytesPerRow = m_bytesPerRow.unsafeGet();
-        destRows = reinterpret_cast&lt;unsigned char*&gt;(m_data) + (desty * destBytesPerRow + destx * 4).unsafeGet();
</del><ins>+        destBytesPerRow = bytesPerRow.unsafeGet();
+        destRows = reinterpret_cast&lt;unsigned char*&gt;(data) + (desty * destBytesPerRow + destx * 4).unsafeGet();
</ins><span class="cx">         
</span><span class="cx"> #if  USE(ACCELERATE)
</span><span class="cx">         if (unmultiplied) {
</span><span class="lines">@@ -470,9 +471,9 @@
</span><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="cx">         if (resolutionScale != 1) {
</span><del>-            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             RetainPtr&lt;CGImageRef&gt; sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
</span><del>-            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
</span><span class="cx">             CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
</span><span class="cx">             if (!unmultiplied)
</span><span class="lines">@@ -516,10 +517,10 @@
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><del>-        IOSurfaceRef surface = m_surface-&gt;surface();
-        IOSurfaceLock(surface, 0, 0);
-        destBytesPerRow = IOSurfaceGetBytesPerRow(surface);
-        destRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + (desty * destBytesPerRow + destx * 4).unsafeGet();
</del><ins>+        IOSurfaceRef surfaceRef = surface-&gt;surface();
+        IOSurfaceLock(surfaceRef, 0, nullptr);
+        destBytesPerRow = IOSurfaceGetBytesPerRow(surfaceRef);
+        destRows = static_cast&lt;unsigned char*&gt;(IOSurfaceGetBaseAddress(surfaceRef)) + (desty * destBytesPerRow + destx * 4).unsafeGet();
</ins><span class="cx"> 
</span><span class="cx"> #if USE(ACCELERATE)
</span><span class="cx">         vImage_Buffer src;
</span><span class="lines">@@ -564,9 +565,9 @@
</span><span class="cx">         }
</span><span class="cx"> #else
</span><span class="cx">         if (resolutionScale != 1) {
</span><del>-            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; sourceContext = adoptCF(CGBitmapContextCreate(srcRows, width.unsafeGet(), height.unsafeGet(), 8, srcBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             RetainPtr&lt;CGImageRef&gt; sourceImage = adoptCF(CGBitmapContextCreateImage(sourceContext.get()));
</span><del>-            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, m_colorSpace, kCGImageAlphaPremultipliedLast));
</del><ins>+            RetainPtr&lt;CGContextRef&gt; destinationContext = adoptCF(CGBitmapContextCreate(destRows, destw.unsafeGet(), desth.unsafeGet(), 8, destBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast));
</ins><span class="cx">             CGContextSetBlendMode(destinationContext.get(), kCGBlendModeCopy);
</span><span class="cx">             CGContextDrawImage(destinationContext.get(), CGRectMake(0, 0, width.unsafeGet() / resolutionScale, height.unsafeGet() / resolutionScale), sourceImage.get()); // FIXME: Add subpixel translation.
</span><span class="cx"> 
</span><span class="lines">@@ -598,7 +599,7 @@
</span><span class="cx">         }
</span><span class="cx"> #endif // USE(ACCELERATE)
</span><span class="cx"> 
</span><del>-        IOSurfaceUnlock(surface, 0, 0);
</del><ins>+        IOSurfaceUnlock(surfaceRef, 0, nullptr);
</ins><span class="cx"> #else
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx"> #endif // USE(IOSURFACE_CANVAS_BACKING_STORE)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageBufferDataCGh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -46,23 +46,22 @@
</span><span class="cx"> class IOSurface;
</span><span class="cx"> class IntSize;
</span><span class="cx"> 
</span><del>-class ImageBufferData {
-public:
-    ImageBufferData();
</del><ins>+struct ImageBufferData {
+    ~ImageBufferData();
</ins><span class="cx"> 
</span><del>-    IntSize m_backingStoreSize;
-    Checked&lt;unsigned, RecordOverflow&gt; m_bytesPerRow;
-    CGColorSpaceRef m_colorSpace;
</del><ins>+    IntSize backingStoreSize;
+    Checked&lt;unsigned, RecordOverflow&gt; bytesPerRow;
+    CGColorSpaceRef colorSpace;
</ins><span class="cx"> 
</span><span class="cx">     // Only for Software ImageBuffers.
</span><del>-    void* m_data;
-    RetainPtr&lt;CGDataProviderRef&gt; m_dataProvider;
-    CGBitmapInfo m_bitmapInfo;
-    OwnPtr&lt;GraphicsContext&gt; m_context;
</del><ins>+    void* data { nullptr };
+    RetainPtr&lt;CGDataProviderRef&gt; dataProvider;
+    CGBitmapInfo bitmapInfo;
+    OwnPtr&lt;GraphicsContext&gt; context;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE)
</span><span class="cx">     // Only for Accelerated ImageBuffers.
</span><del>-    std::unique_ptr&lt;IOSurface&gt; m_surface;
</del><ins>+    std::unique_ptr&lt;IOSurface&gt; surface;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     PassRefPtr&lt;Uint8ClampedArray&gt; getData(const IntRect&amp;, const IntSize&amp;, bool accelerateRendering, bool unmultiplied, float resolutionScale) const;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscocoaIOSurfaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -85,6 +85,10 @@
</span><span class="cx">     IOSurface(IntSize, IntSize contextSize, ColorSpace);
</span><span class="cx">     IOSurface(IOSurfaceRef, ColorSpace);
</span><span class="cx"> 
</span><ins>+    static std::unique_ptr&lt;IOSurface&gt; surfaceFromPool(IntSize, IntSize contextSize, ColorSpace);
+    IntSize contextSize() const { return m_contextSize; }
+    void setContextSize(IntSize);
+
</ins><span class="cx">     ColorSpace m_colorSpace;
</span><span class="cx">     IntSize m_size;
</span><span class="cx">     IntSize m_contextSize;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscocoaIOSurfacemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm (181300 => 181301)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm        2015-03-10 01:00:15 UTC (rev 181300)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm        2015-03-10 01:24:14 UTC (rev 181301)
</span><span class="lines">@@ -41,22 +41,33 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><ins>+inline std::unique_ptr&lt;IOSurface&gt; IOSurface::surfaceFromPool(IntSize size, IntSize contextSize, ColorSpace colorSpace)
+{
+    auto cachedSurface = IOSurfacePool::sharedPool().takeSurface(size, colorSpace);
+    if (!cachedSurface)
+        return nullptr;
+
+    cachedSurface-&gt;setContextSize(contextSize);
+    return cachedSurface;
+}
+
</ins><span class="cx"> std::unique_ptr&lt;IOSurface&gt; IOSurface::create(IntSize size, ColorSpace colorSpace)
</span><span class="cx"> {
</span><del>-    if (std::unique_ptr&lt;IOSurface&gt; cachedSurface = IOSurfacePool::sharedPool().takeSurface(size, colorSpace))
</del><ins>+    if (auto cachedSurface = surfaceFromPool(size, size, colorSpace))
</ins><span class="cx">         return cachedSurface;
</span><span class="cx">     return std::unique_ptr&lt;IOSurface&gt;(new IOSurface(size, colorSpace));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> std::unique_ptr&lt;IOSurface&gt; IOSurface::create(IntSize size, IntSize contextSize, ColorSpace colorSpace)
</span><span class="cx"> {
</span><del>-    // FIXME: We should be able to pull surfaces out of the IOSurfacePool and adjust their contextSize.
</del><ins>+    if (auto cachedSurface = surfaceFromPool(size, contextSize, colorSpace))
+        return cachedSurface;
</ins><span class="cx">     return std::unique_ptr&lt;IOSurface&gt;(new IOSurface(size, contextSize, colorSpace));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> std::unique_ptr&lt;IOSurface&gt; IOSurface::createFromSendRight(const MachSendRight&amp; sendRight, ColorSpace colorSpace)
</span><span class="cx"> {
</span><del>-    RetainPtr&lt;IOSurfaceRef&gt; surface = adoptCF(IOSurfaceLookupFromMachPort(sendRight.sendRight()));
</del><ins>+    auto surface = adoptCF(IOSurfaceLookupFromMachPort(sendRight.sendRight()));
</ins><span class="cx">     return IOSurface::createFromSurface(surface.get(), colorSpace);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -73,7 +84,7 @@
</span><span class="cx">     size_t width = CGImageGetWidth(image);
</span><span class="cx">     size_t height = CGImageGetHeight(image);
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;IOSurface&gt; surface = IOSurface::create(IntSize(width, height), ColorSpaceDeviceRGB);
</del><ins>+    auto surface = IOSurface::create(IntSize(width, height), ColorSpaceDeviceRGB);
</ins><span class="cx">     auto surfaceContext = surface-&gt;ensurePlatformContext();
</span><span class="cx">     CGContextDrawImage(surfaceContext, CGRectMake(0, 0, width, height), image);
</span><span class="cx">     CGContextFlush(surfaceContext);
</span><span class="lines">@@ -143,6 +154,17 @@
</span><span class="cx">     return adoptCF(CGIOSurfaceContextCreateImage(ensurePlatformContext()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IOSurface::setContextSize(IntSize contextSize)
+{
+    if (contextSize == m_contextSize)
+        return;
+
+    // Release the graphics context and update the context size. Next time the graphics context is
+    // accessed, we will construct it again with the right size.
+    releaseGraphicsContext();
+    m_contextSize = contextSize;
+}
+
</ins><span class="cx"> CGContextRef IOSurface::ensurePlatformContext()
</span><span class="cx"> {
</span><span class="cx">     if (m_cgContext)
</span></span></pre>
</div>
</div>

</body>
</html>