Title: [290968] trunk
Revision
290968
Author
[email protected]
Date
2022-03-07 17:39:15 -0800 (Mon, 07 Mar 2022)

Log Message

Add ability to convert FragmentedSharedBuffer to CMBlockBuffer
https://bugs.webkit.org/show_bug.cgi?id=237075
Source/WebCore:

rdar://89338447

Reviewed by Jer Noble.

Add FragmentedSharedBuffer::getContiguousData and
FragmentedSharedBuffer::createCMBlockBuffer methods.

API tests added for getContiguousData.
createCMBlockBuffer will be used in a follow-up patch.

* platform/SharedBuffer.cpp:
(WebCore::FragmentedSharedBuffer::getContiguousData const):
* platform/SharedBuffer.h:
* platform/cocoa/SharedBufferCocoa.mm:
(WebCore::FreeSharedBuffer):
(WebCore::FragmentedSharedBuffer::createCMBlockBuffer const):

Tools:

Reviewed by Jer Noble.

* TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp:
(TestWebKitAPI::TEST_F):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (290967 => 290968)


--- trunk/Source/WebCore/ChangeLog	2022-03-08 01:28:40 UTC (rev 290967)
+++ trunk/Source/WebCore/ChangeLog	2022-03-08 01:39:15 UTC (rev 290968)
@@ -1,3 +1,24 @@
+2022-03-07  Jean-Yves Avenard  <[email protected]>
+
+        Add ability to convert FragmentedSharedBuffer to CMBlockBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=237075
+        rdar://89338447
+
+        Reviewed by Jer Noble.
+
+        Add FragmentedSharedBuffer::getContiguousData and
+        FragmentedSharedBuffer::createCMBlockBuffer methods.
+
+        API tests added for getContiguousData.
+        createCMBlockBuffer will be used in a follow-up patch.
+
+        * platform/SharedBuffer.cpp:
+        (WebCore::FragmentedSharedBuffer::getContiguousData const):
+        * platform/SharedBuffer.h:
+        * platform/cocoa/SharedBufferCocoa.mm:
+        (WebCore::FreeSharedBuffer):
+        (WebCore::FragmentedSharedBuffer::createCMBlockBuffer const):
+
 2022-03-07  Andres Gonzalez  <[email protected]>
 
         Fix for <select> elements in isolated tree mode.

Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (290967 => 290968)


--- trunk/Source/WebCore/platform/SharedBuffer.cpp	2022-03-08 01:28:40 UTC (rev 290967)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp	2022-03-08 01:39:15 UTC (rev 290968)
@@ -152,6 +152,26 @@
     return { element->segment.copyRef(), position - element->beginPosition };
 }
 
+Ref<SharedBuffer> FragmentedSharedBuffer::getContiguousData(size_t position, size_t length) const
+{
+    if (position >= m_size)
+        return SharedBuffer::create();
+    length = std::min(m_size - position, length);
+    const DataSegmentVectorEntry* element = getSegmentForPosition(position);
+    size_t offsetInSegment = position - element->beginPosition;
+    ASSERT(element->segment->size() > offsetInSegment);
+    if (element->segment->size() - offsetInSegment >= length)
+        return SharedBufferDataView { element->segment.copyRef(), offsetInSegment, length }.createSharedBuffer();
+    Vector<uint8_t> combinedData;
+    combinedData.reserveInitialCapacity(length);
+    combinedData.append(element->segment->data() + offsetInSegment, element->segment->size() - offsetInSegment);
+    for (++element; combinedData.size() < length && element != m_segments.end(); element++) {
+        auto canCopy = std::min(length - combinedData.size(), element->segment->size());
+        combinedData.append(element->segment->data(), canCopy);
+    }
+    return SharedBuffer::create(WTFMove(combinedData));
+}
+
 const FragmentedSharedBuffer::DataSegmentVectorEntry* FragmentedSharedBuffer::getSegmentForPosition(size_t position) const
 {
     RELEASE_ASSERT(position < m_size);

Modified: trunk/Source/WebCore/platform/SharedBuffer.h (290967 => 290968)


--- trunk/Source/WebCore/platform/SharedBuffer.h	2022-03-08 01:28:40 UTC (rev 290967)
+++ trunk/Source/WebCore/platform/SharedBuffer.h	2022-03-08 01:39:15 UTC (rev 290968)
@@ -54,6 +54,7 @@
 #if USE(FOUNDATION)
 OBJC_CLASS NSArray;
 OBJC_CLASS NSData;
+typedef struct OpaqueCMBlockBuffer* CMBlockBufferRef;
 #endif
 
 namespace WTF {
@@ -149,6 +150,7 @@
 #if USE(FOUNDATION)
     WEBCORE_EXPORT RetainPtr<NSArray> createNSDataArray() const;
     WEBCORE_EXPORT static Ref<FragmentedSharedBuffer> create(NSData*);
+    WEBCORE_EXPORT RetainPtr<CMBlockBufferRef> createCMBlockBuffer() const;
 #endif
 #if USE(CF)
     WEBCORE_EXPORT static Ref<FragmentedSharedBuffer> create(CFDataRef);
@@ -194,6 +196,7 @@
 
     // begin and end take O(1) time, this takes O(log(N)) time.
     WEBCORE_EXPORT SharedBufferDataView getSomeData(size_t position) const;
+    WEBCORE_EXPORT Ref<SharedBuffer> getContiguousData(size_t position, size_t length) const;
 
     WEBCORE_EXPORT String toHexString() const;
 
@@ -246,7 +249,7 @@
 
     // Combines all the segments into a Vector and returns that vector after clearing the FragmentedSharedBuffer.
     WEBCORE_EXPORT Vector<uint8_t> takeData();
-    const DataSegmentVectorEntry* getSegmentForPosition(size_t positition) const;
+    const DataSegmentVectorEntry* getSegmentForPosition(size_t position) const;
 
 #if ASSERT_ENABLED
     bool internallyConsistent() const;

Modified: trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm (290967 => 290968)


--- trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm	2022-03-08 01:28:40 UTC (rev 290967)
+++ trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm	2022-03-08 01:39:15 UTC (rev 290968)
@@ -29,6 +29,7 @@
 #import "WebCoreJITOperations.h"
 #import "WebCoreObjCExtras.h"
 #import <_javascript_Core/InitializeThreading.h>
+#import <pal/cf/CoreMediaSoftLink.h>
 #import <string.h>
 #import <wtf/MainThread.h>
 #import <wtf/cocoa/TypeCastsCocoa.h>
@@ -99,6 +100,55 @@
     return append(bridge_cast(data));
 }
 
+static void FreeDataSegment(void* refcon, void*, size_t)
+{
+    auto* buffer = reinterpret_cast<const DataSegment*>(refcon);
+    buffer->deref();
+}
+
+RetainPtr<CMBlockBufferRef> FragmentedSharedBuffer::createCMBlockBuffer() const
+{
+    auto segmentToCMBlockBuffer = [] (const DataSegment& segment) -> RetainPtr<CMBlockBufferRef> {
+        // From CMBlockBufferCustomBlockSource documentation:
+        // Note that for 64-bit architectures, this struct contains misaligned function pointers.
+        // To avoid link-time issues, it is recommended that clients fill CMBlockBufferCustomBlockSource's function pointer fields
+        // by using assignment statements, rather than declaring them as global or static structs.
+        CMBlockBufferCustomBlockSource allocator;
+        allocator.version = 0;
+        allocator.AllocateBlock = nullptr;
+        allocator.FreeBlock = FreeDataSegment;
+        allocator.refCon = const_cast<DataSegment*>(&segment);
+        segment.ref();
+        CMBlockBufferRef partialBuffer = nullptr;
+        if (PAL::CMBlockBufferCreateWithMemoryBlock(nullptr, static_cast<void*>(const_cast<uint8_t*>(segment.data())), segment.size(), nullptr, &allocator, 0, segment.size(), 0, &partialBuffer) != kCMBlockBufferNoErr)
+            return nullptr;
+        return adoptCF(partialBuffer);
+    };
+
+    if (hasOneSegment() && !isEmpty())
+        return segmentToCMBlockBuffer(m_segments[0].segment);
+
+    CMBlockBufferRef rawBlockBuffer = nullptr;
+    auto err = PAL::CMBlockBufferCreateEmpty(kCFAllocatorDefault, isEmpty() ? 0 : m_segments.size(), 0, &rawBlockBuffer);
+    if (err != kCMBlockBufferNoErr || !rawBlockBuffer)
+        return nullptr;
+    auto blockBuffer = adoptCF(rawBlockBuffer);
+
+    if (isEmpty())
+        return blockBuffer;
+
+    for (auto& segment : m_segments) {
+        if (!segment.segment->size())
+            continue;
+        auto partialBuffer = segmentToCMBlockBuffer(segment.segment);
+        if (!partialBuffer)
+            return nullptr;
+        if (PAL::CMBlockBufferAppendBufferReference(rawBlockBuffer, partialBuffer.get(), 0, 0, 0) != kCMBlockBufferNoErr)
+            return nullptr;
+    }
+    return blockBuffer;
+}
+
 RetainPtr<NSData> SharedBuffer::createNSData() const
 {
     return bridge_cast(createCFData());

Modified: trunk/Tools/ChangeLog (290967 => 290968)


--- trunk/Tools/ChangeLog	2022-03-08 01:28:40 UTC (rev 290967)
+++ trunk/Tools/ChangeLog	2022-03-08 01:39:15 UTC (rev 290968)
@@ -1,5 +1,15 @@
 2022-03-07  Jean-Yves Avenard  <[email protected]>
 
+        Add ability to convert FragmentedSharedBuffer to CMBlockBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=237075
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp:
+        (TestWebKitAPI::TEST_F):
+
+2022-03-07  Jean-Yves Avenard  <[email protected]>
+
         MediaTime::invalidTime() conversion to CMTime incorrectly creates a valid time.
         https://bugs.webkit.org/show_bug.cgi?id=237473
         rdar://problem/89814921

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp (290967 => 290968)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp	2022-03-08 01:28:40 UTC (rev 290967)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp	2022-03-08 01:39:15 UTC (rev 290968)
@@ -239,6 +239,41 @@
     checkBuffer(l.data(), l.size(), "l");
 }
 
+TEST_F(FragmentedSharedBufferTest, getContiguousData)
+{
+    Vector<uint8_t> s1 = { 'a', 'b', 'c', 'd' };
+    Vector<uint8_t> s2 = { 'e', 'f', 'g', 'h' };
+    Vector<uint8_t> s3 = { 'i', 'j', 'k', 'l' };
+
+    SharedBufferBuilder builder;
+    builder.append(WTFMove(s1));
+    builder.append(WTFMove(s2));
+    builder.append(WTFMove(s3));
+    auto buffer = builder.take();
+
+    auto abcd = buffer->getContiguousData(0, 4);
+    auto bcdefghi = buffer->getContiguousData(1, 8);
+    auto gh = buffer->getContiguousData(6, 2);
+    auto ghij = buffer->getContiguousData(6, 4);
+    auto h = buffer->getContiguousData(7, 1);
+    auto ijk = buffer->getContiguousData(8, 3);
+    auto kl = buffer->getContiguousData(10, 2);
+    auto l = buffer->getContiguousData(11, 1);
+    checkBuffer(abcd->data(), abcd->size(), "abcd");
+    checkBuffer(bcdefghi->data(), bcdefghi->size(), "bcdefghi");
+    checkBuffer(gh->data(), gh->size(), "gh");
+    checkBuffer(ghij->data(), ghij->size(), "ghij");
+    checkBuffer(h->data(), h->size(), "h");
+    checkBuffer(ijk->data(), ijk->size(), "ijk");
+    checkBuffer(kl->data(), kl->size(), "kl");
+    checkBuffer(l->data(), l->size(), "l");
+    auto fghijkl = buffer->getContiguousData(5, 20);
+    EXPECT_EQ(fghijkl->size(), buffer->size() - 5);
+    checkBuffer(fghijkl->data(), fghijkl->size(), "fghijkl");
+    auto outBound = buffer->getContiguousData(30, 20);
+    EXPECT_EQ(outBound->size(), 0u);
+}
+
 TEST_F(FragmentedSharedBufferTest, isEqualTo)
 {
     auto makeBuffer = [] (Vector<Vector<uint8_t>>&& contents) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to