Title: [284569] branches/safari-613.1.6-branch/Source/WebKit
Revision
284569
Author
[email protected]
Date
2021-10-20 14:32:07 -0700 (Wed, 20 Oct 2021)

Log Message

Revert r284079. rdar://problem/84478842

Modified Paths

Diff

Modified: branches/safari-613.1.6-branch/Source/WebKit/ChangeLog (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/ChangeLog	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/ChangeLog	2021-10-20 21:32:07 UTC (rev 284569)
@@ -1,3 +1,7 @@
+2021-10-20  Alan Coon  <[email protected]>
+
+        Revert r284079. rdar://problem/84478842
+
 2021-10-19  Alan Coon  <[email protected]>
 
         Cherry-pick r284489. rdar://problem/84439180

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-10-20 21:32:07 UTC (rev 284569)
@@ -481,10 +481,10 @@
 }
 #endif
 
-void GPUConnectionToWebProcess::createRenderingBackend(RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
+void GPUConnectionToWebProcess::createRenderingBackend(RemoteRenderingBackendCreationParameters&& creationParameters)
 {
     auto addResult = m_remoteRenderingBackendMap.ensure(creationParameters.identifier, [&]() {
-        return IPC::ScopedActiveMessageReceiveQueue { RemoteRenderingBackend::create(*this, WTFMove(creationParameters), WTFMove(streamBuffer)) };
+        return IPC::ScopedActiveMessageReceiveQueue { RemoteRenderingBackend::create(*this, WTFMove(creationParameters)) };
     });
     ASSERT_UNUSED(addResult, addResult.isNewEntry);
 }

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h	2021-10-20 21:32:07 UTC (rev 284569)
@@ -187,7 +187,7 @@
     RemoteMediaRecorderManager& mediaRecorderManager();
 #endif
 
-    void createRenderingBackend(RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
+    void createRenderingBackend(RemoteRenderingBackendCreationParameters&&);
     void releaseRenderingBackend(RenderingBackendIdentifier);
 
 #if ENABLE(WEBGL)

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in	2021-10-20 21:32:07 UTC (rev 284569)
@@ -23,7 +23,7 @@
 #if ENABLE(GPU_PROCESS)
 
 messages -> GPUConnectionToWebProcess WantsDispatchMessage {
-    void CreateRenderingBackend(struct WebKit::RemoteRenderingBackendCreationParameters creationParameters, IPC::StreamConnectionBuffer streamBuffer)
+    void CreateRenderingBackend(struct WebKit::RemoteRenderingBackendCreationParameters creationParameters)
     void ReleaseRenderingBackend(WebKit::RenderingBackendIdentifier renderingBackendIdentifier)
 #if ENABLE(WEBGL)
     void CreateGraphicsContextGL(struct WebCore::GraphicsContextGLAttributes attributes, WebKit::GraphicsContextGLIdentifier graphicsContextGLIdentifier, WebKit::RenderingBackendIdentifier renderingBackendIdentifier, IPC::StreamConnectionBuffer stream)

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm	2021-10-20 21:32:07 UTC (rev 284569)
@@ -51,7 +51,10 @@
                 continue;
 
             auto stateInfo = adoptNS([[NSMutableDictionary alloc] initWithCapacity:backendMap.size()]);
-            // FIXME: Log some additional diagnostic state on RemoteRenderingBackend.
+            for (auto& identifierAndBackend : backendMap) {
+                auto& [backendIdentifier, backend] = identifierAndBackend;
+                [stateInfo setObject:@(name(backend->lastKnownState())) forKey:backendIdentifier.loggingString()];
+            }
             [webProcessConnectionInfo setObject:stateInfo.get() forKey:webProcessIdentifier.loggingString()];
         }
 

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2021-10-20 21:32:07 UTC (rev 284569)
@@ -55,10 +55,7 @@
 {
     ASSERT(!m_isListeningForIPC);
     m_isListeningForIPC = true;
-    // FIXME: Can we avoid synchronous dispatch here by adjusting the assertion in `Connection::enqueueMatchingMessagesToMessageReceiveQueue`?
-    callOnMainRunLoopAndWait([&] {
-        m_renderingBackend->streamConnection().startReceivingMessages(*this, Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
-    });
+    // FIXME: Not implemented yet.
 }
 
 void RemoteDisplayListRecorder::stopListeningForIPC()
@@ -66,7 +63,7 @@
     if (!m_isListeningForIPC)
         return;
 
-    m_renderingBackend->streamConnection().stopReceivingMessages(Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
+    // FIXME: Not implemented yet.
     m_isListeningForIPC = false;
 }
 

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h	2021-10-20 21:32:07 UTC (rev 284569)
@@ -30,8 +30,6 @@
 #include "Decoder.h"
 #include "GPUConnectionToWebProcess.h"
 #include "Logging.h"
-#include "RemoteDisplayListRecorder.h"
-#include "ScopedActiveMessageReceiveQueue.h"
 #include <WebCore/ConcreteImageBuffer.h>
 #include <WebCore/DisplayList.h>
 #include <WebCore/DisplayListItems.h>
@@ -56,9 +54,8 @@
         : BaseConcreteImageBuffer(parameters, WTFMove(backend), renderingResourceIdentifier.object())
         , m_remoteRenderingBackend(remoteRenderingBackend)
         , m_renderingResourceIdentifier(renderingResourceIdentifier)
-        , m_remoteDisplayList({ RemoteDisplayListRecorder::create(*this, renderingResourceIdentifier, renderingResourceIdentifier.processIdentifier(), remoteRenderingBackend) })
     {
-        m_remoteRenderingBackend.didCreateImageBufferBackend(m_backend->createImageBufferBackendHandle(), renderingResourceIdentifier, *m_remoteDisplayList.get());
+        m_remoteRenderingBackend.didCreateImageBufferBackend(m_backend->createImageBufferBackendHandle(), renderingResourceIdentifier);
     }
 
     ~RemoteImageBuffer()
@@ -80,9 +77,41 @@
 private:
     friend class RemoteRenderingBackend;
 
+    bool apply(WebCore::DisplayList::ItemHandle item, WebCore::GraphicsContext& context)
+    {
+        if (item.is<WebCore::DisplayList::GetPixelBuffer>()) {
+            auto& getPixelBufferItem = item.get<WebCore::DisplayList::GetPixelBuffer>();
+            auto pixelBuffer = BaseConcreteImageBuffer::getPixelBuffer(getPixelBufferItem.outputFormat(), getPixelBufferItem.srcRect());
+            m_remoteRenderingBackend.populateGetPixelBufferSharedMemory(WTFMove(pixelBuffer));
+            return true;
+        }
+
+        if (item.is<WebCore::DisplayList::PutPixelBuffer>()) {
+            auto& putPixelBufferItem = item.get<WebCore::DisplayList::PutPixelBuffer>();
+            putPixelBuffer(putPixelBufferItem.pixelBuffer(), putPixelBufferItem.srcRect(), putPixelBufferItem.destPoint(), putPixelBufferItem.destFormat());
+            return true;
+        }
+
+        if (item.is<WebCore::DisplayList::FlushContext>()) {
+            BaseConcreteImageBuffer::flushContext();
+            auto identifier = item.get<WebCore::DisplayList::FlushContext>().identifier();
+            LOG_WITH_STREAM(SharedDisplayLists, stream << "Acknowledging Flush{" << identifier << "} in Image(" << m_renderingResourceIdentifier << ")");
+            m_remoteRenderingBackend.didFlush(identifier, m_renderingResourceIdentifier);
+            return true;
+        }
+
+        if (item.is<WebCore::DisplayList::MetaCommandChangeItemBuffer>()) {
+            auto nextBufferIdentifier = item.get<WebCore::DisplayList::MetaCommandChangeItemBuffer>().identifier();
+            LOG_WITH_STREAM(SharedDisplayLists, stream << "Switching to Items[" << nextBufferIdentifier << "]");
+            m_remoteRenderingBackend.setNextItemBufferToRead(nextBufferIdentifier, m_renderingResourceIdentifier);
+            return true;
+        }
+
+        return m_remoteRenderingBackend.applyMediaItem(item, context);
+    }
+
     RemoteRenderingBackend& m_remoteRenderingBackend;
     QualifiedRenderingResourceIdentifier m_renderingResourceIdentifier;
-    IPC::ScopedActiveMessageReceiveQueue<RemoteDisplayListRecorder> m_remoteDisplayList;
 };
 
 } // namespace WebKit

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2021-10-20 21:32:07 UTC (rev 284569)
@@ -28,6 +28,7 @@
 
 #if ENABLE(GPU_PROCESS)
 
+#include "DisplayListReaderHandle.h"
 #include "GPUConnectionToWebProcess.h"
 #include "Logging.h"
 #include "PlatformRemoteImageBuffer.h"
@@ -72,27 +73,26 @@
 namespace WebKit {
 using namespace WebCore;
 
-Ref<RemoteRenderingBackend> RemoteRenderingBackend::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
+Ref<RemoteRenderingBackend> RemoteRenderingBackend::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters)
 {
-    auto instance = adoptRef(*new RemoteRenderingBackend(gpuConnectionToWebProcess, WTFMove(creationParameters), WTFMove(streamBuffer)));
+    auto instance = adoptRef(*new RemoteRenderingBackend(gpuConnectionToWebProcess, WTFMove(creationParameters)));
     instance->startListeningForIPC();
     return instance;
 }
 
-RemoteRenderingBackend::RemoteRenderingBackend(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
-    : m_workQueue("RemoteRenderingBackend work queue")
-    , m_streamConnection(IPC::StreamServerConnection::create(gpuConnectionToWebProcess.connection(), WTFMove(streamBuffer), m_workQueue))
+RemoteRenderingBackend::RemoteRenderingBackend(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters)
+    : m_workQueue(WorkQueue::create("RemoteRenderingBackend work queue", WorkQueue::Type::Serial, WorkQueue::QOS::UserInteractive))
     , m_remoteResourceCache(gpuConnectionToWebProcess.webProcessIdentifier())
     , m_gpuConnectionToWebProcess(gpuConnectionToWebProcess)
     , m_renderingBackendIdentifier(creationParameters.identifier)
+    , m_resumeDisplayListSemaphore(WTFMove(creationParameters.resumeDisplayListSemaphore))
 {
     ASSERT(RunLoop::isMain());
-    send(Messages::RemoteRenderingBackendProxy::DidCreateWakeUpSemaphoreForDisplayListStream(m_workQueue.wakeUpSemaphore()), m_renderingBackendIdentifier);
 }
 
 void RemoteRenderingBackend::startListeningForIPC()
 {
-    m_streamConnection->startReceivingMessages(*this, Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
+    m_gpuConnectionToWebProcess->connection().addWorkQueueMessageReceiver(Messages::RemoteRenderingBackend::messageReceiverName(), m_workQueue, this, m_renderingBackendIdentifier.toUInt64());
 }
 
 RemoteRenderingBackend::~RemoteRenderingBackend()
@@ -99,20 +99,21 @@
 {
     // Make sure we destroy the ResourceCache on the WorkQueue since it gets populated on the WorkQueue.
     // Make sure rendering resource request is released after destroying the cache.
-    m_workQueue.dispatch([renderingResourcesRequest = WTFMove(m_renderingResourcesRequest), remoteResourceCache = WTFMove(m_remoteResourceCache)] { });
+    m_workQueue->dispatch([renderingResourcesRequest = WTFMove(m_renderingResourcesRequest), remoteResourceCache = WTFMove(m_remoteResourceCache)] { });
 }
 
 void RemoteRenderingBackend::stopListeningForIPC()
 {
     ASSERT(RunLoop::isMain());
-    m_streamConnection->stopReceivingMessages(Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
-    for (auto& remoteContext : std::exchange(m_remoteDisplayLists, { }))
-        remoteContext.stopListeningForIPC();
+
+    // The RemoteRenderingBackend destructor won't be called until disconnect() is called and we unregister ourselves as a WorkQueueMessageReceiver because
+    // the IPC::Connection refs its WorkQueueMessageReceivers.
+    m_gpuConnectionToWebProcess->connection().removeWorkQueueMessageReceiver(Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
 }
 
 void RemoteRenderingBackend::dispatch(Function<void()>&& task)
 {
-    m_workQueue.dispatch(WTFMove(task));
+    m_workQueue->dispatch(WTFMove(task));
 }
 
 IPC::Connection* RemoteRenderingBackend::messageSenderConnection() const
@@ -125,9 +126,26 @@
     return m_renderingBackendIdentifier.toUInt64();
 }
 
-void RemoteRenderingBackend::didCreateImageBufferBackend(ImageBufferBackendHandle handle, QualifiedRenderingResourceIdentifier renderingResourceIdentifier, RemoteDisplayListRecorder& remoteDisplayList)
+bool RemoteRenderingBackend::applyMediaItem(DisplayList::ItemHandle item, GraphicsContext& context)
 {
-    m_remoteDisplayLists.add(remoteDisplayList);
+    ASSERT(!RunLoop::isMain());
+
+    if (!item.is<DisplayList::PaintFrameForMedia>())
+        return false;
+
+    auto& mediaItem = item.get<DisplayList::PaintFrameForMedia>();
+    callOnMainRunLoopAndWait([&, gpuConnectionToWebProcess = m_gpuConnectionToWebProcess, mediaPlayerIdentifier = mediaItem.identifier()] {
+        auto player = gpuConnectionToWebProcess->remoteMediaPlayerManagerProxy().mediaPlayer(mediaPlayerIdentifier);
+        if (!player)
+            return;
+        // It is currently not safe to call paintFrameForMedia() off the main thread.
+        context.paintFrameForMedia(*player, mediaItem.destination());
+    });
+    return true;
+}
+
+void RemoteRenderingBackend::didCreateImageBufferBackend(ImageBufferBackendHandle handle, QualifiedRenderingResourceIdentifier renderingResourceIdentifier)
+{
     MESSAGE_CHECK(renderingResourceIdentifier.processIdentifier() == m_gpuConnectionToWebProcess->webProcessIdentifier(), "Sending didCreateImageBufferBackend() message to the wrong web process.");
     send(Messages::RemoteRenderingBackendProxy::DidCreateImageBufferBackend(WTFMove(handle), renderingResourceIdentifier.object()), m_renderingBackendIdentifier);
 }
@@ -172,8 +190,215 @@
 
     m_remoteResourceCache.cacheImageBuffer(*imageBuffer, imageBufferResourceIdentifier);
     updateRenderingResourceRequest();
+
+    if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(imageBufferResourceIdentifier))
+        resumeFromPendingWakeupInformation();
 }
 
+RemoteRenderingBackend::ReplayerDelegate::ReplayerDelegate(WebCore::ImageBuffer& destination, RemoteRenderingBackend& remoteRenderingBackend, ProcessIdentifier webProcessIdentifier)
+    : m_destination(destination)
+    , m_remoteRenderingBackend(remoteRenderingBackend)
+    , m_webProcessIdentifier(webProcessIdentifier)
+{
+}
+
+bool RemoteRenderingBackend::ReplayerDelegate::apply(WebCore::DisplayList::ItemHandle item, WebCore::GraphicsContext& graphicsContext)
+{
+    auto apply = [&](auto&& destination) {
+        return destination.apply(item, graphicsContext);
+    };
+
+    if (m_destination.renderingMode() == RenderingMode::Accelerated)
+        return apply(static_cast<AcceleratedRemoteImageBuffer&>(m_destination));
+    return apply(static_cast<UnacceleratedRemoteImageBuffer&>(m_destination));
+}
+
+void RemoteRenderingBackend::ReplayerDelegate::didCreateMaskImageBuffer(WebCore::ImageBuffer& imageBuffer)
+{
+    m_remoteRenderingBackend.didCreateMaskImageBuffer(imageBuffer);
+}
+
+void RemoteRenderingBackend::ReplayerDelegate::didResetMaskImageBuffer()
+{
+    m_remoteRenderingBackend.didResetMaskImageBuffer();
+}
+
+void RemoteRenderingBackend::ReplayerDelegate::recordResourceUse(RenderingResourceIdentifier renderingResourceIdentifier)
+{
+    m_remoteRenderingBackend.remoteResourceCache().recordResourceUse({ renderingResourceIdentifier, m_webProcessIdentifier });
+}
+
+DisplayList::ReplayResult RemoteRenderingBackend::submit(const DisplayList::DisplayList& displayList, ImageBuffer& destination)
+{
+    if (displayList.isEmpty())
+        return { };
+
+    ReplayerDelegate replayerDelegate(destination, *this, m_gpuConnectionToWebProcess->webProcessIdentifier());
+
+    return WebCore::DisplayList::Replayer {
+        destination.context(),
+        displayList,
+        &remoteResourceCache().resourceHeap(),
+        m_currentMaskImageBuffer.get(),
+        &replayerDelegate
+    }.replay();
+}
+
+RefPtr<ImageBuffer> RemoteRenderingBackend::nextDestinationImageBufferAfterApplyingDisplayLists(ImageBuffer& initialDestination, size_t initialOffset, DisplayListReaderHandle& handle, GPUProcessWakeupReason reason, ProcessIdentifier webProcessIdentifier)
+{
+    RefPtr destination { &initialDestination };
+    Ref handleProtector { handle };
+
+    auto offset = initialOffset;
+    size_t sizeToRead = 0;
+    do {
+        sizeToRead = handle.unreadBytes();
+    } while (!sizeToRead);
+
+    while (destination) {
+        auto displayList = handle.displayListForReading(offset, sizeToRead, *this);
+        MESSAGE_CHECK_WITH_RETURN_VALUE(displayList, nullptr, "Failed to map display list from shared memory");
+
+#if !LOG_DISABLED
+        auto startTime = MonotonicTime::now();
+#endif
+        auto result = submit(*displayList, *destination);
+        LOG_WITH_STREAM(SharedDisplayLists, stream << "Read [" << offset << ", " << offset + result.numberOfBytesRead << "]; Items[" << handle.identifier() << "] => Image(" << destination->renderingResourceIdentifier() << ") in " << MonotonicTime::now() - startTime);
+        MESSAGE_CHECK_WITH_RETURN_VALUE(result.reasonForStopping != DisplayList::StopReplayReason::InvalidItemOrExtent, nullptr, "Detected invalid display list item or extent");
+        MESSAGE_CHECK_WITH_RETURN_VALUE(result.reasonForStopping != DisplayList::StopReplayReason::OutOfMemory, nullptr, "Cound not allocate memory");
+
+        auto advanceResult = handle.advance(result.numberOfBytesRead);
+        MESSAGE_CHECK_WITH_RETURN_VALUE(advanceResult, nullptr, "Failed to advance display list reader handle");
+        sizeToRead = *advanceResult;
+
+        CheckedSize checkedOffset = offset;
+        checkedOffset += result.numberOfBytesRead;
+        MESSAGE_CHECK_WITH_RETURN_VALUE(!checkedOffset.hasOverflowed(), nullptr, "Overflowed when advancing shared display list handle offset");
+
+        offset = checkedOffset;
+        MESSAGE_CHECK_WITH_RETURN_VALUE(offset <= handle.sharedMemory().size(), nullptr, "Out-of-bounds offset into shared display list handle");
+
+        if (result.reasonForStopping == DisplayList::StopReplayReason::ChangeDestinationImageBuffer) {
+            destination = m_remoteResourceCache.cachedImageBuffer({ *result.nextDestinationImageBuffer, m_gpuConnectionToWebProcess->webProcessIdentifier() });
+            if (!destination) {
+                ASSERT(!m_pendingWakeupInfo);
+                m_pendingWakeupInfo = {{
+                    handle.identifier(),
+                    offset,
+                    { *result.nextDestinationImageBuffer, webProcessIdentifier },
+                    reason,
+                    std::nullopt,
+                    RemoteRenderingBackendState::WaitingForDestinationImageBuffer
+                }};
+            }
+        }
+
+        if (result.reasonForStopping == DisplayList::StopReplayReason::MissingCachedResource) {
+            m_pendingWakeupInfo = {{
+                handle.identifier(),
+                offset,
+                { destination->renderingResourceIdentifier(), webProcessIdentifier },
+                reason,
+                { { *result.missingCachedResourceIdentifier, webProcessIdentifier } },
+                RemoteRenderingBackendState::WaitingForCachedResource
+            }};
+        }
+
+        if (m_pendingWakeupInfo)
+            break;
+
+        if (!sizeToRead) {
+            if (reason != GPUProcessWakeupReason::ItemCountHysteresisExceeded)
+                break;
+
+            handle.startWaiting();
+            m_resumeDisplayListSemaphore.waitFor(30_us);
+
+            auto stopWaitingResult = handle.stopWaiting();
+            MESSAGE_CHECK_WITH_RETURN_VALUE(stopWaitingResult, nullptr, "Invalid waiting status detected when resuming display list processing");
+
+            auto resumeReadingInfo = stopWaitingResult.value();
+            if (!resumeReadingInfo)
+                break;
+
+            sizeToRead = handle.unreadBytes();
+            MESSAGE_CHECK_WITH_RETURN_VALUE(sizeToRead, nullptr, "No unread bytes when resuming display list processing");
+
+            auto newDestinationIdentifier = makeObjectIdentifier<RenderingResourceIdentifierType>(resumeReadingInfo->destination);
+            MESSAGE_CHECK_WITH_RETURN_VALUE(newDestinationIdentifier.isValid(), nullptr, "Invalid image buffer destination when resuming display list processing");
+
+            destination = m_remoteResourceCache.cachedImageBuffer({ newDestinationIdentifier, m_gpuConnectionToWebProcess->webProcessIdentifier() });
+            MESSAGE_CHECK_WITH_RETURN_VALUE(destination, nullptr, "Missing image buffer destination when resuming display list processing");
+
+            offset = resumeReadingInfo->offset;
+        }
+    }
+
+    return destination;
+}
+
+void RemoteRenderingBackend::wakeUpAndApplyDisplayList(const GPUProcessWakeupMessageArguments& arguments)
+{
+    // Immediately turn the RenderingResourceIdentifier (which is error-prone) to a QualifiedRenderingResourceIdentifier,
+    // and use a helper function to make sure that don't accidentally use the RenderingResourceIdentifier (because the helper function can't see it).
+    wakeUpAndApplyDisplayListWithQualifiedIdentifier(arguments.itemBufferIdentifier, arguments.offset, { arguments.destinationImageBufferIdentifier, m_gpuConnectionToWebProcess->webProcessIdentifier() }, arguments.reason);
+}
+
+void RemoteRenderingBackend::wakeUpAndApplyDisplayListWithQualifiedIdentifier(WebCore::DisplayList::ItemBufferIdentifier itemBufferIdentifier, uint64_t offset, QualifiedRenderingResourceIdentifier destinationImageBufferIdentifier, GPUProcessWakeupReason reason)
+{
+    ASSERT(!RunLoop::isMain());
+
+    TraceScope tracingScope(WakeUpAndApplyDisplayListStart, WakeUpAndApplyDisplayListEnd);
+
+    updateLastKnownState(RemoteRenderingBackendState::BeganReplayingDisplayList);
+
+    RefPtr destinationImageBuffer = m_remoteResourceCache.cachedImageBuffer(destinationImageBufferIdentifier);
+    MESSAGE_CHECK(destinationImageBuffer, "Missing destination image buffer");
+
+    auto initialHandle = m_sharedDisplayListHandles.get(itemBufferIdentifier);
+    MESSAGE_CHECK(initialHandle, "Missing initial shared display list handle");
+
+    LOG_WITH_STREAM(SharedDisplayLists, stream << "Waking up to Items[" << itemBufferIdentifier << "] => Image(" << destinationImageBufferIdentifier.object() << ") at " << offset);
+    destinationImageBuffer = nextDestinationImageBufferAfterApplyingDisplayLists(*destinationImageBuffer, offset, *initialHandle, reason, m_gpuConnectionToWebProcess->webProcessIdentifier());
+
+    // FIXME: All the callers pass m_pendingWakeupInfo's fields so the body of this function should just be this loop.
+    while (destinationImageBuffer && m_pendingWakeupInfo) {
+        if (m_pendingWakeupInfo->missingCachedResourceIdentifier)
+            break;
+
+        auto nextHandle = m_sharedDisplayListHandles.get(m_pendingWakeupInfo->itemBufferIdentifier);
+        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.
+        auto offset = m_pendingWakeupInfo->offset;
+        auto reason = m_pendingWakeupInfo->reason;
+        m_pendingWakeupInfo = std::nullopt;
+        destinationImageBuffer = nextDestinationImageBufferAfterApplyingDisplayLists(*destinationImageBuffer, offset, *nextHandle, reason, m_gpuConnectionToWebProcess->webProcessIdentifier());
+    }
+    LOG_WITH_STREAM(SharedDisplayLists, stream << "Going back to sleep.");
+
+    if (m_pendingWakeupInfo)
+        updateLastKnownState(m_pendingWakeupInfo->state);
+    else
+        updateLastKnownState(RemoteRenderingBackendState::FinishedReplayingDisplayList);
+}
+
+void RemoteRenderingBackend::setNextItemBufferToRead(DisplayList::ItemBufferIdentifier identifier, QualifiedRenderingResourceIdentifier destinationIdentifier)
+{
+    m_pendingWakeupInfo = {{
+        identifier,
+        SharedDisplayListHandle::headerSize(),
+        destinationIdentifier,
+        GPUProcessWakeupReason::Unspecified,
+        std::nullopt,
+        RemoteRenderingBackendState::WaitingForItemBuffer
+    }};
+}
+
 std::optional<SharedMemory::IPCHandle> RemoteRenderingBackend::updateSharedMemoryForGetPixelBufferHelper(size_t byteCount)
 {
     MESSAGE_CHECK_WITH_RETURN_VALUE(!m_getPixelBufferSharedMemory || byteCount > m_getPixelBufferSharedMemory->size(), std::nullopt, "The existing Shmem for getPixelBuffer() is already big enough to handle the request");
@@ -322,6 +547,9 @@
         return;
 
     m_remoteResourceCache.cacheNativeImage(*image, nativeImageResourceIdentifier);
+
+    if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(nativeImageResourceIdentifier))
+        resumeFromPendingWakeupInformation();
 }
 
 void RemoteRenderingBackend::cacheFont(Ref<WebCore::Font>&& font)
@@ -337,6 +565,8 @@
     ASSERT(!RunLoop::isMain());
 
     m_remoteResourceCache.cacheFont(WTFMove(font), fontResourceIdentifier);
+    if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(fontResourceIdentifier))
+        resumeFromPendingWakeupInformation();
 }
 
 void RemoteRenderingBackend::deleteAllFonts()
@@ -362,9 +592,169 @@
 
 void RemoteRenderingBackend::finalizeRenderingUpdate(RenderingUpdateID renderingUpdateID)
 {
+    auto shouldPerformWakeup = [&] {
+        return m_remoteResourceCache.cachedImageBuffer(m_pendingWakeupInfo->destinationImageBufferIdentifier) && m_sharedDisplayListHandles.contains(m_pendingWakeupInfo->itemBufferIdentifier);
+    };
+
+    if (m_pendingWakeupInfo && shouldPerformWakeup())
+        resumeFromPendingWakeupInformation();
+
     send(Messages::RemoteRenderingBackendProxy::DidFinalizeRenderingUpdate(renderingUpdateID), m_renderingBackendIdentifier);
 }
 
+void RemoteRenderingBackend::didCreateSharedDisplayListHandle(DisplayList::ItemBufferIdentifier itemBufferIdentifier, const SharedMemory::IPCHandle& handle, RenderingResourceIdentifier destinationBufferIdentifier)
+{
+    // Immediately turn the RenderingResourceIdentifier (which is error-prone) to a QualifiedRenderingResourceIdentifier,
+    // and use a helper function to make sure that don't accidentally use the RenderingResourceIdentifier (because the helper function can't see it).
+    didCreateSharedDisplayListHandleWithQualifiedIdentifier(itemBufferIdentifier, handle, { destinationBufferIdentifier, m_gpuConnectionToWebProcess->webProcessIdentifier() });
+}
+
+void RemoteRenderingBackend::didCreateSharedDisplayListHandleWithQualifiedIdentifier(DisplayList::ItemBufferIdentifier itemBufferIdentifier, const SharedMemory::IPCHandle& handle, QualifiedRenderingResourceIdentifier)
+{
+    ASSERT(!RunLoop::isMain());
+    MESSAGE_CHECK(!m_sharedDisplayListHandles.contains(itemBufferIdentifier), "Duplicate shared display list handle");
+
+    if (auto sharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadWrite)) {
+        auto handle = DisplayListReaderHandle::create(itemBufferIdentifier, sharedMemory.releaseNonNull());
+        MESSAGE_CHECK(handle, "There must be enough space to create the handle.");
+        m_sharedDisplayListHandles.set(itemBufferIdentifier, handle);
+    }
+
+    if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(itemBufferIdentifier))
+        resumeFromPendingWakeupInformation();
+}
+
+void RemoteRenderingBackend::resumeFromPendingWakeupInformation()
+{
+    auto itemBufferIdentifier = m_pendingWakeupInfo->itemBufferIdentifier;
+    auto offset = m_pendingWakeupInfo->offset;
+    auto destinationImageBufferIdentifier = m_pendingWakeupInfo->destinationImageBufferIdentifier;
+    auto reason = m_pendingWakeupInfo->reason;
+    m_pendingWakeupInfo = std::nullopt;
+    wakeUpAndApplyDisplayListWithQualifiedIdentifier(itemBufferIdentifier, offset, destinationImageBufferIdentifier, reason);
+}
+
+void RemoteRenderingBackend::didCreateMaskImageBuffer(ImageBuffer& imageBuffer)
+{
+    ASSERT(!RunLoop::isMain());
+    MESSAGE_CHECK(!m_currentMaskImageBuffer, "Current mask image buffer is already set.");
+    m_currentMaskImageBuffer = &imageBuffer;
+}
+
+void RemoteRenderingBackend::didResetMaskImageBuffer()
+{
+    ASSERT(!RunLoop::isMain());
+    MESSAGE_CHECK(m_currentMaskImageBuffer, "Current mask image buffer was not already set.");
+    m_currentMaskImageBuffer = nullptr;
+}
+
+std::optional<DisplayList::ItemHandle> WARN_UNUSED_RETURN RemoteRenderingBackend::decodeItem(const uint8_t* data, size_t length, DisplayList::ItemType type, uint8_t* handleLocation)
+{
+    /* This needs to match (1) isInlineItem() in DisplayListItemType.cpp, (2) RemoteImageBufferProxy::encodeItem(),
+     * and (3) all the "static constexpr bool isInlineItem"s inside the individual item classes.
+     * See the comment at the top of DisplayListItems.h for why. */
+
+    switch (type) {
+    case DisplayList::ItemType::BeginClipToDrawingCommands:
+        return decodeAndCreate<DisplayList::BeginClipToDrawingCommands>(data, length, handleLocation);
+    case DisplayList::ItemType::ClipOutToPath:
+        return decodeAndCreate<DisplayList::ClipOutToPath>(data, length, handleLocation);
+    case DisplayList::ItemType::ClipPath:
+        return decodeAndCreate<DisplayList::ClipPath>(data, length, handleLocation);
+    case DisplayList::ItemType::DrawFocusRingPath:
+        return decodeAndCreate<DisplayList::DrawFocusRingPath>(data, length, handleLocation);
+    case DisplayList::ItemType::DrawFocusRingRects:
+        return decodeAndCreate<DisplayList::DrawFocusRingRects>(data, length, handleLocation);
+    case DisplayList::ItemType::DrawGlyphs:
+        return decodeAndCreate<DisplayList::DrawGlyphs>(data, length, handleLocation);
+    case DisplayList::ItemType::DrawLinesForText:
+        return decodeAndCreate<DisplayList::DrawLinesForText>(data, length, handleLocation);
+    case DisplayList::ItemType::DrawPath:
+        return decodeAndCreate<DisplayList::DrawPath>(data, length, handleLocation);
+    case DisplayList::ItemType::FillCompositedRect:
+        return decodeAndCreate<DisplayList::FillCompositedRect>(data, length, handleLocation);
+    case DisplayList::ItemType::FillPath:
+        return decodeAndCreate<DisplayList::FillPath>(data, length, handleLocation);
+    case DisplayList::ItemType::FillRectWithColor:
+        return decodeAndCreate<DisplayList::FillRectWithColor>(data, length, handleLocation);
+    case DisplayList::ItemType::FillRectWithGradient:
+        return decodeAndCreate<DisplayList::FillRectWithGradient>(data, length, handleLocation);
+    case DisplayList::ItemType::FillRectWithRoundedHole:
+        return decodeAndCreate<DisplayList::FillRectWithRoundedHole>(data, length, handleLocation);
+    case DisplayList::ItemType::FillRoundedRect:
+        return decodeAndCreate<DisplayList::FillRoundedRect>(data, length, handleLocation);
+    case DisplayList::ItemType::GetPixelBuffer:
+        return decodeAndCreate<DisplayList::GetPixelBuffer>(data, length, handleLocation);
+    case DisplayList::ItemType::PutPixelBuffer:
+        return decodeAndCreate<DisplayList::PutPixelBuffer>(data, length, handleLocation);
+    case DisplayList::ItemType::SetLineDash:
+        return decodeAndCreate<DisplayList::SetLineDash>(data, length, handleLocation);
+    case DisplayList::ItemType::SetState:
+        return decodeAndCreate<DisplayList::SetState>(data, length, handleLocation);
+    case DisplayList::ItemType::StrokePath:
+        return decodeAndCreate<DisplayList::StrokePath>(data, length, handleLocation);
+    case DisplayList::ItemType::ApplyDeviceScaleFactor:
+#if USE(CG)
+    case DisplayList::ItemType::ApplyFillPattern:
+    case DisplayList::ItemType::ApplyStrokePattern:
+#endif
+    case DisplayList::ItemType::BeginTransparencyLayer:
+    case DisplayList::ItemType::ClearRect:
+    case DisplayList::ItemType::ClearShadow:
+    case DisplayList::ItemType::Clip:
+    case DisplayList::ItemType::ClipOut:
+    case DisplayList::ItemType::ClipToImageBuffer:
+    case DisplayList::ItemType::EndClipToDrawingCommands:
+    case DisplayList::ItemType::ConcatenateCTM:
+    case DisplayList::ItemType::DrawDotsForDocumentMarker:
+    case DisplayList::ItemType::DrawEllipse:
+    case DisplayList::ItemType::DrawImageBuffer:
+    case DisplayList::ItemType::DrawNativeImage:
+    case DisplayList::ItemType::DrawPattern:
+    case DisplayList::ItemType::DrawLine:
+    case DisplayList::ItemType::DrawRect:
+    case DisplayList::ItemType::EndTransparencyLayer:
+    case DisplayList::ItemType::FillEllipse:
+#if ENABLE(INLINE_PATH_DATA)
+    case DisplayList::ItemType::FillLine:
+    case DisplayList::ItemType::FillArc:
+    case DisplayList::ItemType::FillQuadCurve:
+    case DisplayList::ItemType::FillBezierCurve:
+#endif
+    case DisplayList::ItemType::FillRect:
+    case DisplayList::ItemType::FlushContext:
+    case DisplayList::ItemType::MetaCommandChangeDestinationImageBuffer:
+    case DisplayList::ItemType::MetaCommandChangeItemBuffer:
+#if ENABLE(VIDEO)
+    case DisplayList::ItemType::PaintFrameForMedia:
+#endif
+    case DisplayList::ItemType::Restore:
+    case DisplayList::ItemType::Rotate:
+    case DisplayList::ItemType::Save:
+    case DisplayList::ItemType::Scale:
+    case DisplayList::ItemType::SetCTM:
+    case DisplayList::ItemType::SetInlineFillColor:
+    case DisplayList::ItemType::SetInlineStrokeColor:
+    case DisplayList::ItemType::SetLineCap:
+    case DisplayList::ItemType::SetLineJoin:
+    case DisplayList::ItemType::SetMiterLimit:
+    case DisplayList::ItemType::SetStrokeThickness:
+    case DisplayList::ItemType::StrokeEllipse:
+#if ENABLE(INLINE_PATH_DATA)
+    case DisplayList::ItemType::StrokeArc:
+    case DisplayList::ItemType::StrokeQuadCurve:
+    case DisplayList::ItemType::StrokeBezierCurve:
+#endif
+    case DisplayList::ItemType::StrokeRect:
+    case DisplayList::ItemType::StrokeLine:
+    case DisplayList::ItemType::Translate:
+        ASSERT_NOT_REACHED();
+        return std::nullopt;
+    }
+    ASSERT_NOT_REACHED();
+    return std::nullopt;
+}
+
 void RemoteRenderingBackend::updateRenderingResourceRequest()
 {
     bool hasActiveDrawables = m_remoteResourceCache.hasActiveDrawables();
@@ -381,6 +771,18 @@
     return !m_remoteResourceCache.hasActiveDrawables();
 }
 
+RemoteRenderingBackendState RemoteRenderingBackend::lastKnownState() const
+{
+    ASSERT(RunLoop::isMain());
+    return m_lastKnownState.load();
+}
+
+void RemoteRenderingBackend::updateLastKnownState(RemoteRenderingBackendState state)
+{
+    ASSERT(!RunLoop::isMain());
+    m_lastKnownState.storeRelaxed(state);
+}
+
 void RemoteRenderingBackend::performWithMediaPlayerOnMainThread(MediaPlayerIdentifier identifier, Function<void(MediaPlayer&)>&& callback)
 {
     callOnMainRunLoopAndWait([&, gpuConnectionToWebProcess = m_gpuConnectionToWebProcess, identifier] {

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h	2021-10-20 21:32:07 UTC (rev 284569)
@@ -28,20 +28,17 @@
 #if ENABLE(GPU_PROCESS)
 
 #include "Connection.h"
+#include "GPUProcessWakeupMessageArguments.h"
 #include "IPCSemaphore.h"
 #include "ImageBufferBackendHandle.h"
 #include "MessageReceiver.h"
 #include "MessageSender.h"
 #include "QualifiedRenderingResourceIdentifier.h"
-#include "RemoteDisplayListRecorder.h"
 #include "RemoteRenderingBackendState.h"
 #include "RemoteResourceCache.h"
 #include "RenderingBackendIdentifier.h"
 #include "RenderingUpdateID.h"
 #include "ScopedRenderingResourcesRequest.h"
-#include "StreamConnectionWorkQueue.h"
-#include "StreamMessageReceiver.h"
-#include "StreamServerConnection.h"
 #include <WebCore/ColorSpace.h>
 #include <WebCore/DisplayList.h>
 #include <WebCore/DisplayListItems.h>
@@ -51,6 +48,11 @@
 
 namespace WebCore {
 
+namespace DisplayList {
+class DisplayList;
+class Item;
+}
+
 class DestinationColorSpace;
 class FloatSize;
 class NativeImage;
@@ -61,24 +63,34 @@
 
 namespace WebKit {
 
+class DisplayListReaderHandle;
 class GPUConnectionToWebProcess;
-class RemoteDisplayListRecorder;
 struct RemoteRenderingBackendCreationParameters;
 
-class RemoteRenderingBackend : private IPC::MessageSender, public IPC::StreamMessageReceiver {
+class RemoteRenderingBackend
+    : private IPC::MessageSender
+    , public IPC::Connection::WorkQueueMessageReceiver
+    , public WebCore::DisplayList::ItemBufferReadingClient {
 public:
-    static Ref<RemoteRenderingBackend> create(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
+
+    static Ref<RemoteRenderingBackend> create(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&);
     virtual ~RemoteRenderingBackend();
     void stopListeningForIPC();
 
     RemoteResourceCache& remoteResourceCache() { return m_remoteResourceCache; }
 
-    void didReceiveStreamMessage(IPC::StreamServerConnectionBase&, IPC::Decoder&) final;
+    // Rendering operations.
+    bool applyMediaItem(WebCore::DisplayList::ItemHandle, WebCore::GraphicsContext&);
 
     // Messages to be sent.
-    void didCreateImageBufferBackend(ImageBufferBackendHandle, QualifiedRenderingResourceIdentifier, RemoteDisplayListRecorder&);
+    void didCreateImageBufferBackend(ImageBufferBackendHandle, QualifiedRenderingResourceIdentifier);
     void didFlush(WebCore::GraphicsContextFlushIdentifier, QualifiedRenderingResourceIdentifier);
 
+    void setNextItemBufferToRead(WebCore::DisplayList::ItemBufferIdentifier, QualifiedRenderingResourceIdentifier destination);
+
+    void didCreateMaskImageBuffer(WebCore::ImageBuffer&);
+    void didResetMaskImageBuffer();
+
     void populateGetPixelBufferSharedMemory(std::optional<WebCore::PixelBuffer>&&);
 
     bool allowsExitUnderMemoryPressure() const;
@@ -86,22 +98,47 @@
     // Runs Function in RemoteRenderingBackend task queue.
     void dispatch(Function<void()>&&);
 
-    IPC::StreamServerConnection& streamConnection() const { return m_streamConnection.get(); }
+    RemoteRenderingBackendState lastKnownState() const;
+
     void performWithMediaPlayerOnMainThread(WebCore::MediaPlayerIdentifier, Function<void(WebCore::MediaPlayer&)>&&);
 
 private:
-    RemoteRenderingBackend(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
+    RemoteRenderingBackend(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&);
     void startListeningForIPC();
 
+    std::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>
+    std::optional<WebCore::DisplayList::ItemHandle> WARN_UNUSED_RETURN decodeAndCreate(const uint8_t* data, size_t length, uint8_t* handleLocation)
+    {
+        if (auto item = IPC::Decoder::decodeSingleObject<T>(data, length)) {
+            // FIXME: WebKit2 should not need to know that the first 8 bytes at the handle are reserved for the type.
+            // Need to figure out a way to keep this knowledge within display list code in WebCore.
+            new (handleLocation + sizeof(uint64_t)) T(WTFMove(*item));
+            return {{ handleLocation }};
+        }
+        return std::nullopt;
+    }
+
+    WebCore::DisplayList::ReplayResult submit(const WebCore::DisplayList::DisplayList&, WebCore::ImageBuffer& destination);
+    RefPtr<WebCore::ImageBuffer> nextDestinationImageBufferAfterApplyingDisplayLists(WebCore::ImageBuffer& initialDestination, size_t initialOffset, DisplayListReaderHandle&, GPUProcessWakeupReason, WebCore::ProcessIdentifier webProcessIdentifier);
+
     std::optional<SharedMemory::IPCHandle> updateSharedMemoryForGetPixelBufferHelper(size_t byteCount);
     void updateRenderingResourceRequest();
 
+    void updateLastKnownState(RemoteRenderingBackendState);
+
     // IPC::MessageSender.
     IPC::Connection* messageSenderConnection() const override;
     uint64_t messageSenderDestinationID() const override;
 
+    // IPC::MessageReceiver
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) override;
+
     // Messages to be received.
     void createImageBuffer(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, WebCore::RenderingResourceIdentifier);
+    void wakeUpAndApplyDisplayList(const GPUProcessWakeupMessageArguments&);
     void updateSharedMemoryForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&)>&&);
     void semaphoreForGetPixelBuffer(CompletionHandler<void(const IPC::Semaphore&)>&&);
     void updateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&, const IPC::Semaphore&)>&&);
@@ -114,8 +151,10 @@
     void deleteAllFonts();
     void releaseRemoteResource(WebCore::RenderingResourceIdentifier, uint64_t useCount);
     void finalizeRenderingUpdate(RenderingUpdateID);
+    void didCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier, const SharedMemory::IPCHandle&, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
 
     // Received messages translated to use QualifiedRenderingResourceIdentifier.
+    void wakeUpAndApplyDisplayListWithQualifiedIdentifier(WebCore::DisplayList::ItemBufferIdentifier, uint64_t offset, QualifiedRenderingResourceIdentifier, GPUProcessWakeupReason);
     void createImageBufferWithQualifiedIdentifier(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, QualifiedRenderingResourceIdentifier);
     void getDataURLForImageBufferWithQualifiedIdentifier(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, QualifiedRenderingResourceIdentifier, CompletionHandler<void(String&&)>&&);
     void getDataForImageBufferWithQualifiedIdentifier(const String& mimeType, std::optional<double> quality, QualifiedRenderingResourceIdentifier, CompletionHandler<void(Vector<uint8_t>&&)>&&);
@@ -125,15 +164,55 @@
     void releaseRemoteResourceWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier, uint64_t useCount);
     void cacheFontWithQualifiedIdentifier(Ref<WebCore::Font>&&, QualifiedRenderingResourceIdentifier);
 
-    IPC::StreamConnectionWorkQueue m_workQueue;
-    Ref<IPC::StreamServerConnection> m_streamConnection;
+    void resumeFromPendingWakeupInformation();
+
+    class ReplayerDelegate : public WebCore::DisplayList::Replayer::Delegate {
+    public:
+        ReplayerDelegate(WebCore::ImageBuffer&, RemoteRenderingBackend&, WebCore::ProcessIdentifier webProcessIdentifier);
+
+    private:
+        bool apply(WebCore::DisplayList::ItemHandle, WebCore::GraphicsContext&) final;
+        void didCreateMaskImageBuffer(WebCore::ImageBuffer&) final;
+        void didResetMaskImageBuffer() final;
+        void recordResourceUse(WebCore::RenderingResourceIdentifier) final;
+
+        WebCore::ImageBuffer& m_destination;
+        RemoteRenderingBackend& m_remoteRenderingBackend;
+        WebCore::ProcessIdentifier m_webProcessIdentifier;
+    };
+
+    struct PendingWakeupInformation {
+        WebCore::DisplayList::ItemBufferIdentifier itemBufferIdentifier;
+        uint64_t offset { 0 };
+        QualifiedRenderingResourceIdentifier destinationImageBufferIdentifier;
+        GPUProcessWakeupReason reason { GPUProcessWakeupReason::Unspecified };
+        std::optional<QualifiedRenderingResourceIdentifier> missingCachedResourceIdentifier;
+        RemoteRenderingBackendState state { RemoteRenderingBackendState::Initialized };
+
+        bool shouldPerformWakeup(QualifiedRenderingResourceIdentifier identifier) const
+        {
+            return destinationImageBufferIdentifier == identifier
+                || missingCachedResourceIdentifier == identifier;
+        }
+
+        bool shouldPerformWakeup(WebCore::DisplayList::ItemBufferIdentifier identifier) const
+        {
+            return itemBufferIdentifier == identifier;
+        }
+    };
+
+    Ref<WorkQueue> m_workQueue;
     RemoteResourceCache m_remoteResourceCache;
     Ref<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
     RenderingBackendIdentifier m_renderingBackendIdentifier;
+    HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListReaderHandle>> m_sharedDisplayListHandles;
+    std::optional<PendingWakeupInformation> m_pendingWakeupInfo;
+    IPC::Semaphore m_resumeDisplayListSemaphore;
     IPC::Semaphore m_getPixelBufferSemaphore;
     RefPtr<SharedMemory> m_getPixelBufferSharedMemory;
     ScopedRenderingResourcesRequest m_renderingResourcesRequest;
-    WeakHashSet<RemoteDisplayListRecorder> m_remoteDisplayLists;
+    RefPtr<WebCore::ImageBuffer> m_currentMaskImageBuffer;
+    Atomic<RemoteRenderingBackendState> m_lastKnownState { RemoteRenderingBackendState::Initialized };
 };
 
 } // namespace WebKit

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in	2021-10-20 21:32:07 UTC (rev 284569)
@@ -22,18 +22,20 @@
 
 #if ENABLE(GPU_PROCESS)
 
-messages -> RemoteRenderingBackend NotRefCounted Stream {
+messages -> RemoteRenderingBackend {
     CreateImageBuffer(WebCore::FloatSize logicalSize, WebCore::RenderingMode renderingMode, float resolutionScale, WebCore::DestinationColorSpace colorSpace, enum:uint8_t WebCore::PixelFormat pixelFormat, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
-    UpdateSharedMemoryForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle) Synchronous NotStreamEncodableReply
-    SemaphoreForGetPixelBuffer() -> (IPC::Semaphore semaphore) Synchronous NotStreamEncodableReply
-    UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle, IPC::Semaphore semaphore) Synchronous NotStreamEncodableReply
+    WakeUpAndApplyDisplayList(struct WebKit::GPUProcessWakeupMessageArguments arguments)
+    UpdateSharedMemoryForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle) Synchronous
+    SemaphoreForGetPixelBuffer() -> (IPC::Semaphore semaphore) Synchronous
+    UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle, IPC::Semaphore semaphore) Synchronous
     DestroyGetPixelBufferSharedMemory()
     GetDataURLForImageBuffer(String mimeType, std::optional<double> quality, enum:uint8_t WebCore::PreserveResolution preserveResolution, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (String urlString) Synchronous
     GetDataForImageBuffer(String mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (Vector<uint8_t> data) Synchronous
-    GetShareableBitmapForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, enum:uint8_t WebCore::PreserveResolution preserveResolution) -> (WebKit::ShareableBitmap::Handle handle) Synchronous NotStreamEncodableReply
-    CacheNativeImage(WebKit::ShareableBitmap::Handle handle, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) NotStreamEncodable
-    CacheFont(IPC::FontReference font) NotStreamEncodable
+    GetShareableBitmapForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, enum:uint8_t WebCore::PreserveResolution preserveResolution) -> (WebKit::ShareableBitmap::Handle handle) Synchronous
+    CacheNativeImage(WebKit::ShareableBitmap::Handle handle, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
+    CacheFont(IPC::FontReference font)
     DeleteAllFonts()
+    DidCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier identifier, WebKit::SharedMemory::IPCHandle handle, WebCore::RenderingResourceIdentifier destinationBufferIdentifier)
     ReleaseRemoteResource(WebCore::RenderingResourceIdentifier renderingResourceIdentifier, uint64_t useCount)
     FinalizeRenderingUpdate(WebKit::RenderingUpdateID renderingUpdateID)
 }

Modified: branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h	2021-10-20 21:32:07 UTC (rev 284569)
@@ -36,12 +36,13 @@
 
 struct RemoteRenderingBackendCreationParameters {
     RenderingBackendIdentifier identifier;
+    IPC::Semaphore resumeDisplayListSemaphore;
     WebPageProxyIdentifier pageProxyID;
     WebCore::PageIdentifier pageID;
 
     void encode(IPC::Encoder& encoder) const
     {
-        encoder << identifier << pageProxyID << pageID;
+        encoder << identifier << resumeDisplayListSemaphore << pageProxyID << pageID;
     }
 
     static std::optional<RemoteRenderingBackendCreationParameters> decode(IPC::Decoder& decoder)
@@ -51,6 +52,11 @@
         if (!identifier)
             return std::nullopt;
 
+        std::optional<IPC::Semaphore> resumeDisplayListSemaphore;
+        decoder >> resumeDisplayListSemaphore;
+        if (!resumeDisplayListSemaphore)
+            return std::nullopt;
+
         std::optional<WebPageProxyIdentifier> pageProxyID;
         decoder >> pageProxyID;
         if (!pageProxyID)
@@ -61,7 +67,7 @@
         if (!pageID)
             return std::nullopt;
 
-        return { { *identifier, *pageProxyID, *pageID } };
+        return {{ *identifier, WTFMove(*resumeDisplayListSemaphore), *pageProxyID, *pageID }};
     }
 };
 

Modified: branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2021-10-20 21:32:07 UTC (rev 284569)
@@ -29,13 +29,13 @@
 
 #include "Encoder.h"
 #include "Logging.h"
-#include "RemoteDisplayListRecorderProxy.h"
-#include "RemoteRenderingBackendMessages.h"
 #include "RemoteRenderingBackendProxy.h"
 #include "SharedMemory.h"
-#include <WebCore/ConcreteImageBuffer.h>
 #include <WebCore/DisplayList.h>
+#include <WebCore/DisplayListImageBuffer.h>
 #include <WebCore/DisplayListItems.h>
+#include <WebCore/DisplayListRecorder.h>
+#include <WebCore/DisplayListReplayer.h>
 #include <WebCore/MIMETypeRegistry.h>
 #include <wtf/Condition.h>
 #include <wtf/Lock.h>
@@ -47,11 +47,12 @@
 template<typename BackendType> class ThreadSafeRemoteImageBufferFlusher;
 
 template<typename BackendType>
-class RemoteImageBufferProxy : public WebCore::ConcreteImageBuffer<BackendType> {
-    using BaseConcreteImageBuffer = WebCore::ConcreteImageBuffer<BackendType>;
-    using BaseConcreteImageBuffer::m_backend;
-    using BaseConcreteImageBuffer::m_renderingResourceIdentifier;
-    using BaseConcreteImageBuffer::resolutionScale;
+class RemoteImageBufferProxy : public WebCore::DisplayList::ImageBuffer<BackendType>, public WebCore::DisplayList::RecorderImpl::Delegate, public WebCore::DisplayList::ItemBufferWritingClient {
+    using BaseDisplayListImageBuffer = WebCore::DisplayList::ImageBuffer<BackendType>;
+    using BaseDisplayListImageBuffer::m_backend;
+    using BaseDisplayListImageBuffer::m_drawingContext;
+    using BaseDisplayListImageBuffer::m_renderingResourceIdentifier;
+    using BaseDisplayListImageBuffer::resolutionScale;
 
 public:
     static RefPtr<RemoteImageBufferProxy> create(const WebCore::FloatSize& size, float resolutionScale, const WebCore::DestinationColorSpace& colorSpace, WebCore::PixelFormat pixelFormat, RemoteRenderingBackendProxy& remoteRenderingBackendProxy)
@@ -65,7 +66,7 @@
     ~RemoteImageBufferProxy()
     {
         if (!m_remoteRenderingBackendProxy || m_remoteRenderingBackendProxy->isGPUProcessConnectionClosed()) {
-            m_remoteDisplayList.resetNeedsFlush();
+            clearDisplayList();
             return;
         }
 
@@ -97,14 +98,19 @@
 
 protected:
     RemoteImageBufferProxy(const WebCore::ImageBufferBackend::Parameters& parameters, RemoteRenderingBackendProxy& remoteRenderingBackendProxy)
-        : BaseConcreteImageBuffer(parameters)
-        , m_remoteRenderingBackendProxy(remoteRenderingBackendProxy)
-        , m_remoteDisplayList(*this, remoteRenderingBackendProxy, { { }, BaseConcreteImageBuffer::logicalSize() }, BaseConcreteImageBuffer::baseTransform())
+        : BaseDisplayListImageBuffer(parameters, this)
+        , m_remoteRenderingBackendProxy(makeWeakPtr(remoteRenderingBackendProxy))
     {
         ASSERT(m_remoteRenderingBackendProxy);
         m_remoteRenderingBackendProxy->remoteResourceCacheProxy().cacheImageBuffer(*this);
+
+        m_drawingContext.displayList().setItemBufferWritingClient(this);
+        m_drawingContext.displayList().setItemBufferReadingClient(nullptr);
+        m_drawingContext.displayList().setTracksDrawingItemExtents(false);
     }
 
+    WebCore::RenderingMode renderingMode() const final { return BaseDisplayListImageBuffer::renderingMode(); }
+
     // It is safe to access m_receivedFlushIdentifier from the main thread without locking since it
     // only gets modified on the main thread.
     bool hasPendingFlush() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS
@@ -213,7 +219,7 @@
             return std::nullopt;
 
         auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
-        mutableThis.m_remoteDisplayList.getPixelBuffer(destinationFormat, srcRect);
+        mutableThis.m_drawingContext.recorder().getPixelBuffer(destinationFormat, srcRect);
         mutableThis.flushDrawingContextAsync();
 
         if (m_remoteRenderingBackendProxy->waitForGetPixelBufferToComplete(timeout))
@@ -223,28 +229,12 @@
         return pixelBuffer;
     }
 
-    void clearBackend() final
-    {
-        m_remoteDisplayList.resetNeedsFlush();
-        BaseConcreteImageBuffer::clearBackend();
-    }
-
-    WebCore::GraphicsContext& context() const final
-    {
-        return const_cast<RemoteImageBufferProxy*>(this)->m_remoteDisplayList;
-    }
-
-    WebCore::GraphicsContext* drawingContext() final
-    {
-        return &m_remoteDisplayList;
-    }
-
     void putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) final
     {
         // The math inside PixelBuffer::create() doesn't agree with the math inside ImageBufferBackend::putPixelBuffer() about how m_resolutionScale interacts with the data in the ImageBuffer.
         // This means that putPixelBuffer() is only called when resolutionScale() == 1.
         ASSERT(resolutionScale() == 1);
-        m_remoteDisplayList.putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
+        m_drawingContext.recorder().putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
     }
 
     bool prefersPreparationForDisplay() final { return true; }
@@ -270,32 +260,94 @@
         if (UNLIKELY(!m_remoteRenderingBackendProxy))
             return;
 
-        if (m_remoteDisplayList.needsFlush() || !hasPendingFlush()) {
+        if (!m_drawingContext.displayList().isEmpty() || !hasPendingFlush()) {
             m_sentFlushIdentifier = WebCore::GraphicsContextFlushIdentifier::generate();
-            m_remoteDisplayList.flushContext(m_sentFlushIdentifier);
+            m_drawingContext.recorder().flushContext(m_sentFlushIdentifier);
         }
 
-        m_remoteDisplayList.resetNeedsFlush();
+        m_remoteRenderingBackendProxy->sendDeferredWakeupMessageIfNeeded();
+        clearDisplayList();
     }
 
-    void recordNativeImageUse(WebCore::NativeImage& image)
+    void recordNativeImageUse(WebCore::NativeImage& image) final
     {
         if (m_remoteRenderingBackendProxy)
             m_remoteRenderingBackendProxy->remoteResourceCacheProxy().recordNativeImageUse(image);
     }
 
-    void recordFontUse(WebCore::Font& font)
+    bool isCachedImageBuffer(const WebCore::ImageBuffer& imageBuffer) const final
     {
+        if (!m_remoteRenderingBackendProxy)
+            return false;
+        auto cachedImageBuffer = m_remoteRenderingBackendProxy->remoteResourceCacheProxy().cachedImageBuffer(imageBuffer.renderingResourceIdentifier());
+        ASSERT(!cachedImageBuffer || cachedImageBuffer == &imageBuffer);
+        return cachedImageBuffer;
+    }
+
+    void changeDestinationImageBuffer(WebCore::RenderingResourceIdentifier nextImageBuffer) final
+    {
+        bool wasEmpty = m_drawingContext.displayList().isEmpty();
+        m_drawingContext.displayList().template append<WebCore::DisplayList::MetaCommandChangeDestinationImageBuffer>(nextImageBuffer);
+        if (wasEmpty)
+            clearDisplayList();
+    }
+
+    void prepareToAppendDisplayListItems(WebCore::DisplayList::ItemBufferHandle&& handle) final
+    {
+        m_drawingContext.displayList().prepareToAppend(WTFMove(handle));
+    }
+
+    void clearDisplayList()
+    {
+        m_drawingContext.displayList().clear();
+    }
+
+    bool canAppendItemOfType(WebCore::DisplayList::ItemType) final
+    {
+        if (UNLIKELY(!m_remoteRenderingBackendProxy))
+            return false;
+        m_remoteRenderingBackendProxy->willAppendItem(m_renderingResourceIdentifier);
+        return true;
+    }
+
+    void didAppendData(const WebCore::DisplayList::ItemBufferHandle& handle, size_t numberOfBytes, WebCore::DisplayList::DidChangeItemBuffer didChangeItemBuffer) final
+    {
+        if (LIKELY(m_remoteRenderingBackendProxy))
+            m_remoteRenderingBackendProxy->didAppendData(handle, numberOfBytes, didChangeItemBuffer, m_renderingResourceIdentifier);
+    }
+
+    void recordFontUse(WebCore::Font& font) final
+    {
         if (m_remoteRenderingBackendProxy)
             m_remoteRenderingBackendProxy->remoteResourceCacheProxy().recordFontUse(font);
     }
 
-    void recordImageBufferUse(WebCore::ImageBuffer& imageBuffer)
+    void recordImageBufferUse(WebCore::ImageBuffer& imageBuffer) final
     {
         if (m_remoteRenderingBackendProxy)
             m_remoteRenderingBackendProxy->remoteResourceCacheProxy().recordImageBufferUse(imageBuffer);
     }
 
+    WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t capacity) final
+    {
+        if (LIKELY(m_remoteRenderingBackendProxy))
+            return m_remoteRenderingBackendProxy->createItemBuffer(capacity, m_renderingResourceIdentifier);
+
+        ASSERT_NOT_REACHED();
+        return { };
+    }
+
+    RefPtr<WebCore::SharedBuffer> encodeItemOutOfLine(const WebCore::DisplayList::DisplayListItem& item) const final
+    {
+        return std::visit([](const auto& displayListItem) -> RefPtr<WebCore::SharedBuffer> {
+            using DisplayListItemType = typename WTF::RemoveCVAndReference<decltype(displayListItem)>::type;
+            if constexpr (!DisplayListItemType::isInlineItem)
+                return IPC::Encoder::encodeSingleObject<DisplayListItemType>(displayListItem);
+            RELEASE_ASSERT_NOT_REACHED();
+            return nullptr;
+        }, item);
+    }
+
     std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> createFlusher() final
     {
         return WTF::makeUnique<ThreadSafeRemoteImageBufferFlusher<BackendType>>(*this);
@@ -306,7 +358,6 @@
     Condition m_receivedFlushIdentifierChangedCondition;
     WebCore::GraphicsContextFlushIdentifier m_receivedFlushIdentifier WTF_GUARDED_BY_LOCK(m_receivedFlushIdentifierLock); // Only modified on the main thread but may get queried on a secondary thread.
     WeakPtr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy;
-    RemoteDisplayListRecorderProxy m_remoteDisplayList;
 };
 
 template<typename BackendType>

Modified: branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp	2021-10-20 21:32:07 UTC (rev 284569)
@@ -28,6 +28,7 @@
 
 #if ENABLE(GPU_PROCESS)
 
+#include "DisplayListWriterHandle.h"
 #include "GPUConnectionToWebProcess.h"
 #include "Logging.h"
 #include "PlatformRemoteImageBufferProxy.h"
@@ -51,6 +52,7 @@
 RemoteRenderingBackendProxy::RemoteRenderingBackendProxy(WebPage& webPage)
     : m_parameters {
         RenderingBackendIdentifier::generate(),
+        IPC::Semaphore { },
         webPage.webPageProxyIdentifier(),
         webPage.identifier()
     }
@@ -75,10 +77,8 @@
         auto& gpuProcessConnection = WebProcess::singleton().ensureGPUProcessConnection();
         gpuProcessConnection.addClient(*this);
         gpuProcessConnection.messageReceiverMap().addMessageReceiver(Messages::RemoteRenderingBackendProxy::messageReceiverName(), renderingBackendIdentifier().toUInt64(), *this);
-        static constexpr auto connectionBufferSize = 1 << 21;
-        m_streamConnection = makeUnique<IPC::StreamClientConnection>(gpuProcessConnection.connection(), connectionBufferSize);
-        gpuProcessConnection.connection().send(Messages::GPUConnectionToWebProcess::CreateRenderingBackend(m_parameters, m_streamConnection->streamBuffer()), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
-        m_gpuProcessConnection = gpuProcessConnection;
+        gpuProcessConnection.connection().send(Messages::GPUConnectionToWebProcess::CreateRenderingBackend(m_parameters), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+        m_gpuProcessConnection = makeWeakPtr(gpuProcessConnection);
     }
     return *m_gpuProcessConnection;
 }
@@ -91,6 +91,12 @@
 
     m_remoteResourceCacheProxy.remoteResourceCacheWasDestroyed();
 
+    m_identifiersOfReusableHandles.clear();
+    m_sharedDisplayListHandles.clear();
+    m_currentDestinationImageBufferIdentifier = std::nullopt;
+    m_deferredWakeupMessageArguments = std::nullopt;
+    m_remainingItemsToAppendBeforeSendingWakeup = 0;
+
     if (m_destroyGetPixelBufferSharedMemoryTimer.isActive())
         m_destroyGetPixelBufferSharedMemoryTimer.stop();
     m_getPixelBufferSemaphore = std::nullopt;
@@ -127,7 +133,7 @@
 
 void RemoteRenderingBackendProxy::createRemoteImageBuffer(ImageBuffer& imageBuffer)
 {
-    sendToStream(Messages::RemoteRenderingBackend::CreateImageBuffer(imageBuffer.logicalSize(), imageBuffer.renderingMode(), imageBuffer.resolutionScale(), imageBuffer.colorSpace(), imageBuffer.pixelFormat(), imageBuffer.renderingResourceIdentifier()));
+    send(Messages::RemoteRenderingBackend::CreateImageBuffer(imageBuffer.logicalSize(), imageBuffer.renderingMode(), imageBuffer.resolutionScale(), imageBuffer.colorSpace(), imageBuffer.pixelFormat(), imageBuffer.renderingResourceIdentifier()), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 RefPtr<ImageBuffer> RemoteRenderingBackendProxy::createImageBuffer(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, const DestinationColorSpace& colorSpace, PixelFormat pixelFormat)
@@ -157,6 +163,8 @@
 
 SharedMemory* RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer(size_t dataSize, IPC::Timeout timeout)
 {
+    sendDeferredWakeupMessageIfNeeded();
+
     bool needsSharedMemory = !m_getPixelBufferSharedMemory || dataSize > m_getPixelBufferSharedMemoryLength;
     bool needsSemaphore = !m_getPixelBufferSemaphore;
 
@@ -167,11 +175,11 @@
     IPC::Semaphore semaphore;
 
     if (needsSharedMemory && needsSemaphore)
-        sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore), timeout);
+        sendSync(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore), renderingBackendIdentifier(), timeout, IPC::SendSyncOption::MaintainOrderingWithAsyncMessages);
     else if (needsSharedMemory)
-        sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle), timeout);
+        sendSync(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle), renderingBackendIdentifier(), timeout, IPC::SendSyncOption::MaintainOrderingWithAsyncMessages);
     else if (needsSemaphore)
-        sendSyncToStream(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore), timeout);
+        sendSync(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore), renderingBackendIdentifier(), timeout);
 
     if (!handle.handle.isNull()) {
         m_getPixelBufferSharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadOnly);
@@ -196,27 +204,33 @@
 void RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory()
 {
     m_getPixelBufferSharedMemory = nullptr;
-    sendToStream(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory());
+    send(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory(), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 String RemoteRenderingBackendProxy::getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, PreserveResolution preserveResolution, RenderingResourceIdentifier renderingResourceIdentifier)
 {
+    sendDeferredWakeupMessageIfNeeded();
+
     String urlString;
-    sendSyncToStream(Messages::RemoteRenderingBackend::GetDataURLForImageBuffer(mimeType, quality, preserveResolution, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataURLForImageBuffer::Reply(urlString), 1_s);
+    sendSync(Messages::RemoteRenderingBackend::GetDataURLForImageBuffer(mimeType, quality, preserveResolution, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataURLForImageBuffer::Reply(urlString), renderingBackendIdentifier(), 1_s);
     return urlString;
 }
 
 Vector<uint8_t> RemoteRenderingBackendProxy::getDataForImageBuffer(const String& mimeType, std::optional<double> quality, RenderingResourceIdentifier renderingResourceIdentifier)
 {
+    sendDeferredWakeupMessageIfNeeded();
+
     Vector<uint8_t> data;
-    sendSyncToStream(Messages::RemoteRenderingBackend::GetDataForImageBuffer(mimeType, quality, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataForImageBuffer::Reply(data), 1_s);
+    sendSync(Messages::RemoteRenderingBackend::GetDataForImageBuffer(mimeType, quality, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataForImageBuffer::Reply(data), renderingBackendIdentifier(), 1_s);
     return data;
 }
 
 RefPtr<ShareableBitmap> RemoteRenderingBackendProxy::getShareableBitmap(RenderingResourceIdentifier imageBuffer, PreserveResolution preserveResolution)
 {
+    sendDeferredWakeupMessageIfNeeded();
+
     ShareableBitmap::Handle handle;
-    auto sendResult = sendSyncToStream(Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer(imageBuffer, preserveResolution), Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer::Reply(handle), 1_s);
+    auto sendResult = sendSync(Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer(imageBuffer, preserveResolution), Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer::Reply(handle), renderingBackendIdentifier(), 1_s);
     if (handle.isNull())
         return { };
     ASSERT_UNUSED(sendResult, sendResult);
@@ -225,27 +239,30 @@
 
 void RemoteRenderingBackendProxy::cacheNativeImage(const ShareableBitmap::Handle& handle, RenderingResourceIdentifier renderingResourceIdentifier)
 {
-    sendToStream(Messages::RemoteRenderingBackend::CacheNativeImage(handle, renderingResourceIdentifier));
+    send(Messages::RemoteRenderingBackend::CacheNativeImage(handle, renderingResourceIdentifier), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
-void RemoteRenderingBackendProxy::cacheFont(Ref<Font>&& font)
+void RemoteRenderingBackendProxy::cacheFont(Ref<WebCore::Font>&& font)
 {
-    sendToStream(Messages::RemoteRenderingBackend::CacheFont(WTFMove(font)));
+    send(Messages::RemoteRenderingBackend::CacheFont(WTFMove(font)), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 void RemoteRenderingBackendProxy::deleteAllFonts()
 {
-    sendToStream(Messages::RemoteRenderingBackend::DeleteAllFonts());
+    send(Messages::RemoteRenderingBackend::DeleteAllFonts(), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 void RemoteRenderingBackendProxy::releaseRemoteResource(RenderingResourceIdentifier renderingResourceIdentifier, uint64_t useCount)
 {
-    sendToStream(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier, useCount));
+    if (renderingResourceIdentifier == m_currentDestinationImageBufferIdentifier)
+        m_currentDestinationImageBufferIdentifier = std::nullopt;
+
+    send(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier, useCount), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 void RemoteRenderingBackendProxy::finalizeRenderingUpdate()
 {
-    sendToStream(Messages::RemoteRenderingBackend::FinalizeRenderingUpdate(m_renderingUpdateID));
+    send(Messages::RemoteRenderingBackend::FinalizeRenderingUpdate(m_renderingUpdateID), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     m_remoteResourceCacheProxy.finalizeRenderingUpdate();
     m_renderingUpdateID.increment();
 }
@@ -276,36 +293,160 @@
     m_didRenderingUpdateID = std::min(didRenderingUpdateID, m_renderingUpdateID);
 }
 
-RenderingBackendIdentifier RemoteRenderingBackendProxy::renderingBackendIdentifier() const
+void RemoteRenderingBackendProxy::willAppendItem(RenderingResourceIdentifier newDestinationIdentifier)
 {
-    return m_parameters.identifier;
+    if (m_currentDestinationImageBufferIdentifier == newDestinationIdentifier)
+        return;
+
+    if (auto previousDestinationBufferIdentifier = std::exchange(m_currentDestinationImageBufferIdentifier, newDestinationIdentifier)) {
+        if (auto imageBuffer = m_remoteResourceCacheProxy.cachedImageBuffer(*previousDestinationBufferIdentifier))
+            imageBuffer->changeDestinationImageBuffer(newDestinationIdentifier);
+        else
+            ASSERT_NOT_REACHED();
+    }
+
+    auto handle = mostRecentlyUsedDisplayListHandle();
+    if (UNLIKELY(!handle))
+        return;
+
+    auto newDestination = m_remoteResourceCacheProxy.cachedImageBuffer(newDestinationIdentifier);
+    if (UNLIKELY(!newDestination)) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    handle->moveWritableOffsetToStartIfPossible();
+    newDestination->prepareToAppendDisplayListItems(handle->createHandle());
 }
 
-RenderingBackendIdentifier RemoteRenderingBackendProxy::ensureBackendCreated()
+void RemoteRenderingBackendProxy::sendWakeupMessage(const GPUProcessWakeupMessageArguments& arguments)
 {
-    ensureGPUProcessConnection();
-    return renderingBackendIdentifier();
+    LOG_WITH_STREAM(SharedDisplayLists, stream << "Sending wakeup: Items[" << arguments.itemBufferIdentifier << "] => Image(" << arguments.destinationImageBufferIdentifier << ") at " << arguments.offset);
+    send(Messages::RemoteRenderingBackend::WakeUpAndApplyDisplayList(arguments), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
-IPC::StreamClientConnection& RemoteRenderingBackendProxy::streamConnection()
+void RemoteRenderingBackendProxy::sendDeferredWakeupMessageIfNeeded()
 {
-    ensureGPUProcessConnection();
-    if (UNLIKELY(m_needsWakeUpSemaphoreForDisplayListStream))
-        messageSenderConnection()->waitForAndDispatchImmediately<Messages::RemoteRenderingBackendProxy::DidCreateWakeUpSemaphoreForDisplayListStream>(renderingBackendIdentifier(), 3_s, IPC::WaitForOption::InterruptWaitingIfSyncMessageArrives);
-    return *m_streamConnection;
+    auto arguments = std::exchange(m_deferredWakeupMessageArguments, std::nullopt);
+    if (!arguments)
+        return;
+
+    sendWakeupMessage(*arguments);
+    m_remainingItemsToAppendBeforeSendingWakeup = 0;
 }
 
-void RemoteRenderingBackendProxy::didCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore&& semaphore)
+void RemoteRenderingBackendProxy::didAppendData(const DisplayList::ItemBufferHandle& handle, size_t numberOfBytes, DisplayList::DidChangeItemBuffer didChangeItemBuffer, RenderingResourceIdentifier destinationImageBuffer)
 {
-    if (!m_streamConnection) {
-        ASSERT_NOT_REACHED();
+    auto* sharedHandle = m_sharedDisplayListHandles.get(handle.identifier);
+    if (UNLIKELY(!sharedHandle))
+        RELEASE_ASSERT_NOT_REACHED();
+
+    bool wasEmpty = sharedHandle->advance(numberOfBytes) == numberOfBytes;
+    if (!wasEmpty || didChangeItemBuffer == DisplayList::DidChangeItemBuffer::Yes) {
+        if (m_deferredWakeupMessageArguments) {
+            auto imageBuffer = m_remoteResourceCacheProxy.cachedImageBuffer(m_deferredWakeupMessageArguments->destinationImageBufferIdentifier);
+            if (imageBuffer && imageBuffer->backend() && sharedHandle->tryToResume({ m_deferredWakeupMessageArguments->offset, m_deferredWakeupMessageArguments->destinationImageBufferIdentifier.toUInt64() })) {
+                m_parameters.resumeDisplayListSemaphore.signal();
+                m_deferredWakeupMessageArguments = std::nullopt;
+                m_remainingItemsToAppendBeforeSendingWakeup = 0;
+            } else if (!--m_remainingItemsToAppendBeforeSendingWakeup) {
+                m_deferredWakeupMessageArguments->reason = GPUProcessWakeupReason::ItemCountHysteresisExceeded;
+                sendWakeupMessage(*std::exchange(m_deferredWakeupMessageArguments, std::nullopt));
+            }
+        }
         return;
     }
 
-    m_streamConnection->setWakeUpSemaphore(WTFMove(semaphore));
-    m_needsWakeUpSemaphoreForDisplayListStream = false;
+    sendDeferredWakeupMessageIfNeeded();
+
+    auto imageBuffer = m_remoteResourceCacheProxy.cachedImageBuffer(destinationImageBuffer);
+    auto offsetToRead = sharedHandle->writableOffset() - numberOfBytes;
+    if (imageBuffer && imageBuffer->backend() && sharedHandle->tryToResume({ offsetToRead, destinationImageBuffer.toUInt64() })) {
+        m_parameters.resumeDisplayListSemaphore.signal();
+        return;
+    }
+
+    // Instead of sending the wakeup message immediately, wait for some additional data. This gives the
+    // web process a "head start", decreasing the likelihood that the GPU process will encounter frequent
+    // wakeups when processing a large amount of display list items.
+    constexpr unsigned itemCountHysteresisBeforeSendingWakeup = 512;
+
+    m_remainingItemsToAppendBeforeSendingWakeup = itemCountHysteresisBeforeSendingWakeup;
+    m_deferredWakeupMessageArguments = {{ handle.identifier, offsetToRead, destinationImageBuffer }};
 }
 
+RefPtr<DisplayListWriterHandle> RemoteRenderingBackendProxy::mostRecentlyUsedDisplayListHandle()
+{
+    if (UNLIKELY(m_identifiersOfReusableHandles.isEmpty()))
+        return nullptr;
+
+    return m_sharedDisplayListHandles.get(m_identifiersOfReusableHandles.first());
+}
+
+RefPtr<DisplayListWriterHandle> RemoteRenderingBackendProxy::findReusableDisplayListHandle(size_t capacity)
+{
+    auto mostRecentlyUsedHandle = mostRecentlyUsedDisplayListHandle();
+    if (UNLIKELY(!mostRecentlyUsedHandle))
+        return nullptr;
+
+    mostRecentlyUsedHandle->moveWritableOffsetToStartIfPossible();
+    if (mostRecentlyUsedHandle->availableCapacity() >= capacity)
+        return mostRecentlyUsedHandle;
+
+    m_identifiersOfReusableHandles.append(m_identifiersOfReusableHandles.takeFirst());
+
+    auto leastRecentlyUsedIdentifier = m_identifiersOfReusableHandles.first();
+    if (leastRecentlyUsedIdentifier != mostRecentlyUsedHandle->identifier()) {
+        RefPtr handle = m_sharedDisplayListHandles.get(leastRecentlyUsedIdentifier);
+        if (handle->moveWritableOffsetToStartIfPossible() && handle->availableCapacity() >= capacity)
+            return handle;
+    }
+
+    return nullptr;
+}
+
+DisplayList::ItemBufferHandle RemoteRenderingBackendProxy::createItemBuffer(size_t capacity, RenderingResourceIdentifier destinationBufferIdentifier)
+{
+    if (auto handle = findReusableDisplayListHandle(capacity)) {
+        LOG_WITH_STREAM(SharedDisplayLists, stream << "Reusing Items[" << handle->identifier() << "] => Image(" << destinationBufferIdentifier << ") (remaining capacity: " << handle->availableCapacity() << ")");
+        return handle->createHandle();
+    }
+
+    static constexpr size_t defaultSharedItemBufferSize = 1 << 16;
+    static_assert(defaultSharedItemBufferSize > SharedDisplayListHandle::headerSize());
+
+    auto sharedMemory = SharedMemory::allocate(std::max(defaultSharedItemBufferSize, capacity + SharedDisplayListHandle::headerSize()));
+    if (!sharedMemory)
+        return { };
+
+    SharedMemory::Handle sharedMemoryHandle;
+    sharedMemory->createHandle(sharedMemoryHandle, SharedMemory::Protection::ReadWrite);
+
+    auto identifier = DisplayList::ItemBufferIdentifier::generate();
+    send(Messages::RemoteRenderingBackend::DidCreateSharedDisplayListHandle(identifier, { WTFMove(sharedMemoryHandle), sharedMemory->size() }, destinationBufferIdentifier), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+
+    auto newHandle = DisplayListWriterHandle::create(identifier, sharedMemory.releaseNonNull());
+    RELEASE_ASSERT(newHandle, "There must be enough space to create the handle.");
+    auto displayListHandle = newHandle->createHandle();
+
+    m_identifiersOfReusableHandles.prepend(identifier);
+    m_sharedDisplayListHandles.set(identifier, WTFMove(newHandle));
+
+    LOG_WITH_STREAM(SharedDisplayLists, stream << "Allocated Items[" << identifier << "] => Image(" << destinationBufferIdentifier << ")");
+    return displayListHandle;
+}
+
+RenderingBackendIdentifier RemoteRenderingBackendProxy::renderingBackendIdentifier() const
+{
+    return m_parameters.identifier;
+}
+
+RenderingBackendIdentifier RemoteRenderingBackendProxy::ensureBackendCreated()
+{
+    ensureGPUProcessConnection();
+    return renderingBackendIdentifier();
+}
+
 void RemoteRenderingBackendProxy::recordNativeImageUse(NativeImage& image)
 {
     m_remoteResourceCacheProxy.recordNativeImageUse(image);

Modified: branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h	2021-10-20 21:32:07 UTC (rev 284569)
@@ -33,13 +33,11 @@
 #include "ImageBufferBackendHandle.h"
 #include "MessageReceiver.h"
 #include "MessageSender.h"
-#include "RemoteDisplayListRecorderMessages.h"
 #include "RemoteRenderingBackendCreationParameters.h"
-#include "RemoteRenderingBackendMessages.h"
 #include "RemoteResourceCacheProxy.h"
 #include "RenderingBackendIdentifier.h"
 #include "RenderingUpdateID.h"
-#include "StreamClientConnection.h"
+#include <WebCore/DisplayList.h>
 #include <WebCore/RenderingResourceIdentifier.h>
 #include <WebCore/Timer.h>
 #include <wtf/Deque.h>
@@ -47,6 +45,11 @@
 
 namespace WebCore {
 
+namespace DisplayList {
+class DisplayList;
+class Item;
+}
+
 class DestinationColorSpace;
 class FloatSize;
 class PixelBuffer;
@@ -58,6 +61,7 @@
 
 namespace WebKit {
 
+class DisplayListWriterHandle;
 class WebPage;
 
 class RemoteRenderingBackendProxy
@@ -73,7 +77,12 @@
     using WeakValueType = GPUProcessConnection::Client::WeakValueType;
 
     RemoteResourceCacheProxy& remoteResourceCacheProxy() { return m_remoteResourceCacheProxy; }
+    WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t capacity, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
 
+    void didAppendData(const WebCore::DisplayList::ItemBufferHandle&, size_t numberOfBytes, WebCore::DisplayList::DidChangeItemBuffer, WebCore::RenderingResourceIdentifier destinationImageBuffer);
+    void willAppendItem(WebCore::RenderingResourceIdentifier);
+    void sendDeferredWakeupMessageIfNeeded();
+
     SharedMemory* sharedMemoryForGetPixelBuffer(size_t dataSize, IPC::Timeout);
     bool waitForGetPixelBufferToComplete(IPC::Timeout);
     void destroyGetPixelBufferSharedMemory();
@@ -92,6 +101,7 @@
     RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat);
     String getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, WebCore::RenderingResourceIdentifier);
     Vector<uint8_t> getDataForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier);
+    WebCore::GraphicsContextFlushIdentifier flushDisplayListAndCommit(const WebCore::DisplayList::DisplayList&, WebCore::RenderingResourceIdentifier);
     RefPtr<ShareableBitmap> getShareableBitmap(WebCore::RenderingResourceIdentifier, WebCore::PreserveResolution);
     void cacheNativeImage(const ShareableBitmap::Handle&, WebCore::RenderingResourceIdentifier);
     void cacheFont(Ref<WebCore::Font>&&);
@@ -115,13 +125,10 @@
 
     bool isGPUProcessConnectionClosed() const { return !m_gpuProcessConnection; }
 
-    void didCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore&&);
-
     template<typename T, typename U>
     void sendToStream(T&& message, ObjectIdentifier<U> identifier)
     {
-        // FIXME: We should consider making the send timeout finite.
-        streamConnection().send(WTFMove(message), identifier, Seconds::infinity());
+        // FIXME: Not yet implemented.
     }
 
     template<typename T>
@@ -137,14 +144,6 @@
 private:
     explicit RemoteRenderingBackendProxy(WebPage&);
 
-    IPC::StreamClientConnection& streamConnection();
-
-    template<typename T>
-    auto sendSyncToStream(T&& message, typename T::Reply&& reply, IPC::Timeout timeout)
-    {
-        return streamConnection().sendSync(WTFMove(message), WTFMove(reply), renderingBackendIdentifier(), timeout);
-    }
-
     // GPUProcessConnection::Client
     void gpuProcessConnectionDidClose(GPUProcessConnection&) final;
 
@@ -155,11 +154,21 @@
     void didFlush(WebCore::GraphicsContextFlushIdentifier, WebCore::RenderingResourceIdentifier);
     void didFinalizeRenderingUpdate(RenderingUpdateID didRenderingUpdateID);
 
-    std::unique_ptr<IPC::StreamClientConnection> m_streamConnection;
+    RefPtr<DisplayListWriterHandle> mostRecentlyUsedDisplayListHandle();
+    RefPtr<DisplayListWriterHandle> findReusableDisplayListHandle(size_t capacity);
+
+    void sendWakeupMessage(const GPUProcessWakeupMessageArguments&);
+
     RemoteRenderingBackendCreationParameters m_parameters;
     WeakPtr<GPUProcessConnection> m_gpuProcessConnection;
     RemoteResourceCacheProxy m_remoteResourceCacheProxy { *this };
 
+    HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListWriterHandle>> m_sharedDisplayListHandles;
+    Deque<WebCore::DisplayList::ItemBufferIdentifier> m_identifiersOfReusableHandles;
+    std::optional<WebCore::RenderingResourceIdentifier> m_currentDestinationImageBufferIdentifier;
+    std::optional<GPUProcessWakeupMessageArguments> m_deferredWakeupMessageArguments;
+    unsigned m_remainingItemsToAppendBeforeSendingWakeup { 0 };
+
     std::optional<IPC::Semaphore> m_getPixelBufferSemaphore;
     RefPtr<SharedMemory> m_getPixelBufferSharedMemory;
     uint64_t m_getPixelBufferSharedMemoryLength { 0 };
@@ -167,8 +176,6 @@
 
     RenderingUpdateID m_renderingUpdateID;
     RenderingUpdateID m_didRenderingUpdateID;
-
-    bool m_needsWakeUpSemaphoreForDisplayListStream { true };
 };
 
 } // namespace WebKit

Modified: branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in	2021-10-20 21:32:07 UTC (rev 284569)
@@ -26,7 +26,6 @@
     DidCreateImageBufferBackend(WebKit::ImageBufferBackendHandle handle, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
     DidFlush(WebCore::GraphicsContextFlushIdentifier flushIdentifier, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
     DidFinalizeRenderingUpdate(WebKit::RenderingUpdateID didRenderingUpdateID)
-    DidCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore wakeUpSemaphore)
 }
 
 #endif // ENABLE(GPU_PROCESS)

Modified: branches/safari-613.1.6-branch/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp (284568 => 284569)


--- branches/safari-613.1.6-branch/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp	2021-10-20 21:26:04 UTC (rev 284568)
+++ branches/safari-613.1.6-branch/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp	2021-10-20 21:32:07 UTC (rev 284569)
@@ -1109,6 +1109,13 @@
     if (!identifier)
         return false;
 
+    auto jsSemaphore = jsObject->get(globalObject, JSC::Identifier::fromString(globalObject->vm(), "semaphore"_s));
+    if (scope.exception())
+        return false;
+    RefPtr semaphoreObject = JSIPCSemaphore::toWrapped(toRef(globalObject), toRef(jsSemaphore));
+    if (!semaphoreObject)
+        return false;
+
     auto pageProxyID = getObjectIdentifierFromProperty<WebPageProxyIdentifierType>(globalObject, jsObject, "pageProxyID"_s, scope);
     if (!pageProxyID)
         return false;
@@ -1117,8 +1124,10 @@
     if (!pageID)
         return false;
 
-    RemoteRenderingBackendCreationParameters parameters { *identifier, *pageProxyID, *pageID };
+    auto semaphore = semaphoreObject->exchange();
+    RemoteRenderingBackendCreationParameters parameters { *identifier, WTFMove(semaphore), *pageProxyID, *pageID };
     encoder << parameters;
+    semaphoreObject->exchange(WTFMove(parameters.resumeDisplayListSemaphore));
     return true;
 }
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to