Title: [291733] trunk/Source/WebKit
Revision
291733
Author
simon.fra...@apple.com
Date
2022-03-22 19:06:04 -0700 (Tue, 22 Mar 2022)

Log Message

Swap all RemoteLayerBackingStore buffers in a single IPC
https://bugs.webkit.org/show_bug.cgi?id=238210

Reviewed by Tim Horton.

PrepareBuffersForDisplay is a sync IPC (since we need the result before painting), and sync
IPC per-layer has performance impact. So group all the swapping into a single IPC with the
GPU Process.

The PrepareBuffersForDisplay message now takes a vector of
PrepareBackingStoreBuffersInputData, and returns a vector of
PrepareBackingStoreBuffersOutputData. Swapped buffers are applied to the
RemoteLayerBackingStore as before, with a minor change in the place that setNeedsDisplay()
is called in the case where we need a full display.

* GPUProcess/graphics/RemoteRenderingBackend.cpp:
(WebKit::RemoteRenderingBackend::prepareBuffersForDisplay):
(WebKit::RemoteRenderingBackend::prepareLayerBuffersForDisplay):
* GPUProcess/graphics/RemoteRenderingBackend.h:
* GPUProcess/graphics/RemoteRenderingBackend.messages.in:
* Scripts/webkit/messages.py:
(headers_for_type):
* Shared/RemoteLayerTree/RemoteLayerBackingStore.h:
* Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::applySwappedBuffers):
(WebKit::RemoteLayerBackingStore::performDelegatedLayerDisplay):
(WebKit::RemoteLayerBackingStore::prepareToDisplay):
(WebKit::RemoteLayerBackingStore::ensureFrontBuffer):
(WebKit::RemoteLayerBackingStore::prepareBuffers):
(WebKit::operator<<): Deleted.
* Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h:
* Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm:
(WebKit::RemoteLayerBackingStoreCollection::prepareBackingStoreBuffers): Deleted.
* Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.h:
* Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.mm:
(WebKit::RemoteLayerWithRemoteRenderingBackingStoreCollection::prepareBackingStoresForDisplay):
(WebKit::RemoteLayerWithRemoteRenderingBackingStoreCollection::prepareBackingStoreBuffers): Deleted.
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/GPU/graphics/PrepareBackingStoreBuffersData.h: Added.
(WebKit::PrepareBackingStoreBuffersInputData::encode const):
(WebKit::PrepareBackingStoreBuffersInputData::decode):
(WebKit::PrepareBackingStoreBuffersOutputData::encode const):
(WebKit::PrepareBackingStoreBuffersOutputData::decode):
* WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
(WebKit::RemoteRenderingBackendProxy::prepareBuffersForDisplay):
* WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (291732 => 291733)


--- trunk/Source/WebKit/ChangeLog	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/ChangeLog	2022-03-23 02:06:04 UTC (rev 291733)
@@ -1,3 +1,52 @@
+2022-03-22  Simon Fraser  <simon.fra...@apple.com>
+
+        Swap all RemoteLayerBackingStore buffers in a single IPC
+        https://bugs.webkit.org/show_bug.cgi?id=238210
+
+        Reviewed by Tim Horton.
+
+        PrepareBuffersForDisplay is a sync IPC (since we need the result before painting), and sync
+        IPC per-layer has performance impact. So group all the swapping into a single IPC with the
+        GPU Process.
+
+        The PrepareBuffersForDisplay message now takes a vector of
+        PrepareBackingStoreBuffersInputData, and returns a vector of
+        PrepareBackingStoreBuffersOutputData. Swapped buffers are applied to the
+        RemoteLayerBackingStore as before, with a minor change in the place that setNeedsDisplay()
+        is called in the case where we need a full display.
+
+        * GPUProcess/graphics/RemoteRenderingBackend.cpp:
+        (WebKit::RemoteRenderingBackend::prepareBuffersForDisplay):
+        (WebKit::RemoteRenderingBackend::prepareLayerBuffersForDisplay):
+        * GPUProcess/graphics/RemoteRenderingBackend.h:
+        * GPUProcess/graphics/RemoteRenderingBackend.messages.in:
+        * Scripts/webkit/messages.py:
+        (headers_for_type):
+        * Shared/RemoteLayerTree/RemoteLayerBackingStore.h:
+        * Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
+        (WebKit::RemoteLayerBackingStore::applySwappedBuffers):
+        (WebKit::RemoteLayerBackingStore::performDelegatedLayerDisplay):
+        (WebKit::RemoteLayerBackingStore::prepareToDisplay):
+        (WebKit::RemoteLayerBackingStore::ensureFrontBuffer):
+        (WebKit::RemoteLayerBackingStore::prepareBuffers):
+        (WebKit::operator<<): Deleted.
+        * Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h:
+        * Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm:
+        (WebKit::RemoteLayerBackingStoreCollection::prepareBackingStoreBuffers): Deleted.
+        * Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.h:
+        * Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.mm:
+        (WebKit::RemoteLayerWithRemoteRenderingBackingStoreCollection::prepareBackingStoresForDisplay):
+        (WebKit::RemoteLayerWithRemoteRenderingBackingStoreCollection::prepareBackingStoreBuffers): Deleted.
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/GPU/graphics/PrepareBackingStoreBuffersData.h: Added.
+        (WebKit::PrepareBackingStoreBuffersInputData::encode const):
+        (WebKit::PrepareBackingStoreBuffersInputData::decode):
+        (WebKit::PrepareBackingStoreBuffersOutputData::encode const):
+        (WebKit::PrepareBackingStoreBuffersOutputData::decode):
+        * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
+        (WebKit::RemoteRenderingBackendProxy::prepareBuffersForDisplay):
+        * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
+
 2022-03-22  Sihui Liu  <sihui_...@apple.com>
 
         REGRESSION (248499@main): [iOS] ASSERTION FAILED: Completion handler should always be called under WebKit::NetworkProcess::prepareToSuspend()

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (291732 => 291733)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2022-03-23 02:06:04 UTC (rev 291733)
@@ -399,8 +399,19 @@
     return std::nullopt;
 }
 
+void RemoteRenderingBackend::prepareBuffersForDisplay(Vector<PrepareBackingStoreBuffersInputData> swapBuffersInput, CompletionHandler<void(const Vector<PrepareBackingStoreBuffersOutputData>&)>&& completionHandler)
+{
+    Vector<PrepareBackingStoreBuffersOutputData> outputData;
+    outputData.resizeToFit(swapBuffersInput.size());
+
+    for (unsigned i = 0; i < swapBuffersInput.size(); ++i)
+        prepareLayerBuffersForDisplay(swapBuffersInput[i], outputData[i]);
+
+    completionHandler(outputData);
+}
+
 // This is the GPU Process version of RemoteLayerBackingStore::prepareBuffers().
-void RemoteRenderingBackend::prepareBuffersForDisplay(const BufferIdentifierSet& bufferSet, bool supportsPartialRepaint, bool hasEmptyDirtyRegion, CompletionHandler<void(const BufferIdentifierSet& swappedBufferSet, std::optional<ImageBufferBackendHandle>&& frontBufferHandle, SwapBuffersDisplayRequirement prepareResult)>&& completionHandler)
+void RemoteRenderingBackend::prepareLayerBuffersForDisplay(const PrepareBackingStoreBuffersInputData& inputData, PrepareBackingStoreBuffersOutputData& outputData)
 {
     auto fetchBuffer = [&](std::optional<RenderingResourceIdentifier> identifier) -> ImageBuffer* {
         return identifier ? m_remoteResourceCache.cachedImageBuffer({ *identifier, m_gpuConnectionToWebProcess->webProcessIdentifier() }) : nullptr;
@@ -412,14 +423,14 @@
         return buffer->renderingResourceIdentifier();
     };
 
-    auto frontBuffer = fetchBuffer(bufferSet.front);
-    auto backBuffer = fetchBuffer(bufferSet.back);
-    auto secondaryBackBuffer = fetchBuffer(bufferSet.secondaryBack);
+    auto frontBuffer = fetchBuffer(inputData.bufferSet.front);
+    auto backBuffer = fetchBuffer(inputData.bufferSet.back);
+    auto secondaryBackBuffer = fetchBuffer(inputData.bufferSet.secondaryBack);
 
     LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "GPU Process: RemoteRenderingBackend::prepareBuffersForDisplay - front "
-        << bufferSet.front << " (in-use " << (frontBuffer && frontBuffer->isInUse()) << ") "
-        << bufferSet.back << " (in-use " << (backBuffer && backBuffer->isInUse()) << ") "
-        << bufferSet.secondaryBack << " (in-use " << (secondaryBackBuffer && secondaryBackBuffer->isInUse()) << ") ");
+        << inputData.bufferSet.front << " (in-use " << (frontBuffer && frontBuffer->isInUse()) << ") "
+        << inputData.bufferSet.back << " (in-use " << (backBuffer && backBuffer->isInUse()) << ") "
+        << inputData.bufferSet.secondaryBack << " (in-use " << (secondaryBackBuffer && secondaryBackBuffer->isInUse()) << ") ");
 
     bool needsFullDisplay = false;
 
@@ -429,15 +440,15 @@
             needsFullDisplay = true;
     }
 
-    if (frontBuffer && !needsFullDisplay && hasEmptyDirtyRegion) {
+    if (frontBuffer && !needsFullDisplay && inputData.hasEmptyDirtyRegion) {
         // No swap necessary, but we do need to return the front buffer handle.
-        auto frontBufferHandle = handleFromBuffer(*frontBuffer);
-        auto resultBufferSet = BufferIdentifierSet { bufferIdentifer(frontBuffer), bufferIdentifer(backBuffer), bufferIdentifer(secondaryBackBuffer) };
-        completionHandler(resultBufferSet, WTFMove(frontBufferHandle), SwapBuffersDisplayRequirement::NeedsNoDisplay);
+        outputData.frontBufferHandle = handleFromBuffer(*frontBuffer);
+        outputData.bufferSet = BufferIdentifierSet { bufferIdentifer(frontBuffer), bufferIdentifer(backBuffer), bufferIdentifer(secondaryBackBuffer) };
+        outputData.displayRequirement = SwapBuffersDisplayRequirement::NeedsNoDisplay;
         return;
     }
     
-    if (!frontBuffer || !supportsPartialRepaint)
+    if (!frontBuffer || !inputData.supportsPartialRepaint)
         needsFullDisplay = true;
 
     if (!backBuffer || backBuffer->isInUse()) {
@@ -452,23 +463,21 @@
 
     std::swap(frontBuffer, backBuffer);
 
-    std::optional<ImageBufferBackendHandle> frontBufferHandle;
+    outputData.bufferSet = BufferIdentifierSet { bufferIdentifer(frontBuffer), bufferIdentifer(backBuffer), bufferIdentifer(secondaryBackBuffer) };
     if (frontBuffer) {
         auto previousState = frontBuffer->setNonVolatile();
         if (previousState == SetNonVolatileResult::Empty)
             needsFullDisplay = true;
 
-        frontBufferHandle = handleFromBuffer(*frontBuffer);
-    }
+        outputData.frontBufferHandle = handleFromBuffer(*frontBuffer);
+    } else
+        needsFullDisplay = true;
 
-    auto resultBufferSet = BufferIdentifierSet { bufferIdentifer(frontBuffer), bufferIdentifer(backBuffer), bufferIdentifer(secondaryBackBuffer) };
-
     LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "GPU Process: prepareBuffersForDisplay - swapped from ["
-        << bufferSet.front << ", " << bufferSet.back << ", " << bufferSet.secondaryBack << "] to ["
-        << resultBufferSet.front << ", " << resultBufferSet.back << ", " << resultBufferSet.secondaryBack << "]");
+        << inputData.bufferSet.front << ", " << inputData.bufferSet.back << ", " << inputData.bufferSet.secondaryBack << "] to ["
+        << outputData.bufferSet.front << ", " << outputData.bufferSet.back << ", " << outputData.bufferSet.secondaryBack << "]");
 
-    auto displayRequirement = needsFullDisplay ? SwapBuffersDisplayRequirement::NeedsFullDisplay : SwapBuffersDisplayRequirement::NeedsNormalDisplay;
-    completionHandler(resultBufferSet, WTFMove(frontBufferHandle), displayRequirement);
+    outputData.displayRequirement = needsFullDisplay ? SwapBuffersDisplayRequirement::NeedsFullDisplay : SwapBuffersDisplayRequirement::NeedsNormalDisplay;
 }
 
 void RemoteRenderingBackend::markSurfacesVolatile(const Vector<WebCore::RenderingResourceIdentifier>& identifiers, CompletionHandler<void(const Vector<WebCore::RenderingResourceIdentifier>& markedVolatileBufferIdentifiers)>&& completionHandler)

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h (291732 => 291733)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h	2022-03-23 02:06:04 UTC (rev 291733)
@@ -68,6 +68,8 @@
 class GPUConnectionToWebProcess;
 class RemoteDisplayListRecorder;
 struct BufferIdentifierSet;
+struct PrepareBackingStoreBuffersInputData;
+struct PrepareBackingStoreBuffersOutputData;
 struct RemoteRenderingBackendCreationParameters;
 enum class SwapBuffersDisplayRequirement : uint8_t;
 
@@ -120,9 +122,8 @@
     void releaseRemoteResource(WebCore::RenderingResourceIdentifier);
     void finalizeRenderingUpdate(RenderingUpdateID);
     void markSurfacesVolatile(const Vector<WebCore::RenderingResourceIdentifier>&, CompletionHandler<void(const Vector<WebCore::RenderingResourceIdentifier>& markedVolatileBufferIdentifiers)>&&);
+    void prepareBuffersForDisplay(Vector<PrepareBackingStoreBuffersInputData> swapBuffersInput, CompletionHandler<void(const Vector<PrepareBackingStoreBuffersOutputData>&)>&&);
 
-    void prepareBuffersForDisplay(const BufferIdentifierSet& bufferSet, bool supportsPartialRepaint, bool hasEmptyDirtyRegion, CompletionHandler<void(const BufferIdentifierSet& swappedBufferSet, std::optional<ImageBufferBackendHandle>&& frontBufferHandle, SwapBuffersDisplayRequirement prepareResult)>&&);
-
     // Received messages translated to use QualifiedRenderingResourceIdentifier.
     void createImageBufferWithQualifiedIdentifier(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, QualifiedRenderingResourceIdentifier);
     void getDataURLForImageBufferWithQualifiedIdentifier(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, QualifiedRenderingResourceIdentifier, CompletionHandler<void(String&&)>&&);
@@ -133,6 +134,8 @@
     void releaseRemoteResourceWithQualifiedIdentifier(QualifiedRenderingResourceIdentifier);
     void cacheFontWithQualifiedIdentifier(Ref<WebCore::Font>&&, QualifiedRenderingResourceIdentifier);
 
+    void prepareLayerBuffersForDisplay(const PrepareBackingStoreBuffersInputData&, PrepareBackingStoreBuffersOutputData&);
+
     Ref<IPC::StreamConnectionWorkQueue> m_workQueue;
     Ref<IPC::StreamServerConnection> m_streamConnection;
     RemoteResourceCache m_remoteResourceCache;

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in (291732 => 291733)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in	2022-03-23 02:06:04 UTC (rev 291733)
@@ -37,7 +37,7 @@
     DeleteAllFonts()
     ReleaseRemoteResource(WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
 
-    PrepareBuffersForDisplay(struct WebKit::BufferIdentifierSet bufferSet, bool supportsPartialRepaint, bool hasEmptyDirtyRegion) -> (struct WebKit::BufferIdentifierSet swappedBufferSet, std::optional<WebKit::ImageBufferBackendHandle> frontBufferHandle, enum:uint8_t WebKit::SwapBuffersDisplayRequirement prepareResult) Synchronous NotStreamEncodable NotStreamEncodableReply
+    PrepareBuffersForDisplay(Vector<WebKit::PrepareBackingStoreBuffersInputData> swapBuffersInput) -> (Vector<WebKit::PrepareBackingStoreBuffersOutputData> swapBuffersOutput) Synchronous NotStreamEncodable NotStreamEncodableReply
 
     MarkSurfacesVolatile(Vector<WebCore::RenderingResourceIdentifier> renderingResourceIdentifiers) -> (Vector<WebCore::RenderingResourceIdentifier> markedVolatileBufferIdentifiers) Synchronous
 

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (291732 => 291733)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2022-03-23 02:06:04 UTC (rev 291733)
@@ -889,6 +889,8 @@
         'WebKit::PageState': ['"SessionState.h"'],
         'WebKit::PaymentSetupConfiguration': ['"PaymentSetupConfigurationWebKit.h"'],
         'WebKit::PaymentSetupFeatures': ['"ApplePayPaymentSetupFeaturesWebKit.h"'],
+        'WebKit::PrepareBackingStoreBuffersInputData': ['"PrepareBackingStoreBuffersData.h"'],
+        'WebKit::PrepareBackingStoreBuffersOutputData': ['"PrepareBackingStoreBuffersData.h"'],
         'WebKit::RespectSelectionAnchor': ['"GestureTypes.h"'],
         'WebKit::RemoteVideoFrameReadReference': ['"RemoteVideoFrameIdentifier.h"'],
         'WebKit::RemoteVideoFrameWriteReference': ['"RemoteVideoFrameIdentifier.h"'],

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h (291732 => 291733)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h	2022-03-23 02:06:04 UTC (rev 291733)
@@ -67,12 +67,11 @@
 
     void setContents(WTF::MachSendRight&& surfaceHandle);
 
-    SwapBuffersDisplayRequirement prepareBuffers(bool hasEmptyDirtyRegion);
-
     // Returns true if we need encode the buffer.
     bool layerWillBeDisplayed();
     bool needsDisplay() const;
 
+    bool performDelegatedLayerDisplay();
     void prepareToDisplay();
     void paintContents();
 
@@ -99,7 +98,7 @@
     }
 
     // Just for RemoteBackingStoreCollection.
-    void applySwappedBuffers(RefPtr<WebCore::ImageBuffer>&& front, RefPtr<WebCore::ImageBuffer>&& back, RefPtr<WebCore::ImageBuffer>&& secondaryBack);
+    void applySwappedBuffers(RefPtr<WebCore::ImageBuffer>&& front, RefPtr<WebCore::ImageBuffer>&& back, RefPtr<WebCore::ImageBuffer>&& secondaryBack, SwapBuffersDisplayRequirement);
     WebCore::SetNonVolatileResult swapToValidFrontBuffer();
 
     Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>> takePendingFlushers();
@@ -143,6 +142,10 @@
 
     bool setBufferVolatile(Buffer&);
     WebCore::SetNonVolatileResult setBufferNonVolatile(Buffer&);
+    
+    SwapBuffersDisplayRequirement prepareBuffers();
+    void ensureFrontBuffer();
+    void dirtyRepaintCounterIfNecessary();
 
     PlatformCALayerRemote* m_layer;
 

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm (291732 => 291733)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm	2022-03-23 02:06:04 UTC (rev 291733)
@@ -249,13 +249,23 @@
 }
 
 // Called after buffer swapping in the GPU process.
-void RemoteLayerBackingStore::applySwappedBuffers(RefPtr<WebCore::ImageBuffer>&& front, RefPtr<WebCore::ImageBuffer>&& back, RefPtr<WebCore::ImageBuffer>&& secondaryBack)
+void RemoteLayerBackingStore::applySwappedBuffers(RefPtr<WebCore::ImageBuffer>&& front, RefPtr<WebCore::ImageBuffer>&& back, RefPtr<WebCore::ImageBuffer>&& secondaryBack, SwapBuffersDisplayRequirement displayRequirement)
 {
     ASSERT(WebProcess::singleton().shouldUseRemoteRenderingFor(WebCore::RenderingPurpose::DOM));
+    m_contentsBufferHandle = std::nullopt;
 
     m_frontBuffer.imageBuffer = WTFMove(front);
     m_backBuffer.imageBuffer = WTFMove(back);
     m_secondaryBackBuffer.imageBuffer = WTFMove(secondaryBack);
+
+    if (displayRequirement == SwapBuffersDisplayRequirement::NeedsNoDisplay)
+        return;
+
+    if (displayRequirement == SwapBuffersDisplayRequirement::NeedsFullDisplay)
+        setNeedsDisplay();
+
+    dirtyRepaintCounterIfNecessary();
+    ensureFrontBuffer();
 }
 
 bool RemoteLayerBackingStore::supportsPartialRepaint() const
@@ -272,18 +282,6 @@
     m_paintingRects.clear();
 }
 
-#if !LOG_DISABLED
-static TextStream& operator<<(TextStream& ts, SwapBuffersDisplayRequirement result)
-{
-    switch (result) {
-    case SwapBuffersDisplayRequirement::NeedsFullDisplay: ts << "full display"; break;
-    case SwapBuffersDisplayRequirement::NeedsNormalDisplay: ts << "normal display"; break;
-    case SwapBuffersDisplayRequirement::NeedsNoDisplay: ts << "no display"; break;
-    }
-    return ts;
-}
-#endif
-
 bool RemoteLayerBackingStore::needsDisplay() const
 {
     auto* collection = backingStoreCollection();
@@ -302,8 +300,22 @@
     return needsDisplay;
 }
 
+bool RemoteLayerBackingStore::performDelegatedLayerDisplay()
+{
+    auto& layerOwner = *m_layer->owner();
+    if (layerOwner.platformCALayerDelegatesDisplay(m_layer)) {
+        // This can call back to setContents(), setting m_contentsBufferHandle.
+        layerOwner.platformCALayerLayerDisplay(m_layer);
+        layerOwner.platformCALayerLayerDidDisplay(m_layer);
+        return true;
+    }
+    
+    return false;
+}
+
 void RemoteLayerBackingStore::prepareToDisplay()
 {
+    ASSERT(!WebProcess::singleton().shouldUseRemoteRenderingFor(WebCore::RenderingPurpose::DOM));
     ASSERT(!m_frontBufferFlushers.size());
 
     auto* collection = backingStoreCollection();
@@ -316,67 +328,92 @@
 
     LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "RemoteLayerBackingStore " << m_layer->layerID() << " prepareToDisplay()");
 
-    auto& layerOwner = *m_layer->owner();
-    if (layerOwner.platformCALayerDelegatesDisplay(m_layer)) {
-        // This can call back to setContents(), setting m_contentsBufferHandle.
-        layerOwner.platformCALayerLayerDisplay(m_layer);
-        layerOwner.platformCALayerLayerDidDisplay(m_layer);
+    if (performDelegatedLayerDisplay())
         return;
-    }
 
-    m_contentsBufferHandle = std::nullopt;
+    auto displayRequirement = prepareBuffers();
+    if (displayRequirement == SwapBuffersDisplayRequirement::NeedsNoDisplay)
+        return;
 
-    auto displayRequirement = collection->prepareBackingStoreBuffers(*this);
-
-    LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "RemoteLayerBackingStore " << m_layer->layerID() << " prepareToDisplay() - " << displayRequirement);
-
-    ASSERT(displayRequirement != SwapBuffersDisplayRequirement::NeedsNoDisplay);
-
     if (displayRequirement == SwapBuffersDisplayRequirement::NeedsFullDisplay)
         setNeedsDisplay();
 
-    if (layerOwner.platformCALayerShowRepaintCounter(m_layer)) {
+    dirtyRepaintCounterIfNecessary();
+    ensureFrontBuffer();
+}
+
+void RemoteLayerBackingStore::dirtyRepaintCounterIfNecessary()
+{
+    if (m_layer->owner()->platformCALayerShowRepaintCounter(m_layer)) {
         WebCore::IntRect indicatorRect(0, 0, 52, 27);
         m_dirtyRegion.unite(indicatorRect);
     }
+}
 
-    if (!m_frontBuffer.imageBuffer) {
-        m_frontBuffer.imageBuffer = collection->allocateBufferForBackingStore(*this);
+void RemoteLayerBackingStore::ensureFrontBuffer()
+{
+    if (m_frontBuffer.imageBuffer)
+        return;
 
+    auto* collection = backingStoreCollection();
+    if (!collection) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    m_frontBuffer.imageBuffer = collection->allocateBufferForBackingStore(*this);
+
 #if ENABLE(CG_DISPLAY_LIST_BACKED_IMAGE_BUFFER)
-        if (m_includeDisplayList == IncludeDisplayList::Yes)
-            m_frontBuffer.displayListImageBuffer = WebCore::ConcreteImageBuffer<CGDisplayListImageBufferBackend>::create(m_size, m_scale, WebCore::DestinationColorSpace::SRGB(), pixelFormat(), nullptr);
+    if (m_includeDisplayList == IncludeDisplayList::Yes)
+        m_frontBuffer.displayListImageBuffer = WebCore::ConcreteImageBuffer<CGDisplayListImageBufferBackend>::create(m_size, m_scale, WebCore::DestinationColorSpace::SRGB(), pixelFormat(), nullptr);
 #endif
+}
+
+#if !LOG_DISABLED
+static TextStream& operator<<(TextStream& ts, SwapBuffersDisplayRequirement result)
+{
+    switch (result) {
+    case SwapBuffersDisplayRequirement::NeedsFullDisplay: ts << "full display"; break;
+    case SwapBuffersDisplayRequirement::NeedsNormalDisplay: ts << "normal display"; break;
+    case SwapBuffersDisplayRequirement::NeedsNoDisplay: ts << "no display"; break;
     }
+    return ts;
 }
+#endif
 
-SwapBuffersDisplayRequirement RemoteLayerBackingStore::prepareBuffers(bool hasEmptyDirtyRegion)
+SwapBuffersDisplayRequirement RemoteLayerBackingStore::prepareBuffers()
 {
     ASSERT(!WebProcess::singleton().shouldUseRemoteRenderingFor(WebCore::RenderingPurpose::DOM));
+    m_contentsBufferHandle = std::nullopt;
 
-    bool needsFullDisplay = false;
+    auto displayRequirement = SwapBuffersDisplayRequirement::NeedsNoDisplay;
 
     // Make the previous front buffer non-volatile early, so that we can dirty the whole layer if it comes back empty.
-    if (setFrontBufferNonVolatile() == WebCore::SetNonVolatileResult::Empty)
-        needsFullDisplay = true;
+    if (!hasFrontBuffer() || setFrontBufferNonVolatile() == WebCore::SetNonVolatileResult::Empty)
+        displayRequirement = SwapBuffersDisplayRequirement::NeedsFullDisplay;
+    else if (!hasEmptyDirtyRegion())
+        displayRequirement = SwapBuffersDisplayRequirement::NeedsNormalDisplay;
 
-    if (!needsFullDisplay && hasEmptyDirtyRegion)
-        return SwapBuffersDisplayRequirement::NeedsNoDisplay;
+    if (displayRequirement == SwapBuffersDisplayRequirement::NeedsNoDisplay)
+        return displayRequirement;
 
-    if (!hasFrontBuffer() || !supportsPartialRepaint())
-        needsFullDisplay = true;
+    if (!supportsPartialRepaint())
+        displayRequirement = SwapBuffersDisplayRequirement::NeedsFullDisplay;
 
     auto result = swapToValidFrontBuffer();
-    if (result == WebCore::SetNonVolatileResult::Empty)
-        needsFullDisplay = true;
+    if (!hasFrontBuffer() || result == WebCore::SetNonVolatileResult::Empty)
+        displayRequirement = SwapBuffersDisplayRequirement::NeedsFullDisplay;
 
-    return needsFullDisplay ? SwapBuffersDisplayRequirement::NeedsFullDisplay : SwapBuffersDisplayRequirement::NeedsNormalDisplay;
+    LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "RemoteLayerBackingStore " << m_layer->layerID() << " prepareBuffers() - " << displayRequirement);
+    return displayRequirement;
 }
 
 void RemoteLayerBackingStore::paintContents()
 {
-    if (!m_frontBuffer.imageBuffer)
+    if (!m_frontBuffer.imageBuffer) {
+        ASSERT(m_layer->owner()->platformCALayerDelegatesDisplay(m_layer));
         return;
+    }
 
     LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "RemoteLayerBackingStore " << m_layer->layerID() << " paintContents() - has dirty region " << !hasEmptyDirtyRegion());
     if (hasEmptyDirtyRegion())

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h (291732 => 291733)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.h	2022-03-23 02:06:04 UTC (rev 291733)
@@ -61,9 +61,7 @@
 
     virtual bool backingStoreNeedsDisplay(const RemoteLayerBackingStore&);
 
-    virtual SwapBuffersDisplayRequirement prepareBackingStoreBuffers(RemoteLayerBackingStore&);
-
-    void prepareBackingStoresForDisplay(RemoteLayerTreeTransaction&);
+    virtual void prepareBackingStoresForDisplay(RemoteLayerTreeTransaction&);
     void paintReachableBackingStoreContents();
 
     void willFlushLayers();

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm (291732 => 291733)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm	2022-03-23 02:06:04 UTC (rev 291733)
@@ -163,11 +163,6 @@
     return true;
 }
 
-SwapBuffersDisplayRequirement RemoteLayerBackingStoreCollection::prepareBackingStoreBuffers(RemoteLayerBackingStore& backingStore)
-{
-    return backingStore.prepareBuffers(backingStore.hasEmptyDirtyRegion());
-}
-
 bool RemoteLayerBackingStoreCollection::markBackingStoreVolatile(RemoteLayerBackingStore& backingStore, OptionSet<VolatilityMarkingBehavior> markingBehavior, MonotonicTime now)
 {
     ASSERT(!m_inLayerFlush);

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.h (291732 => 291733)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.h	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.h	2022-03-23 02:06:04 UTC (rev 291733)
@@ -44,7 +44,7 @@
     RemoteRenderingBackendProxy& remoteRenderingBackendProxy();
 
     bool backingStoreNeedsDisplay(const RemoteLayerBackingStore&) final;
-    SwapBuffersDisplayRequirement prepareBackingStoreBuffers(RemoteLayerBackingStore&) final;
+    void prepareBackingStoresForDisplay(RemoteLayerTreeTransaction&) final;
 
     bool collectBackingStoreBufferIdentifiersToMarkVolatile(RemoteLayerBackingStore&, OptionSet<VolatilityMarkingBehavior>, MonotonicTime now, Vector<WebCore::RenderingResourceIdentifier>&);
 

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.mm (291732 => 291733)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.mm	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.mm	2022-03-23 02:06:04 UTC (rev 291733)
@@ -64,20 +64,43 @@
     return !backingStore.hasEmptyDirtyRegion();
 }
 
-SwapBuffersDisplayRequirement RemoteLayerWithRemoteRenderingBackingStoreCollection::prepareBackingStoreBuffers(RemoteLayerBackingStore& backingStore)
+void RemoteLayerWithRemoteRenderingBackingStoreCollection::prepareBackingStoresForDisplay(RemoteLayerTreeTransaction& transaction)
 {
-    auto& remoteRenderingBackend = layerTreeContext().ensureRemoteRenderingBackendProxy();
+    Vector<RemoteRenderingBackendProxy::LayerPrepareBuffersData> prepareBuffersData;
+    prepareBuffersData.reserveInitialCapacity(m_backingStoresNeedingDisplay.size());
 
-    auto identifiers = RemoteRenderingBackendProxy::BufferSet {
-        backingStore.bufferForType(RemoteLayerBackingStore::BufferType::Front),
-        backingStore.bufferForType(RemoteLayerBackingStore::BufferType::Back),
-        backingStore.bufferForType(RemoteLayerBackingStore::BufferType::SecondaryBack)
-    };
+    Vector<RemoteLayerBackingStore*> backingStoreList;
+    backingStoreList.reserveInitialCapacity(m_backingStoresNeedingDisplay.size());
 
-    auto swapResult = remoteRenderingBackend.prepareBuffersForDisplay(WTFMove(identifiers), backingStore.supportsPartialRepaint(), backingStore.hasEmptyDirtyRegion());
+    for (auto* backingStore : m_backingStoresNeedingDisplay) {
+        backingStore->layer()->properties().notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreChanged);
+        transaction.layerPropertiesChanged(*backingStore->layer());
 
-    backingStore.applySwappedBuffers(WTFMove(swapResult.buffers.front), WTFMove(swapResult.buffers.back), WTFMove(swapResult.buffers.secondaryBack));
-    return swapResult.displayRequirement;
+        if (backingStore->performDelegatedLayerDisplay())
+            continue;
+
+        prepareBuffersData.uncheckedAppend({
+            {
+                backingStore->bufferForType(RemoteLayerBackingStore::BufferType::Front),
+                backingStore->bufferForType(RemoteLayerBackingStore::BufferType::Back),
+                backingStore->bufferForType(RemoteLayerBackingStore::BufferType::SecondaryBack)
+            },
+            backingStore->supportsPartialRepaint(),
+            backingStore->hasEmptyDirtyRegion(),
+        });
+        
+        backingStoreList.uncheckedAppend(backingStore);
+    }
+
+    auto& remoteRenderingBackend = layerTreeContext().ensureRemoteRenderingBackendProxy();
+    auto swapResult = remoteRenderingBackend.prepareBuffersForDisplay(WTFMove(prepareBuffersData));
+
+    RELEASE_ASSERT(swapResult.size() == backingStoreList.size());
+    for (unsigned i = 0; i < swapResult.size(); ++i) {
+        auto& backingStoreSwapResult = swapResult[i];
+        auto* backingStore = backingStoreList[i];
+        backingStore->applySwappedBuffers(WTFMove(backingStoreSwapResult.buffers.front), WTFMove(backingStoreSwapResult.buffers.back), WTFMove(backingStoreSwapResult.buffers.secondaryBack), backingStoreSwapResult.displayRequirement);
+    }
 }
 
 RefPtr<WebCore::ImageBuffer> RemoteLayerWithRemoteRenderingBackingStoreCollection::allocateBufferForBackingStore(const RemoteLayerBackingStore& backingStore)

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (291732 => 291733)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2022-03-23 02:06:04 UTC (rev 291733)
@@ -2621,6 +2621,7 @@
 		0F5E200118E77051003EC3E5 /* PlatformCAAnimationRemote.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformCAAnimationRemote.mm; sourceTree = "<group>"; };
 		0F5E200218E77051003EC3E5 /* PlatformCAAnimationRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformCAAnimationRemote.h; sourceTree = "<group>"; };
 		0F65956727DB1D5800EE874B /* SwapBuffersDisplayRequirement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwapBuffersDisplayRequirement.h; sourceTree = "<group>"; };
+		0F65956C27E10C2C00EE874B /* PrepareBackingStoreBuffersData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrepareBackingStoreBuffersData.h; sourceTree = "<group>"; };
 		0F707C771A1FEE8300DA7A45 /* RemoteLayerTreeScrollingPerformanceData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteLayerTreeScrollingPerformanceData.mm; sourceTree = "<group>"; };
 		0F707C791A1FEEA300DA7A45 /* RemoteLayerTreeScrollingPerformanceData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteLayerTreeScrollingPerformanceData.h; sourceTree = "<group>"; };
 		0F73B767222B38C600805316 /* ScrollingTreeOverflowScrollingNodeRemoteMac.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeOverflowScrollingNodeRemoteMac.cpp; sourceTree = "<group>"; };
@@ -9900,6 +9901,7 @@
 				727A7F36240788F0004D2931 /* ImageBufferShareableBitmapBackend.h */,
 				727A7F38240788F0004D2931 /* PlatformImageBufferShareableBackend.h */,
 				7227800B2408BD7D007D376B /* PlatformRemoteImageBufferProxy.h */,
+				0F65956C27E10C2C00EE874B /* PrepareBackingStoreBuffersData.h */,
 				F48BB8DE26F9635D001C1C40 /* RemoteDisplayListRecorderProxy.cpp */,
 				F48BB8DD26F9635D001C1C40 /* RemoteDisplayListRecorderProxy.h */,
 				7B904165254AFDEA006EEB8C /* RemoteGraphicsContextGLProxy.cpp */,

Added: trunk/Source/WebKit/WebProcess/GPU/graphics/PrepareBackingStoreBuffersData.h (0 => 291733)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/PrepareBackingStoreBuffersData.h	                        (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/PrepareBackingStoreBuffersData.h	2022-03-23 02:06:04 UTC (rev 291733)
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(GPU_PROCESS)
+
+#include "BufferIdentifierSet.h"
+#include "SwapBuffersDisplayRequirement.h"
+#include <WebCore/RenderingResourceIdentifier.h>
+
+namespace WebKit {
+
+struct PrepareBackingStoreBuffersInputData {
+    BufferIdentifierSet bufferSet;
+    bool supportsPartialRepaint { true };
+    bool hasEmptyDirtyRegion { true };
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<PrepareBackingStoreBuffersInputData> decode(Decoder&);
+};
+
+template<class Encoder>
+void PrepareBackingStoreBuffersInputData::encode(Encoder& encoder) const
+{
+    encoder << bufferSet;
+    encoder << supportsPartialRepaint;
+    encoder << hasEmptyDirtyRegion;
+}
+
+template<class Decoder>
+std::optional<PrepareBackingStoreBuffersInputData> PrepareBackingStoreBuffersInputData::decode(Decoder& decoder)
+{
+    std::optional<BufferIdentifierSet> bufferSet;
+    decoder >> bufferSet;
+    if (!bufferSet)
+        return std::nullopt;
+
+    std::optional<bool> supportsPartialRepaint;
+    decoder >> supportsPartialRepaint;
+    if (!supportsPartialRepaint)
+        return std::nullopt;
+
+    std::optional<bool> hasEmptyDirtyRegion;
+    decoder >> hasEmptyDirtyRegion;
+    if (!hasEmptyDirtyRegion)
+        return std::nullopt;
+
+    return PrepareBackingStoreBuffersInputData { WTFMove(*bufferSet), *supportsPartialRepaint, *hasEmptyDirtyRegion };
+}
+
+
+struct PrepareBackingStoreBuffersOutputData {
+    BufferIdentifierSet bufferSet;
+    std::optional<ImageBufferBackendHandle> frontBufferHandle;
+    SwapBuffersDisplayRequirement displayRequirement { SwapBuffersDisplayRequirement::NeedsNoDisplay };
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<PrepareBackingStoreBuffersOutputData> decode(Decoder&);
+};
+
+template<class Encoder>
+void PrepareBackingStoreBuffersOutputData::encode(Encoder& encoder) const
+{
+    encoder << bufferSet;
+    encoder << frontBufferHandle;
+    encoder << displayRequirement;
+}
+
+template<class Decoder>
+std::optional<PrepareBackingStoreBuffersOutputData> PrepareBackingStoreBuffersOutputData::decode(Decoder& decoder)
+{
+    std::optional<BufferIdentifierSet> bufferSet;
+    decoder >> bufferSet;
+    if (!bufferSet)
+        return std::nullopt;
+
+    std::optional<std::optional<ImageBufferBackendHandle>> bufferHandle;
+    decoder >> bufferHandle;
+    if (!bufferHandle)
+        return std::nullopt;
+
+    std::optional<SwapBuffersDisplayRequirement> displayRequirement;
+    decoder >> displayRequirement;
+    if (!displayRequirement)
+        return std::nullopt;
+
+    return PrepareBackingStoreBuffersOutputData { WTFMove(*bufferSet), WTFMove(*bufferHandle), *displayRequirement };
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(GPU_PROCESS)

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp (291732 => 291733)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp	2022-03-23 02:06:04 UTC (rev 291733)
@@ -267,7 +267,7 @@
     sendToStream(Messages::RemoteRenderingBackend::ReleaseRemoteResource(renderingResourceIdentifier));
 }
 
-auto RemoteRenderingBackendProxy::prepareBuffersForDisplay(const BufferSet& buffers, bool supportsPartialRepaint, bool hasEmptyDirtyRegion) -> SwapBuffersResult
+auto RemoteRenderingBackendProxy::prepareBuffersForDisplay(const Vector<LayerPrepareBuffersData>& prepareBuffersInput) -> Vector<SwapBuffersResult>
 {
     auto bufferIdentifier = [](ImageBuffer* buffer) -> std::optional<RenderingResourceIdentifier> {
         if (!buffer)
@@ -286,27 +286,31 @@
         }
     };
 
-    // Clear all the buffer's MachSendRights to avoid all the surfaces appearing to be in-use.
-    // We get back the new front buffer's MachSendRight in the reply.
-    clearBackendHandle(buffers.front.get());
-    clearBackendHandle(buffers.back.get());
-    clearBackendHandle(buffers.secondaryBack.get());
+    Vector<PrepareBackingStoreBuffersInputData> inputData;
+    inputData.reserveInitialCapacity(prepareBuffersInput.size());
 
-    auto bufferSet = BufferIdentifierSet {
-        bufferIdentifier(buffers.front.get()),
-        bufferIdentifier(buffers.back.get()),
-        bufferIdentifier(buffers.secondaryBack.get())
-    };
+    for (const auto& perLayerData : prepareBuffersInput) {
+        // Clear all the buffer's MachSendRights to avoid all the surfaces appearing to be in-use.
+        // We get back the new front buffer's MachSendRight in the reply.
+        clearBackendHandle(perLayerData.buffers.front.get());
+        clearBackendHandle(perLayerData.buffers.back.get());
+        clearBackendHandle(perLayerData.buffers.secondaryBack.get());
 
-    BufferIdentifierSet swappedBufferSet;
-    std::optional<ImageBufferBackendHandle> frontBufferHandle;
-    auto displayRequirement = SwapBuffersDisplayRequirement::NeedsNoDisplay;
+        inputData.uncheckedAppend({
+            {
+                bufferIdentifier(perLayerData.buffers.front.get()),
+                bufferIdentifier(perLayerData.buffers.back.get()),
+                bufferIdentifier(perLayerData.buffers.secondaryBack.get())
+            },
+            perLayerData.supportsPartialRepaint,
+            perLayerData.hasEmptyDirtyRegion
+        });
+    }
 
-    sendSyncToStream(Messages::RemoteRenderingBackend::PrepareBuffersForDisplay(bufferSet, supportsPartialRepaint, hasEmptyDirtyRegion),
-        Messages::RemoteRenderingBackend::PrepareBuffersForDisplay::Reply(swappedBufferSet, frontBufferHandle, displayRequirement));
+    Vector<PrepareBackingStoreBuffersOutputData> outputData;
+    sendSyncToStream(Messages::RemoteRenderingBackend::PrepareBuffersForDisplay(inputData), Messages::RemoteRenderingBackend::PrepareBuffersForDisplay::Reply(outputData));
+    RELEASE_ASSERT(inputData.size() == outputData.size());
 
-    LOG_WITH_STREAM(RemoteRenderingBufferVolatility, stream << "RemoteRenderingBackendProxy::prepareBuffersForDisplay swapped to " << swappedBufferSet.front << " " << swappedBufferSet.back << " " << swappedBufferSet.secondaryBack);
-
     auto fetchBufferWithIdentifier = [&](std::optional<RenderingResourceIdentifier> identifier, std::optional<ImageBufferBackendHandle>&& handle = std::nullopt, bool isFrontBuffer = false) -> RefPtr<ImageBuffer> {
         if (!identifier)
             return nullptr;
@@ -331,14 +335,21 @@
         return buffer;
     };
 
-    return {
-        {
-            fetchBufferWithIdentifier(swappedBufferSet.front, WTFMove(frontBufferHandle), true),
-            fetchBufferWithIdentifier(swappedBufferSet.back),
-            fetchBufferWithIdentifier(swappedBufferSet.secondaryBack)
-        },
-        displayRequirement
-    };
+    Vector<SwapBuffersResult> result;
+    result.reserveInitialCapacity(outputData.size());
+
+    for (auto& perLayerOutputData : outputData) {
+        result.uncheckedAppend({
+            {
+                fetchBufferWithIdentifier(perLayerOutputData.bufferSet.front, WTFMove(perLayerOutputData.frontBufferHandle), true),
+                fetchBufferWithIdentifier(perLayerOutputData.bufferSet.back),
+                fetchBufferWithIdentifier(perLayerOutputData.bufferSet.secondaryBack)
+            },
+            perLayerOutputData.displayRequirement
+        });
+    }
+
+    return result;
 }
 
 void RemoteRenderingBackendProxy::markSurfacesVolatile(Vector<WebCore::RenderingResourceIdentifier>&& identifiers, CompletionHandler<void(bool)>&& completionHandler)

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h (291732 => 291733)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h	2022-03-23 01:39:19 UTC (rev 291732)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h	2022-03-23 02:06:04 UTC (rev 291733)
@@ -101,12 +101,19 @@
         RefPtr<WebCore::ImageBuffer> secondaryBack;
     };
     
+    struct LayerPrepareBuffersData {
+        BufferSet buffers;
+        bool supportsPartialRepaint { true };
+        bool hasEmptyDirtyRegion { false };
+    };
+    
     struct SwapBuffersResult {
         BufferSet buffers;
         SwapBuffersDisplayRequirement displayRequirement;
     };
-    SwapBuffersResult prepareBuffersForDisplay(const BufferSet&, bool supportsPartialRepaint, bool hasEmptyDirtyRegion);
 
+    Vector<SwapBuffersResult> prepareBuffersForDisplay(const Vector<LayerPrepareBuffersData>&);
+
     void finalizeRenderingUpdate();
     RenderingUpdateID renderingUpdateID() const { return m_renderingUpdateID; }
     unsigned delayedRenderingUpdateCount() const { return m_renderingUpdateID - m_didRenderingUpdateID; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to