⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 284079 in webkit


Ignore:
Timestamp:
Oct 12, 2021, 10:50:33 PM (5 years ago)
Author:
Wenson Hsieh
Message:

[GPU Process] Use IPC streaming for concurrent display list processing
https://bugs.webkit.org/show_bug.cgi?id=230860
rdar://83438038

Reviewed by Tim Horton.

This patch rebuilds the concurrent display list architecture in the web and GPU processes on top of the
streamable IPC connections currently used by WebGL in the GPU process. See below for more details.

There should be no change in behavior.

  • GPUProcess/GPUConnectionToWebProcess.cpp:

(WebKit::GPUConnectionToWebProcess::createRenderingBackend):

Pass a StreamConnectionBuffer from the web process to the GPU process when constructing
RemoteRenderingBackend; this serves as the pool of shared memory used to store streaming IPC messages sent from
the web process to the GPU process. I've (somewhat arbitrarily) chosen the size of this StreamConnectionBuffer
to match WebGL's connection buffer, though this can be tuned as needed. In a future patch, we may also want to
implement a mechanism for starting out with a small connection buffer, and growing it by successively larger
segments as needed.

  • GPUProcess/GPUConnectionToWebProcess.h:
  • GPUProcess/GPUConnectionToWebProcess.messages.in:
  • GPUProcess/cocoa/GPUProcessCocoa.mm:

(WebKit::GPUProcess::additionalStateForDiagnosticReport const):

Add a FIXME for re-introducing diagnostic state logging when using streamable IPC.

  • GPUProcess/graphics/RemoteDisplayListRecorder.cpp:

(WebKit::RemoteDisplayListRecorder::RemoteDisplayListRecorder):
(WebKit::RemoteDisplayListRecorder::startListeningForIPC):
(WebKit::RemoteDisplayListRecorder::stopListeningForIPC):

Add and remove the remote display list as a destination on the RemoteRenderingBackend's stream connection. Note
that the synchronous dispatch to the main thread here is necessary to maintain the ordering of out-of-stream IPC
messages that may have been received on the IPC thread.

  • GPUProcess/graphics/RemoteDisplayListRecorder.h:

(WebKit::RemoteDisplayListRecorder::create):
(WebKit::RemoteDisplayListRecorder::handleItem):

  • GPUProcess/graphics/RemoteImageBuffer.h:

(WebKit::RemoteImageBuffer::RemoteImageBuffer):
(WebKit::RemoteImageBuffer::apply): Deleted.

Introduce m_remoteDisplayList to RemoteImageBuffer, and remove some logic for applying display list items that
is no longer necessary.

  • GPUProcess/graphics/RemoteRenderingBackend.cpp:

(WebKit::RemoteRenderingBackend::create):
(WebKit::RemoteRenderingBackend::RemoteRenderingBackend):

Set up the IPC stream connection and stream connection work queue, and immediately send a wakeup semaphore back
to the web process.

(WebKit::RemoteRenderingBackend::startListeningForIPC):
(WebKit::RemoteRenderingBackend::~RemoteRenderingBackend):
(WebKit::RemoteRenderingBackend::stopListeningForIPC):

Add a mechanism to immediately tell all m_remoteDisplayLists to stop listening for streaming IPC messages when
the owning RemoteRenderingBackend stops listening.

(WebKit::RemoteRenderingBackend::dispatch):
(WebKit::RemoteRenderingBackend::didCreateImageBufferBackend):
(WebKit::RemoteRenderingBackend::createImageBufferWithQualifiedIdentifier):
(WebKit::RemoteRenderingBackend::cacheNativeImageWithQualifiedIdentifier):
(WebKit::RemoteRenderingBackend::cacheFontWithQualifiedIdentifier):
(WebKit::RemoteRenderingBackend::finalizeRenderingUpdate):
(WebKit::RemoteRenderingBackend::applyMediaItem): Deleted.
(WebKit::RemoteRenderingBackend::ReplayerDelegate::ReplayerDelegate): Deleted.
(WebKit::RemoteRenderingBackend::ReplayerDelegate::apply): Deleted.
(WebKit::RemoteRenderingBackend::ReplayerDelegate::didCreateMaskImageBuffer): Deleted.
(WebKit::RemoteRenderingBackend::ReplayerDelegate::didResetMaskImageBuffer): Deleted.
(WebKit::RemoteRenderingBackend::ReplayerDelegate::recordResourceUse): Deleted.
(WebKit::RemoteRenderingBackend::submit): Deleted.
(WebKit::RemoteRenderingBackend::nextDestinationImageBufferAfterApplyingDisplayLists): Deleted.
(WebKit::RemoteRenderingBackend::wakeUpAndApplyDisplayList): Deleted.
(WebKit::RemoteRenderingBackend::wakeUpAndApplyDisplayListWithQualifiedIdentifier): Deleted.
(WebKit::RemoteRenderingBackend::setNextItemBufferToRead): Deleted.
(WebKit::RemoteRenderingBackend::didCreateSharedDisplayListHandle): Deleted.
(WebKit::RemoteRenderingBackend::didCreateSharedDisplayListHandleWithQualifiedIdentifier): Deleted.
(WebKit::RemoteRenderingBackend::resumeFromPendingWakeupInformation): Deleted.
(WebKit::RemoteRenderingBackend::didCreateMaskImageBuffer): Deleted.
(WebKit::RemoteRenderingBackend::didResetMaskImageBuffer): Deleted.
(WebKit::RemoteRenderingBackend::decodeItem): Deleted.
(WebKit::RemoteRenderingBackend::lastKnownState const): Deleted.
(WebKit::RemoteRenderingBackend::updateLastKnownState): Deleted.

Remove logic for coordinating wakeups and shared display list item buffers in the GPU process.

  • GPUProcess/graphics/RemoteRenderingBackend.h:

Subclass IPC::StreamMessageReceiver. In this new concurrent display list model, RemoteRenderingBackend serves
as a streaming IPC destination alongside each RemoteDisplayListRecorder in the GPU process; all messages
previously sent to the RemoteRenderingBackend as normal IPC are now sent through the connection stream (though
some must be marked as non-stream-encodable).

(WebKit::RemoteRenderingBackend::streamConnection const):
(WebKit::RemoteRenderingBackend::decodeAndCreate): Deleted.
(): Deleted.
(WebKit::RemoteRenderingBackend::PendingWakeupInformation::shouldPerformWakeup const): Deleted.

Delete more logic related to concurrent display lists.

  • GPUProcess/graphics/RemoteRenderingBackend.messages.in:

Make RemoteRenderingBackend a stream message receiver.

  • GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h:

(WebKit::RemoteRenderingBackendCreationParameters::encode const):
(WebKit::RemoteRenderingBackendCreationParameters::decode):

Remove the IPC::Semaphore here, that was previously used for quick GPU process wakeups. This semaphore is no
longer needed because we always use IPC::Semaphore for waking the GPU process when using streaming IPC.

  • GPUProcess/graphics/RemoteResourceCache.h:
  • WebProcess/GPU/graphics/RemoteImageBufferProxy.h:

Make the RemoteImageBufferProxy template class directly subclass ConcreteImageBuffer instead of
DisplayList::ImageBuffer; additionally, introduce a RemoteDisplayListRecorderProxy m_remoteDisplayList here,
which we use as our drawing graphics context.

(WebKit::RemoteImageBufferProxy::~RemoteImageBufferProxy):
(WebKit::RemoteImageBufferProxy::RemoteImageBufferProxy):
(WebKit::RemoteImageBufferProxy::recordNativeImageUse):
(WebKit::RemoteImageBufferProxy::recordFontUse):
(WebKit::RemoteImageBufferProxy::recordImageBufferUse):
(WebKit::RemoteImageBufferProxy::clearDisplayList): Deleted.

  • WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:

(WebKit::RemoteRenderingBackendProxy::RemoteRenderingBackendProxy):
(WebKit::RemoteRenderingBackendProxy::ensureGPUProcessConnection):
(WebKit::RemoteRenderingBackendProxy::gpuProcessConnectionDidClose):
(WebKit::RemoteRenderingBackendProxy::createRemoteImageBuffer):
(WebKit::RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer):
(WebKit::RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory):
(WebKit::RemoteRenderingBackendProxy::getDataURLForImageBuffer):
(WebKit::RemoteRenderingBackendProxy::getDataForImageBuffer):
(WebKit::RemoteRenderingBackendProxy::getShareableBitmap):

Send all IPC messages to RemoteRenderingBackend in the GPU process through the stream connection, instead of
using standard IPC messages. This guarantees ordering when receiving cached resources.

(WebKit::RemoteRenderingBackendProxy::cacheNativeImage):
(WebKit::RemoteRenderingBackendProxy::cacheFont):
(WebKit::RemoteRenderingBackendProxy::deleteAllFonts):
(WebKit::RemoteRenderingBackendProxy::releaseRemoteResource):
(WebKit::RemoteRenderingBackendProxy::finalizeRenderingUpdate):
(WebKit::RemoteRenderingBackendProxy::renderingBackendIdentifier const):
(WebKit::RemoteRenderingBackendProxy::ensureBackendCreated):
(WebKit::RemoteRenderingBackendProxy::streamConnection):

Add a mechanism to ensure that we have the IPC stream wakeup semaphore before grabbing the stream connection.

(WebKit::RemoteRenderingBackendProxy::didCreateWakeUpSemaphoreForDisplayListStream):
(WebKit::RemoteRenderingBackendProxy::willAppendItem): Deleted.
(WebKit::RemoteRenderingBackendProxy::sendWakeupMessage): Deleted.
(WebKit::RemoteRenderingBackendProxy::sendDeferredWakeupMessageIfNeeded): Deleted.
(WebKit::RemoteRenderingBackendProxy::didAppendData): Deleted.
(WebKit::RemoteRenderingBackendProxy::mostRecentlyUsedDisplayListHandle): Deleted.
(WebKit::RemoteRenderingBackendProxy::findReusableDisplayListHandle): Deleted.
(WebKit::RemoteRenderingBackendProxy::createItemBuffer): Deleted.

Remove all logic previously used to coordinate concurrent display list processing on the remote rendering
backend.

  • WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:

(WebKit::RemoteRenderingBackendProxy::remoteResourceCacheProxy):
(WebKit::RemoteRenderingBackendProxy::sendToStream):
(WebKit::RemoteRenderingBackendProxy::sendSyncToStream):

Add helper methods to send IPC messages to the remote rendering backend through the connection stream.

  • WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in:
  • WebProcess/WebPage/IPCTestingAPI.cpp:

(WebKit::IPCTestingAPI::encodeRemoteRenderingBackendCreationParameters):

Location:
trunk/Source/WebKit
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r284078 r284079  
     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 Tim Horton.
     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::renderingBackendIdentifier const):
     150        (WebKit::RemoteRenderingBackendProxy::ensureBackendCreated):
     151        (WebKit::RemoteRenderingBackendProxy::streamConnection):
     152
     153        Add a mechanism to ensure that we have the IPC stream wakeup semaphore before grabbing the stream connection.
     154
     155        (WebKit::RemoteRenderingBackendProxy::didCreateWakeUpSemaphoreForDisplayListStream):
     156        (WebKit::RemoteRenderingBackendProxy::willAppendItem): Deleted.
     157        (WebKit::RemoteRenderingBackendProxy::sendWakeupMessage): Deleted.
     158        (WebKit::RemoteRenderingBackendProxy::sendDeferredWakeupMessageIfNeeded): Deleted.
     159        (WebKit::RemoteRenderingBackendProxy::didAppendData): Deleted.
     160        (WebKit::RemoteRenderingBackendProxy::mostRecentlyUsedDisplayListHandle): Deleted.
     161        (WebKit::RemoteRenderingBackendProxy::findReusableDisplayListHandle): Deleted.
     162        (WebKit::RemoteRenderingBackendProxy::createItemBuffer): Deleted.
     163
     164        Remove all logic previously used to coordinate concurrent display list processing on the remote rendering
     165        backend.
     166
     167        * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
     168        (WebKit::RemoteRenderingBackendProxy::remoteResourceCacheProxy):
     169        (WebKit::RemoteRenderingBackendProxy::sendToStream):
     170        (WebKit::RemoteRenderingBackendProxy::sendSyncToStream):
     171
     172        Add helper methods to send IPC messages to the remote rendering backend through the connection stream.
     173
     174        * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in:
     175        * WebProcess/WebPage/IPCTestingAPI.cpp:
     176        (WebKit::IPCTestingAPI::encodeRemoteRenderingBackendCreationParameters):
     177
    11782021-10-12  Ross Kirsling  <ross.kirsling@sony.com>
    2179
  • trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp

    r283431 r284079  
    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);
  • trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h

    r283431 r284079  
    179179#endif
    180180
    181     void createRenderingBackend(RemoteRenderingBackendCreationParameters&&);
     181    void createRenderingBackend(RemoteRenderingBackendCreationParameters&&, IPC::StreamConnectionBuffer&&);
    182182    void releaseRenderingBackend(RenderingBackendIdentifier);
    183183
  • trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in

    r277835 r284079  
    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)
  • trunk/Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm

    r282669 r284079  
    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        }
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp

    r283968 r284079  
    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
     
    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}
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h

    r283814 r284079  
    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>
     
    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
     
    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
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp

    r283971 r284079  
    2929#if ENABLE(GPU_PROCESS)
    3030
    31 #include "DisplayListReaderHandle.h"
    3231#include "GPUConnectionToWebProcess.h"
    3332#include "Logging.h"
     
    7473using namespace WebCore;
    7574
    76 Ref<RemoteRenderingBackend> RemoteRenderingBackend::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters)
    77 {
    78     auto instance = adoptRef(*new RemoteRenderingBackend(gpuConnectionToWebProcess, WTFMove(creationParameters)));
     75Ref<RemoteRenderingBackend> RemoteRenderingBackend::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RemoteRenderingBackendCreationParameters&& creationParameters, IPC::StreamConnectionBuffer&& streamBuffer)
     76{
     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
     
    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
     
    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
     
    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)
    148 {
     128void RemoteRenderingBackend::didCreateImageBufferBackend(ImageBufferBackendHandle handle, QualifiedRenderingResourceIdentifier renderingResourceIdentifier, RemoteDisplayListRecorder& remoteDisplayList)
     129{
     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);
     
    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
     
    548323
    549324    m_remoteResourceCache.cacheNativeImage(*image, nativeImageResourceIdentifier);
    550 
    551     if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(nativeImageResourceIdentifier))
    552         resumeFromPendingWakeupInformation();
    553325}
    554326
     
    566338
    567339    m_remoteResourceCache.cacheFont(WTFMove(font), fontResourceIdentifier);
    568     if (m_pendingWakeupInfo && m_pendingWakeupInfo->shouldPerformWakeup(fontResourceIdentifier))
    569         resumeFromPendingWakeupInformation();
    570340}
    571341
     
    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);
    603 }
    604 
    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;
    756366}
    757367
     
    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{
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h

    r283968 r284079  
    2929
    3030#include "Connection.h"
    31 #include "GPUProcessWakeupMessageArguments.h"
    3231#include "IPCSemaphore.h"
    3332#include "ImageBufferBackendHandle.h"
     
    3534#include "MessageSender.h"
    3635#include "QualifiedRenderingResourceIdentifier.h"
     36#include "RemoteDisplayListRecorder.h"
    3737#include "RemoteRenderingBackendState.h"
    3838#include "RemoteResourceCache.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>
     
    4851
    4952namespace WebCore {
    50 
    51 namespace DisplayList {
    52 class DisplayList;
    53 class Item;
    54 }
    5553
    5654class DestinationColorSpace;
     
    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();
     
    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);
    88 
    89     void setNextItemBufferToRead(WebCore::DisplayList::ItemBufferIdentifier, QualifiedRenderingResourceIdentifier destination);
    90 
    91     void didCreateMaskImageBuffer(WebCore::ImageBuffer&);
    92     void didResetMaskImageBuffer();
    9381
    9482    void populateGetPixelBufferSharedMemory(std::optional<WebCore::PixelBuffer>&&);
     
    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();
    108 
    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);
    12595
    12696    std::optional<SharedMemory::IPCHandle> updateSharedMemoryForGetPixelBufferHelper(size_t byteCount);
    12797    void updateRenderingResourceRequest();
    128 
    129     void updateLastKnownState(RemoteRenderingBackendState);
    13098
    13199    // IPC::MessageSender.
     
    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&)>&&);
     
    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&&)>&&);
     
    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
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in

    r280337 r284079  
    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)
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackendCreationParameters.h

    r278253 r284079  
    3737struct RemoteRenderingBackendCreationParameters {
    3838    RenderingBackendIdentifier identifier;
    39     IPC::Semaphore resumeDisplayListSemaphore;
    4039    WebPageProxyIdentifier pageProxyID;
    4140    WebCore::PageIdentifier pageID;
     
    4342    void encode(IPC::Encoder& encoder) const
    4443    {
    45         encoder << identifier << resumeDisplayListSemaphore << pageProxyID << pageID;
     44        encoder << identifier << pageProxyID << pageID;
    4645    }
    4746
     
    5150        decoder >> identifier;
    5251        if (!identifier)
    53             return std::nullopt;
    54 
    55         std::optional<IPC::Semaphore> resumeDisplayListSemaphore;
    56         decoder >> resumeDisplayListSemaphore;
    57         if (!resumeDisplayListSemaphore)
    5852            return std::nullopt;
    5953
     
    6862            return std::nullopt;
    6963
    70         return {{ *identifier, WTFMove(*resumeDisplayListSemaphore), *pageProxyID, *pageID }};
     64        return { { *identifier, *pageProxyID, *pageID } };
    7165    }
    7266};
  • trunk/Source/WebKit/GPUProcess/mac/com.apple.WebKit.GPUProcess.sb.in

    r283998 r284079  
    743743       (global-name "com.apple.audio.audiohald")
    744744       (global-name "com.apple.CARenderServer") ; Needed for [CAContext remoteContextWithOptions]
    745 #if __MAC_OS_X_VERSION_MIN_REQUIRED < 120000
    746745       (global-name "com.apple.lsd.mapdb")
    747 #endif
    748746       (global-name "com.apple.fonts")
    749747       (global-name "com.apple.PowerManagement.control")
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h

    r284016 r284079  
    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>
     
    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:
     
    6766    {
    6867        if (!m_remoteRenderingBackendProxy || m_remoteRenderingBackendProxy->isGPUProcessConnectionClosed()) {
    69             clearDisplayList();
     68            m_remoteDisplayList.resetNeedsFlush();
    7069            return;
    7170        }
     
    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);
    110     }
    111 
    112     WebCore::RenderingMode renderingMode() const final { return BaseDisplayListImageBuffer::renderingMode(); }
     106    }
    113107
    114108    // It is safe to access m_receivedFlushIdentifier from the main thread without locking since it
     
    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
     
    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    {
     
    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
     
    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();
    270     }
    271 
    272     void recordNativeImageUse(WebCore::NativeImage& image) final
     278        m_remoteDisplayList.resetNeedsFlush();
     279    }
     280
     281    void recordNativeImageUse(WebCore::NativeImage& image)
    273282    {
    274283        if (m_remoteRenderingBackendProxy)
     
    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)
     
    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);
    329     }
    330 
    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 std::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);
    349297    }
    350298
     
    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
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp

    r283941 r284079  
    2929#if ENABLE(GPU_PROCESS)
    3030
    31 #include "DisplayListWriterHandle.h"
    3231#include "GPUConnectionToWebProcess.h"
    3332#include "Logging.h"
     
    5352    : m_parameters {
    5453        RenderingBackendIdentifier::generate(),
    55         IPC::Semaphore { },
    5654        webPage.webPageProxyIdentifier(),
    5755        webPage.identifier()
     
    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        static constexpr auto connectionBufferSize = 1 << 21;
     79        m_streamConnection = makeUnique<IPC::StreamClientConnection>(gpuProcessConnection.connection(), connectionBufferSize);
     80        gpuProcessConnection.connection().send(Messages::GPUConnectionToWebProcess::CreateRenderingBackend(m_parameters, m_streamConnection->streamBuffer()), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
    8181        m_gpuProcessConnection = makeWeakPtr(gpuProcessConnection);
    8282    }
     
    9191
    9292    m_remoteResourceCacheProxy.remoteResourceCacheWasDestroyed();
    93 
    94     m_identifiersOfReusableHandles.clear();
    95     m_sharedDisplayListHandles.clear();
    96     m_currentDestinationImageBufferIdentifier = std::nullopt;
    97     m_deferredWakeupMessageArguments = std::nullopt;
    98     m_remainingItemsToAppendBeforeSendingWakeup = 0;
    9993
    10094    if (m_destroyGetPixelBufferSharedMemoryTimer.isActive())
     
    134128void RemoteRenderingBackendProxy::createRemoteImageBuffer(ImageBuffer& imageBuffer)
    135129{
    136     send(Messages::RemoteRenderingBackend::CreateImageBuffer(imageBuffer.logicalSize(), imageBuffer.renderingMode(), imageBuffer.resolutionScale(), imageBuffer.colorSpace(), imageBuffer.pixelFormat(), imageBuffer.renderingResourceIdentifier()), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     130    sendToStream(Messages::RemoteRenderingBackend::CreateImageBuffer(imageBuffer.logicalSize(), imageBuffer.renderingMode(), imageBuffer.resolutionScale(), imageBuffer.colorSpace(), imageBuffer.pixelFormat(), imageBuffer.renderingResourceIdentifier()));
    137131}
    138132
     
    164158SharedMemory* RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer(size_t dataSize, IPC::Timeout timeout)
    165159{
    166     sendDeferredWakeupMessageIfNeeded();
    167 
    168160    bool needsSharedMemory = !m_getPixelBufferSharedMemory || dataSize > m_getPixelBufferSharedMemoryLength;
    169161    bool needsSemaphore = !m_getPixelBufferSemaphore;
     
    176168
    177169    if (needsSharedMemory && needsSemaphore)
    178         sendSync(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore), renderingBackendIdentifier(), timeout, IPC::SendSyncOption::MaintainOrderingWithAsyncMessages);
     170        sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore), timeout);
    179171    else if (needsSharedMemory)
    180         sendSync(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle), renderingBackendIdentifier(), timeout, IPC::SendSyncOption::MaintainOrderingWithAsyncMessages);
     172        sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle), timeout);
    181173    else if (needsSemaphore)
    182         sendSync(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore), renderingBackendIdentifier(), timeout);
     174        sendSyncToStream(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore), timeout);
    183175
    184176    if (!handle.handle.isNull()) {
     
    205197{
    206198    m_getPixelBufferSharedMemory = nullptr;
    207     send(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory(), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     199    sendToStream(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory());
    208200}
    209201
    210202String RemoteRenderingBackendProxy::getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, PreserveResolution preserveResolution, RenderingResourceIdentifier renderingResourceIdentifier)
    211203{
    212     sendDeferredWakeupMessageIfNeeded();
    213 
    214204    String urlString;
    215     sendSync(Messages::RemoteRenderingBackend::GetDataURLForImageBuffer(mimeType, quality, preserveResolution, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataURLForImageBuffer::Reply(urlString), renderingBackendIdentifier(), 1_s);
     205    sendSyncToStream(Messages::RemoteRenderingBackend::GetDataURLForImageBuffer(mimeType, quality, preserveResolution, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataURLForImageBuffer::Reply(urlString), 1_s);
    216206    return urlString;
    217207}
     
    219209Vector<uint8_t> RemoteRenderingBackendProxy::getDataForImageBuffer(const String& mimeType, std::optional<double> quality, RenderingResourceIdentifier renderingResourceIdentifier)
    220210{
    221     sendDeferredWakeupMessageIfNeeded();
    222 
    223211    Vector<uint8_t> data;
    224     sendSync(Messages::RemoteRenderingBackend::GetDataForImageBuffer(mimeType, quality, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataForImageBuffer::Reply(data), renderingBackendIdentifier(), 1_s);
     212    sendSyncToStream(Messages::RemoteRenderingBackend::GetDataForImageBuffer(mimeType, quality, renderingResourceIdentifier), Messages::RemoteRenderingBackend::GetDataForImageBuffer::Reply(data), 1_s);
    225213    return data;
    226214}
     
    228216RefPtr<ShareableBitmap> RemoteRenderingBackendProxy::getShareableBitmap(RenderingResourceIdentifier imageBuffer, PreserveResolution preserveResolution)
    229217{
    230     sendDeferredWakeupMessageIfNeeded();
    231 
    232218    ShareableBitmap::Handle handle;
    233     auto sendResult = sendSync(Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer(imageBuffer, preserveResolution), Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer::Reply(handle), renderingBackendIdentifier(), 1_s);
     219    auto sendResult = sendSyncToStream(Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer(imageBuffer, preserveResolution), Messages::RemoteRenderingBackend::GetShareableBitmapForImageBuffer::Reply(handle), 1_s);
    234220    if (handle.isNull())
    235221        return { };
     
    240226void RemoteRenderingBackendProxy::cacheNativeImage(const ShareableBitmap::Handle& handle, RenderingResourceIdentifier renderingResourceIdentifier)
    241227{
    242     send(Messages::RemoteRenderingBackend::CacheNativeImage(handle, renderingResourceIdentifier), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
    243 }
    244 
    245 void RemoteRenderingBackendProxy::cacheFont(Ref<WebCore::Font>&& font)
    246 {
    247     send(Messages::RemoteRenderingBackend::CacheFont(WTFMove(font)), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     228    sendToStream(Messages::RemoteRenderingBackend::CacheNativeImage(handle, renderingResourceIdentifier));
     229}
     230
     231void RemoteRenderingBackendProxy::cacheFont(Ref<Font>&& font)
     232{
     233    sendToStream(Messages::RemoteRenderingBackend::CacheFont(WTFMove(font)));
    248234}
    249235
    250236void RemoteRenderingBackendProxy::deleteAllFonts()
    251237{
    252     send(Messages::RemoteRenderingBackend::DeleteAllFonts(), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     238    sendToStream(Messages::RemoteRenderingBackend::DeleteAllFonts());
    253239}
    254240
    255241void RemoteRenderingBackendProxy::releaseRemoteResource(RenderingResourceIdentifier renderingResourceIdentifier, uint64_t useCount)
    256242{
    257     if (renderingResourceIdentifier == m_currentDestinationImageBufferIdentifier)
    258         m_currentDestinationImageBufferIdentifier = std::nullopt;
    259 
    260     send(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier, useCount), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     243    sendToStream(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier, useCount));
    261244}
    262245
    263246void RemoteRenderingBackendProxy::finalizeRenderingUpdate()
    264247{
    265     send(Messages::RemoteRenderingBackend::FinalizeRenderingUpdate(m_renderingUpdateID), renderingBackendIdentifier(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
     248    sendToStream(Messages::RemoteRenderingBackend::FinalizeRenderingUpdate(m_renderingUpdateID));
    266249    m_remoteResourceCacheProxy.finalizeRenderingUpdate();
    267250    m_renderingUpdateID.increment();
     
    294277}
    295278
    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)) {
     279RenderingBackendIdentifier RemoteRenderingBackendProxy::renderingBackendIdentifier() const
     280{
     281    return m_parameters.identifier;
     282}
     283
     284RenderingBackendIdentifier RemoteRenderingBackendProxy::ensureBackendCreated()
     285{
     286    ensureGPUProcessConnection();
     287    return renderingBackendIdentifier();
     288}
     289
     290IPC::StreamClientConnection& RemoteRenderingBackendProxy::streamConnection()
     291{
     292    ensureGPUProcessConnection();
     293    if (UNLIKELY(m_needsWakeUpSemaphoreForDisplayListStream))
     294        messageSenderConnection()->waitForAndDispatchImmediately<Messages::RemoteRenderingBackendProxy::DidCreateWakeUpSemaphoreForDisplayListStream>(renderingBackendIdentifier(), 3_s, IPC::WaitForOption::InterruptWaitingIfSyncMessageArrives);
     295    return *m_streamConnection;
     296}
     297
     298void RemoteRenderingBackendProxy::didCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore&& semaphore)
     299{
     300    if (!m_streamConnection) {
    314301        ASSERT_NOT_REACHED();
    315302        return;
    316303    }
    317304
    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()
    329 {
    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 }};
    376 }
    377 
    378 RefPtr<DisplayListWriterHandle> RemoteRenderingBackendProxy::mostRecentlyUsedDisplayListHandle()
    379 {
    380     if (UNLIKELY(m_identifiersOfReusableHandles.isEmpty()))
    381         return nullptr;
    382 
    383     return m_sharedDisplayListHandles.get(m_identifiersOfReusableHandles.first());
    384 }
    385 
    386 RefPtr<DisplayListWriterHandle> RemoteRenderingBackendProxy::findReusableDisplayListHandle(size_t capacity)
    387 {
    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;
    406 }
    407 
    408 DisplayList::ItemBufferHandle RemoteRenderingBackendProxy::createItemBuffer(size_t capacity, RenderingResourceIdentifier destinationBufferIdentifier)
    409 {
    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();
    413     }
    414 
    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();
     305    m_streamConnection->setWakeUpSemaphore(WTFMove(semaphore));
     306    m_needsWakeUpSemaphoreForDisplayListStream = false;
    448307}
    449308
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h

    r283941 r284079  
    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>
     
    4547
    4648namespace WebCore {
    47 
    48 namespace DisplayList {
    49 class DisplayList;
    50 class Item;
    51 }
    5249
    5350class DestinationColorSpace;
     
    6259namespace WebKit {
    6360
    64 class DisplayListWriterHandle;
    6561class WebPage;
    6662
     
    7874
    7975    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();
    8576
    8677    SharedMemory* sharedMemoryForGetPixelBuffer(size_t dataSize, IPC::Timeout);
     
    10293    String getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, WebCore::RenderingResourceIdentifier);
    10394    Vector<uint8_t> getDataForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier);
    104     WebCore::GraphicsContextFlushIdentifier flushDisplayListAndCommit(const WebCore::DisplayList::DisplayList&, WebCore::RenderingResourceIdentifier);
    10595    RefPtr<ShareableBitmap> getShareableBitmap(WebCore::RenderingResourceIdentifier, WebCore::PreserveResolution);
    10696    void cacheNativeImage(const ShareableBitmap::Handle&, WebCore::RenderingResourceIdentifier);
     
    126116    bool isGPUProcessConnectionClosed() const { return !m_gpuProcessConnection; }
    127117
     118    void didCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore&&);
     119
    128120    template<typename T, typename U>
    129121    void sendToStream(T&& message, ObjectIdentifier<U> identifier)
    130122    {
    131         // FIXME: Not yet implemented.
     123        // FIXME: We should consider making the send timeout finite.
     124        streamConnection().send(WTFMove(message), identifier, Seconds::infinity());
    132125    }
    133126
     
    145138    explicit RemoteRenderingBackendProxy(WebPage&);
    146139
     140    IPC::StreamClientConnection& streamConnection();
     141
     142    template<typename T>
     143    auto sendSyncToStream(T&& message, typename T::Reply&& reply, IPC::Timeout timeout)
     144    {
     145        return streamConnection().sendSync(WTFMove(message), WTFMove(reply), renderingBackendIdentifier(), timeout);
     146    }
     147
    147148    // GPUProcessConnection::Client
    148149    void gpuProcessConnectionDidClose(GPUProcessConnection&) final;
     
    155156    void didFinalizeRenderingUpdate(RenderingUpdateID didRenderingUpdateID);
    156157
    157     RefPtr<DisplayListWriterHandle> mostRecentlyUsedDisplayListHandle();
    158     RefPtr<DisplayListWriterHandle> findReusableDisplayListHandle(size_t capacity);
    159 
    160     void sendWakeupMessage(const GPUProcessWakeupMessageArguments&);
    161 
     158    std::unique_ptr<IPC::StreamClientConnection> m_streamConnection;
    162159    RemoteRenderingBackendCreationParameters m_parameters;
    163160    WeakPtr<GPUProcessConnection> m_gpuProcessConnection;
    164161    RemoteResourceCacheProxy m_remoteResourceCacheProxy { *this };
    165 
    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 };
    171162
    172163    std::optional<IPC::Semaphore> m_getPixelBufferSemaphore;
     
    177168    RenderingUpdateID m_renderingUpdateID;
    178169    RenderingUpdateID m_didRenderingUpdateID;
     170
     171    bool m_needsWakeUpSemaphoreForDisplayListStream { true };
    179172};
    180173
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.messages.in

    r283670 r284079  
    2727    DidFlush(WebCore::GraphicsContextFlushIdentifier flushIdentifier, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
    2828    DidFinalizeRenderingUpdate(WebKit::RenderingUpdateID didRenderingUpdateID)
     29    DidCreateWakeUpSemaphoreForDisplayListStream(IPC::Semaphore wakeUpSemaphore)
    2930}
    3031
  • trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp

    r282882 r284079  
    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)
     
    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}
Note: See TracChangeset for help on using the changeset viewer.