Source/WebKit/ChangeLog

 12021-10-12 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 [GPU Process] Use IPC streaming for concurrent display list processing
 4 https://bugs.webkit.org/show_bug.cgi?id=230860
 5 rdar://83438038
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 This patch rebuilds the concurrent display list architecture in the web and GPU processes on top of the
 10 streamable IPC connections currently used by WebGL in the GPU process. See below for more details.
 11
 12 There should be no change in behavior.
 13
 14 * GPUProcess/GPUConnectionToWebProcess.cpp:
 15 (WebKit::GPUConnectionToWebProcess::createRenderingBackend):
 16
 17 Pass a StreamConnectionBuffer from the web process to the GPU process when constructing
 18 RemoteRenderingBackend; this serves as the pool of shared memory used to store streaming IPC messages sent from
 19 the web process to the GPU process. I've (somewhat arbitrarily) chosen the size of this StreamConnectionBuffer
 20 to match WebGL's connection buffer, though this can be tuned as needed. In a future patch, we may also want to
 21 implement a mechanism for starting out with a small connection buffer, and growing it by successively larger
 22 segments as needed.
 23
 24 * GPUProcess/GPUConnectionToWebProcess.h:
 25 * GPUProcess/GPUConnectionToWebProcess.messages.in:
 26 * GPUProcess/cocoa/GPUProcessCocoa.mm:
 27 (WebKit::GPUProcess::additionalStateForDiagnosticReport const):
 28
 29 Add a FIXME for re-introducing diagnostic state logging when using streamable IPC.
 30
 31 * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
 32 (WebKit::RemoteDisplayListRecorder::RemoteDisplayListRecorder):
 33 (WebKit::RemoteDisplayListRecorder::startListeningForIPC):
 34 (WebKit::RemoteDisplayListRecorder::stopListeningForIPC):
 35
 36 Add and remove the remote display list as a destination on the RemoteRenderingBackend's stream connection. Note
 37 that the synchronous dispatch to the main thread here is necessary to maintain the ordering of out-of-stream IPC
 38 messages that may have been received on the IPC thread.
 39
 40 * GPUProcess/graphics/RemoteDisplayListRecorder.h:
 41 (WebKit::RemoteDisplayListRecorder::create):
 42 (WebKit::RemoteDisplayListRecorder::handleItem):
 43 * GPUProcess/graphics/RemoteImageBuffer.h:
 44 (WebKit::RemoteImageBuffer::RemoteImageBuffer):
 45 (WebKit::RemoteImageBuffer::apply): Deleted.
 46
 47 Introduce `m_remoteDisplayList` to RemoteImageBuffer, and remove some logic for applying display list items that
 48 is no longer necessary.
 49
 50 * GPUProcess/graphics/RemoteRenderingBackend.cpp:
 51 (WebKit::RemoteRenderingBackend::create):
 52 (WebKit::RemoteRenderingBackend::RemoteRenderingBackend):
 53
 54 Set up the IPC stream connection and stream connection work queue, and immediately send a wakeup semaphore back
 55 to the web process.
 56
 57 (WebKit::RemoteRenderingBackend::startListeningForIPC):
 58 (WebKit::RemoteRenderingBackend::~RemoteRenderingBackend):
 59 (WebKit::RemoteRenderingBackend::stopListeningForIPC):
 60
 61 Add a mechanism to immediately tell all `m_remoteDisplayLists` to stop listening for streaming IPC messages when
 62 the owning RemoteRenderingBackend stops listening.
 63
 64 (WebKit::RemoteRenderingBackend::dispatch):
 65 (WebKit::RemoteRenderingBackend::didCreateImageBufferBackend):
 66 (WebKit::RemoteRenderingBackend::createImageBufferWithQualifiedIdentifier):
 67 (WebKit::RemoteRenderingBackend::cacheNativeImageWithQualifiedIdentifier):
 68 (WebKit::RemoteRenderingBackend::cacheFontWithQualifiedIdentifier):
 69 (WebKit::RemoteRenderingBackend::finalizeRenderingUpdate):
 70 (WebKit::RemoteRenderingBackend::applyMediaItem): Deleted.
 71 (WebKit::RemoteRenderingBackend::ReplayerDelegate::ReplayerDelegate): Deleted.
 72 (WebKit::RemoteRenderingBackend::ReplayerDelegate::apply): Deleted.
 73 (WebKit::RemoteRenderingBackend::ReplayerDelegate::didCreateMaskImageBuffer): Deleted.
 74 (WebKit::RemoteRenderingBackend::ReplayerDelegate::didResetMaskImageBuffer): Deleted.
 75 (WebKit::RemoteRenderingBackend::ReplayerDelegate::recordResourceUse): Deleted.
 76 (WebKit::RemoteRenderingBackend::submit): Deleted.
 77 (WebKit::RemoteRenderingBackend::nextDestinationImageBufferAfterApplyingDisplayLists): Deleted.
 78 (WebKit::RemoteRenderingBackend::wakeUpAndApplyDisplayList): Deleted.
 79 (WebKit::RemoteRenderingBackend::wakeUpAndApplyDisplayListWithQualifiedIdentifier): Deleted.
 80 (WebKit::RemoteRenderingBackend::setNextItemBufferToRead): Deleted.
 81 (WebKit::RemoteRenderingBackend::didCreateSharedDisplayListHandle): Deleted.
 82 (WebKit::RemoteRenderingBackend::didCreateSharedDisplayListHandleWithQualifiedIdentifier): Deleted.
 83 (WebKit::RemoteRenderingBackend::resumeFromPendingWakeupInformation): Deleted.
 84 (WebKit::RemoteRenderingBackend::didCreateMaskImageBuffer): Deleted.
 85 (WebKit::RemoteRenderingBackend::didResetMaskImageBuffer): Deleted.
 86 (WebKit::RemoteRenderingBackend::decodeItem): Deleted.
 87 (WebKit::RemoteRenderingBackend::lastKnownState const): Deleted.
 88 (WebKit::RemoteRenderingBackend::updateLastKnownState): Deleted.
 89
 90 Remove logic for coordinating wakeups and shared display list item buffers in the GPU process.
 91
 92 * GPUProcess/graphics/RemoteRenderingBackend.h:
 93
 94 Subclass IPC::StreamMessageReceiver. In this new concurrent display list model, RemoteRenderingBackend serves
 95 as a streaming IPC destination alongside each RemoteDisplayListRecorder in the GPU process; all messages
 96 previously sent to the RemoteRenderingBackend as normal IPC are now sent through the connection stream (though
 97 some must be marked as non-stream-encodable).
 98
 99 (WebKit::RemoteRenderingBackend::streamConnection const):
 100 (WebKit::RemoteRenderingBackend::decodeAndCreate): Deleted.
 101 (): Deleted.
 102 (WebKit::RemoteRenderingBackend::PendingWakeupInformation::shouldPerformWakeup const): Deleted.
 103
 104 Delete more logic related to concurrent display lists.
 105
 106 * GPUProcess/graphics/RemoteRenderingBackend.messages.in:
 107
 108 Make RemoteRenderingBackend a stream message receiver.
 109
 110 * GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h:
 111 (WebKit::RemoteRenderingBackendCreationParameters::encode const):
 112 (WebKit::RemoteRenderingBackendCreationParameters::decode):
 113
 114 Remove the IPC::Semaphore here, that was previously used for quick GPU process wakeups. This semaphore is no
 115 longer needed because we always use IPC::Semaphore for waking the GPU process when using streaming IPC.
 116
 117 * GPUProcess/graphics/RemoteResourceCache.h:
 118 * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
 119
 120 Make the RemoteImageBufferProxy template class directly subclass ConcreteImageBuffer instead of
 121 DisplayList::ImageBuffer; additionally, introduce a `RemoteDisplayListRecorderProxy m_remoteDisplayList` here,
 122 which we use as our drawing graphics context.
 123
 124 (WebKit::RemoteImageBufferProxy::~RemoteImageBufferProxy):
 125 (WebKit::RemoteImageBufferProxy::RemoteImageBufferProxy):
 126 (WebKit::RemoteImageBufferProxy::recordNativeImageUse):
 127 (WebKit::RemoteImageBufferProxy::recordFontUse):
 128 (WebKit::RemoteImageBufferProxy::recordImageBufferUse):
 129 (WebKit::RemoteImageBufferProxy::clearDisplayList): Deleted.
 130 * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
 131 (WebKit::RemoteRenderingBackendProxy::RemoteRenderingBackendProxy):
 132 (WebKit::RemoteRenderingBackendProxy::ensureGPUProcessConnection):
 133 (WebKit::RemoteRenderingBackendProxy::gpuProcessConnectionDidClose):
 134 (WebKit::RemoteRenderingBackendProxy::createRemoteImageBuffer):
 135 (WebKit::RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer):
 136 (WebKit::RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory):
 137 (WebKit::RemoteRenderingBackendProxy::getDataURLForImageBuffer):
 138 (WebKit::RemoteRenderingBackendProxy::getDataForImageBuffer):
 139 (WebKit::RemoteRenderingBackendProxy::getShareableBitmap):
 140
 141 Send all IPC messages to RemoteRenderingBackend in the GPU process through the stream connection, instead of
 142 using standard IPC messages. This guarantees ordering when receiving cached resources.
 143
 144 (WebKit::RemoteRenderingBackendProxy::cacheNativeImage):
 145 (WebKit::RemoteRenderingBackendProxy::cacheFont):
 146 (WebKit::RemoteRenderingBackendProxy::deleteAllFonts):
 147 (WebKit::RemoteRenderingBackendProxy::releaseRemoteResource):
 148 (WebKit::RemoteRenderingBackendProxy::finalizeRenderingUpdate):
 149 (WebKit::RemoteRenderingBackendProxy::didFinalizeRenderingUpdate):
 150 (WebKit::RemoteRenderingBackendProxy::renderingBackendIdentifier const):
 151 (WebKit::RemoteRenderingBackendProxy::ensureBackendCreated):
 152 (WebKit::RemoteRenderingBackendProxy::streamConnection):
 153
 154 Add a mechanism to ensure that we have the IPC stream wakeup semaphore before grabbing the stream connection.
 155
 156 (WebKit::RemoteRenderingBackendProxy::didCreateWakeUpSemaphoreForDisplayListStream):
 157 (WebKit::RemoteRenderingBackendProxy::willAppendItem): Deleted.
 158 (WebKit::RemoteRenderingBackendProxy::sendWakeupMessage): Deleted.
 159 (WebKit::RemoteRenderingBackendProxy::sendDeferredWakeupMessageIfNeeded): Deleted.
 160 (WebKit::RemoteRenderingBackendProxy::didAppendData): Deleted.
 161 (WebKit::RemoteRenderingBackendProxy::mostRecentlyUsedDisplayListHandle): Deleted.
 162 (WebKit::RemoteRenderingBackendProxy::findReusableDisplayListHandle): Deleted.
 163 (WebKit::RemoteRenderingBackendProxy::createItemBuffer): Deleted.
 164
 165 Remove all logic previously used to coordinate concurrent display list processing on the remote rendering
 166 backend.
 167
 168 * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
 169 (WebKit::RemoteRenderingBackendProxy::remoteResourceCacheProxy):
 170 (WebKit::RemoteRenderingBackendProxy::sendToStream):
 171 (WebKit::RemoteRenderingBackendProxy::sendSyncToStream):
 172
 173 Add helper methods to send IPC messages to the remote rendering backend through the connection stream.
 174
 175 * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in:
 176 * WebProcess/WebPage/IPCTestingAPI.cpp:
 177 (WebKit::IPCTestingAPI::encodeRemoteRenderingBackendCreationParameters):
 178
11792021-10-12 Wenson Hsieh <wenson_hsieh@apple.com>
2180
3181 Add some missing WebCore:: namespaces in RemoteDisplayListRecorderProxy

Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp

@@RemoteImageDecoderAVFProxy& GPUConnectionToWebProcess::imageDecoderAVFProxy()
474474}
475475#endif
476476
477 void GPUConnectionToWebProcess::createRenderingBackend(RemoteRenderingBackendCreationParameters&& creationParameters)
 477void GPUConnectionToWebProcess::createRenderingBackend(RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
478478{
479479 auto addResult = m_remoteRenderingBackendMap.ensure(creationParameters.identifier, [&]() {
480  return IPC::ScopedActiveMessageReceiveQueue { RemoteRenderingBackend::create(*this, WTFMove(creationParameters)) };
 480 return IPC::ScopedActiveMessageReceiveQueue { RemoteRenderingBackend::create(*this, WTFMove(creationParameters), WTFMove(streamBuffer)) };
481481 });
482482 ASSERT_UNUSED(addResult, addResult.isNewEntry);
483483}

Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h

@@private:
178178 RemoteMediaRecorderManager& mediaRecorderManager();
179179#endif
180180
181  void createRenderingBackend(RemoteRenderingBackendCreationParameters&&);
 181 void createRenderingBackend(RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
182182 void releaseRenderingBackend(RenderingBackendIdentifier);
183183
184184#if ENABLE(WEBGL)

Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in

2323#if ENABLE(GPU_PROCESS)
2424
2525messages -> GPUConnectionToWebProcess WantsDispatchMessage {
26  void CreateRenderingBackend(struct WebKit::RemoteRenderingBackendCreationParameters creationParameters)
 26 void CreateRenderingBackend(struct WebKit::RemoteRenderingBackendCreationParameters creationParameters, IPC::StreamConnectionBuffer streamBuffer)
2727 void ReleaseRenderingBackend(WebKit::RenderingBackendIdentifier renderingBackendIdentifier)
2828#if ENABLE(WEBGL)
2929 void CreateGraphicsContextGL(struct WebCore::GraphicsContextGLAttributes attributes, WebKit::GraphicsContextGLIdentifier graphicsContextGLIdentifier, WebKit::RenderingBackendIdentifier renderingBackendIdentifier, IPC::StreamConnectionBuffer stream)

Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm

@@RetainPtr<NSDictionary> GPUProcess::additionalStateForDiagnosticReport() const
5151 continue;
5252
5353 auto stateInfo = adoptNS([[NSMutableDictionary alloc] initWithCapacity:backendMap.size()]);
54  for (auto& identifierAndBackend : backendMap) {
55  auto& [backendIdentifier, backend] = identifierAndBackend;
56  [stateInfo setObject:@(name(backend->lastKnownState())) forKey:backendIdentifier.loggingString()];
57  }
 54 // FIXME: Log some additional diagnostic state on RemoteRenderingBackend.
5855 [webProcessConnectionInfo setObject:stateInfo.get() forKey:webProcessIdentifier.loggingString()];
5956 }
6057

Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp

@@void RemoteDisplayListRecorder::startListeningForIPC()
5555{
5656 ASSERT(!m_isListeningForIPC);
5757 m_isListeningForIPC = true;
58  // FIXME: Not implemented yet.
 58 // FIXME: Can we avoid synchronous dispatch here by adjusting the assertion in `Connection::enqueueMatchingMessagesToMessageReceiveQueue`?
 59 callOnMainRunLoopAndWait([&] {
 60 m_renderingBackend->streamConnection().startReceivingMessages(*this, Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
 61 });
5962}
6063
6164void RemoteDisplayListRecorder::stopListeningForIPC()

@@void RemoteDisplayListRecorder::stopListeningForIPC()
6366 if (!m_isListeningForIPC)
6467 return;
6568
66  // FIXME: Not implemented yet.
 69 m_renderingBackend->streamConnection().stopReceivingMessages(Messages::RemoteDisplayListRecorder::messageReceiverName(), m_imageBufferIdentifier.object().toUInt64());
6770 m_isListeningForIPC = false;
6871}
6972

Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h

3030#include "Decoder.h"
3131#include "GPUConnectionToWebProcess.h"
3232#include "Logging.h"
 33#include "RemoteDisplayListRecorder.h"
 34#include "ScopedActiveMessageReceiveQueue.h"
3335#include <WebCore/ConcreteImageBuffer.h>
3436#include <WebCore/DisplayList.h>
3537#include <WebCore/DisplayListItems.h>

@@public:
5456 : BaseConcreteImageBuffer(parameters, WTFMove(backend), renderingResourceIdentifier.object())
5557 , m_remoteRenderingBackend(remoteRenderingBackend)
5658 , m_renderingResourceIdentifier(renderingResourceIdentifier)
 59 , m_remoteDisplayList({ RemoteDisplayListRecorder::create(*this, renderingResourceIdentifier, renderingResourceIdentifier.processIdentifier(), remoteRenderingBackend) })
5760 {
58  m_remoteRenderingBackend.didCreateImageBufferBackend(m_backend->createImageBufferBackendHandle(), renderingResourceIdentifier);
 61 m_remoteRenderingBackend.didCreateImageBufferBackend(m_backend->createImageBufferBackendHandle(), renderingResourceIdentifier, *m_remoteDisplayList.get());
5962 }
6063
6164 ~RemoteImageBuffer()

@@public:
7780private:
7881 friend class RemoteRenderingBackend;
7982
80  bool apply(WebCore::DisplayList::ItemHandle item, WebCore::GraphicsContext& context)
81  {
82  if (item.is<WebCore::DisplayList::GetPixelBuffer>()) {
83  auto& getPixelBufferItem = item.get<WebCore::DisplayList::GetPixelBuffer>();
84  auto pixelBuffer = BaseConcreteImageBuffer::getPixelBuffer(getPixelBufferItem.outputFormat(), getPixelBufferItem.srcRect());
85  m_remoteRenderingBackend.populateGetPixelBufferSharedMemory(WTFMove(pixelBuffer));
86  return true;
87  }
88 
89  if (item.is<WebCore::DisplayList::PutPixelBuffer>()) {
90  auto& putPixelBufferItem = item.get<WebCore::DisplayList::PutPixelBuffer>();
91  putPixelBuffer(putPixelBufferItem.pixelBuffer(), putPixelBufferItem.srcRect(), putPixelBufferItem.destPoint(), putPixelBufferItem.destFormat());
92  return true;
93  }
94 
95  if (item.is<WebCore::DisplayList::FlushContext>()) {
96  BaseConcreteImageBuffer::flushContext();
97  auto identifier = item.get<WebCore::DisplayList::FlushContext>().identifier();
98  LOG_WITH_STREAM(SharedDisplayLists, stream << "Acknowledging Flush{" << identifier << "} in Image(" << m_renderingResourceIdentifier << ")");
99  m_remoteRenderingBackend.didFlush(identifier, m_renderingResourceIdentifier);
100  return true;
101  }
102 
103  if (item.is<WebCore::DisplayList::MetaCommandChangeItemBuffer>()) {
104  auto nextBufferIdentifier = item.get<WebCore::DisplayList::MetaCommandChangeItemBuffer>().identifier();
105  LOG_WITH_STREAM(SharedDisplayLists, stream << "Switching to Items[" << nextBufferIdentifier << "]");
106  m_remoteRenderingBackend.setNextItemBufferToRead(nextBufferIdentifier, m_renderingResourceIdentifier);
107  return true;
108  }
109 
110  return m_remoteRenderingBackend.applyMediaItem(item, context);
111  }
112 
11383 RemoteRenderingBackend& m_remoteRenderingBackend;
11484 QualifiedRenderingResourceIdentifier m_renderingResourceIdentifier;
 85 IPC::ScopedActiveMessageReceiveQueue<RemoteDisplayListRecorder> m_remoteDisplayList;
11586};
11687
11788} // namespace WebKit

Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp

2828
2929#if ENABLE(GPU_PROCESS)
3030
31 #include "DisplayListReaderHandle.h"
3231#include "GPUConnectionToWebProcess.h"
3332#include "Logging.h"
3433#include "PlatformRemoteImageBuffer.h"

7372namespace WebKit {
7473using namespace WebCore;
7574
76 Ref<RemoteRenderingBackend> RemoteRenderingBackend::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters)
 75Ref<RemoteRenderingBackend> RemoteRenderingBackend::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
7776{
78  auto instance = adoptRef(*new RemoteRenderingBackend(gpuConnectionToWebProcess, WTFMove(creationParameters)));
 77 auto instance = adoptRef(*new RemoteRenderingBackend(gpuConnectionToWebProcess, WTFMove(creationParameters), WTFMove(streamBuffer)));
7978 instance->startListeningForIPC();
8079 return instance;
8180}
8281
83 RemoteRenderingBackend::RemoteRenderingBackend(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters)
84  : m_workQueue(WorkQueue::create("RemoteRenderingBackend work queue", WorkQueue::Type::Serial, WorkQueue::QOS::UserInteractive))
 82RemoteRenderingBackend::RemoteRenderingBackend(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
 83 : m_workQueue("RemoteRenderingBackend work queue")
 84 , m_streamConnection(IPC::StreamServerConnection::create(gpuConnectionToWebProcess.connection(), WTFMove(streamBuffer), m_workQueue))
8585 , m_remoteResourceCache(gpuConnectionToWebProcess.webProcessIdentifier())
8686 , m_gpuConnectionToWebProcess(gpuConnectionToWebProcess)
8787 , m_renderingBackendIdentifier(creationParameters.identifier)
88  , m_resumeDisplayListSemaphore(WTFMove(creationParameters.resumeDisplayListSemaphore))
8988{
9089 ASSERT(RunLoop::isMain());
 90 send(Messages::RemoteRenderingBackendProxy::DidCreateWakeUpSemaphoreForDisplayListStream(m_workQueue.wakeUpSemaphore()), m_renderingBackendIdentifier);
9191}
9292
9393void RemoteRenderingBackend::startListeningForIPC()
9494{
95  m_gpuConnectionToWebProcess->connection().addWorkQueueMessageReceiver(Messages::RemoteRenderingBackend::messageReceiverName(), m_workQueue, this, m_renderingBackendIdentifier.toUInt64());
 95 m_streamConnection->startReceivingMessages(*this, Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
9696}
9797
9898RemoteRenderingBackend::~RemoteRenderingBackend()
9999{
100100 // Make sure we destroy the ResourceCache on the WorkQueue since it gets populated on the WorkQueue.
101101 // Make sure rendering resource request is released after destroying the cache.
102  m_workQueue->dispatch([renderingResourcesRequest = WTFMove(m_renderingResourcesRequest), remoteResourceCache = WTFMove(m_remoteResourceCache)] { });
 102 m_workQueue.dispatch([renderingResourcesRequest = WTFMove(m_renderingResourcesRequest), remoteResourceCache = WTFMove(m_remoteResourceCache)] { });
103103}
104104
105105void RemoteRenderingBackend::stopListeningForIPC()
106106{
107107 ASSERT(RunLoop::isMain());
108 
109  // The RemoteRenderingBackend destructor won't be called until disconnect() is called and we unregister ourselves as a WorkQueueMessageReceiver because
110  // the IPC::Connection refs its WorkQueueMessageReceivers.
111  m_gpuConnectionToWebProcess->connection().removeWorkQueueMessageReceiver(Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
 108 m_streamConnection->stopReceivingMessages(Messages::RemoteRenderingBackend::messageReceiverName(), m_renderingBackendIdentifier.toUInt64());
 109 for (auto& remoteContext : std::exchange(m_remoteDisplayLists, { }))
 110 remoteContext.stopListeningForIPC();
112111}
113112
114113void RemoteRenderingBackend::dispatch(Function<void()>&& task)
115114{
116  m_workQueue->dispatch(WTFMove(task));
 115 m_workQueue.dispatch(WTFMove(task));
117116}
118117
119118IPC::Connection* RemoteRenderingBackend::messageSenderConnection() const

@@uint64_t RemoteRenderingBackend::messageSenderDestinationID() const
126125 return m_renderingBackendIdentifier.toUInt64();
127126}
128127
129 bool RemoteRenderingBackend::applyMediaItem(DisplayList::ItemHandle item, GraphicsContext& context)
130 {
131  ASSERT(!RunLoop::isMain());
132 
133  if (!item.is<DisplayList::PaintFrameForMedia>())
134  return false;
135 
136  auto& mediaItem = item.get<DisplayList::PaintFrameForMedia>();
137  callOnMainRunLoopAndWait([&, gpuConnectionToWebProcess = m_gpuConnectionToWebProcess, mediaPlayerIdentifier = mediaItem.identifier()] {
138  auto player = gpuConnectionToWebProcess->remoteMediaPlayerManagerProxy().mediaPlayer(mediaPlayerIdentifier);
139  if (!player)
140  return;
141  // It is currently not safe to call paintFrameForMedia() off the main thread.
142  context.paintFrameForMedia(*player, mediaItem.destination());
143  });
144  return true;
145 }
146 
147 void RemoteRenderingBackend::didCreateImageBufferBackend(ImageBufferBackendHandle handle, QualifiedRenderingResourceIdentifier renderingResourceIdentifier)
 128void RemoteRenderingBackend::didCreateImageBufferBackend(ImageBufferBackendHandle handle, QualifiedRenderingResourceIdentifier renderingResourceIdentifier, RemoteDisplayListRecorder& remoteDisplayList)
148129{
 130 m_remoteDisplayLists.add(remoteDisplayList);
149131 MESSAGE_CHECK(renderingResourceIdentifier.processIdentifier() == m_gpuConnectionToWebProcess->webProcessIdentifier(), "Sending didCreateImageBufferBackend() message to the wrong web process.");
150132 send(Messages::RemoteRenderingBackendProxy::DidCreateImageBufferBackend(WTFMove(handle), renderingResourceIdentifier.object()), m_renderingBackendIdentifier);
151133}

@@void RemoteRenderingBackend::createImageBufferWithQualifiedIdentifier(const Floa
190172
191173 m_remoteResourceCache.cacheImageBuffer(*imageBuffer, imageBufferResourceIdentifier);
192174 updateRenderingResourceRequest();
193 
194  if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(imageBufferResourceIdentifier))
195  resumeFromPendingWakeupInformation();
196 }
197 
198 RemoteRenderingBackend::ReplayerDelegate::ReplayerDelegate(WebCore::ImageBuffer& destination, RemoteRenderingBackend& remoteRenderingBackend, ProcessIdentifier webProcessIdentifier)
199  : m_destination(destination)
200  , m_remoteRenderingBackend(remoteRenderingBackend)
201  , m_webProcessIdentifier(webProcessIdentifier)
202 {
203 }
204 
205 bool RemoteRenderingBackend::ReplayerDelegate::apply(WebCore::DisplayList::ItemHandle item, WebCore::GraphicsContext& graphicsContext)
206 {
207  auto apply = [&](auto&& destination) {
208  return destination.apply(item, graphicsContext);
209  };
210 
211  if (m_destination.renderingMode() == RenderingMode::Accelerated)
212  return apply(static_cast<AcceleratedRemoteImageBuffer&>(m_destination));
213  return apply(static_cast<UnacceleratedRemoteImageBuffer&>(m_destination));
214 }
215 
216 void RemoteRenderingBackend::ReplayerDelegate::didCreateMaskImageBuffer(WebCore::ImageBuffer& imageBuffer)
217 {
218  m_remoteRenderingBackend.didCreateMaskImageBuffer(imageBuffer);
219 }
220 
221 void RemoteRenderingBackend::ReplayerDelegate::didResetMaskImageBuffer()
222 {
223  m_remoteRenderingBackend.didResetMaskImageBuffer();
224 }
225 
226 void RemoteRenderingBackend::ReplayerDelegate::recordResourceUse(RenderingResourceIdentifier renderingResourceIdentifier)
227 {
228  m_remoteRenderingBackend.remoteResourceCache().recordResourceUse({ renderingResourceIdentifier, m_webProcessIdentifier });
229 }
230 
231 DisplayList::ReplayResult RemoteRenderingBackend::submit(const DisplayList::DisplayList& displayList, ImageBuffer& destination)
232 {
233  if (displayList.isEmpty())
234  return { };
235 
236  ReplayerDelegate replayerDelegate(destination, *this, m_gpuConnectionToWebProcess->webProcessIdentifier());
237 
238  return WebCore::DisplayList::Replayer {
239  destination.context(),
240  displayList,
241  &remoteResourceCache().resourceHeap(),
242  m_currentMaskImageBuffer.get(),
243  &replayerDelegate
244  }.replay();
245 }
246 
247 RefPtr<ImageBuffer> RemoteRenderingBackend::nextDestinationImageBufferAfterApplyingDisplayLists(ImageBuffer& initialDestination, size_t initialOffset, DisplayListReaderHandle& handle, GPUProcessWakeupReason reason, ProcessIdentifier webProcessIdentifier)
248 {
249  RefPtr destination { &initialDestination };
250  Ref handleProtector { handle };
251 
252  auto offset = initialOffset;
253  size_t sizeToRead = 0;
254  do {
255  sizeToRead = handle.unreadBytes();
256  } while (!sizeToRead);
257 
258  while (destination) {
259  auto displayList = handle.displayListForReading(offset, sizeToRead, *this);
260  MESSAGE_CHECK_WITH_RETURN_VALUE(displayList, nullptr, "Failed to map display list from shared memory");
261 
262 #if !LOG_DISABLED
263  auto startTime = MonotonicTime::now();
264 #endif
265  auto result = submit(*displayList, *destination);
266  LOG_WITH_STREAM(SharedDisplayLists, stream << "Read [" << offset << ", " << offset + result.numberOfBytesRead << "]; Items[" << handle.identifier() << "] => Image(" << destination->renderingResourceIdentifier() << ") in " << MonotonicTime::now() - startTime);
267  MESSAGE_CHECK_WITH_RETURN_VALUE(result.reasonForStopping != DisplayList::StopReplayReason::InvalidItemOrExtent, nullptr, "Detected invalid display list item or extent");
268  MESSAGE_CHECK_WITH_RETURN_VALUE(result.reasonForStopping != DisplayList::StopReplayReason::OutOfMemory, nullptr, "Cound not allocate memory");
269 
270  auto advanceResult = handle.advance(result.numberOfBytesRead);
271  MESSAGE_CHECK_WITH_RETURN_VALUE(advanceResult, nullptr, "Failed to advance display list reader handle");
272  sizeToRead = *advanceResult;
273 
274  CheckedSize checkedOffset = offset;
275  checkedOffset += result.numberOfBytesRead;
276  MESSAGE_CHECK_WITH_RETURN_VALUE(!checkedOffset.hasOverflowed(), nullptr, "Overflowed when advancing shared display list handle offset");
277 
278  offset = checkedOffset;
279  MESSAGE_CHECK_WITH_RETURN_VALUE(offset <= handle.sharedMemory().size(), nullptr, "Out-of-bounds offset into shared display list handle");
280 
281  if (result.reasonForStopping == DisplayList::StopReplayReason::ChangeDestinationImageBuffer) {
282  destination = m_remoteResourceCache.cachedImageBuffer({ *result.nextDestinationImageBuffer, m_gpuConnectionToWebProcess->webProcessIdentifier() });
283  if (!destination) {
284  ASSERT(!m_pendingWakeupInfo);
285  m_pendingWakeupInfo = {{
286  handle.identifier(),
287  offset,
288  { *result.nextDestinationImageBuffer, webProcessIdentifier },
289  reason,
290  std::nullopt,
291  RemoteRenderingBackendState::WaitingForDestinationImageBuffer
292  }};
293  }
294  }
295 
296  if (result.reasonForStopping == DisplayList::StopReplayReason::MissingCachedResource) {
297  m_pendingWakeupInfo = {{
298  handle.identifier(),
299  offset,
300  { destination->renderingResourceIdentifier(), webProcessIdentifier },
301  reason,
302  { { *result.missingCachedResourceIdentifier, webProcessIdentifier } },
303  RemoteRenderingBackendState::WaitingForCachedResource
304  }};
305  }
306 
307  if (m_pendingWakeupInfo)
308  break;
309 
310  if (!sizeToRead) {
311  if (reason != GPUProcessWakeupReason::ItemCountHysteresisExceeded)
312  break;
313 
314  handle.startWaiting();
315  m_resumeDisplayListSemaphore.waitFor(30_us);
316 
317  auto stopWaitingResult = handle.stopWaiting();
318  MESSAGE_CHECK_WITH_RETURN_VALUE(stopWaitingResult, nullptr, "Invalid waiting status detected when resuming display list processing");
319 
320  auto resumeReadingInfo = stopWaitingResult.value();
321  if (!resumeReadingInfo)
322  break;
323 
324  sizeToRead = handle.unreadBytes();
325  MESSAGE_CHECK_WITH_RETURN_VALUE(sizeToRead, nullptr, "No unread bytes when resuming display list processing");
326 
327  auto newDestinationIdentifier = makeObjectIdentifier<RenderingResourceIdentifierType>(resumeReadingInfo->destination);
328  MESSAGE_CHECK_WITH_RETURN_VALUE(newDestinationIdentifier.isValid(), nullptr, "Invalid image buffer destination when resuming display list processing");
329 
330  destination = m_remoteResourceCache.cachedImageBuffer({ newDestinationIdentifier, m_gpuConnectionToWebProcess->webProcessIdentifier() });
331  MESSAGE_CHECK_WITH_RETURN_VALUE(destination, nullptr, "Missing image buffer destination when resuming display list processing");
332 
333  offset = resumeReadingInfo->offset;
334  }
335  }
336 
337  return destination;
338 }
339 
340 void RemoteRenderingBackend::wakeUpAndApplyDisplayList(const GPUProcessWakeupMessageArguments& arguments)
341 {
342  // Immediately turn the RenderingResourceIdentifier (which is error-prone) to a QualifiedRenderingResourceIdentifier,
343  // and use a helper function to make sure that don't accidentally use the RenderingResourceIdentifier (because the helper function can't see it).
344  wakeUpAndApplyDisplayListWithQualifiedIdentifier(arguments.itemBufferIdentifier, arguments.offset, { arguments.destinationImageBufferIdentifier, m_gpuConnectionToWebProcess->webProcessIdentifier() }, arguments.reason);
345 }
346 
347 void RemoteRenderingBackend::wakeUpAndApplyDisplayListWithQualifiedIdentifier(WebCore::DisplayList::ItemBufferIdentifier itemBufferIdentifier, uint64_t offset, QualifiedRenderingResourceIdentifier destinationImageBufferIdentifier, GPUProcessWakeupReason reason)
348 {
349  ASSERT(!RunLoop::isMain());
350 
351  TraceScope tracingScope(WakeUpAndApplyDisplayListStart, WakeUpAndApplyDisplayListEnd);
352 
353  updateLastKnownState(RemoteRenderingBackendState::BeganReplayingDisplayList);
354 
355  RefPtr destinationImageBuffer = m_remoteResourceCache.cachedImageBuffer(destinationImageBufferIdentifier);
356  MESSAGE_CHECK(destinationImageBuffer, "Missing destination image buffer");
357 
358  auto initialHandle = m_sharedDisplayListHandles.get(itemBufferIdentifier);
359  MESSAGE_CHECK(initialHandle, "Missing initial shared display list handle");
360 
361  LOG_WITH_STREAM(SharedDisplayLists, stream << "Waking up to Items[" << itemBufferIdentifier << "] => Image(" << destinationImageBufferIdentifier.object() << ") at " << offset);
362  destinationImageBuffer = nextDestinationImageBufferAfterApplyingDisplayLists(*destinationImageBuffer, offset, *initialHandle, reason, m_gpuConnectionToWebProcess->webProcessIdentifier());
363 
364  // FIXME: All the callers pass m_pendingWakeupInfo's fields so the body of this function should just be this loop.
365  while (destinationImageBuffer && m_pendingWakeupInfo) {
366  if (m_pendingWakeupInfo->missingCachedResourceIdentifier)
367  break;
368 
369  auto nextHandle = m_sharedDisplayListHandles.get(m_pendingWakeupInfo->itemBufferIdentifier);
370  if (!nextHandle) {
371  // If the handle identifier is currently unknown, wait until the GPU process receives an
372  // IPC message with a shared memory handle to the next item buffer.
373  break;
374  }
375 
376  // Otherwise, continue reading the next display list item buffer from the start.
377  auto offset = m_pendingWakeupInfo->offset;
378  auto reason = m_pendingWakeupInfo->reason;
379  m_pendingWakeupInfo = std::nullopt;
380  destinationImageBuffer = nextDestinationImageBufferAfterApplyingDisplayLists(*destinationImageBuffer, offset, *nextHandle, reason, m_gpuConnectionToWebProcess->webProcessIdentifier());
381  }
382  LOG_WITH_STREAM(SharedDisplayLists, stream << "Going back to sleep.");
383 
384  if (m_pendingWakeupInfo)
385  updateLastKnownState(m_pendingWakeupInfo->state);
386  else
387  updateLastKnownState(RemoteRenderingBackendState::FinishedReplayingDisplayList);
388 }
389 
390 void RemoteRenderingBackend::setNextItemBufferToRead(DisplayList::ItemBufferIdentifier identifier, QualifiedRenderingResourceIdentifier destinationIdentifier)
391 {
392  m_pendingWakeupInfo = {{
393  identifier,
394  SharedDisplayListHandle::headerSize(),
395  destinationIdentifier,
396  GPUProcessWakeupReason::Unspecified,
397  std::nullopt,
398  RemoteRenderingBackendState::WaitingForItemBuffer
399  }};
400175}
401176
402177std::optional<SharedMemory::IPCHandle> RemoteRenderingBackend::updateSharedMemoryForGetPixelBufferHelper(size_t byteCount)

@@void RemoteRenderingBackend::cacheNativeImageWithQualifiedIdentifier(const Share
547322 return;
548323
549324 m_remoteResourceCache.cacheNativeImage(*image, nativeImageResourceIdentifier);
550 
551  if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(nativeImageResourceIdentifier))
552  resumeFromPendingWakeupInformation();
553325}
554326
555327void RemoteRenderingBackend::cacheFont(Ref<WebCore::Font>&& font)

@@void RemoteRenderingBackend::cacheFontWithQualifiedIdentifier(Ref<Font>&& font,
565337 ASSERT(!RunLoop::isMain());
566338
567339 m_remoteResourceCache.cacheFont(WTFMove(font), fontResourceIdentifier);
568  if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(fontResourceIdentifier))
569  resumeFromPendingWakeupInformation();
570340}
571341
572342void RemoteRenderingBackend::deleteAllFonts()

@@void RemoteRenderingBackend::releaseRemoteResourceWithQualifiedIdentifier(Qualif
592362
593363void RemoteRenderingBackend::finalizeRenderingUpdate(RenderingUpdateID renderingUpdateID)
594364{
595  auto shouldPerformWakeup = [&] {
596  return m_remoteResourceCache.cachedImageBuffer(m_pendingWakeupInfo->destinationImageBufferIdentifier) && m_sharedDisplayListHandles.contains(m_pendingWakeupInfo->itemBufferIdentifier);
597  };
598 
599  if (m_pendingWakeupInfo && shouldPerformWakeup())
600  resumeFromPendingWakeupInformation();
601 
602365 send(Messages::RemoteRenderingBackendProxy::DidFinalizeRenderingUpdate(renderingUpdateID), m_renderingBackendIdentifier);
603366}
604367
605 void RemoteRenderingBackend::didCreateSharedDisplayListHandle(DisplayList::ItemBufferIdentifier itemBufferIdentifier, const SharedMemory::IPCHandle& handle, RenderingResourceIdentifier destinationBufferIdentifier)
606 {
607  // Immediately turn the RenderingResourceIdentifier (which is error-prone) to a QualifiedRenderingResourceIdentifier,
608  // and use a helper function to make sure that don't accidentally use the RenderingResourceIdentifier (because the helper function can't see it).
609  didCreateSharedDisplayListHandleWithQualifiedIdentifier(itemBufferIdentifier, handle, { destinationBufferIdentifier, m_gpuConnectionToWebProcess->webProcessIdentifier() });
610 }
611 
612 void RemoteRenderingBackend::didCreateSharedDisplayListHandleWithQualifiedIdentifier(DisplayList::ItemBufferIdentifier itemBufferIdentifier, const SharedMemory::IPCHandle& handle, QualifiedRenderingResourceIdentifier)
613 {
614  ASSERT(!RunLoop::isMain());
615  MESSAGE_CHECK(!m_sharedDisplayListHandles.contains(itemBufferIdentifier), "Duplicate shared display list handle");
616 
617  if (auto sharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadWrite)) {
618  auto handle = DisplayListReaderHandle::create(itemBufferIdentifier, sharedMemory.releaseNonNull());
619  MESSAGE_CHECK(handle, "There must be enough space to create the handle.");
620  m_sharedDisplayListHandles.set(itemBufferIdentifier, handle);
621  }
622 
623  if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(itemBufferIdentifier))
624  resumeFromPendingWakeupInformation();
625 }
626 
627 void RemoteRenderingBackend::resumeFromPendingWakeupInformation()
628 {
629  auto itemBufferIdentifier = m_pendingWakeupInfo->itemBufferIdentifier;
630  auto offset = m_pendingWakeupInfo->offset;
631  auto destinationImageBufferIdentifier = m_pendingWakeupInfo->destinationImageBufferIdentifier;
632  auto reason = m_pendingWakeupInfo->reason;
633  m_pendingWakeupInfo = std::nullopt;
634  wakeUpAndApplyDisplayListWithQualifiedIdentifier(itemBufferIdentifier, offset, destinationImageBufferIdentifier, reason);
635 }
636 
637 void RemoteRenderingBackend::didCreateMaskImageBuffer(ImageBuffer& imageBuffer)
638 {
639  ASSERT(!RunLoop::isMain());
640  MESSAGE_CHECK(!m_currentMaskImageBuffer, "Current mask image buffer is already set.");
641  m_currentMaskImageBuffer = &imageBuffer;
642 }
643 
644 void RemoteRenderingBackend::didResetMaskImageBuffer()
645 {
646  ASSERT(!RunLoop::isMain());
647  MESSAGE_CHECK(m_currentMaskImageBuffer, "Current mask image buffer was not already set.");
648  m_currentMaskImageBuffer = nullptr;
649 }
650 
651 std::optional<DisplayList::ItemHandle> WARN_UNUSED_RETURN RemoteRenderingBackend::decodeItem(const uint8_t* data, size_t length, DisplayList::ItemType type, uint8_t* handleLocation)
652 {
653  /* This needs to match (1) isInlineItem() in DisplayListItemType.cpp, (2) RemoteImageBufferProxy::encodeItem(),
654  * and (3) all the "static constexpr bool isInlineItem"s inside the individual item classes.
655  * See the comment at the top of DisplayListItems.h for why. */
656 
657  switch (type) {
658  case DisplayList::ItemType::BeginClipToDrawingCommands:
659  return decodeAndCreate<DisplayList::BeginClipToDrawingCommands>(data, length, handleLocation);
660  case DisplayList::ItemType::ClipOutToPath:
661  return decodeAndCreate<DisplayList::ClipOutToPath>(data, length, handleLocation);
662  case DisplayList::ItemType::ClipPath:
663  return decodeAndCreate<DisplayList::ClipPath>(data, length, handleLocation);
664  case DisplayList::ItemType::DrawFocusRingPath:
665  return decodeAndCreate<DisplayList::DrawFocusRingPath>(data, length, handleLocation);
666  case DisplayList::ItemType::DrawFocusRingRects:
667  return decodeAndCreate<DisplayList::DrawFocusRingRects>(data, length, handleLocation);
668  case DisplayList::ItemType::DrawGlyphs:
669  return decodeAndCreate<DisplayList::DrawGlyphs>(data, length, handleLocation);
670  case DisplayList::ItemType::DrawLinesForText:
671  return decodeAndCreate<DisplayList::DrawLinesForText>(data, length, handleLocation);
672  case DisplayList::ItemType::DrawPath:
673  return decodeAndCreate<DisplayList::DrawPath>(data, length, handleLocation);
674  case DisplayList::ItemType::FillCompositedRect:
675  return decodeAndCreate<DisplayList::FillCompositedRect>(data, length, handleLocation);
676  case DisplayList::ItemType::FillPath:
677  return decodeAndCreate<DisplayList::FillPath>(data, length, handleLocation);
678  case DisplayList::ItemType::FillRectWithColor:
679  return decodeAndCreate<DisplayList::FillRectWithColor>(data, length, handleLocation);
680  case DisplayList::ItemType::FillRectWithGradient:
681  return decodeAndCreate<DisplayList::FillRectWithGradient>(data, length, handleLocation);
682  case DisplayList::ItemType::FillRectWithRoundedHole:
683  return decodeAndCreate<DisplayList::FillRectWithRoundedHole>(data, length, handleLocation);
684  case DisplayList::ItemType::FillRoundedRect:
685  return decodeAndCreate<DisplayList::FillRoundedRect>(data, length, handleLocation);
686  case DisplayList::ItemType::GetPixelBuffer:
687  return decodeAndCreate<DisplayList::GetPixelBuffer>(data, length, handleLocation);
688  case DisplayList::ItemType::PutPixelBuffer:
689  return decodeAndCreate<DisplayList::PutPixelBuffer>(data, length, handleLocation);
690  case DisplayList::ItemType::SetLineDash:
691  return decodeAndCreate<DisplayList::SetLineDash>(data, length, handleLocation);
692  case DisplayList::ItemType::SetState:
693  return decodeAndCreate<DisplayList::SetState>(data, length, handleLocation);
694  case DisplayList::ItemType::StrokePath:
695  return decodeAndCreate<DisplayList::StrokePath>(data, length, handleLocation);
696  case DisplayList::ItemType::ApplyDeviceScaleFactor:
697 #if USE(CG)
698  case DisplayList::ItemType::ApplyFillPattern:
699  case DisplayList::ItemType::ApplyStrokePattern:
700 #endif
701  case DisplayList::ItemType::BeginTransparencyLayer:
702  case DisplayList::ItemType::ClearRect:
703  case DisplayList::ItemType::ClearShadow:
704  case DisplayList::ItemType::Clip:
705  case DisplayList::ItemType::ClipOut:
706  case DisplayList::ItemType::ClipToImageBuffer:
707  case DisplayList::ItemType::EndClipToDrawingCommands:
708  case DisplayList::ItemType::ConcatenateCTM:
709  case DisplayList::ItemType::DrawDotsForDocumentMarker:
710  case DisplayList::ItemType::DrawEllipse:
711  case DisplayList::ItemType::DrawImageBuffer:
712  case DisplayList::ItemType::DrawNativeImage:
713  case DisplayList::ItemType::DrawPattern:
714  case DisplayList::ItemType::DrawLine:
715  case DisplayList::ItemType::DrawRect:
716  case DisplayList::ItemType::EndTransparencyLayer:
717  case DisplayList::ItemType::FillEllipse:
718 #if ENABLE(INLINE_PATH_DATA)
719  case DisplayList::ItemType::FillLine:
720  case DisplayList::ItemType::FillArc:
721  case DisplayList::ItemType::FillQuadCurve:
722  case DisplayList::ItemType::FillBezierCurve:
723 #endif
724  case DisplayList::ItemType::FillRect:
725  case DisplayList::ItemType::FlushContext:
726  case DisplayList::ItemType::MetaCommandChangeDestinationImageBuffer:
727  case DisplayList::ItemType::MetaCommandChangeItemBuffer:
728 #if ENABLE(VIDEO)
729  case DisplayList::ItemType::PaintFrameForMedia:
730 #endif
731  case DisplayList::ItemType::Restore:
732  case DisplayList::ItemType::Rotate:
733  case DisplayList::ItemType::Save:
734  case DisplayList::ItemType::Scale:
735  case DisplayList::ItemType::SetCTM:
736  case DisplayList::ItemType::SetInlineFillColor:
737  case DisplayList::ItemType::SetInlineStrokeColor:
738  case DisplayList::ItemType::SetLineCap:
739  case DisplayList::ItemType::SetLineJoin:
740  case DisplayList::ItemType::SetMiterLimit:
741  case DisplayList::ItemType::SetStrokeThickness:
742  case DisplayList::ItemType::StrokeEllipse:
743 #if ENABLE(INLINE_PATH_DATA)
744  case DisplayList::ItemType::StrokeArc:
745  case DisplayList::ItemType::StrokeQuadCurve:
746  case DisplayList::ItemType::StrokeBezierCurve:
747 #endif
748  case DisplayList::ItemType::StrokeRect:
749  case DisplayList::ItemType::StrokeLine:
750  case DisplayList::ItemType::Translate:
751  ASSERT_NOT_REACHED();
752  return std::nullopt;
753  }
754  ASSERT_NOT_REACHED();
755  return std::nullopt;
756 }
757 
758368void RemoteRenderingBackend::updateRenderingResourceRequest()
759369{
760370 bool hasActiveDrawables = m_remoteResourceCache.hasActiveDrawables();

@@bool RemoteRenderingBackend::allowsExitUnderMemoryPressure() const
771381 return !m_remoteResourceCache.hasActiveDrawables();
772382}
773383
774 RemoteRenderingBackendState RemoteRenderingBackend::lastKnownState() const
775 {
776  ASSERT(RunLoop::isMain());
777  return m_lastKnownState.load();
778 }
779 
780 void RemoteRenderingBackend::updateLastKnownState(RemoteRenderingBackendState state)
781 {
782  ASSERT(!RunLoop::isMain());
783  m_lastKnownState.storeRelaxed(state);
784 }
785 
786384void RemoteRenderingBackend::performWithMediaPlayerOnMainThread(MediaPlayerIdentifier identifier, Function<void(MediaPlayer&)>&& callback)
787385{
788386 callOnMainRunLoopAndWait([&, gpuConnectionToWebProcess = m_gpuConnectionToWebProcess, identifier] {

Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h

2828#if ENABLE(GPU_PROCESS)
2929
3030#include "Connection.h"
31 #include "GPUProcessWakeupMessageArguments.h"
3231#include "IPCSemaphore.h"
3332#include "ImageBufferBackendHandle.h"
3433#include "MessageReceiver.h"
3534#include "MessageSender.h"
3635#include "QualifiedRenderingResourceIdentifier.h"
 36#include "RemoteDisplayListRecorder.h"
3737#include "RemoteRenderingBackendState.h"
3838#include "RemoteResourceCache.h"
3939#include "RenderingBackendIdentifier.h"
4040#include "RenderingUpdateID.h"
4141#include "ScopedRenderingResourcesRequest.h"
 42#include "StreamConnectionWorkQueue.h"
 43#include "StreamMessageReceiver.h"
 44#include "StreamServerConnection.h"
4245#include <WebCore/ColorSpace.h>
4346#include <WebCore/DisplayList.h>
4447#include <WebCore/DisplayListItems.h>

4851
4952namespace WebCore {
5053
51 namespace DisplayList {
52 class DisplayList;
53 class Item;
54 }
55 
5654class DestinationColorSpace;
5755class FloatSize;
5856class NativeImage;

@@enum class RenderingMode : bool;
6361
6462namespace WebKit {
6563
66 class DisplayListReaderHandle;
6764class GPUConnectionToWebProcess;
 65class RemoteDisplayListRecorder;
6866struct RemoteRenderingBackendCreationParameters;
6967
70 class RemoteRenderingBackend
71  : private IPC::MessageSender
72  , public IPC::Connection::WorkQueueMessageReceiver
73  , public WebCore::DisplayList::ItemBufferReadingClient {
 68class RemoteRenderingBackend : private IPC::MessageSender, public IPC::StreamMessageReceiver {
7469public:
75 
76  static Ref<RemoteRenderingBackend> create(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&);
 70 static Ref<RemoteRenderingBackend> create(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
7771 virtual ~RemoteRenderingBackend();
7872 void stopListeningForIPC();
7973
8074 RemoteResourceCache& remoteResourceCache() { return m_remoteResourceCache; }
8175
82  // Rendering operations.
83  bool applyMediaItem(WebCore::DisplayList::ItemHandle, WebCore::GraphicsContext&);
 76 void didReceiveStreamMessage(IPC::StreamServerConnectionBase&, IPC::Decoder&) final;
8477
8578 // Messages to be sent.
86  void didCreateImageBufferBackend(ImageBufferBackendHandle, QualifiedRenderingResourceIdentifier);
 79 void didCreateImageBufferBackend(ImageBufferBackendHandle, QualifiedRenderingResourceIdentifier, RemoteDisplayListRecorder&);
8780 void didFlush(WebCore::GraphicsContextFlushIdentifier, QualifiedRenderingResourceIdentifier);
8881
89  void setNextItemBufferToRead(WebCore::DisplayList::ItemBufferIdentifier, QualifiedRenderingResourceIdentifier destination);
90 
91  void didCreateMaskImageBuffer(WebCore::ImageBuffer&);
92  void didResetMaskImageBuffer();
93 
9482 void populateGetPixelBufferSharedMemory(std::optional<WebCore::PixelBuffer>&&);
9583
9684 bool allowsExitUnderMemoryPressure() const;

@@public:
9886 // Runs Function in RemoteRenderingBackend task queue.
9987 void dispatch(Function<void()>&&);
10088
101  RemoteRenderingBackendState lastKnownState() const;
102 
 89 IPC::StreamServerConnection& streamConnection() const { return m_streamConnection.get(); }
10390 void performWithMediaPlayerOnMainThread(WebCore::MediaPlayerIdentifier, Function<void(WebCore::MediaPlayer&)>&&);
10491
10592private:
106  RemoteRenderingBackend(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&);
 93 RemoteRenderingBackend(GPUConnectionToWebProcess&, RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
10794 void startListeningForIPC();
10895
109  std::optional<WebCore::DisplayList::ItemHandle> WARN_UNUSED_RETURN decodeItem(const uint8_t* data, size_t length, WebCore::DisplayList::ItemType, uint8_t* handleLocation) override;
110 
111  template<typename T>
112  std::optional<WebCore::DisplayList::ItemHandle> WARN_UNUSED_RETURN decodeAndCreate(const uint8_t* data, size_t length, uint8_t* handleLocation)
113  {
114  if (auto item = IPC::Decoder::decodeSingleObject<T>(data, length)) {
115  // FIXME: WebKit2 should not need to know that the first 8 bytes at the handle are reserved for the type.
116  // Need to figure out a way to keep this knowledge within display list code in WebCore.
117  new (handleLocation + sizeof(uint64_t)) T(WTFMove(*item));
118  return {{ handleLocation }};
119  }
120  return std::nullopt;
121  }
122 
123  WebCore::DisplayList::ReplayResult submit(const WebCore::DisplayList::DisplayList&, WebCore::ImageBuffer& destination);
124  RefPtr<WebCore::ImageBuffer> nextDestinationImageBufferAfterApplyingDisplayLists(WebCore::ImageBuffer& initialDestination, size_t initialOffset, DisplayListReaderHandle&, GPUProcessWakeupReason, WebCore::ProcessIdentifier webProcessIdentifier);
125 
12696 std::optional<SharedMemory::IPCHandle> updateSharedMemoryForGetPixelBufferHelper(size_t byteCount);
12797 void updateRenderingResourceRequest();
12898
129  void updateLastKnownState(RemoteRenderingBackendState);
130 
13199 // IPC::MessageSender.
132100 IPC::Connection* messageSenderConnection() const override;
133101 uint64_t messageSenderDestinationID() const override;
134102
135  // IPC::MessageReceiver
136  void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
137  bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) override;
138 
139103 // Messages to be received.
140104 void createImageBuffer(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, WebCore::RenderingResourceIdentifier);
141  void wakeUpAndApplyDisplayList(const GPUProcessWakeupMessageArguments&);
142105 void updateSharedMemoryForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&)>&&);
143106 void semaphoreForGetPixelBuffer(CompletionHandler<void(const IPC::Semaphore&)>&&);
144107 void updateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&, const IPC::Semaphore&)>&&);

@@private:
151114 void deleteAllFonts();
152115 void releaseRemoteResource(WebCore::RenderingResourceIdentifier, uint64_t useCount);
153116 void finalizeRenderingUpdate(RenderingUpdateID);
154  void didCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier, const SharedMemory::IPCHandle&, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
155117
156118 // Received messages translated to use QualifiedRenderingResourceIdentifier.
157  void wakeUpAndApplyDisplayListWithQualifiedIdentifier(WebCore::DisplayList::ItemBufferIdentifier, uint64_t offset, QualifiedRenderingResourceIdentifier, GPUProcessWakeupReason);
158119 void createImageBufferWithQualifiedIdentifier(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, QualifiedRenderingResourceIdentifier);
159120 void getDataURLForImageBufferWithQualifiedIdentifier(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, QualifiedRenderingResourceIdentifier, CompletionHandler<void(String&&)>&&);
160121 void getDataForImageBufferWithQualifiedIdentifier(const String& mimeType, std::optional<double> quality, QualifiedRenderingResourceIdentifier, CompletionHandler<void(Vector<uint8_t>&&)>&&);

@@private:
164125 void releaseRemoteResourceWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier, uint64_t useCount);
165126 void cacheFontWithQualifiedIdentifier(Ref<WebCore::Font>&&, QualifiedRenderingResourceIdentifier);
166127
167  void resumeFromPendingWakeupInformation();
168 
169  class ReplayerDelegate : public WebCore::DisplayList::Replayer::Delegate {
170  public:
171  ReplayerDelegate(WebCore::ImageBuffer&, RemoteRenderingBackend&, WebCore::ProcessIdentifier webProcessIdentifier);
172 
173  private:
174  bool apply(WebCore::DisplayList::ItemHandle, WebCore::GraphicsContext&) final;
175  void didCreateMaskImageBuffer(WebCore::ImageBuffer&) final;
176  void didResetMaskImageBuffer() final;
177  void recordResourceUse(WebCore::RenderingResourceIdentifier) final;
178 
179  WebCore::ImageBuffer& m_destination;
180  RemoteRenderingBackend& m_remoteRenderingBackend;
181  WebCore::ProcessIdentifier m_webProcessIdentifier;
182  };
183 
184  struct PendingWakeupInformation {
185  WebCore::DisplayList::ItemBufferIdentifier itemBufferIdentifier;
186  uint64_t offset { 0 };
187  QualifiedRenderingResourceIdentifier destinationImageBufferIdentifier;
188  GPUProcessWakeupReason reason { GPUProcessWakeupReason::Unspecified };
189  std::optional<QualifiedRenderingResourceIdentifier> missingCachedResourceIdentifier;
190  RemoteRenderingBackendState state { RemoteRenderingBackendState::Initialized };
191 
192  bool shouldPerformWakeup(QualifiedRenderingResourceIdentifier identifier) const
193  {
194  return destinationImageBufferIdentifier == identifier
195  || missingCachedResourceIdentifier == identifier;
196  }
197 
198  bool shouldPerformWakeup(WebCore::DisplayList::ItemBufferIdentifier identifier) const
199  {
200  return itemBufferIdentifier == identifier;
201  }
202  };
203 
204  Ref<WorkQueue> m_workQueue;
 128 IPC::StreamConnectionWorkQueue m_workQueue;
 129 Ref<IPC::StreamServerConnection> m_streamConnection;
205130 RemoteResourceCache m_remoteResourceCache;
206131 Ref<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
207132 RenderingBackendIdentifier m_renderingBackendIdentifier;
208  HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListReaderHandle>> m_sharedDisplayListHandles;
209  std::optional<PendingWakeupInformation> m_pendingWakeupInfo;
210  IPC::Semaphore m_resumeDisplayListSemaphore;
211133 IPC::Semaphore m_getPixelBufferSemaphore;
212134 RefPtr<SharedMemory> m_getPixelBufferSharedMemory;
213135 ScopedRenderingResourcesRequest m_renderingResourcesRequest;
214  RefPtr<WebCore::ImageBuffer> m_currentMaskImageBuffer;
215  Atomic<RemoteRenderingBackendState> m_lastKnownState { RemoteRenderingBackendState::Initialized };
 136 WeakHashSet<RemoteDisplayListRecorder> m_remoteDisplayLists;
216137};
217138
218139} // namespace WebKit

Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in

2222
2323#if ENABLE(GPU_PROCESS)
2424
25 messages -> RemoteRenderingBackend {
 25messages -> RemoteRenderingBackend NotRefCounted Stream {
2626 CreateImageBuffer(WebCore::FloatSize logicalSize, WebCore::RenderingMode renderingMode, float resolutionScale, WebCore::DestinationColorSpace colorSpace, enum:uint8_t WebCore::PixelFormat pixelFormat, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
27  WakeUpAndApplyDisplayList(struct WebKit::GPUProcessWakeupMessageArguments arguments)
28  UpdateSharedMemoryForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle) Synchronous
29  SemaphoreForGetPixelBuffer() -> (IPC::Semaphore semaphore) Synchronous
30  UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle, IPC::Semaphore semaphore) Synchronous
 27 UpdateSharedMemoryForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle) Synchronous NotStreamEncodableReply
 28 SemaphoreForGetPixelBuffer() -> (IPC::Semaphore semaphore) Synchronous NotStreamEncodableReply
 29 UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle, IPC::Semaphore semaphore) Synchronous NotStreamEncodableReply
3130 DestroyGetPixelBufferSharedMemory()
3231 GetDataURLForImageBuffer(String mimeType, std::optional<double> quality, enum:uint8_t WebCore::PreserveResolution preserveResolution, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (String urlString) Synchronous
3332 GetDataForImageBuffer(String mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (Vector<uint8_t> data) Synchronous
34  GetShareableBitmapForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, enum:uint8_t WebCore::PreserveResolution preserveResolution) -> (WebKit::ShareableBitmap::Handle handle) Synchronous
35  CacheNativeImage(WebKit::ShareableBitmap::Handle handle, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
36  CacheFont(IPC::FontReference font)
 33 GetShareableBitmapForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, enum:uint8_t WebCore::PreserveResolution preserveResolution) -> (WebKit::ShareableBitmap::Handle handle) Synchronous NotStreamEncodableReply
 34 CacheNativeImage(WebKit::ShareableBitmap::Handle handle, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) NotStreamEncodable
 35 CacheFont(IPC::FontReference font) NotStreamEncodable
3736 DeleteAllFonts()
38  DidCreateSharedDisplayListHandle(WebCore::DisplayList::ItemBufferIdentifier identifier, WebKit::SharedMemory::IPCHandle handle, WebCore::RenderingResourceIdentifier destinationBufferIdentifier)
3937 ReleaseRemoteResource(WebCore::RenderingResourceIdentifier renderingResourceIdentifier, uint64_t useCount)
4038 FinalizeRenderingUpdate(WebKit::RenderingUpdateID renderingUpdateID)
4139}

Source/WebKit/GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h

@@namespace WebKit {
3636
3737struct RemoteRenderingBackendCreationParameters {
3838 RenderingBackendIdentifier identifier;
39  IPC::Semaphore resumeDisplayListSemaphore;
4039 WebPageProxyIdentifier pageProxyID;
4140 WebCore::PageIdentifier pageID;
4241
4342 void encode(IPC::Encoder& encoder) const
4443 {
45  encoder << identifier << resumeDisplayListSemaphore << pageProxyID << pageID;
 44 encoder << identifier << pageProxyID << pageID;
4645 }
4746
4847 static std::optional<RemoteRenderingBackendCreationParameters> decode(IPC::Decoder& decoder)

@@struct RemoteRenderingBackendCreationParameters {
5251 if (!identifier)
5352 return std::nullopt;
5453
55  std::optional<IPC::Semaphore> resumeDisplayListSemaphore;
56  decoder >> resumeDisplayListSemaphore;
57  if (!resumeDisplayListSemaphore)
58  return std::nullopt;
59 
6054 std::optional<WebPageProxyIdentifier> pageProxyID;
6155 decoder >> pageProxyID;
6256 if (!pageProxyID)

@@struct RemoteRenderingBackendCreationParameters {
6761 if (!pageID)
6862 return std::nullopt;
6963
70  return {{ *identifier, WTFMove(*resumeDisplayListSemaphore), *pageProxyID, *pageID }};
 64 return { { *identifier, *pageProxyID, *pageID } };
7165 }
7266};
7367

Source/WebKit/GPUProcess/graphics/RemoteResourceCache.h

2828#if ENABLE(GPU_PROCESS)
2929
3030#include "QualifiedRenderingResourceIdentifier.h"
 31#include <WebCore/DisplayList.h>
3132#include <WebCore/Font.h>
3233#include <WebCore/ImageBuffer.h>
3334#include <WebCore/NativeImage.h>

Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h

2929
3030#include "Encoder.h"
3131#include "Logging.h"
 32#include "RemoteDisplayListRecorderProxy.h"
 33#include "RemoteRenderingBackendMessages.h"
3234#include "RemoteRenderingBackendProxy.h"
3335#include "SharedMemory.h"
 36#include <WebCore/ConcreteImageBuffer.h>
3437#include <WebCore/DisplayList.h>
35 #include <WebCore/DisplayListImageBuffer.h>
3638#include <WebCore/DisplayListItems.h>
37 #include <WebCore/DisplayListRecorder.h>
38 #include <WebCore/DisplayListReplayer.h>
3939#include <WebCore/MIMETypeRegistry.h>
4040#include <wtf/Condition.h>
4141#include <wtf/Lock.h>

@@class RemoteRenderingBackend;
4747template<typename BackendType> class ThreadSafeRemoteImageBufferFlusher;
4848
4949template<typename BackendType>
50 class RemoteImageBufferProxy : public WebCore::DisplayList::ImageBuffer<BackendType>, public WebCore::DisplayList::RecorderImpl::Delegate, public WebCore::DisplayList::ItemBufferWritingClient {
51  using BaseDisplayListImageBuffer = WebCore::DisplayList::ImageBuffer<BackendType>;
52  using BaseDisplayListImageBuffer::m_backend;
53  using BaseDisplayListImageBuffer::m_drawingContext;
54  using BaseDisplayListImageBuffer::m_renderingResourceIdentifier;
55  using BaseDisplayListImageBuffer::resolutionScale;
 50class RemoteImageBufferProxy : public WebCore::ConcreteImageBuffer<BackendType> {
 51 using BaseConcreteImageBuffer = WebCore::ConcreteImageBuffer<BackendType>;
 52 using BaseConcreteImageBuffer::m_backend;
 53 using BaseConcreteImageBuffer::m_renderingResourceIdentifier;
 54 using BaseConcreteImageBuffer::resolutionScale;
5655
5756public:
5857 static RefPtr<RemoteImageBufferProxy> create(const WebCore::FloatSize& size, float resolutionScale, const WebCore::DestinationColorSpace& colorSpace, WebCore::PixelFormat pixelFormat, RemoteRenderingBackendProxy& remoteRenderingBackendProxy)

@@public:
6665 ~RemoteImageBufferProxy()
6766 {
6867 if (!m_remoteRenderingBackendProxy || m_remoteRenderingBackendProxy->isGPUProcessConnectionClosed()) {
69  clearDisplayList();
 68 m_remoteDisplayList.resetNeedsFlush();
7069 return;
7170 }
7271

@@public:
9897
9998protected:
10099 RemoteImageBufferProxy(const WebCore::ImageBufferBackend::Parameters& parameters, RemoteRenderingBackendProxy& remoteRenderingBackendProxy)
101  : BaseDisplayListImageBuffer(parameters, this)
 100 : BaseConcreteImageBuffer(parameters)
102101 , m_remoteRenderingBackendProxy(makeWeakPtr(remoteRenderingBackendProxy))
 102 , m_remoteDisplayList(*this, remoteRenderingBackendProxy, { { }, BaseConcreteImageBuffer::logicalSize() }, BaseConcreteImageBuffer::baseTransform())
103103 {
104104 ASSERT(m_remoteRenderingBackendProxy);
105105 m_remoteRenderingBackendProxy->remoteResourceCacheProxy().cacheImageBuffer(*this);
106 
107  m_drawingContext.displayList().setItemBufferWritingClient(this);
108  m_drawingContext.displayList().setItemBufferReadingClient(nullptr);
109  m_drawingContext.displayList().setTracksDrawingItemExtents(false);
110106 }
111107
112  WebCore::RenderingMode renderingMode() const final { return BaseDisplayListImageBuffer::renderingMode(); }
113 
114108 // It is safe to access m_receivedFlushIdentifier from the main thread without locking since it
115109 // only gets modified on the main thread.
116110 bool hasPendingFlush() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS

@@protected:
219213 return std::nullopt;
220214
221215 auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
222  mutableThis.m_drawingContext.recorder().getPixelBuffer(destinationFormat, srcRect);
 216 mutableThis.m_remoteDisplayList.getPixelBuffer(destinationFormat, srcRect);
223217 mutableThis.flushDrawingContextAsync();
224218
225219 if (m_remoteRenderingBackendProxy->waitForGetPixelBufferToComplete(timeout))

@@protected:
229223 return pixelBuffer;
230224 }
231225
 226 void clearBackend() final
 227 {
 228 m_remoteDisplayList.resetNeedsFlush();
 229 BaseConcreteImageBuffer::clearBackend();
 230 }
 231
 232 WebCore::GraphicsContext& context() const final
 233 {
 234 return const_cast<RemoteImageBufferProxy*>(this)->m_remoteDisplayList;
 235 }
 236
 237 WebCore::GraphicsContext* drawingContext() final
 238 {
 239 return &m_remoteDisplayList;
 240 }
 241
232242 void putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) final
233243 {
234244 // 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.
235245 // This means that putPixelBuffer() is only called when resolutionScale() == 1.
236246 ASSERT(resolutionScale() == 1);
237  m_drawingContext.recorder().putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
 247 m_remoteDisplayList.putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
238248 }
239249
240250 bool prefersPreparationForDisplay() final { return true; }

@@protected:
260270 if (UNLIKELY(!m_remoteRenderingBackendProxy))
261271 return;
262272
263  if (!m_drawingContext.displayList().isEmpty() || !hasPendingFlush()) {
 273 if (m_remoteDisplayList.needsFlush() || !hasPendingFlush()) {
264274 m_sentFlushIdentifier = WebCore::GraphicsContextFlushIdentifier::generate();
265  m_drawingContext.recorder().flushContext(m_sentFlushIdentifier);
 275 m_remoteDisplayList.flushContext(m_sentFlushIdentifier);
266276 }
267277
268  m_remoteRenderingBackendProxy->sendDeferredWakeupMessageIfNeeded();
269  clearDisplayList();
 278 m_remoteDisplayList.resetNeedsFlush();
270279 }
271280
272  void recordNativeImageUse(WebCore::NativeImage& image) final
 281 void recordNativeImageUse(WebCore::NativeImage& image)
273282 {
274283 if (m_remoteRenderingBackendProxy)
275284 m_remoteRenderingBackendProxy->remoteResourceCacheProxy().recordNativeImageUse(image);
276285 }
277286
278  bool isCachedImageBuffer(const WebCore::ImageBuffer& imageBuffer) const final
279  {
280  if (!m_remoteRenderingBackendProxy)
281  return false;
282  auto cachedImageBuffer = m_remoteRenderingBackendProxy->remoteResourceCacheProxy().cachedImageBuffer(imageBuffer.renderingResourceIdentifier());
283  ASSERT(!cachedImageBuffer || cachedImageBuffer == &imageBuffer);
284  return cachedImageBuffer;
285  }
286 
287  void changeDestinationImageBuffer(WebCore::RenderingResourceIdentifier nextImageBuffer) final
288  {
289  bool wasEmpty = m_drawingContext.displayList().isEmpty();
290  m_drawingContext.displayList().template append<WebCore::DisplayList::MetaCommandChangeDestinationImageBuffer>(nextImageBuffer);
291  if (wasEmpty)
292  clearDisplayList();
293  }
294 
295  void prepareToAppendDisplayListItems(WebCore::DisplayList::ItemBufferHandle&& handle) final
296  {
297  m_drawingContext.displayList().prepareToAppend(WTFMove(handle));
298  }
299 
300  void clearDisplayList()
301  {
302  m_drawingContext.displayList().clear();
303  }
304 
305  bool canAppendItemOfType(WebCore::DisplayList::ItemType) final
306  {
307  if (UNLIKELY(!m_remoteRenderingBackendProxy))
308  return false;
309  m_remoteRenderingBackendProxy->willAppendItem(m_renderingResourceIdentifier);
310  return true;
311  }
312 
313  void didAppendData(const WebCore::DisplayList::ItemBufferHandle& handle, size_t numberOfBytes, WebCore::DisplayList::DidChangeItemBuffer didChangeItemBuffer) final
314  {
315  if (LIKELY(m_remoteRenderingBackendProxy))
316  m_remoteRenderingBackendProxy->didAppendData(handle, numberOfBytes, didChangeItemBuffer, m_renderingResourceIdentifier);
317  }
318 
319  void recordFontUse(WebCore::Font& font) final
 287 void recordFontUse(WebCore::Font& font)
320288 {
321289 if (m_remoteRenderingBackendProxy)
322290 m_remoteRenderingBackendProxy->remoteResourceCacheProxy().recordFontUse(font);
323291 }
324292
325  void recordImageBufferUse(WebCore::ImageBuffer& imageBuffer) final
 293 void recordImageBufferUse(WebCore::ImageBuffer& imageBuffer)
326294 {
327295 if (m_remoteRenderingBackendProxy)
328296 m_remoteRenderingBackendProxy->remoteResourceCacheProxy().recordImageBufferUse(imageBuffer);
329297 }
330298
331  WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t capacity) final
332  {
333  if (LIKELY(m_remoteRenderingBackendProxy))
334  return m_remoteRenderingBackendProxy->createItemBuffer(capacity, m_renderingResourceIdentifier);
335 
336  ASSERT_NOT_REACHED();
337  return { };
338  }
339 
340  RefPtr<WebCore::SharedBuffer> encodeItemOutOfLine(const WebCore::DisplayList::DisplayListItem& item) const final
341  {
342  return WTF::visit([](const auto& displayListItem) -> RefPtr<WebCore::SharedBuffer> {
343  using DisplayListItemType = typename WTF::RemoveCVAndReference<decltype(displayListItem)>::type;
344  if constexpr (!DisplayListItemType::isInlineItem)
345  return IPC::Encoder::encodeSingleObject<DisplayListItemType>(displayListItem);
346  RELEASE_ASSERT_NOT_REACHED();
347  return nullptr;
348  }, item);
349  }
350 
351299 std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> createFlusher() final
352300 {
353301 return WTF::makeUnique<ThreadSafeRemoteImageBufferFlusher<BackendType>>(*this);

@@protected:
358306 Condition m_receivedFlushIdentifierChangedCondition;
359307 WebCore::GraphicsContextFlushIdentifier m_receivedFlushIdentifier WTF_GUARDED_BY_LOCK(m_receivedFlushIdentifierLock); // Only modified on the main thread but may get queried on a secondary thread.
360308 WeakPtr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy;
 309 RemoteDisplayListRecorderProxy m_remoteDisplayList;
361310};
362311
363312template<typename BackendType>

Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp

2828
2929#if ENABLE(GPU_PROCESS)
3030
31 #include "DisplayListWriterHandle.h"
3231#include "GPUConnectionToWebProcess.h"
3332#include "Logging.h"
3433#include "PlatformRemoteImageBufferProxy.h"

@@std::unique_ptr<RemoteRenderingBackendProxy> RemoteRenderingBackendProxy::create
5251RemoteRenderingBackendProxy::RemoteRenderingBackendProxy(WebPage& webPage)
5352 : m_parameters {
5453 RenderingBackendIdentifier::generate(),
55  IPC::Semaphore { },
5654 webPage.webPageProxyIdentifier(),
5755 webPage.identifier()
5856 }

@@GPUProcessConnection& RemoteRenderingBackendProxy::ensureGPUProcessConnection()
7775 auto& gpuProcessConnection = WebProcess::singleton().ensureGPUProcessConnection();
7876 gpuProcessConnection.addClient(*this);
7977 gpuProcessConnection.messageReceiverMap().addMessageReceiver(Messages::RemoteRenderingBackendProxy::messageReceiverName(), renderingBackendIdentifier().toUInt64(), *this);
80  gpuProcessConnection.connection().send(Messages::GPUConnectionToWebProcess::CreateRenderingBackend(m_parameters), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 78 m_streamConnection = makeUnique<IPC::StreamClientConnection>(gpuProcessConnection.connection(), 1 << 21);
 79 gpuProcessConnection.connection().send(Messages::GPUConnectionToWebProcess::CreateRenderingBackend(m_parameters, m_streamConnection->streamBuffer()), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
8180 m_gpuProcessConnection = makeWeakPtr(gpuProcessConnection);
8281 }
8382 return *m_gpuProcessConnection;

@@void RemoteRenderingBackendProxy::gpuProcessConnectionDidClose(GPUProcessConnect
9190
9291 m_remoteResourceCacheProxy.remoteResourceCacheWasDestroyed();
9392
94  m_identifiersOfReusableHandles.clear();
95  m_sharedDisplayListHandles.clear();
96  m_currentDestinationImageBufferIdentifier = std::nullopt;
97  m_deferredWakeupMessageArguments = std::nullopt;
98  m_remainingItemsToAppendBeforeSendingWakeup = 0;
99 
10093 if (m_destroyGetPixelBufferSharedMemoryTimer.isActive())
10194 m_destroyGetPixelBufferSharedMemoryTimer.stop();
10295 m_getPixelBufferSemaphore = std::nullopt;

@@bool RemoteRenderingBackendProxy::waitForDidFlush()
133126
134127void RemoteRenderingBackendProxy::createRemoteImageBuffer(ImageBuffer& imageBuffer)
135128{
136  send(Messages::RemoteRenderingBackend::CreateImageBuffer(imageBuffer.logicalSize(), imageBuffer.renderingMode(), imageBuffer.resolutionScale(), imageBuffer.colorSpace(), imageBuffer.pixelFormat(), imageBuffer.renderingResourceIdentifier()), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 129 sendToStream(Messages::RemoteRenderingBackend::CreateImageBuffer(imageBuffer.logicalSize(), imageBuffer.renderingMode(), imageBuffer.resolutionScale(), imageBuffer.colorSpace(), imageBuffer.pixelFormat(), imageBuffer.renderingResourceIdentifier()));
137130}
138131
139132RefPtr<ImageBuffer> RemoteRenderingBackendProxy::createImageBuffer(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, const DestinationColorSpace& colorSpace, PixelFormat pixelFormat)

@@RefPtr<ImageBuffer> RemoteRenderingBackendProxy::createImageBuffer(const FloatSi
163156
164157SharedMemory* RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer(size_t dataSize, IPC::Timeout timeout)
165158{
166  sendDeferredWakeupMessageIfNeeded();
167 
168159 bool needsSharedMemory = !m_getPixelBufferSharedMemory || dataSize > m_getPixelBufferSharedMemoryLength;
169160 bool needsSemaphore = !m_getPixelBufferSemaphore;
170161

@@SharedMemory* RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer(size_t
175166 IPC::Semaphore semaphore;
176167
177168 if (needsSharedMemory && needsSemaphore)
178  sendSync(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore), renderingBackendIdentifier(), timeout, IPC::SendSyncOption::MaintainOrderingWithAsyncMessages);
 169 sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore), timeout);
179170 else if (needsSharedMemory)
180  sendSync(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle), renderingBackendIdentifier(), timeout, IPC::SendSyncOption::MaintainOrderingWithAsyncMessages);
 171 sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle), timeout);
181172 else if (needsSemaphore)
182  sendSync(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore), renderingBackendIdentifier(), timeout);
 173 sendSyncToStream(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore), timeout);
183174
184175 if (!handle.handle.isNull()) {
185176 m_getPixelBufferSharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadOnly);

@@bool RemoteRenderingBackendProxy::waitForGetPixelBufferToComplete(IPC::Timeout t
204195void RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory()
205196{
206197 m_getPixelBufferSharedMemory = nullptr;
207  send(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory(), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 198 sendToStream(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory());
208199}
209200
210201String RemoteRenderingBackendProxy::getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, PreserveResolution preserveResolution, RenderingResourceIdentifier renderingResourceIdentifier)
211202{
212  sendDeferredWakeupMessageIfNeeded();
213 
214203 String urlString;
215  sendSync(Messages::RemoteRenderingBackend::GetDataURLForImageBuffer(mimeType, quality, preserveResolution, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataURLForImageBuffer::Reply(urlString), renderingBackendIdentifier(), 1_s);
 204 sendSyncToStream(Messages::RemoteRenderingBackend::GetDataURLForImageBuffer(mimeType, quality, preserveResolution, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataURLForImageBuffer::Reply(urlString), 3_s);
216205 return urlString;
217206}
218207
219208Vector<uint8_t> RemoteRenderingBackendProxy::getDataForImageBuffer(const String& mimeType, std::optional<double> quality, RenderingResourceIdentifier renderingResourceIdentifier)
220209{
221  sendDeferredWakeupMessageIfNeeded();
222 
223210 Vector<uint8_t> data;
224  sendSync(Messages::RemoteRenderingBackend::GetDataForImageBuffer(mimeType, quality, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataForImageBuffer::Reply(data), renderingBackendIdentifier(), 1_s);
 211 sendSyncToStream(Messages::RemoteRenderingBackend::GetDataForImageBuffer(mimeType, quality, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataForImageBuffer::Reply(data), 3_s);
225212 return data;
226213}
227214
228215RefPtr<ShareableBitmap> RemoteRenderingBackendProxy::getShareableBitmap(RenderingResourceIdentifier imageBuffer, PreserveResolution preserveResolution)
229216{
230  sendDeferredWakeupMessageIfNeeded();
231 
232217 ShareableBitmap::Handle handle;
233  auto sendResult = sendSync(Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer(imageBuffer, preserveResolution), Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer::Reply(handle), renderingBackendIdentifier(), 1_s);
 218 auto sendResult = sendSyncToStream(Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer(imageBuffer, preserveResolution), Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer::Reply(handle), 3_s);
234219 if (handle.isNull())
235220 return { };
236221 ASSERT_UNUSED(sendResult, sendResult);

@@RefPtr<ShareableBitmap> RemoteRenderingBackendProxy::getShareableBitmap(Renderin
239224
240225void RemoteRenderingBackendProxy::cacheNativeImage(const ShareableBitmap::Handle& handle, RenderingResourceIdentifier renderingResourceIdentifier)
241226{
242  send(Messages::RemoteRenderingBackend::CacheNativeImage(handle, renderingResourceIdentifier), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 227 sendToStream(Messages::RemoteRenderingBackend::CacheNativeImage(handle, renderingResourceIdentifier));
243228}
244229
245 void RemoteRenderingBackendProxy::cacheFont(Ref<WebCore::Font>&& font)
 230void RemoteRenderingBackendProxy::cacheFont(Ref<Font>&& font)
246231{
247  send(Messages::RemoteRenderingBackend::CacheFont(WTFMove(font)), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 232 sendToStream(Messages::RemoteRenderingBackend::CacheFont(WTFMove(font)));
248233}
249234
250235void RemoteRenderingBackendProxy::deleteAllFonts()
251236{
252  send(Messages::RemoteRenderingBackend::DeleteAllFonts(), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 237 sendToStream(Messages::RemoteRenderingBackend::DeleteAllFonts());
253238}
254239
255240void RemoteRenderingBackendProxy::releaseRemoteResource(RenderingResourceIdentifier renderingResourceIdentifier, uint64_t useCount)
256241{
257  if (renderingResourceIdentifier == m_currentDestinationImageBufferIdentifier)
258  m_currentDestinationImageBufferIdentifier = std::nullopt;
259 
260  send(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier, useCount), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 242 sendToStream(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier, useCount));
261243}
262244
263245void RemoteRenderingBackendProxy::finalizeRenderingUpdate()
264246{
265  send(Messages::RemoteRenderingBackend::FinalizeRenderingUpdate(m_renderingUpdateID), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 247 sendToStream(Messages::RemoteRenderingBackend::FinalizeRenderingUpdate(m_renderingUpdateID));
266248 m_remoteResourceCacheProxy.finalizeRenderingUpdate();
267249 m_renderingUpdateID.increment();
268250}

@@void RemoteRenderingBackendProxy::didFlush(GraphicsContextFlushIdentifier flushI
287269 imageBuffer->didFlush(flushIdentifier);
288270}
289271
290 void RemoteRenderingBackendProxy::didFinalizeRenderingUpdate(RenderingUpdateID didRenderingUpdateID)
 272void RemoteRenderingBackendProxy::didFinalizeRenderingUpdate(RenderingUpdateID renderingUpdateID)
291273{
292  ASSERT(didRenderingUpdateID <= m_renderingUpdateID);
293  m_didRenderingUpdateID = std::min(didRenderingUpdateID, m_renderingUpdateID);
 274 ASSERT(renderingUpdateID <= m_renderingUpdateID);
 275 m_didRenderingUpdateID = std::min(renderingUpdateID, m_renderingUpdateID);
294276}
295277
296 void RemoteRenderingBackendProxy::willAppendItem(RenderingResourceIdentifier newDestinationIdentifier)
297 {
298  if (m_currentDestinationImageBufferIdentifier == newDestinationIdentifier)
299  return;
300 
301  if (auto previousDestinationBufferIdentifier = std::exchange(m_currentDestinationImageBufferIdentifier, newDestinationIdentifier)) {
302  if (auto imageBuffer = m_remoteResourceCacheProxy.cachedImageBuffer(*previousDestinationBufferIdentifier))
303  imageBuffer->changeDestinationImageBuffer(newDestinationIdentifier);
304  else
305  ASSERT_NOT_REACHED();
306  }
307 
308  auto handle = mostRecentlyUsedDisplayListHandle();
309  if (UNLIKELY(!handle))
310  return;
311 
312  auto newDestination = m_remoteResourceCacheProxy.cachedImageBuffer(newDestinationIdentifier);
313  if (UNLIKELY(!newDestination)) {
314  ASSERT_NOT_REACHED();
315  return;
316  }
317 
318  handle->moveWritableOffsetToStartIfPossible();
319  newDestination->prepareToAppendDisplayListItems(handle->createHandle());
320 }
321 
322 void RemoteRenderingBackendProxy::sendWakeupMessage(const GPUProcessWakeupMessageArguments& arguments)
323 {
324  LOG_WITH_STREAM(SharedDisplayLists, stream << "Sending wakeup: Items[" << arguments.itemBufferIdentifier << "] => Image(" << arguments.destinationImageBufferIdentifier << ") at " << arguments.offset);
325  send(Messages::RemoteRenderingBackend::WakeUpAndApplyDisplayList(arguments), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
326 }
327 
328 void RemoteRenderingBackendProxy::sendDeferredWakeupMessageIfNeeded()
 278RenderingBackendIdentifier RemoteRenderingBackendProxy::renderingBackendIdentifier() const
329279{
330  auto arguments = std::exchange(m_deferredWakeupMessageArguments, std::nullopt);
331  if (!arguments)
332  return;
333 
334  sendWakeupMessage(*arguments);
335  m_remainingItemsToAppendBeforeSendingWakeup = 0;
336 }
337 
338 void RemoteRenderingBackendProxy::didAppendData(const DisplayList::ItemBufferHandle& handle, size_t numberOfBytes, DisplayList::DidChangeItemBuffer didChangeItemBuffer, RenderingResourceIdentifier destinationImageBuffer)
339 {
340  auto* sharedHandle = m_sharedDisplayListHandles.get(handle.identifier);
341  if (UNLIKELY(!sharedHandle))
342  RELEASE_ASSERT_NOT_REACHED();
343 
344  bool wasEmpty = sharedHandle->advance(numberOfBytes) == numberOfBytes;
345  if (!wasEmpty || didChangeItemBuffer == DisplayList::DidChangeItemBuffer::Yes) {
346  if (m_deferredWakeupMessageArguments) {
347  auto imageBuffer = m_remoteResourceCacheProxy.cachedImageBuffer(m_deferredWakeupMessageArguments->destinationImageBufferIdentifier);
348  if (imageBuffer && imageBuffer->backend() && sharedHandle->tryToResume({ m_deferredWakeupMessageArguments->offset, m_deferredWakeupMessageArguments->destinationImageBufferIdentifier.toUInt64() })) {
349  m_parameters.resumeDisplayListSemaphore.signal();
350  m_deferredWakeupMessageArguments = std::nullopt;
351  m_remainingItemsToAppendBeforeSendingWakeup = 0;
352  } else if (!--m_remainingItemsToAppendBeforeSendingWakeup) {
353  m_deferredWakeupMessageArguments->reason = GPUProcessWakeupReason::ItemCountHysteresisExceeded;
354  sendWakeupMessage(*std::exchange(m_deferredWakeupMessageArguments, std::nullopt));
355  }
356  }
357  return;
358  }
359 
360  sendDeferredWakeupMessageIfNeeded();
361 
362  auto imageBuffer = m_remoteResourceCacheProxy.cachedImageBuffer(destinationImageBuffer);
363  auto offsetToRead = sharedHandle->writableOffset() - numberOfBytes;
364  if (imageBuffer && imageBuffer->backend() && sharedHandle->tryToResume({ offsetToRead, destinationImageBuffer.toUInt64() })) {
365  m_parameters.resumeDisplayListSemaphore.signal();
366  return;
367  }
368 
369  // Instead of sending the wakeup message immediately, wait for some additional data. This gives the
370  // web process a "head start", decreasing the likelihood that the GPU process will encounter frequent
371  // wakeups when processing a large amount of display list items.
372  constexpr unsigned itemCountHysteresisBeforeSendingWakeup = 512;
373 
374  m_remainingItemsToAppendBeforeSendingWakeup = itemCountHysteresisBeforeSendingWakeup;
375  m_deferredWakeupMessageArguments = {{ handle.identifier, offsetToRead, destinationImageBuffer }};
 280 return m_parameters.identifier;
376281}
377282
378 RefPtr<DisplayListWriterHandle> RemoteRenderingBackendProxy::mostRecentlyUsedDisplayListHandle()
 283RenderingBackendIdentifier RemoteRenderingBackendProxy::ensureBackendCreated()
379284{
380  if (UNLIKELY(m_identifiersOfReusableHandles.isEmpty()))
381  return nullptr;
382 
383  return m_sharedDisplayListHandles.get(m_identifiersOfReusableHandles.first());
 285 ensureGPUProcessConnection();
 286 return renderingBackendIdentifier();
384287}
385288
386 RefPtr<DisplayListWriterHandle> RemoteRenderingBackendProxy::findReusableDisplayListHandle(size_t capacity)
 289IPC::StreamClientConnection& RemoteRenderingBackendProxy::streamConnection()
387290{
388  auto mostRecentlyUsedHandle = mostRecentlyUsedDisplayListHandle();
389  if (UNLIKELY(!mostRecentlyUsedHandle))
390  return nullptr;
391 
392  mostRecentlyUsedHandle->moveWritableOffsetToStartIfPossible();
393  if (mostRecentlyUsedHandle->availableCapacity() >= capacity)
394  return mostRecentlyUsedHandle;
395 
396  m_identifiersOfReusableHandles.append(m_identifiersOfReusableHandles.takeFirst());
397 
398  auto leastRecentlyUsedIdentifier = m_identifiersOfReusableHandles.first();
399  if (leastRecentlyUsedIdentifier != mostRecentlyUsedHandle->identifier()) {
400  RefPtr handle = m_sharedDisplayListHandles.get(leastRecentlyUsedIdentifier);
401  if (handle->moveWritableOffsetToStartIfPossible() && handle->availableCapacity() >= capacity)
402  return handle;
403  }
404 
405  return nullptr;
 291 ensureGPUProcessConnection();
 292 if (UNLIKELY(m_needsWakeUpSemaphoreForDisplayListStream))
 293 messageSenderConnection()->waitForAndDispatchImmediately<Messages::RemoteRenderingBackendProxy::DidCreateWakeUpSemaphoreForDisplayListStream>(renderingBackendIdentifier(), 3_s, IPC::WaitForOption::InterruptWaitingIfSyncMessageArrives);
 294 return *m_streamConnection;
406295}
407296
408 DisplayList::ItemBufferHandle RemoteRenderingBackendProxy::createItemBuffer(size_t capacity, RenderingResourceIdentifier destinationBufferIdentifier)
 297void RemoteRenderingBackendProxy::didCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore&& semaphore)
409298{
410  if (auto handle = findReusableDisplayListHandle(capacity)) {
411  LOG_WITH_STREAM(SharedDisplayLists, stream << "Reusing Items[" << handle->identifier() << "] => Image(" << destinationBufferIdentifier << ") (remaining capacity: " << handle->availableCapacity() << ")");
412  return handle->createHandle();
 299 if (!m_streamConnection) {
 300 ASSERT_NOT_REACHED();
 301 return;
413302 }
414303
415  static constexpr size_t defaultSharedItemBufferSize = 1 << 16;
416  static_assert(defaultSharedItemBufferSize > SharedDisplayListHandle::headerSize());
417 
418  auto sharedMemory = SharedMemory::allocate(std::max(defaultSharedItemBufferSize, capacity + SharedDisplayListHandle::headerSize()));
419  if (!sharedMemory)
420  return { };
421 
422  SharedMemory::Handle sharedMemoryHandle;
423  sharedMemory->createHandle(sharedMemoryHandle, SharedMemory::Protection::ReadWrite);
424 
425  auto identifier = DisplayList::ItemBufferIdentifier::generate();
426  send(Messages::RemoteRenderingBackend::DidCreateSharedDisplayListHandle(identifier, { WTFMove(sharedMemoryHandle), sharedMemory->size() }, destinationBufferIdentifier), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
427 
428  auto newHandle = DisplayListWriterHandle::create(identifier, sharedMemory.releaseNonNull());
429  RELEASE_ASSERT(newHandle, "There must be enough space to create the handle.");
430  auto displayListHandle = newHandle->createHandle();
431 
432  m_identifiersOfReusableHandles.prepend(identifier);
433  m_sharedDisplayListHandles.set(identifier, WTFMove(newHandle));
434 
435  LOG_WITH_STREAM(SharedDisplayLists, stream << "Allocated Items[" << identifier << "] => Image(" << destinationBufferIdentifier << ")");
436  return displayListHandle;
437 }
438 
439 RenderingBackendIdentifier RemoteRenderingBackendProxy::renderingBackendIdentifier() const
440 {
441  return m_parameters.identifier;
442 }
443 
444 RenderingBackendIdentifier RemoteRenderingBackendProxy::ensureBackendCreated()
445 {
446  ensureGPUProcessConnection();
447  return renderingBackendIdentifier();
 304 m_streamConnection->setWakeUpSemaphore(WTFMove(semaphore));
 305 m_needsWakeUpSemaphoreForDisplayListStream = false;
448306}
449307
450308void RemoteRenderingBackendProxy::recordNativeImageUse(NativeImage& image)

Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h

3333#include "ImageBufferBackendHandle.h"
3434#include "MessageReceiver.h"
3535#include "MessageSender.h"
 36#include "RemoteDisplayListRecorderMessages.h"
3637#include "RemoteRenderingBackendCreationParameters.h"
 38#include "RemoteRenderingBackendMessages.h"
3739#include "RemoteResourceCacheProxy.h"
3840#include "RenderingBackendIdentifier.h"
3941#include "RenderingUpdateID.h"
40 #include <WebCore/DisplayList.h>
 42#include "StreamClientConnection.h"
4143#include <WebCore/RenderingResourceIdentifier.h>
4244#include <WebCore/Timer.h>
4345#include <wtf/Deque.h>

4547
4648namespace WebCore {
4749
48 namespace DisplayList {
49 class DisplayList;
50 class Item;
51 }
52 
5350class DestinationColorSpace;
5451class FloatSize;
5552class PixelBuffer;

@@enum class RenderingMode : bool;
6158
6259namespace WebKit {
6360
64 class DisplayListWriterHandle;
6561class WebPage;
6662
6763class RemoteRenderingBackendProxy
6864 : public IPC::MessageSender
6965 , private IPC::MessageReceiver
70  , public GPUProcessConnection::Client {
 66 , public GPUProcessConnection::Client
 67 , public RefCounted<RemoteRenderingBackendProxy> {
7168public:
7269 static std::unique_ptr<RemoteRenderingBackendProxy> create(WebPage&);
7370

@@public:
7774 using WeakValueType = GPUProcessConnection::Client::WeakValueType;
7875
7976 RemoteResourceCacheProxy& remoteResourceCacheProxy() { return m_remoteResourceCacheProxy; }
80  WebCore::DisplayList::ItemBufferHandle createItemBuffer(size_t capacity, WebCore::RenderingResourceIdentifier destinationBufferIdentifier);
81 
82  void didAppendData(const WebCore::DisplayList::ItemBufferHandle&, size_t numberOfBytes, WebCore::DisplayList::DidChangeItemBuffer, WebCore::RenderingResourceIdentifier destinationImageBuffer);
83  void willAppendItem(WebCore::RenderingResourceIdentifier);
84  void sendDeferredWakeupMessageIfNeeded();
8577
8678 SharedMemory* sharedMemoryForGetPixelBuffer(size_t dataSize, IPC::Timeout);
8779 bool waitForGetPixelBufferToComplete(IPC::Timeout);

@@public:
10193 RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat);
10294 String getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, WebCore::RenderingResourceIdentifier);
10395 Vector<uint8_t> getDataForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier);
104  WebCore::GraphicsContextFlushIdentifier flushDisplayListAndCommit(const WebCore::DisplayList::DisplayList&, WebCore::RenderingResourceIdentifier);
10596 RefPtr<ShareableBitmap> getShareableBitmap(WebCore::RenderingResourceIdentifier, WebCore::PreserveResolution);
10697 void cacheNativeImage(const ShareableBitmap::Handle&, WebCore::RenderingResourceIdentifier);
10798 void cacheFont(Ref<WebCore::Font>&&);

@@public:
125116
126117 bool isGPUProcessConnectionClosed() const { return !m_gpuProcessConnection; }
127118
 119 void didCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore&&);
 120
128121 template<typename T, typename U>
129122 void sendToStream(T&& message, ObjectIdentifier<U> identifier)
130123 {
131  // FIXME: Not yet implemented.
 124 // FIXME: We should consider making the send timeout finite.
 125 streamConnection().send(WTFMove(message), identifier, Seconds::infinity());
132126 }
133127
134128 template<typename T>

@@public:
144138private:
145139 explicit RemoteRenderingBackendProxy(WebPage&);
146140
 141 IPC::StreamClientConnection& streamConnection();
 142
 143 template<typename T>
 144 auto sendSyncToStream(T&& message, typename T::Reply&& reply, IPC::Timeout timeout)
 145 {
 146 return streamConnection().sendSync(WTFMove(message), WTFMove(reply), renderingBackendIdentifier(), timeout);
 147 }
 148
147149 // GPUProcessConnection::Client
148150 void gpuProcessConnectionDidClose(GPUProcessConnection&) final;
149151

@@private:
154156 void didFlush(WebCore::GraphicsContextFlushIdentifier, WebCore::RenderingResourceIdentifier);
155157 void didFinalizeRenderingUpdate(RenderingUpdateID didRenderingUpdateID);
156158
157  RefPtr<DisplayListWriterHandle> mostRecentlyUsedDisplayListHandle();
158  RefPtr<DisplayListWriterHandle> findReusableDisplayListHandle(size_t capacity);
159 
160  void sendWakeupMessage(const GPUProcessWakeupMessageArguments&);
161 
 159 std::unique_ptr<IPC::StreamClientConnection> m_streamConnection;
162160 RemoteRenderingBackendCreationParameters m_parameters;
163161 WeakPtr<GPUProcessConnection> m_gpuProcessConnection;
164162 RemoteResourceCacheProxy m_remoteResourceCacheProxy { *this };
165163
166  HashMap<WebCore::DisplayList::ItemBufferIdentifier, RefPtr<DisplayListWriterHandle>> m_sharedDisplayListHandles;
167  Deque<WebCore::DisplayList::ItemBufferIdentifier> m_identifiersOfReusableHandles;
168  std::optional<WebCore::RenderingResourceIdentifier> m_currentDestinationImageBufferIdentifier;
169  std::optional<GPUProcessWakeupMessageArguments> m_deferredWakeupMessageArguments;
170  unsigned m_remainingItemsToAppendBeforeSendingWakeup { 0 };
171 
172164 std::optional<IPC::Semaphore> m_getPixelBufferSemaphore;
173165 RefPtr<SharedMemory> m_getPixelBufferSharedMemory;
174166 uint64_t m_getPixelBufferSharedMemoryLength { 0 };

@@private:
176168
177169 RenderingUpdateID m_renderingUpdateID;
178170 RenderingUpdateID m_didRenderingUpdateID;
 171
 172 bool m_needsWakeUpSemaphoreForDisplayListStream { true };
179173};
180174
181175} // namespace WebKit

Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in

@@messages -> RemoteRenderingBackendProxy NotRefCounted {
2626 DidCreateImageBufferBackend(WebKit::ImageBufferBackendHandle handle, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
2727 DidFlush(WebCore::GraphicsContextFlushIdentifier flushIdentifier, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
2828 DidFinalizeRenderingUpdate(WebKit::RenderingUpdateID didRenderingUpdateID)
 29 DidCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore wakeUpSemaphore)
2930}
3031
3132#endif // ENABLE(GPU_PROCESS)

Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp

@@static bool encodeRemoteRenderingBackendCreationParameters(IPC::Encoder& encoder
761761 if (!identifier)
762762 return false;
763763
764  auto jsSemaphore = jsObject->get(globalObject, JSC::Identifier::fromString(globalObject->vm(), "semaphore"_s));
765  if (scope.exception())
766  return false;
767  RefPtr semaphoreObject = JSIPCSemaphore::toWrapped(toRef(globalObject), toRef(jsSemaphore));
768  if (!semaphoreObject)
769  return false;
770 
771764 auto pageProxyID = getObjectIdentifierFromProperty<WebPageProxyIdentifierType>(globalObject, jsObject, "pageProxyID"_s, scope);
772765 if (!pageProxyID)
773766 return false;

@@static bool encodeRemoteRenderingBackendCreationParameters(IPC::Encoder& encoder
776769 if (!pageID)
777770 return false;
778771
779  auto semaphore = semaphoreObject->exchange();
780  RemoteRenderingBackendCreationParameters parameters { *identifier, WTFMove(semaphore), *pageProxyID, *pageID };
 772 RemoteRenderingBackendCreationParameters parameters { *identifier, *pageProxyID, *pageID };
781773 encoder << parameters;
782  semaphoreObject->exchange(WTFMove(parameters.resumeDisplayListSemaphore));
783774 return true;
784775}
785776#endif