Diff
Modified: trunk/Source/WebKit/ChangeLog (269681 => 269682)
--- trunk/Source/WebKit/ChangeLog 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/ChangeLog 2020-11-11 15:06:54 UTC (rev 269682)
@@ -1,3 +1,153 @@
+2020-11-11 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [Concurrent display lists] Add an initial implementation of concurrent display list rendering
+ https://bugs.webkit.org/show_bug.cgi?id=218426
+ <rdar://problem/71167220>
+
+ Reviewed by Ryosuke Niwa.
+
+ This patch adds a first-cut implementation of concurrent display list rendering, which allows the GPU and web
+ processes to read and write display list data at the same time. To achieve this, we remove the placeholder
+ shared memory display list encoding mechanism previously added in <webkit.org/b/218406>, and replace it with a
+ new model in which a writer (i.e. the web process) and a reader (i.e. the GPU process) share a set of reusable
+ shared memory buffers which contain display list item data. As the writer appends data to shared memory, it
+ increments a counter in each shared memory buffer that represents the number of bytes that the reader has yet to
+ read; as the reader reads display list items from shared memory, it decrements this counter.
+
+ This patch also implements a simple strategy for reusing these shared item buffers. The web process maintains a
+ queue of reusable buffers; when display list items are appended and the current writable buffer is out of
+ capacity, the display list item buffer calls out to WebKit2 via a client method to request more shared memory.
+ Here, the web process traverses the queue of reusable item buffers in search of a buffer with sufficient
+ capacity; if found, we hand this back to WebCore as an opaque `ItemBufferHandle`; otherwise, we allocate a new
+ reusable shared memory buffer. Item buffers that have been used become reusable only after they are (1) no
+ longer being read from -- i.e., the counter value is 0, and (2) they are not actively being written to.
+ Buffers that have been used are lazily reintroduced into the reuse queue when a display list requests a handle
+ to writable item buffer data.
+
+ See below for more details.
+
+ * GPUProcess/graphics/DisplayListReaderHandle.cpp: Copied from Source/WebKit/Shared/SharedDisplayListHandle.cpp.
+ (WebKit::DisplayListReaderHandle::advance):
+ (WebKit::DisplayListReaderHandle::displayListForReading const):
+ * GPUProcess/graphics/DisplayListReaderHandle.h: Copied from Source/WebKit/Shared/SharedDisplayListHandle.cpp.
+ (WebKit::DisplayListReaderHandle::create):
+ (WebKit::DisplayListReaderHandle::DisplayListReaderHandle):
+
+ Add a new helper class to represent a shared display list item buffer that the GPU process can use to consume
+ display list items. Advancing the cursor in `DisplayListReaderHandle` decrements the "remaining bytes" counter;
+ the class also has a helper method for creating a new `DisplayList` with a given offset into the shared buffer,
+ as well the number of bytes to read.
+
+ * GPUProcess/graphics/RemoteImageBuffer.h:
+
+ Handle the `MetaCommandSwitchTo` and `FlushContext` items by (respectively) informing the rendering backend
+ about the next buffer to read from, and sending a "flush committed" IPC message back to the web process.
+
+ (WebKit::RemoteImageBuffer::RemoteImageBuffer):
+ * GPUProcess/graphics/RemoteRenderingBackend.cpp:
+ (WebKit::RemoteRenderingBackend::applyDisplayListsFromHandle):
+ (WebKit::RemoteRenderingBackend::wakeUpAndApplyDisplayList):
+
+ This is the main loop in the GPU process that is responsible for applying incoming display list item data. This
+ IPC endpoint receives information about where to start (i.e. an item buffer ID and an offset into shared memory
+ in that buffer) and begins reading ranges of display list item data inside that buffer. After it is done
+ processing all of its unread bytes, it then checks the unread byte count once again, and continues the loop if
+ the web process has advanced this count.
+
+ (WebKit::RemoteRenderingBackend::setNextItemBufferToRead):
+ (WebKit::RemoteRenderingBackend::didCreateSharedDisplayListHandle):
+
+ Add logic to handle the case where we reached the end of an item buffer, but the next buffer identifier is still
+ unknown to us (since it is still "in transit" via the `DidCreateSharedDisplayListHandle` IPC message). In this
+ case, we remember the next buffer identifier in `m_nextItemBufferToRead`, and exit the processing loop inside
+ `wakeUpAndApplyDisplayList`. Upon receiving the shared memory handle in `didCreateSharedDisplayListHandle`, we
+ then automatically resume display list processing, starting from the beginning of this new buffer.
+
+ (WebKit::RemoteRenderingBackend::applyDisplayList): Deleted.
+ (WebKit::RemoteRenderingBackend::submitDisplayList): Deleted.
+ (WebKit::RemoteRenderingBackend::flushDisplayListAndCommit): Deleted.
+ (WebKit::RemoteRenderingBackend::didCreateSharedItemData): Deleted.
+
+ We don't need any of these methods anymore, now that there is only one codepath for processing display list
+ items. See `RemoteRenderingBackend::wakeUpAndApplyDisplayList` above. Also, rename `didCreateSharedItemData`
+ to `didCreateSharedDisplayListHandle` (also above).
+
+ * GPUProcess/graphics/RemoteRenderingBackend.h:
+ * GPUProcess/graphics/RemoteRenderingBackend.messages.in:
+ * Shared/SharedDisplayListHandle.h:
+ (WebKit::SharedDisplayListHandle::sharedMemory):
+ (WebKit::SharedDisplayListHandle::sharedMemory const):
+ (WebKit::SharedDisplayListHandle::identifier const):
+ (WebKit::SharedDisplayListHandle::data const):
+ (WebKit::SharedDisplayListHandle::unreadBytes):
+ (WebKit::SharedDisplayListHandle::Lock::Lock):
+ (WebKit::SharedDisplayListHandle::Lock::~Lock):
+ (WebKit::SharedDisplayListHandle::SharedDisplayListHandle):
+ (WebKit::SharedDisplayListHandle::header):
+ (WebKit::SharedDisplayListHandle::header const):
+ (WebKit::SharedDisplayListHandle::encode const): Deleted.
+ (WebKit::SharedDisplayListHandle::decode): Deleted.
+
+ Repurpose `SharedDisplayListHandle` to serve as a base class for both `DisplayListReaderHandle` and
+ `DisplayListWriterHandle`. This base class is aware of the memory layout of the display list item buffer in
+ shared memory (in particular, the fact that the first 8 bytes are the atomic lock and the next 8 bytes contain
+ the unread byte counter).
+
+ Internally, this uses a protected RAII class, `SharedDisplayListHandle::Lock`, to grab the lock before either
+ reading or writing the unread bytes count.
+
+ * Sources.txt:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/GPU/graphics/DisplayListWriterHandle.cpp: Added.
+ (WebKit::DisplayListWriterHandle::advance):
+ (WebKit::DisplayListWriterHandle::availableCapacity const):
+ (WebKit::DisplayListWriterHandle::createHandle const):
+ (WebKit::DisplayListWriterHandle::resetWritableOffsetIfPossible):
+
+ This helper method moves the writable offset (see below) back to the start of the buffer if it is not being read
+ from by the GPU process.
+
+ * WebProcess/GPU/graphics/DisplayListWriterHandle.h: Renamed from Source/WebKit/Shared/SharedDisplayListHandle.cpp.
+ (WebKit::DisplayListWriterHandle::create):
+ (WebKit::DisplayListWriterHandle::writableOffset const):
+
+ Similar to `DisplayListReaderHandle`, except that this contains logic specific to the web process for writing
+ display list items into shared memory. Advancing the cursor in `DisplayListWriterHandle` increments the counter.
+ It also increments the `writableOffset` of the handle, which represents the minimum offset into the shared
+ buffer that may contain newly appended display list items.
+
+ (WebKit::DisplayListWriterHandle::DisplayListWriterHandle):
+ * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
+ * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
+ (WebKit::RemoteRenderingBackendProxy::submitDisplayList):
+ (WebKit::RemoteRenderingBackendProxy::updateReusableHandles):
+
+ This private helper iterates the set of buffers that are not currently being written to, and adds each one to
+ the reusable buffer queue only if its writable offset is at the start.
+
+ (WebKit::RemoteRenderingBackendProxy::createItemBuffer):
+
+ Implements logic that hands shared item buffer data handles to WebCore for writing display list items. This will
+ try to reuse an item buffer in the reuse queue, if possible, and fall back to allocating a new chunk of shared
+ memory if no reusable buffer is found (or the existing buffers have insufficient capacity). The fact that we
+ iterate through each reusable buffer in order, combined with the above logic in `updateReusableHandles`, ensures
+ that once we begin writing to a item buffer, we will continue using that item buffer until it exhausts available
+ capacity.
+
+ This property is important because it allows the GPU process to simply start reading item data from a given
+ offset and buffer ID (specified in the `WakeUpAndApplyDisplayList` IPC message), and seamlessly continue
+ reading data even after it exhausts all available item data in the current buffer by continuing from the start
+ of the item buffer that contains the next display list items (which we learn in the GPU process by encountering
+ a `MetaCommandSwitchTo` item at the end of the previous buffer).
+
+ In "steady state" (wherein both processes are concurrently writing and reading items as quickly as possible),
+ this means that as the web process is busy filling up each item buffer with item data, the GPU process is also
+ busy applying all the item data in one buffer and automatically moving on to the next buffer with no additional
+ IPC messages required.
+
+ (WebKit::RemoteRenderingBackendProxy::flushDisplayListAndCommit): Deleted.
+ * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
+
2020-11-11 Commit Queue <commit-qu...@webkit.org>
Unreviewed, reverting r269244.
Copied: trunk/Source/WebKit/GPUProcess/graphics/DisplayListReaderHandle.cpp (from rev 269681, trunk/Source/WebKit/Shared/SharedDisplayListHandle.cpp) (0 => 269682)
--- trunk/Source/WebKit/GPUProcess/graphics/DisplayListReaderHandle.cpp (rev 0)
+++ trunk/Source/WebKit/GPUProcess/graphics/DisplayListReaderHandle.cpp 2020-11-11 15:06:54 UTC (rev 269682)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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 "config.h"
+#include "DisplayListReaderHandle.h"
+
+namespace WebKit {
+using namespace WebCore;
+
+size_t DisplayListReaderHandle::advance(size_t amount)
+{
+ auto locker = SharedDisplayListHandle::Lock { *this };
+ if (LIKELY(amount <= header().unreadBytes))
+ return header().unreadBytes -= amount;
+
+ // FIXME: This should result in terminating the web process.
+ ASSERT_NOT_REACHED();
+ header().unreadBytes = 0;
+ return 0;
+}
+
+std::unique_ptr<DisplayList::DisplayList> DisplayListReaderHandle::displayListForReading(size_t offset, size_t capacity, DisplayList::ItemBufferReadingClient& client) const
+{
+ auto displayList = makeUnique<DisplayList::DisplayList>(DisplayList::ItemBufferHandles {{ identifier(), data() + offset, capacity }});
+ displayList->setItemBufferClient(&client);
+ return displayList;
+}
+
+} // namespace WebKit
Copied: trunk/Source/WebKit/GPUProcess/graphics/DisplayListReaderHandle.h (from rev 269681, trunk/Source/WebKit/Shared/SharedDisplayListHandle.cpp) (0 => 269682)
--- trunk/Source/WebKit/GPUProcess/graphics/DisplayListReaderHandle.h (rev 0)
+++ trunk/Source/WebKit/GPUProcess/graphics/DisplayListReaderHandle.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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
+
+#include "SharedDisplayListHandle.h"
+#include <wtf/FastMalloc.h>
+
+namespace WebKit {
+
+class DisplayListReaderHandle : public SharedDisplayListHandle {
+ WTF_MAKE_NONCOPYABLE(DisplayListReaderHandle); WTF_MAKE_FAST_ALLOCATED;
+public:
+ static Ref<DisplayListReaderHandle> create(WebCore::DisplayList::ItemBufferIdentifier identifier, Ref<SharedMemory>&& sharedMemory)
+ {
+ return adoptRef(*new DisplayListReaderHandle(identifier, WTFMove(sharedMemory)));
+ }
+
+ size_t advance(size_t amount) override;
+ std::unique_ptr<WebCore::DisplayList::DisplayList> displayListForReading(size_t offset, size_t capacity, WebCore::DisplayList::ItemBufferReadingClient&) const;
+
+private:
+ DisplayListReaderHandle(WebCore::DisplayList::ItemBufferIdentifier identifier, Ref<SharedMemory>&& sharedMemory)
+ : SharedDisplayListHandle(identifier, WTFMove(sharedMemory))
+ {
+ }
+};
+
+} // namespace WebKit
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h (269681 => 269682)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -52,6 +52,7 @@
RemoteImageBuffer(std::unique_ptr<BackendType>&& backend, RemoteRenderingBackend& remoteRenderingBackend, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
: BaseConcreteImageBuffer(WTFMove(backend), renderingResourceIdentifier)
, m_remoteRenderingBackend(remoteRenderingBackend)
+ , m_renderingResourceIdentifier(renderingResourceIdentifier)
{
m_remoteRenderingBackend.imageBufferBackendWasCreated(m_backend->logicalSize(), m_backend->backendSize(), m_backend->resolutionScale(), m_backend->colorSpace(), m_backend->createImageBufferBackendHandle(), renderingResourceIdentifier);
}
@@ -83,12 +84,15 @@
}
if (item.is<WebCore::DisplayList::FlushContext>()) {
- // FIXME: Not implemented yet.
+ BaseConcreteImageBuffer::flushContext();
+ auto identifier = item.get<WebCore::DisplayList::FlushContext>().identifier();
+ m_remoteRenderingBackend.flushDisplayListWasCommitted(identifier, m_renderingResourceIdentifier);
return true;
}
if (item.is<WebCore::DisplayList::MetaCommandSwitchTo>()) {
- // FIXME: Not implemented yet.
+ auto nextBufferIdentifier = item.get<WebCore::DisplayList::MetaCommandSwitchTo>().identifier();
+ m_remoteRenderingBackend.setNextItemBufferToRead(nextBufferIdentifier);
return true;
}
@@ -96,6 +100,7 @@
}
RemoteRenderingBackend& m_remoteRenderingBackend;
+ WebCore::RenderingResourceIdentifier m_renderingResourceIdentifier;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (269681 => 269682)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp 2020-11-11 15:06:54 UTC (rev 269682)
@@ -28,10 +28,12 @@
#if ENABLE(GPU_PROCESS)
+#include "DisplayListReaderHandle.h"
#include "GPUConnectionToWebProcess.h"
#include "PlatformRemoteImageBuffer.h"
#include "RemoteRenderingBackendMessages.h"
#include "RemoteRenderingBackendProxyMessages.h"
+#include <wtf/CheckedArithmetic.h>
namespace WebKit {
using namespace WebCore;
@@ -124,46 +126,88 @@
m_remoteResourceCache.cacheImageBuffer(makeRef(*imageBuffer));
}
-void RemoteRenderingBackend::applyDisplayList(const SharedDisplayListHandle& handle, RenderingResourceIdentifier renderingResourceIdentifier, ShouldFlushContext flushContext)
+void RemoteRenderingBackend::applyDisplayListsFromHandle(ImageBuffer& destination, DisplayListReaderHandle& handle, size_t initialOffset)
{
- Vector<Ref<SharedMemory>> removedItemBuffers;
- auto displayList = handle.createDisplayList([&] (DisplayList::ItemBufferIdentifier identifier) -> uint8_t* {
- if (auto sharedMemory = m_sharedItemBuffers.take(identifier)) {
- removedItemBuffers.append(*sharedMemory);
- return reinterpret_cast<uint8_t*>(sharedMemory->data());
+ auto handleProtector = makeRef(handle);
+
+ size_t offset = initialOffset;
+ size_t sizeToRead = 0;
+
+ do {
+ sizeToRead = handle.unreadBytes();
+ } while (!sizeToRead);
+
+ while (sizeToRead) {
+ auto displayList = handle.displayListForReading(offset, sizeToRead, *this);
+ if (UNLIKELY(!displayList)) {
+ // FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
+ return;
}
- return nullptr;
- });
- if (!displayList) {
+ destination.submitDisplayList(*displayList);
+
+ CheckedSize checkedOffset = offset;
+ checkedOffset += sizeToRead;
+ if (UNLIKELY(checkedOffset.hasOverflowed())) {
+ // FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ offset = checkedOffset.unsafeGet();
+
+ if (UNLIKELY(offset > handle.sharedMemory().size())) {
+ // FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ sizeToRead = handle.advance(sizeToRead);
+ }
+}
+
+void RemoteRenderingBackend::wakeUpAndApplyDisplayList(DisplayList::ItemBufferIdentifier initialIdentifier, uint64_t initialOffset, RenderingResourceIdentifier destinationBufferIdentifier)
+{
+ auto imageBuffer = m_remoteResourceCache.cachedImageBuffer(destinationBufferIdentifier);
+ if (UNLIKELY(!imageBuffer)) {
// FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
return;
}
- auto imageBuffer = m_remoteResourceCache.cachedImageBuffer(renderingResourceIdentifier);
- if (!imageBuffer) {
+ auto initialHandle = m_sharedDisplayListHandles.get(initialIdentifier);
+ if (UNLIKELY(!initialHandle)) {
// FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
return;
}
- displayList->setItemBufferClient(this);
- imageBuffer->submitDisplayList(*displayList);
+ applyDisplayListsFromHandle(*imageBuffer, *initialHandle, initialOffset);
- if (flushContext == ShouldFlushContext::Yes)
- imageBuffer->flushContext();
+ while (m_nextItemBufferToRead) {
+ auto nextHandle = m_sharedDisplayListHandles.get(m_nextItemBufferToRead);
+ if (!nextHandle) {
+ // If the handle identifier is currently unknown, wait until the GPU process receives an
+ // IPC message with a shared memory handle to the next item buffer.
+ break;
+ }
+ // Otherwise, continue reading the next display list item buffer from the start.
+ m_nextItemBufferToRead = { };
+ applyDisplayListsFromHandle(*imageBuffer, *nextHandle, SharedDisplayListHandle::reservedCapacityAtStart);
+ }
}
-void RemoteRenderingBackend::submitDisplayList(const SharedDisplayListHandle& handle, RenderingResourceIdentifier renderingResourceIdentifier)
+void RemoteRenderingBackend::setNextItemBufferToRead(DisplayList::ItemBufferIdentifier identifier)
{
- applyDisplayList(handle, renderingResourceIdentifier, ShouldFlushContext::No);
+ if (UNLIKELY(m_nextItemBufferToRead)) {
+ // FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ m_nextItemBufferToRead = identifier;
}
-void RemoteRenderingBackend::flushDisplayListAndCommit(const SharedDisplayListHandle& handle, DisplayList::FlushIdentifier flushIdentifier, RenderingResourceIdentifier renderingResourceIdentifier)
-{
- applyDisplayList(handle, renderingResourceIdentifier, ShouldFlushContext::Yes);
- flushDisplayListWasCommitted(flushIdentifier, renderingResourceIdentifier);
-}
-
void RemoteRenderingBackend::getImageData(AlphaPremultiplication outputFormat, IntRect srcRect, RenderingResourceIdentifier renderingResourceIdentifier, CompletionHandler<void(IPC::ImageDataReference&&)>&& completionHandler)
{
RefPtr<ImageData> imageData;
@@ -177,10 +221,21 @@
m_remoteResourceCache.releaseRemoteResource(renderingResourceIdentifier);
}
-void RemoteRenderingBackend::didCreateSharedItemData(DisplayList::ItemBufferIdentifier identifier, const SharedMemory::IPCHandle& handle)
+void RemoteRenderingBackend::didCreateSharedDisplayListHandle(DisplayList::ItemBufferIdentifier identifier, const SharedMemory::IPCHandle& handle, RenderingResourceIdentifier destinationBufferIdentifier)
{
- if (auto sharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadOnly))
- m_sharedItemBuffers.set(identifier, WTFMove(sharedMemory));
+ if (UNLIKELY(m_sharedDisplayListHandles.contains(identifier))) {
+ // FIXME: Add a message check to terminate the web process.
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ if (auto sharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadWrite))
+ m_sharedDisplayListHandles.set(identifier, DisplayListReaderHandle::create(identifier, sharedMemory.releaseNonNull()));
+
+ if (m_nextItemBufferToRead == identifier) {
+ m_nextItemBufferToRead = { };
+ wakeUpAndApplyDisplayList(identifier, SharedDisplayListHandle::reservedCapacityAtStart, destinationBufferIdentifier);
+ }
}
Optional<DisplayList::ItemHandle> WARN_UNUSED_RETURN RemoteRenderingBackend::decodeItem(const uint8_t* data, size_t length, DisplayList::ItemType type, uint8_t* handleLocation)
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h (269681 => 269682)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -34,7 +34,6 @@
#include "MessageSender.h"
#include "RemoteResourceCache.h"
#include "RenderingBackendIdentifier.h"
-#include "SharedDisplayListHandle.h"
#include <WebCore/ColorSpace.h>
#include <WebCore/DisplayList.h>
#include <WebCore/DisplayListItems.h>
@@ -52,6 +51,7 @@
namespace WebKit {
+class DisplayListReaderHandle;
class GPUConnectionToWebProcess;
class RemoteRenderingBackend
@@ -72,12 +72,11 @@
void imageBufferBackendWasCreated(const WebCore::FloatSize& logicalSize, const WebCore::IntSize& backendSize, float resolutionScale, WebCore::ColorSpace, ImageBufferBackendHandle, WebCore::RenderingResourceIdentifier);
void flushDisplayListWasCommitted(WebCore::DisplayList::FlushIdentifier, WebCore::RenderingResourceIdentifier);
+ void setNextItemBufferToRead(WebCore::DisplayList::ItemBufferIdentifier);
+
private:
RemoteRenderingBackend(GPUConnectionToWebProcess&, RenderingBackendIdentifier);
- enum class ShouldFlushContext : bool { No, Yes };
- void applyDisplayList(const SharedDisplayListHandle&, WebCore::RenderingResourceIdentifier, ShouldFlushContext);
-
Optional<WebCore::DisplayList::ItemHandle> WARN_UNUSED_RETURN decodeItem(const uint8_t* data, size_t length, WebCore::DisplayList::ItemType, uint8_t* handleLocation) override;
template<typename T>
@@ -92,6 +91,8 @@
return WTF::nullopt;
}
+ void applyDisplayListsFromHandle(WebCore::ImageBuffer& destination, DisplayListReaderHandle&, size_t offset);
+
// IPC::MessageSender.
IPC::Connection* messageSenderConnection() const override;
uint64_t messageSenderDestinationID() const override;
@@ -102,16 +103,16 @@
// Messages to be received.
void createImageBuffer(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, WebCore::ColorSpace, WebCore::RenderingResourceIdentifier);
- void submitDisplayList(const SharedDisplayListHandle&, WebCore::RenderingResourceIdentifier);
- void flushDisplayListAndCommit(const SharedDisplayListHandle&, WebCore::DisplayList::FlushIdentifier, WebCore::RenderingResourceIdentifier);
+ void wakeUpAndApplyDisplayList(WebCore::DisplayList::ItemBufferIdentifier initialIdentifier, uint64_t initialOffset, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
void getImageData(WebCore::AlphaPremultiplication outputFormat, WebCore::IntRect srcRect, WebCore::RenderingResourceIdentifier, CompletionHandler<void(IPC::ImageDataReference&&)>&&);
void releaseRemoteResource(WebCore::RenderingResourceIdentifier);
- void didCreateSharedItemData(WebCore::DisplayList::ItemBufferIdentifier, const SharedMemory::IPCHandle&);
+ void didCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier, const SharedMemory::IPCHandle&, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
RemoteResourceCache m_remoteResourceCache;
WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
RenderingBackendIdentifier m_renderingBackendIdentifier;
- HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<SharedMemory>> m_sharedItemBuffers;
+ HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListReaderHandle>> m_sharedDisplayListHandles;
+ WebCore::DisplayList::ItemBufferIdentifier m_nextItemBufferToRead;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in (269681 => 269682)
--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in 2020-11-11 15:06:54 UTC (rev 269682)
@@ -24,10 +24,9 @@
messages -> RemoteRenderingBackend NotRefCounted {
CreateImageBuffer(WebCore::FloatSize logicalSize, WebCore::RenderingMode renderingMode, float resolutionScale, WebCore::ColorSpace colorSpace, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
- SubmitDisplayList(WebKit::SharedDisplayListHandle displayList, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
- FlushDisplayListAndCommit(WebKit::SharedDisplayListHandle displayList, WebCore::DisplayList::FlushIdentifier flushIdentifier, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
+ WakeUpAndApplyDisplayList(WebCore::DisplayList::ItemBufferIdentifier initialIdentifier, uint64_t initialOffset, WebCore::RenderingResourceIdentifier destinationBufferIdentifier)
GetImageData(enum:uint8_t WebCore::AlphaPremultiplication outputFormat, WebCore::IntRect srcRect, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (IPC::ImageDataReference imageData) Synchronous
- DidCreateSharedItemData(WebCore::DisplayList::ItemBufferIdentifier identifier, WebKit::SharedMemory::IPCHandle handle)
+ DidCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier identifier, WebKit::SharedMemory::IPCHandle handle, WebCore::RenderingResourceIdentifier destinationBufferIdentifier)
ReleaseRemoteResource(WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
}
Deleted: trunk/Source/WebKit/Shared/SharedDisplayListHandle.cpp (269681 => 269682)
--- trunk/Source/WebKit/Shared/SharedDisplayListHandle.cpp 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/Shared/SharedDisplayListHandle.cpp 2020-11-11 15:06:54 UTC (rev 269682)
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2020 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 "config.h"
-#include "SharedDisplayListHandle.h"
-
-namespace WebKit {
-using namespace WebCore;
-
-SharedDisplayListHandle::SharedDisplayListHandle(const DisplayList::DisplayList& displayList)
-{
- displayList.forEachItemBuffer([&] (auto& handle) {
- m_buffers.append({ handle.identifier, handle.capacity });
- });
-}
-
-std::unique_ptr<DisplayList::DisplayList> SharedDisplayListHandle::createDisplayList(ItemBufferProvider&& bufferProvider) const
-{
- DisplayList::ItemBufferHandles handles;
- handles.reserveInitialCapacity(m_buffers.size());
- for (auto& [identifier, capacity] : m_buffers) {
- auto* data = ""
- if (!data)
- return nullptr;
-
- handles.uncheckedAppend({ identifier, data, capacity });
- }
- return makeUnique<DisplayList::DisplayList>(WTFMove(handles));
-}
-
-} // namespace WebKit
Modified: trunk/Source/WebKit/Shared/SharedDisplayListHandle.h (269681 => 269682)
--- trunk/Source/WebKit/Shared/SharedDisplayListHandle.h 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/Shared/SharedDisplayListHandle.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -25,42 +25,76 @@
#pragma once
+#include "SharedMemory.h"
#include <WebCore/DisplayList.h>
+#include <wtf/Atomics.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Threading.h>
namespace WebKit {
-class SharedDisplayListHandle {
+class SharedDisplayListHandle : public RefCounted<SharedDisplayListHandle> {
public:
- using ItemBufferProvider = Function<uint8_t*(WebCore::DisplayList::ItemBufferIdentifier)>;
+ virtual ~SharedDisplayListHandle() = default;
- SharedDisplayListHandle(const WebCore::DisplayList::DisplayList&);
- std::unique_ptr<WebCore::DisplayList::DisplayList> createDisplayList(ItemBufferProvider&&) const;
+ static constexpr auto reservedCapacityAtStart = 2 * sizeof(uint64_t);
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<SharedDisplayListHandle> decode(Decoder&);
+ SharedMemory& sharedMemory() { return m_sharedMemory.get(); }
+ const SharedMemory& sharedMemory() const { return m_sharedMemory.get(); }
-private:
- SharedDisplayListHandle(Vector<std::pair<WebCore::DisplayList::ItemBufferIdentifier, size_t>>&& buffers)
- : m_buffers(WTFMove(buffers))
+ WebCore::DisplayList::ItemBufferIdentifier identifier() const { return m_identifier; }
+ uint8_t* data() const { return reinterpret_cast<uint8_t*>(sharedMemory().data()); }
+
+ uint64_t unreadBytes()
{
+ auto locker = SharedDisplayListHandle::Lock { *this };
+ return header().unreadBytes;
}
- Vector<std::pair<WebCore::DisplayList::ItemBufferIdentifier, size_t>> m_buffers;
-};
+ virtual size_t advance(size_t amount) = 0;
-template<class Encoder> void SharedDisplayListHandle::encode(Encoder& encoder) const
-{
- encoder << m_buffers;
-}
+protected:
+ class Lock {
+ public:
+ Lock(SharedDisplayListHandle& handle)
+ : m_handle(handle)
+ {
+ auto& atomicValue = m_handle.header().lock;
+ while (true) {
+ // FIXME: We need to avoid waiting forever in the case where the web content process
+ // holds on to the lock indefinitely (or crashes while holding the lock).
+ uint64_t unlocked = 0;
+ if (atomicValue.compareExchangeWeak(unlocked, 1))
+ break;
+ Thread::yield();
+ }
+ }
-template<class Decoder> Optional<SharedDisplayListHandle> SharedDisplayListHandle::decode(Decoder& decoder)
-{
- Optional<Vector<std::pair<WebCore::DisplayList::ItemBufferIdentifier, size_t>>> buffers;
- decoder >> buffers;
- if (!buffers)
- return WTF::nullopt;
+ ~Lock()
+ {
+ m_handle.header().lock.store(0);
+ }
- return {{ WTFMove(*buffers) }};
-}
+ private:
+ SharedDisplayListHandle& m_handle;
+ };
+ SharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier identifier, Ref<SharedMemory>&& sharedMemory)
+ : m_identifier(identifier)
+ , m_sharedMemory(WTFMove(sharedMemory))
+ {
+ }
+
+ struct DisplayListSharedMemoryHeader {
+ Atomic<uint64_t> lock;
+ uint64_t unreadBytes;
+ };
+
+ DisplayListSharedMemoryHeader& header() { return *reinterpret_cast<DisplayListSharedMemoryHeader*>(data()); }
+
+private:
+ WebCore::DisplayList::ItemBufferIdentifier m_identifier;
+ Ref<SharedMemory> m_sharedMemory;
+};
+
} // namespace WebKit
Modified: trunk/Source/WebKit/Sources.txt (269681 => 269682)
--- trunk/Source/WebKit/Sources.txt 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/Sources.txt 2020-11-11 15:06:54 UTC (rev 269682)
@@ -24,6 +24,7 @@
GPUProcess/GPUProcess.cpp
GPUProcess/GPUConnectionToWebProcess.cpp
GPUProcess/GPUProcessCreationParameters.cpp
+GPUProcess/graphics/DisplayListReaderHandle.cpp
GPUProcess/graphics/RemoteRenderingBackend.cpp
GPUProcess/graphics/RemoteResourceCache.cpp
GPUProcess/media/RemoteAudioSessionProxy.cpp
@@ -173,7 +174,6 @@
Shared/SessionState.cpp
Shared/ShareableBitmap.cpp @no-unify
Shared/ShareableResource.cpp
-Shared/SharedDisplayListHandle.cpp
Shared/SharedStringHashStore.cpp
Shared/SharedStringHashTableReadOnly.cpp
Shared/SharedStringHashTable.cpp
@@ -560,6 +560,7 @@
WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp
WebProcess/GPU/GPUProcessConnection.cpp
+WebProcess/GPU/graphics/DisplayListWriterHandle.cpp
WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp
WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp
WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (269681 => 269682)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-11-11 15:06:54 UTC (rev 269682)
@@ -1871,6 +1871,8 @@
E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; };
E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; };
ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ F4094CBD2553053D003D73E3 /* DisplayListReaderHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = F4094CBB255304AF003D73E3 /* DisplayListReaderHandle.h */; };
+ F4094CBE25530540003D73E3 /* DisplayListWriterHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = F4094CB92553047E003D73E3 /* DisplayListWriterHandle.h */; };
F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
F42D634122A0EFDF00D2FB3A /* WebAutocorrectionData.h in Headers */ = {isa = PBXBuildFile; fileRef = F42D633F22A0EFD300D2FB3A /* WebAutocorrectionData.h */; };
F430E9422247335F005FE053 /* WebsiteMetaViewportPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = F430E941224732A9005FE053 /* WebsiteMetaViewportPolicy.h */; };
@@ -5470,6 +5472,10 @@
ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; };
ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; };
+ F4094CB92553047E003D73E3 /* DisplayListWriterHandle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayListWriterHandle.h; sourceTree = "<group>"; };
+ F4094CBA2553047E003D73E3 /* DisplayListWriterHandle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayListWriterHandle.cpp; sourceTree = "<group>"; };
+ F4094CBB255304AF003D73E3 /* DisplayListReaderHandle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayListReaderHandle.h; sourceTree = "<group>"; };
+ F4094CBC255304AF003D73E3 /* DisplayListReaderHandle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayListReaderHandle.cpp; sourceTree = "<group>"; };
F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDragDestinationAction.h; sourceTree = "<group>"; };
F40D1B68220BDC0F00B49A01 /* WebAutocorrectionContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebAutocorrectionContext.h; path = ios/WebAutocorrectionContext.h; sourceTree = "<group>"; };
F41056612130699A0092281D /* APIAttachmentCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = APIAttachmentCocoa.mm; sourceTree = "<group>"; };
@@ -5492,7 +5498,6 @@
F496A42F1F58A272004C1757 /* DragDropInteractionState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DragDropInteractionState.h; path = ios/DragDropInteractionState.h; sourceTree = "<group>"; };
F496A4301F58A272004C1757 /* DragDropInteractionState.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = DragDropInteractionState.mm; path = ios/DragDropInteractionState.mm; sourceTree = "<group>"; };
F4A6D6BB254CA3E900B65FAA /* SharedDisplayListHandle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedDisplayListHandle.h; sourceTree = "<group>"; };
- F4A6D6BD254CA52200B65FAA /* SharedDisplayListHandle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SharedDisplayListHandle.cpp; sourceTree = "<group>"; };
F4AC655E22A3140E00A05607 /* WebPreferencesDefaultValuesIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebPreferencesDefaultValuesIOS.mm; path = ios/WebPreferencesDefaultValuesIOS.mm; sourceTree = "<group>"; };
F4B378D021DDBBAB0095A378 /* WebUndoStepID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebUndoStepID.h; sourceTree = "<group>"; };
F4CB09E4225D5A0300891487 /* WebsiteMediaSourcePolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebsiteMediaSourcePolicy.h; sourceTree = "<group>"; };
@@ -6200,7 +6205,6 @@
1A6420E312DCE2FF00CAAE2C /* ShareableBitmap.h */,
5121745E164C20E30037A5C1 /* ShareableResource.cpp */,
5121745F164C20E30037A5C1 /* ShareableResource.h */,
- F4A6D6BD254CA52200B65FAA /* SharedDisplayListHandle.cpp */,
F4A6D6BB254CA3E900B65FAA /* SharedDisplayListHandle.h */,
8313F7EA1F7DAE0400B944EB /* SharedStringHashStore.cpp */,
8313F7E91F7DAE0300B944EB /* SharedStringHashStore.h */,
@@ -8175,6 +8179,8 @@
isa = PBXGroup;
children = (
727A7F3324078527004D2931 /* cocoa */,
+ F4094CBA2553047E003D73E3 /* DisplayListWriterHandle.cpp */,
+ F4094CB92553047E003D73E3 /* DisplayListWriterHandle.h */,
727A7F39240788F1004D2931 /* ImageBufferBackendHandle.h */,
727A7F37240788F0004D2931 /* ImageBufferShareableBitmapBackend.cpp */,
727A7F36240788F0004D2931 /* ImageBufferShareableBitmapBackend.h */,
@@ -8194,6 +8200,8 @@
550640A124071A2900AAE045 /* graphics */ = {
isa = PBXGroup;
children = (
+ F4094CBC255304AF003D73E3 /* DisplayListReaderHandle.cpp */,
+ F4094CBB255304AF003D73E3 /* DisplayListReaderHandle.h */,
55AD09432408A0E600DE4D2F /* PlatformRemoteImageBuffer.h */,
55AD09422408A02E00DE4D2F /* RemoteImageBuffer.h */,
550640A224071A6100AAE045 /* RemoteRenderingBackend.cpp */,
@@ -11035,6 +11043,8 @@
83891B6C1A68C30B0030F386 /* DiagnosticLoggingClient.h in Headers */,
C18173612058424700DFDA65 /* DisplayLink.h in Headers */,
0F189CAC24749F2F00E58D81 /* DisplayLinkObserverID.h in Headers */,
+ F4094CBD2553053D003D73E3 /* DisplayListReaderHandle.h in Headers */,
+ F4094CBE25530540003D73E3 /* DisplayListWriterHandle.h in Headers */,
5C1427021C23F84C00D41183 /* Download.h in Headers */,
5C1427051C23F84C00D41183 /* DownloadID.h in Headers */,
5C1427071C23F84C00D41183 /* DownloadManager.h in Headers */,
Added: trunk/Source/WebKit/WebProcess/GPU/graphics/DisplayListWriterHandle.cpp (0 => 269682)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/DisplayListWriterHandle.cpp (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/DisplayListWriterHandle.cpp 2020-11-11 15:06:54 UTC (rev 269682)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 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 "config.h"
+#include "DisplayListWriterHandle.h"
+
+#include <wtf/CheckedArithmetic.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+size_t DisplayListWriterHandle::advance(size_t amount)
+{
+ CheckedSize checkedWritableOffset = m_writableOffset;
+ checkedWritableOffset += amount;
+ if (UNLIKELY(checkedWritableOffset.hasOverflowed()))
+ RELEASE_ASSERT_NOT_REACHED();
+
+ auto locker = SharedDisplayListHandle::Lock { *this };
+ CheckedSize checkedUnreadBytes = header().unreadBytes;
+ checkedUnreadBytes += amount;
+ if (UNLIKELY(checkedUnreadBytes.hasOverflowed()))
+ RELEASE_ASSERT_NOT_REACHED();
+
+ m_writableOffset = checkedWritableOffset.unsafeGet();
+ header().unreadBytes = checkedUnreadBytes.unsafeGet();
+ return checkedUnreadBytes.unsafeGet();
+}
+
+size_t DisplayListWriterHandle::availableCapacity() const
+{
+ if (UNLIKELY(sharedMemory().size() < writableOffset()))
+ RELEASE_ASSERT_NOT_REACHED();
+
+ return sharedMemory().size() - writableOffset();
+}
+
+DisplayList::ItemBufferHandle DisplayListWriterHandle::createHandle() const
+{
+ return {
+ identifier(),
+ data() + writableOffset(),
+ availableCapacity()
+ };
+}
+
+bool DisplayListWriterHandle::resetWritableOffsetIfPossible()
+{
+ if (m_writableOffset <= SharedDisplayListHandle::reservedCapacityAtStart) {
+ RELEASE_ASSERT(m_writableOffset == SharedDisplayListHandle::reservedCapacityAtStart);
+ return true;
+ }
+
+ if (unreadBytes())
+ return false;
+
+ m_writableOffset = SharedDisplayListHandle::reservedCapacityAtStart;
+ return true;
+}
+
+} // namespace WebKit
Copied: trunk/Source/WebKit/WebProcess/GPU/graphics/DisplayListWriterHandle.h (from rev 269681, trunk/Source/WebKit/Shared/SharedDisplayListHandle.cpp) (0 => 269682)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/DisplayListWriterHandle.h (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/DisplayListWriterHandle.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 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
+
+#include "SharedDisplayListHandle.h"
+#include <wtf/FastMalloc.h>
+
+namespace WebKit {
+
+class DisplayListWriterHandle : public SharedDisplayListHandle {
+ WTF_MAKE_NONCOPYABLE(DisplayListWriterHandle); WTF_MAKE_FAST_ALLOCATED;
+public:
+ static Ref<DisplayListWriterHandle> create(WebCore::DisplayList::ItemBufferIdentifier identifier, Ref<SharedMemory>&& sharedMemory)
+ {
+ return adoptRef(*new DisplayListWriterHandle(identifier, WTFMove(sharedMemory)));
+ }
+
+ size_t writableOffset() const { return m_writableOffset; }
+ size_t availableCapacity() const;
+
+ bool resetWritableOffsetIfPossible();
+
+ size_t advance(size_t amount) override;
+ WebCore::DisplayList::ItemBufferHandle createHandle() const;
+
+private:
+ DisplayListWriterHandle(WebCore::DisplayList::ItemBufferIdentifier identifier, Ref<SharedMemory>&& sharedMemory)
+ : SharedDisplayListHandle(identifier, WTFMove(sharedMemory))
+ , m_writableOffset(SharedDisplayListHandle::reservedCapacityAtStart)
+ {
+ }
+
+ size_t m_writableOffset { 0 };
+};
+
+} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h (269681 => 269682)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -34,6 +34,7 @@
#include <WebCore/DisplayListImageBuffer.h>
#include <WebCore/DisplayListItems.h>
#include <WebCore/DisplayListRecorder.h>
+#include <wtf/SystemTracing.h>
namespace WebKit {
@@ -139,6 +140,7 @@
void flushDrawingContext() override
{
+ TraceScope tracingScope(FlushRemoteImageBufferStart, FlushRemoteImageBufferEnd);
flushDrawingContextAndCommit();
timeoutWaitForFlushDisplayListWasCommitted();
}
@@ -152,8 +154,9 @@
if (displayList.isEmpty())
return;
- TraceScope tracingScope(FlushRemoteImageBufferStart, FlushRemoteImageBufferEnd, 1);
- m_sentFlushIdentifier = m_remoteRenderingBackendProxy->flushDisplayListAndCommit(displayList, m_renderingResourceIdentifier);
+ m_sentFlushIdentifier = WebCore::DisplayList::FlushIdentifier::generate();
+ displayList.template append<WebCore::DisplayList::FlushContext>(m_sentFlushIdentifier);
+ m_remoteRenderingBackendProxy->submitDisplayList(displayList, m_renderingResourceIdentifier);
m_itemCountInCurrentDisplayList = 0;
displayList.clear();
}
@@ -163,7 +166,6 @@
if (!m_remoteRenderingBackendProxy || displayList.isEmpty())
return;
- TraceScope tracingScope(FlushRemoteImageBufferStart, FlushRemoteImageBufferEnd);
m_remoteRenderingBackendProxy->submitDisplayList(displayList, m_renderingResourceIdentifier);
}
@@ -182,7 +184,7 @@
WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t capacity) override
{
if (m_remoteRenderingBackendProxy)
- return m_remoteRenderingBackendProxy->createItemBuffer(capacity);
+ return m_remoteRenderingBackendProxy->createItemBuffer(capacity, m_renderingResourceIdentifier);
ASSERT_NOT_REACHED();
return { };
Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp (269681 => 269682)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp 2020-11-11 15:06:54 UTC (rev 269682)
@@ -28,6 +28,7 @@
#if ENABLE(GPU_PROCESS)
+#include "DisplayListWriterHandle.h"
#include "GPUConnectionToWebProcess.h"
#include "GPUProcessConnection.h"
#include "ImageDataReference.h"
@@ -34,7 +35,6 @@
#include "PlatformRemoteImageBufferProxy.h"
#include "RemoteRenderingBackendMessages.h"
#include "RemoteRenderingBackendProxyMessages.h"
-#include "SharedDisplayListHandle.h"
#include "SharedMemory.h"
#include "WebProcess.h"
@@ -115,18 +115,28 @@
return imageDataReference.buffer();
}
-void RemoteRenderingBackendProxy::submitDisplayList(const DisplayList::DisplayList& displayList, RenderingResourceIdentifier renderingResourceIdentifier)
+void RemoteRenderingBackendProxy::submitDisplayList(const DisplayList::DisplayList& displayList, RenderingResourceIdentifier destinationBufferIdentifier)
{
- send(Messages::RemoteRenderingBackend::SubmitDisplayList({ displayList }, renderingResourceIdentifier), m_renderingBackendIdentifier);
- m_sharedItemBuffers.clear();
-}
+ Optional<std::pair<DisplayList::ItemBufferIdentifier, size_t>> identifierAndOffsetForWakeUpMessage;
+ bool isFirstHandle = true;
-DisplayList::FlushIdentifier RemoteRenderingBackendProxy::flushDisplayListAndCommit(const DisplayList::DisplayList& displayList, RenderingResourceIdentifier renderingResourceIdentifier)
-{
- auto sentFlushIdentifier = DisplayList::FlushIdentifier::generate();
- send(Messages::RemoteRenderingBackend::FlushDisplayListAndCommit({ displayList }, sentFlushIdentifier, renderingResourceIdentifier), m_renderingBackendIdentifier);
- m_sharedItemBuffers.clear();
- return sentFlushIdentifier;
+ displayList.forEachItemBuffer([&] (auto& handle) {
+ m_identifiersOfHandlesAvailableForWriting.add(handle.identifier);
+
+ auto* sharedHandle = m_sharedDisplayListHandles.get(handle.identifier);
+ RELEASE_ASSERT_WITH_MESSAGE(sharedHandle, "%s failed to find shared display list", __PRETTY_FUNCTION__);
+
+ bool unreadCountWasEmpty = sharedHandle->advance(handle.capacity) == handle.capacity;
+ if (isFirstHandle && unreadCountWasEmpty)
+ identifierAndOffsetForWakeUpMessage = {{ handle.identifier, handle.data - sharedHandle->data() }};
+
+ isFirstHandle = false;
+ });
+
+ if (identifierAndOffsetForWakeUpMessage) {
+ auto [identifier, offset] = *identifierAndOffsetForWakeUpMessage;
+ send(Messages::RemoteRenderingBackend::WakeUpAndApplyDisplayList(identifier, offset, destinationBufferIdentifier), m_renderingBackendIdentifier);
+ }
}
void RemoteRenderingBackendProxy::releaseRemoteResource(RenderingResourceIdentifier renderingResourceIdentifier)
@@ -159,21 +169,56 @@
downcast<UnacceleratedRemoteImageBufferProxy>(*imageBuffer).commitFlushDisplayList(flushIdentifier);
}
-DisplayList::ItemBufferHandle RemoteRenderingBackendProxy::createItemBuffer(size_t capacity)
+void RemoteRenderingBackendProxy::updateReusableHandles()
{
+ for (auto identifier : m_identifiersOfHandlesAvailableForWriting) {
+ auto* handle = m_sharedDisplayListHandles.get(identifier);
+ if (!handle->resetWritableOffsetIfPossible())
+ continue;
+
+ if (m_identifiersOfReusableHandles.contains(identifier))
+ continue;
+
+ m_identifiersOfReusableHandles.append(identifier);
+ }
+}
+
+DisplayList::ItemBufferHandle RemoteRenderingBackendProxy::createItemBuffer(size_t capacity, RenderingResourceIdentifier destinationBufferIdentifier)
+{
+ updateReusableHandles();
+
+ while (!m_identifiersOfReusableHandles.isEmpty()) {
+ auto identifier = m_identifiersOfReusableHandles.first();
+ auto* reusableHandle = m_sharedDisplayListHandles.get(identifier);
+ RELEASE_ASSERT_WITH_MESSAGE(reusableHandle, "%s failed to find shared display list", __PRETTY_FUNCTION__);
+
+ if (m_identifiersOfHandlesAvailableForWriting.contains(identifier) && reusableHandle->availableCapacity() >= capacity) {
+ m_identifiersOfHandlesAvailableForWriting.remove(identifier);
+ return reusableHandle->createHandle();
+ }
+
+ m_identifiersOfReusableHandles.removeFirst();
+ }
+
static constexpr size_t defaultSharedItemBufferSize = 1 << 16;
- auto sharedMemory = SharedMemory::allocate(std::max(defaultSharedItemBufferSize, capacity));
+ auto sharedMemory = SharedMemory::allocate(std::max(defaultSharedItemBufferSize, capacity + SharedDisplayListHandle::reservedCapacityAtStart));
if (!sharedMemory)
return { };
- auto identifier = DisplayList::ItemBufferIdentifier::generate();
SharedMemory::Handle sharedMemoryHandle;
- sharedMemory->createHandle(sharedMemoryHandle, SharedMemory::Protection::ReadOnly);
- send(Messages::RemoteRenderingBackend::DidCreateSharedItemData(identifier, { WTFMove(sharedMemoryHandle), sharedMemory->size() }), m_renderingBackendIdentifier);
- m_sharedItemBuffers.set(identifier, sharedMemory.copyRef());
+ sharedMemory->createHandle(sharedMemoryHandle, SharedMemory::Protection::ReadWrite);
- return { identifier, reinterpret_cast<uint8_t*>(sharedMemory->data()), sharedMemory->size() };
+ auto identifier = DisplayList::ItemBufferIdentifier::generate();
+ send(Messages::RemoteRenderingBackend::DidCreateSharedDisplayListHandle(identifier, { WTFMove(sharedMemoryHandle), sharedMemory->size() }, destinationBufferIdentifier), m_renderingBackendIdentifier);
+
+ auto newHandle = DisplayListWriterHandle::create(identifier, sharedMemory.releaseNonNull());
+ auto displayListHandle = newHandle->createHandle();
+
+ m_identifiersOfReusableHandles.append(identifier);
+ m_sharedDisplayListHandles.set(identifier, WTFMove(newHandle));
+
+ return displayListHandle;
}
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h (269681 => 269682)
--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h 2020-11-11 14:19:46 UTC (rev 269681)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h 2020-11-11 15:06:54 UTC (rev 269682)
@@ -34,6 +34,7 @@
#include "RenderingBackendIdentifier.h"
#include <WebCore/DisplayList.h>
#include <WebCore/RenderingResourceIdentifier.h>
+#include <wtf/Deque.h>
#include <wtf/WeakPtr.h>
namespace WebCore {
@@ -50,6 +51,8 @@
namespace WebKit {
+class DisplayListWriterHandle;
+
class RemoteRenderingBackendProxy
: public IPC::MessageSender
, private IPC::MessageReceiver
@@ -60,7 +63,7 @@
~RemoteRenderingBackendProxy();
RemoteResourceCacheProxy& remoteResourceCacheProxy() { return m_remoteResourceCacheProxy; }
- WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t);
+ WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t capacity, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
// IPC::MessageSender.
IPC::Connection* messageSenderConnection() const override;
@@ -72,7 +75,7 @@
// Messages to be sent.
RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, float resolutionScale, WebCore::ColorSpace);
RefPtr<WebCore::ImageData> getImageData(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect& srcRect, WebCore::RenderingResourceIdentifier);
- void submitDisplayList(const WebCore::DisplayList::DisplayList&, WebCore::RenderingResourceIdentifier);
+ void submitDisplayList(const WebCore::DisplayList::DisplayList&, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
WebCore::DisplayList::FlushIdentifier flushDisplayListAndCommit(const WebCore::DisplayList::DisplayList&, WebCore::RenderingResourceIdentifier);
void releaseRemoteResource(WebCore::RenderingResourceIdentifier);
@@ -82,12 +85,16 @@
private:
RemoteRenderingBackendProxy();
+ void updateReusableHandles();
+
// Messages to be received.
void imageBufferBackendWasCreated(const WebCore::FloatSize& logicalSize, const WebCore::IntSize& backendSize, float resolutionScale, WebCore::ColorSpace, ImageBufferBackendHandle, WebCore::RenderingResourceIdentifier);
void flushDisplayListWasCommitted(WebCore::DisplayList::FlushIdentifier, WebCore::RenderingResourceIdentifier);
RemoteResourceCacheProxy m_remoteResourceCacheProxy;
- HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<SharedMemory>> m_sharedItemBuffers;
+ HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListWriterHandle>> m_sharedDisplayListHandles;
+ Deque<WebCore::DisplayList::ItemBufferIdentifier> m_identifiersOfReusableHandles;
+ HashSet<WebCore::DisplayList::ItemBufferIdentifier> m_identifiersOfHandlesAvailableForWriting;
RenderingBackendIdentifier m_renderingBackendIdentifier { RenderingBackendIdentifier::generate() };
};