Title: [269682] trunk/Source/WebKit
Revision
269682
Author
wenson_hs...@apple.com
Date
2020-11-11 07:06:54 -0800 (Wed, 11 Nov 2020)

Log Message

[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:

Modified Paths

Added Paths

Removed Paths

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() };
 };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to