<!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>[213935] 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/213935">213935</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2017-03-14 13:45:52 -0700 (Tue, 14 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Adapt CARingBuffer to be usable across processes
https://bugs.webkit.org/show_bug.cgi?id=169591

Reviewed by Alex Christensen.

Source/WebCore:

When used with a SharedMemory backing store, storing the pointers to channel data at the beginning
of the channel data itself is problematic: when the SharedMemory is mapped on the far side of the
process boundary, it will not exist at the same memory location as it did on the near side. Instead
of storing these pointers inside the channel data, store them in a small (usually 1 or 2 entry) vector
recreated when the backing store is (re-)allocated.

* platform/audio/mac/CARingBuffer.cpp:
(WebCore::CARingBuffer::CARingBuffer):
(WebCore::CARingBuffer::allocate):
(WebCore::CARingBuffer::deallocate):
(WebCore::ZeroRange):
(WebCore::StoreABL):
(WebCore::FetchABL):
(WebCore::CARingBuffer::store):
(WebCore::CARingBuffer::getCurrentFrameBounds):
(WebCore::CARingBuffer::fetch):
* platform/audio/mac/CARingBuffer.h:

Source/WebKit2:

Add a new class which wraps a SharedMemory object and uses that shared memory as the
backing store of a CARingBuffer. This backing store can be set to &quot;read only&quot;, which
prevents the backing from being de- or re-allocated.

* WebKit2.xcodeproj/project.pbxproj:
* Shared/Cocoa/SharedRingBufferStorage.cpp: Added.
(WebKit::SharedRingBufferStorage::setStorage):
(WebKit::SharedRingBufferStorage::setReadOnly):
(WebKit::SharedRingBufferStorage::allocate):
(WebKit::SharedRingBufferStorage::deallocate):
(WebKit::SharedRingBufferStorage::data):
* Shared/Cocoa/SharedRingBufferStorage.h: Added.
(WebKit::SharedRingBufferStorage::SharedRingBufferStorage):
(WebKit::SharedRingBufferStorage::invalidate):
(WebKit::SharedRingBufferStorage::storage):
(WebKit::SharedRingBufferStorage::readOnly):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformaudiomacCARingBuffercpp">trunk/Source/WebCore/platform/audio/mac/CARingBuffer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudiomacCARingBufferh">trunk/Source/WebCore/platform/audio/mac/CARingBuffer.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2SharedCocoaSharedRingBufferStoragecpp">trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedCocoaSharedRingBufferStorageh">trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213934 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-14 20:07:16 UTC (rev 213934)
+++ trunk/Source/WebCore/ChangeLog        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -1,5 +1,30 @@
</span><span class="cx"> 2017-03-14  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Adapt CARingBuffer to be usable across processes
+        https://bugs.webkit.org/show_bug.cgi?id=169591
+
+        Reviewed by Alex Christensen.
+
+        When used with a SharedMemory backing store, storing the pointers to channel data at the beginning
+        of the channel data itself is problematic: when the SharedMemory is mapped on the far side of the
+        process boundary, it will not exist at the same memory location as it did on the near side. Instead
+        of storing these pointers inside the channel data, store them in a small (usually 1 or 2 entry) vector
+        recreated when the backing store is (re-)allocated.
+
+        * platform/audio/mac/CARingBuffer.cpp:
+        (WebCore::CARingBuffer::CARingBuffer):
+        (WebCore::CARingBuffer::allocate):
+        (WebCore::CARingBuffer::deallocate):
+        (WebCore::ZeroRange):
+        (WebCore::StoreABL):
+        (WebCore::FetchABL):
+        (WebCore::CARingBuffer::store):
+        (WebCore::CARingBuffer::getCurrentFrameBounds):
+        (WebCore::CARingBuffer::fetch):
+        * platform/audio/mac/CARingBuffer.h:
+
+2017-03-14  Jer Noble  &lt;jer.noble@apple.com&gt;
+
</ins><span class="cx">         Pulling more frames from AudioSampleDataSource than the last push added will always fail.
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=168644
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudiomacCARingBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/mac/CARingBuffer.cpp (213934 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/mac/CARingBuffer.cpp        2017-03-14 20:07:16 UTC (rev 213934)
+++ trunk/Source/WebCore/platform/audio/mac/CARingBuffer.cpp        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -39,37 +39,37 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> CARingBuffer::CARingBuffer()
</span><del>-    : m_timeBoundsQueue(kGeneralRingTimeBoundsQueueSize)
</del><ins>+    : m_buffers(makeUniqueRef&lt;CARingBufferStorageVector&gt;())
+    , m_timeBoundsQueue(kGeneralRingTimeBoundsQueueSize)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CARingBuffer::allocate(const CAAudioStreamDescription&amp; format, size_t frameCount)
</del><ins>+CARingBuffer::CARingBuffer(UniqueRef&lt;CARingBufferStorage&gt;&amp;&amp; storage)
+    : m_buffers(WTFMove(storage))
+    , m_timeBoundsQueue(kGeneralRingTimeBoundsQueueSize)
</ins><span class="cx"> {
</span><del>-    m_description = format;
-    allocate(format.numberOfChannelStreams(), format.bytesPerFrame(), frameCount);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CARingBuffer::allocate(uint32_t channelCount, size_t bytesPerFrame, size_t frameCount)
</del><ins>+void CARingBuffer::allocate(const CAAudioStreamDescription&amp; format, size_t frameCount)
</ins><span class="cx"> {
</span><ins>+    m_description = format;
</ins><span class="cx">     deallocate();
</span><span class="cx"> 
</span><span class="cx">     frameCount = WTF::roundUpToPowerOfTwo(frameCount);
</span><span class="cx"> 
</span><del>-    m_channelCount = channelCount;
-    m_bytesPerFrame = bytesPerFrame;
</del><ins>+    m_channelCount = format.numberOfChannelStreams();
+    m_bytesPerFrame = format.bytesPerFrame();
</ins><span class="cx">     m_frameCount = frameCount;
</span><span class="cx">     m_frameCountMask = frameCount - 1;
</span><del>-    m_capacityBytes = bytesPerFrame * frameCount;
</del><ins>+    m_capacityBytes = m_bytesPerFrame * frameCount;
</ins><span class="cx"> 
</span><del>-    size_t pointersSize = channelCount * sizeof(Byte*);
-    size_t allocSize = pointersSize + (m_capacityBytes * channelCount);
-    m_buffers = ArrayBuffer::create(allocSize, 1);
</del><ins>+    m_buffers-&gt;allocate(m_capacityBytes * m_channelCount);
</ins><span class="cx"> 
</span><del>-    Byte** pointers = static_cast&lt;Byte**&gt;(m_buffers-&gt;data());
-    Byte* channelData = static_cast&lt;Byte*&gt;(m_buffers-&gt;data()) + pointersSize;
</del><ins>+    m_pointers.resize(m_channelCount);
+    Byte* channelData = static_cast&lt;Byte*&gt;(m_buffers-&gt;data());
</ins><span class="cx"> 
</span><del>-    for (unsigned i = 0; i &lt; channelCount; ++i) {
-        pointers[i] = channelData;
</del><ins>+    for (auto&amp; pointer : m_pointers) {
+        pointer = channelData;
</ins><span class="cx">         channelData += m_capacityBytes;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -78,51 +78,47 @@
</span><span class="cx"> 
</span><span class="cx"> void CARingBuffer::deallocate()
</span><span class="cx"> {
</span><del>-    if (m_buffers)
-        m_buffers = nullptr;
-
</del><ins>+    m_buffers-&gt;deallocate();
+    m_pointers.clear();
</ins><span class="cx">     m_channelCount = 0;
</span><span class="cx">     m_capacityBytes = 0;
</span><span class="cx">     m_frameCount = 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void ZeroRange(Byte** buffers, int channelCount, size_t offset, size_t nbytes)
</del><ins>+static void ZeroRange(Vector&lt;Byte*&gt;&amp; pointers, size_t offset, size_t nbytes)
</ins><span class="cx"> {
</span><del>-    while (--channelCount &gt;= 0) {
-        memset(*buffers + offset, 0, nbytes);
-        ++buffers;
-    }
</del><ins>+    for (auto&amp; pointer : pointers)
+        memset(pointer + offset, 0, nbytes);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void StoreABL(Byte** buffers, size_t destOffset, const AudioBufferList* list, size_t srcOffset, size_t nbytes)
</del><ins>+static void StoreABL(Vector&lt;Byte*&gt;&amp; pointers, size_t destOffset, const AudioBufferList* list, size_t srcOffset, size_t nbytes)
</ins><span class="cx"> {
</span><del>-    int channelCount = list-&gt;mNumberBuffers;
</del><ins>+    ASSERT(list-&gt;mNumberBuffers == pointers.size());
</ins><span class="cx">     const AudioBuffer* src = list-&gt;mBuffers;
</span><del>-    while (--channelCount &gt;= 0) {
</del><ins>+    for (auto&amp; pointer : pointers) {
</ins><span class="cx">         if (srcOffset &gt; src-&gt;mDataByteSize)
</span><span class="cx">             continue;
</span><del>-        memcpy(*buffers + destOffset, static_cast&lt;Byte*&gt;(src-&gt;mData) + srcOffset, std::min&lt;size_t&gt;(nbytes, src-&gt;mDataByteSize - srcOffset));
-        ++buffers;
</del><ins>+        memcpy(pointer + destOffset, static_cast&lt;Byte*&gt;(src-&gt;mData) + srcOffset, std::min&lt;size_t&gt;(nbytes, src-&gt;mDataByteSize - srcOffset));
</ins><span class="cx">         ++src;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void FetchABL(AudioBufferList* list, size_t destOffset, Byte** buffers, size_t srcOffset, size_t nbytes, AudioStreamDescription::PCMFormat format, CARingBuffer::FetchMode mode)
</del><ins>+static void FetchABL(AudioBufferList* list, size_t destOffset, Vector&lt;Byte*&gt;&amp; pointers, size_t srcOffset, size_t nbytes, AudioStreamDescription::PCMFormat format, CARingBuffer::FetchMode mode)
</ins><span class="cx"> {
</span><del>-    int channelCount = list-&gt;mNumberBuffers;
</del><ins>+    ASSERT(list-&gt;mNumberBuffers == pointers.size());
</ins><span class="cx">     AudioBuffer* dest = list-&gt;mBuffers;
</span><del>-    while (--channelCount &gt;= 0) {
</del><ins>+    for (auto&amp; pointer : pointers) {
</ins><span class="cx">         if (destOffset &gt; dest-&gt;mDataByteSize)
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         nbytes = std::min&lt;size_t&gt;(nbytes, dest-&gt;mDataByteSize - destOffset);
</span><span class="cx">         if (mode == CARingBuffer::Copy)
</span><del>-            memcpy(static_cast&lt;Byte*&gt;(dest-&gt;mData) + destOffset, *buffers + srcOffset, nbytes);
</del><ins>+            memcpy(static_cast&lt;Byte*&gt;(dest-&gt;mData) + destOffset, pointer + srcOffset, nbytes);
</ins><span class="cx">         else {
</span><span class="cx">             switch (format) {
</span><span class="cx">             case AudioStreamDescription::Int16: {
</span><span class="cx">                 int16_t* destination = static_cast&lt;int16_t*&gt;(dest-&gt;mData);
</span><del>-                int16_t* source = reinterpret_cast&lt;int16_t*&gt;(*buffers + srcOffset);
</del><ins>+                int16_t* source = reinterpret_cast&lt;int16_t*&gt;(pointer + srcOffset);
</ins><span class="cx">                 for (size_t i = 0; i &lt; nbytes / sizeof(int16_t); i++)
</span><span class="cx">                     destination[i] += source[i];
</span><span class="cx">                 break;
</span><span class="lines">@@ -129,17 +125,17 @@
</span><span class="cx">             }
</span><span class="cx">             case AudioStreamDescription::Int32: {
</span><span class="cx">                 int32_t* destination = static_cast&lt;int32_t*&gt;(dest-&gt;mData);
</span><del>-                vDSP_vaddi(destination, 1, reinterpret_cast&lt;int32_t*&gt;(*buffers + srcOffset), 1, destination, 1, nbytes / sizeof(int32_t));
</del><ins>+                vDSP_vaddi(destination, 1, reinterpret_cast&lt;int32_t*&gt;(pointer + srcOffset), 1, destination, 1, nbytes / sizeof(int32_t));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case AudioStreamDescription::Float32: {
</span><span class="cx">                 float* destination = static_cast&lt;float*&gt;(dest-&gt;mData);
</span><del>-                vDSP_vadd(destination, 1, reinterpret_cast&lt;float*&gt;(*buffers + srcOffset), 1, destination, 1, nbytes / sizeof(float));
</del><ins>+                vDSP_vadd(destination, 1, reinterpret_cast&lt;float*&gt;(pointer + srcOffset), 1, destination, 1, nbytes / sizeof(float));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case AudioStreamDescription::Float64: {
</span><span class="cx">                 double* destination = static_cast&lt;double*&gt;(dest-&gt;mData);
</span><del>-                vDSP_vaddD(destination, 1, reinterpret_cast&lt;double*&gt;(*buffers + srcOffset), 1, destination, 1, nbytes / sizeof(double));
</del><ins>+                vDSP_vaddD(destination, 1, reinterpret_cast&lt;double*&gt;(pointer + srcOffset), 1, destination, 1, nbytes / sizeof(double));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case AudioStreamDescription::None:
</span><span class="lines">@@ -147,7 +143,6 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">         }
</span><del>-        ++buffers;
</del><span class="cx">         ++dest;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -200,7 +195,6 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Write the new frames.
</span><del>-    Byte** buffers = static_cast&lt;Byte**&gt;(m_buffers-&gt;data());
</del><span class="cx">     size_t offset0;
</span><span class="cx">     size_t offset1;
</span><span class="cx">     uint64_t curEnd = currentEndFrame();
</span><span class="lines">@@ -210,10 +204,10 @@
</span><span class="cx">         offset0 = frameOffset(curEnd);
</span><span class="cx">         offset1 = frameOffset(startFrame);
</span><span class="cx">         if (offset0 &lt; offset1)
</span><del>-            ZeroRange(buffers, m_channelCount, offset0, offset1 - offset0);
</del><ins>+            ZeroRange(m_pointers, offset0, offset1 - offset0);
</ins><span class="cx">         else {
</span><del>-            ZeroRange(buffers, m_channelCount, offset0, m_capacityBytes - offset0);
-            ZeroRange(buffers, m_channelCount, 0, offset1);
</del><ins>+            ZeroRange(m_pointers, offset0, m_capacityBytes - offset0);
+            ZeroRange(m_pointers, 0, offset1);
</ins><span class="cx">         }
</span><span class="cx">         offset0 = offset1;
</span><span class="cx">     } else
</span><span class="lines">@@ -221,11 +215,11 @@
</span><span class="cx"> 
</span><span class="cx">     offset1 = frameOffset(endFrame);
</span><span class="cx">     if (offset0 &lt; offset1)
</span><del>-        StoreABL(buffers, offset0, list, 0, offset1 - offset0);
</del><ins>+        StoreABL(m_pointers, offset0, list, 0, offset1 - offset0);
</ins><span class="cx">     else {
</span><span class="cx">         size_t nbytes = m_capacityBytes - offset0;
</span><del>-        StoreABL(buffers, offset0, list, 0, nbytes);
-        StoreABL(buffers, 0, list, nbytes, offset1);
</del><ins>+        StoreABL(m_pointers, offset0, list, 0, nbytes);
+        StoreABL(m_pointers, 0, list, nbytes, offset1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Now update the end time.
</span><span class="lines">@@ -248,7 +242,6 @@
</span><span class="cx"> 
</span><span class="cx"> void CARingBuffer::getCurrentFrameBounds(uint64_t &amp;startTime, uint64_t &amp;endTime)
</span><span class="cx"> {
</span><del>-    LockHolder locker(m_currentFrameBoundsLock);
</del><span class="cx">     uint32_t curPtr = m_timeBoundsQueuePtr.load();
</span><span class="cx">     uint32_t index = curPtr &amp; kGeneralRingTimeBoundsQueueMask;
</span><span class="cx">     CARingBuffer::TimeBounds&amp; bounds = m_timeBoundsQueue[index];
</span><span class="lines">@@ -316,7 +309,6 @@
</span><span class="cx">     if (destEndSize &gt; 0)
</span><span class="cx">         ZeroABL(list, destStartByteOffset + byteSize, destEndSize * m_bytesPerFrame);
</span><span class="cx"> 
</span><del>-    Byte **buffers = static_cast&lt;Byte**&gt;(m_buffers-&gt;data());
</del><span class="cx">     size_t offset0 = frameOffset(startRead);
</span><span class="cx">     size_t offset1 = frameOffset(endRead);
</span><span class="cx">     size_t nbytes;
</span><span class="lines">@@ -323,12 +315,12 @@
</span><span class="cx">     
</span><span class="cx">     if (offset0 &lt; offset1) {
</span><span class="cx">         nbytes = offset1 - offset0;
</span><del>-        FetchABL(list, destStartByteOffset, buffers, offset0, nbytes, m_description.format(), mode);
</del><ins>+        FetchABL(list, destStartByteOffset, m_pointers, offset0, nbytes, m_description.format(), mode);
</ins><span class="cx">     } else {
</span><span class="cx">         nbytes = m_capacityBytes - offset0;
</span><del>-        FetchABL(list, destStartByteOffset, buffers, offset0, nbytes, m_description.format(), mode);
</del><ins>+        FetchABL(list, destStartByteOffset, m_pointers, offset0, nbytes, m_description.format(), mode);
</ins><span class="cx">         if (offset1)
</span><del>-            FetchABL(list, destStartByteOffset + nbytes, buffers, 0, offset1, m_description.format(), mode);
</del><ins>+            FetchABL(list, destStartByteOffset + nbytes, m_pointers, 0, offset1, m_description.format(), mode);
</ins><span class="cx">         nbytes += offset1;
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudiomacCARingBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/mac/CARingBuffer.h (213934 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/mac/CARingBuffer.h        2017-03-14 20:07:16 UTC (rev 213934)
+++ trunk/Source/WebCore/platform/audio/mac/CARingBuffer.h        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;CAAudioStreamDescription.h&quot;
</span><span class="cx"> #include &lt;runtime/ArrayBuffer.h&gt;
</span><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><ins>+#include &lt;wtf/UniqueRef.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> typedef struct AudioBufferList AudioBufferList;
</span><span class="lines">@@ -37,9 +38,29 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class CARingBufferStorage {
+public:
+    virtual ~CARingBufferStorage() = default;
+    virtual void allocate(size_t) = 0;
+    virtual void deallocate() = 0;
+    virtual void* data() = 0;
+};
+
+class CARingBufferStorageVector : public CARingBufferStorage {
+public:
+    ~CARingBufferStorageVector() = default;
+
+private:
+    void allocate(size_t byteCount) final { m_buffer.grow(byteCount); }
+    void deallocate() final { m_buffer.clear(); }
+    void* data() final { return m_buffer.data(); }
+    Vector&lt;uint8_t&gt; m_buffer;
+};
+
</ins><span class="cx"> class CARingBuffer {
</span><span class="cx"> public:
</span><span class="cx">     WEBCORE_EXPORT CARingBuffer();
</span><ins>+    WEBCORE_EXPORT CARingBuffer(UniqueRef&lt;CARingBufferStorage&gt;&amp;&amp;);
</ins><span class="cx">     WEBCORE_EXPORT ~CARingBuffer()
</span><span class="cx">     {
</span><span class="cx">         deallocate();
</span><span class="lines">@@ -61,11 +82,11 @@
</span><span class="cx">     WEBCORE_EXPORT void flush();
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void getCurrentFrameBounds(uint64_t &amp;startTime, uint64_t &amp;endTime);
</span><ins>+    WEBCORE_EXPORT void setCurrentFrameBounds(uint64_t startFrame, uint64_t endFrame);
</ins><span class="cx"> 
</span><span class="cx">     uint32_t channelCount() const { return m_channelCount; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void allocate(uint32_t m_channelCount, size_t bytesPerFrame, size_t frameCount);
</del><span class="cx">     size_t frameOffset(uint64_t frameNumber) { return (frameNumber &amp; m_frameCountMask) * m_bytesPerFrame; }
</span><span class="cx"> 
</span><span class="cx">     void clipTimeBounds(uint64_t&amp; startRead, uint64_t&amp; endRead);
</span><span class="lines">@@ -72,9 +93,9 @@
</span><span class="cx"> 
</span><span class="cx">     uint64_t currentStartFrame() const;
</span><span class="cx">     uint64_t currentEndFrame() const;
</span><del>-    void setCurrentFrameBounds(uint64_t startFrame, uint64_t endFrame);
</del><span class="cx"> 
</span><del>-    RefPtr&lt;ArrayBuffer&gt; m_buffers;
</del><ins>+    UniqueRef&lt;CARingBufferStorage&gt; m_buffers;
+    Vector&lt;Byte*&gt; m_pointers;
</ins><span class="cx">     uint32_t m_channelCount { 0 };
</span><span class="cx">     size_t m_bytesPerFrame { 0 };
</span><span class="cx">     uint32_t m_frameCount { 0 };
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (213934 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2017-03-14 20:07:16 UTC (rev 213934)
+++ trunk/Source/WebKit2/ChangeLog        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2017-03-14  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        Adapt CARingBuffer to be usable across processes
+        https://bugs.webkit.org/show_bug.cgi?id=169591
+
+        Reviewed by Alex Christensen.
+
+        Add a new class which wraps a SharedMemory object and uses that shared memory as the
+        backing store of a CARingBuffer. This backing store can be set to &quot;read only&quot;, which
+        prevents the backing from being de- or re-allocated.
+
+        * WebKit2.xcodeproj/project.pbxproj:
+        * Shared/Cocoa/SharedRingBufferStorage.cpp: Added.
+        (WebKit::SharedRingBufferStorage::setStorage):
+        (WebKit::SharedRingBufferStorage::setReadOnly):
+        (WebKit::SharedRingBufferStorage::allocate):
+        (WebKit::SharedRingBufferStorage::deallocate):
+        (WebKit::SharedRingBufferStorage::data):
+        * Shared/Cocoa/SharedRingBufferStorage.h: Added.
+        (WebKit::SharedRingBufferStorage::SharedRingBufferStorage):
+        (WebKit::SharedRingBufferStorage::invalidate):
+        (WebKit::SharedRingBufferStorage::storage):
+        (WebKit::SharedRingBufferStorage::readOnly):
+
</ins><span class="cx"> 2017-03-14  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] The web process should inherit application state from UI process
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCocoaSharedRingBufferStoragecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.cpp (0 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.cpp                                (rev 0)
+++ trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.cpp        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;SharedRingBufferStorage.h&quot;
+
+#if USE(MEDIATOOLBOX)
+
+namespace WebKit {
+
+void SharedRingBufferStorage::setStorage(RefPtr&lt;SharedMemory&gt;&amp;&amp; storage)
+{
+    ASSERT(storage || !m_readOnly);
+    m_storage = WTFMove(storage);
+    if (m_client)
+        m_client-&gt;storageChanged(m_storage.get());
+}
+
+void SharedRingBufferStorage::setReadOnly(bool readOnly)
+{
+    ASSERT(m_storage || !readOnly);
+    m_readOnly = readOnly;
+}
+
+void SharedRingBufferStorage::allocate(size_t byteCount)
+{
+    if (!m_readOnly)
+        setStorage(SharedMemory::allocate(byteCount));
+}
+
+void SharedRingBufferStorage::deallocate()
+{
+    if (!m_readOnly)
+        setStorage(nullptr);
+}
+
+void* SharedRingBufferStorage::data()
+{
+    return m_storage ? m_storage-&gt;data() : nullptr;
+}
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebKit2SharedCocoaSharedRingBufferStorageh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.h (0 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.h                                (rev 0)
+++ trunk/Source/WebKit2/Shared/Cocoa/SharedRingBufferStorage.h        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#if USE(MEDIATOOLBOX)
+
+#include &quot;SharedMemory.h&quot;
+#include &lt;WebCore/CARingBuffer.h&gt;
+
+namespace WebKit {
+
+class SharedRingBufferStorage : public WebCore::CARingBufferStorage {
+public:
+    class Client {
+    public:
+        virtual ~Client() = default;
+        virtual void storageChanged(SharedMemory*) = 0;
+    };
+
+    SharedRingBufferStorage(Client* client)
+        : m_client(client)
+    {
+    }
+
+    void invalidate() { m_client = nullptr; }
+
+    RefPtr&lt;SharedMemory&gt; storage() const { return m_storage; }
+    void setStorage(RefPtr&lt;SharedMemory&gt;&amp;&amp;);
+
+    bool readOnly() const { return m_readOnly; }
+    void setReadOnly(bool);
+
+    // WebCore::CARingBufferStorage
+    void allocate(size_t) final;
+    void deallocate() final;
+    void* data() final;
+
+private:
+    Client* m_client;
+    RefPtr&lt;SharedMemory&gt; m_storage;
+    bool m_readOnly { false };
+};
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (213934 => 213935)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2017-03-14 20:07:16 UTC (rev 213934)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2017-03-14 20:45:52 UTC (rev 213935)
</span><span class="lines">@@ -1879,6 +1879,8 @@
</span><span class="cx">                 CD003A5319D49B5D005ABCE0 /* WebMediaKeyStorageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CD003A5119D49B5D005ABCE0 /* WebMediaKeyStorageManager.h */; };
</span><span class="cx">                 CD19A26D1A13E82A008D650E /* WebDiagnosticLoggingClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD19A2691A13E820008D650E /* WebDiagnosticLoggingClient.cpp */; };
</span><span class="cx">                 CD19A26E1A13E834008D650E /* WebDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19A26A1A13E821008D650E /* WebDiagnosticLoggingClient.h */; };
</span><ins>+                CD4B4D9C1E765E0000D27092 /* SharedRingBufferStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD4B4D9A1E765E0000D27092 /* SharedRingBufferStorage.cpp */; };
+                CD4B4D9D1E765E0000D27092 /* SharedRingBufferStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = CD4B4D9B1E765E0000D27092 /* SharedRingBufferStorage.h */; };
</ins><span class="cx">                 CD5C66A0134B9D38004FE2A8 /* InjectedBundlePageFullScreenClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5C669E134B9D36004FE2A8 /* InjectedBundlePageFullScreenClient.cpp */; };
</span><span class="cx">                 CD5C66A1134B9D38004FE2A8 /* InjectedBundlePageFullScreenClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5C669F134B9D37004FE2A8 /* InjectedBundlePageFullScreenClient.h */; };
</span><span class="cx">                 CD6F75F4131B66D000D6B21E /* WebFullScreenManagerProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD73BA3E131A2E8A00EEDED2 /* WebFullScreenManagerProxy.cpp */; };
</span><span class="lines">@@ -4166,6 +4168,8 @@
</span><span class="cx">                 CD003A5119D49B5D005ABCE0 /* WebMediaKeyStorageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMediaKeyStorageManager.h; path = MediaCache/WebMediaKeyStorageManager.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD19A2691A13E820008D650E /* WebDiagnosticLoggingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebDiagnosticLoggingClient.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD19A26A1A13E821008D650E /* WebDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDiagnosticLoggingClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CD4B4D9A1E765E0000D27092 /* SharedRingBufferStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedRingBufferStorage.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                CD4B4D9B1E765E0000D27092 /* SharedRingBufferStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedRingBufferStorage.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CD5C669E134B9D36004FE2A8 /* InjectedBundlePageFullScreenClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageFullScreenClient.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD5C669F134B9D37004FE2A8 /* InjectedBundlePageFullScreenClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundlePageFullScreenClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD73BA37131A29FE00EEDED2 /* WebFullScreenManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebFullScreenManager.cpp; path = FullScreen/WebFullScreenManager.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5673,6 +5677,8 @@
</span><span class="cx">                                 37BF2F051947DEB400723C48 /* WKNSURLRequest.mm */,
</span><span class="cx">                                 378E1A3F181EDA010031007A /* WKObject.h */,
</span><span class="cx">                                 374436871820E7240049579F /* WKObject.mm */,
</span><ins>+                                CD4B4D9A1E765E0000D27092 /* SharedRingBufferStorage.cpp */,
+                                CD4B4D9B1E765E0000D27092 /* SharedRingBufferStorage.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         name = cocoa;
</span><span class="cx">                         path = Cocoa;
</span><span class="lines">@@ -8370,6 +8376,7 @@
</span><span class="cx">                                 2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */,
</span><span class="cx">                                 51D124351E6DF652002B2820 /* WKURLSchemeHandlerTask.h in Headers */,
</span><span class="cx">                                 2DDF731518E95060004F5A66 /* RemoteLayerBackingStoreCollection.h in Headers */,
</span><ins>+                                CD4B4D9D1E765E0000D27092 /* SharedRingBufferStorage.h in Headers */,
</ins><span class="cx">                                 1AB16AEA164B3A8800290D62 /* RemoteLayerTreeContext.h in Headers */,
</span><span class="cx">                                 2D29ECD0192F2C2E00984B78 /* RemoteLayerTreeDisplayRefreshMonitor.h in Headers */,
</span><span class="cx">                                 1AB16ADE1648598400290D62 /* RemoteLayerTreeDrawingArea.h in Headers */,
</span><span class="lines">@@ -10379,6 +10386,7 @@
</span><span class="cx">                                 37183D56182F4E700080C811 /* WKNSURLExtras.mm in Sources */,
</span><span class="cx">                                 37BF2F071947DEB400723C48 /* WKNSURLRequest.mm in Sources */,
</span><span class="cx">                                 BC407601124FF0270068F20A /* WKNumber.cpp in Sources */,
</span><ins>+                                CD4B4D9C1E765E0000D27092 /* SharedRingBufferStorage.cpp in Sources */,
</ins><span class="cx">                                 7CD5EBB81746A15B000C1C45 /* WKObjCTypeWrapperRef.mm in Sources */,
</span><span class="cx">                                 374436881820E7240049579F /* WKObject.mm in Sources */,
</span><span class="cx">                                 1ACC50F11CBC381D003C7D03 /* WKOpenPanelParameters.mm in Sources */,
</span></span></pre>
</div>
</div>

</body>
</html>