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) {