Title: [289580] trunk/Source
Revision
289580
Author
[email protected]
Date
2022-02-10 14:48:55 -0800 (Thu, 10 Feb 2022)

Log Message

ImageBuffer::get/putPixelBuffer should not go through DisplayList
https://bugs.webkit.org/show_bug.cgi?id=236305

Patch by Kimmo Kinnunen <[email protected]> on 2022-02-10
Reviewed by Geoffrey Garen.

Source/WebCore:

Remove GetPixelBuffer / PutPixelBuffer from display list implementation.
Display lists are about GraphicsContext commands.
GetPixelBuffer and PutPixelBuffer are ImageBuffer operations.
Especially GetPixelBuffer does not make sense as a display list item,
and in its current form it does not have parameters to propagate the information
other than to a global variables, like the WebKit side GPUP implementation does.
It is undefined what would two GetPixelBuffer commands one after another mean
in a display list.

The operations in the wrong layer make the correct implementation harder than
neccessary. In this case, GetPixelBuffer is a read operation, but in current
implementation it was invoked by Flush, e.g. GetPixelBuffer would be inside
a section of commands being flushed. Flush is a write operation. As such
it would create a get of unflushed content.

* platform/graphics/displaylists/DisplayList.cpp:
(WebCore::DisplayList::DisplayList::append):
* platform/graphics/displaylists/DisplayListItemBuffer.cpp:
(WebCore::DisplayList::ItemHandle::apply):
(WebCore::DisplayList::ItemHandle::destroy):
(WebCore::DisplayList::ItemHandle::safeCopy const):
* platform/graphics/displaylists/DisplayListItemType.cpp:
(WebCore::DisplayList::sizeOfItemInBytes):
(WebCore::DisplayList::isDrawingItem):
(WebCore::DisplayList::isInlineItem):
* platform/graphics/displaylists/DisplayListItemType.h:
* platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::operator<<):
* platform/graphics/displaylists/DisplayListItems.h:
* platform/graphics/displaylists/DisplayListRecorder.h:
* platform/graphics/displaylists/DisplayListRecorderImpl.cpp:
* platform/graphics/displaylists/DisplayListRecorderImpl.h:

Source/WebKit:

Move code that carries out RemoteImageBufferProxy GetPixelBuffer, PutPixelBuffer
from the display list playback to RemoteImageBuffer implementation
in RemoteRenderingBackend, the same place that hosts other
RemoteImageBuffer function invocations.

This makes it possible in the future to mark GetPixelBuffer as a read operation
depending on the previous write operations. Previously GetPixelBuffer was recorded
to the display list before the display list was flushed, which is semantically wrong
and in practice would cause inverted references.

Simplify the protocol to implement the GetPixelBuffer. Previously it was:
 - If GPUP does not have the semaphore and the shm, ask for GPUP to send them,  sync
 - Else if GPUP does not have the semaphore, ask for GPUP to send it, sync
 - Else if GPUP does not have the shm send, ask for GPUP to send it, sync
 - Send the GetPixelBuffer message via stream async
 - Wait for the semaphore

After it is:
 - If GPUP does not have the shm send GetPixelBuffer with the shm, sync
 - Else send the GetPixelBuffer via stream sync

There's no point in sending a semaphore, the stream sync message is
just a wait on the stream semaphore. Also, since semaphores
might have spurious wakeups, it is not enough of a protocol to wait a
plain semaphore.

* GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
* GPUProcess/graphics/RemoteDisplayListRecorder.h:
* GPUProcess/graphics/RemoteDisplayListRecorder.messages.in:
* GPUProcess/graphics/RemoteRenderingBackend.cpp:
(WebKit::RemoteRenderingBackend::getPixelBufferForImageBuffer):
(WebKit::RemoteRenderingBackend::getPixelBufferForImageBufferWithNewMemory):
(WebKit::RemoteRenderingBackend::putPixelBufferForImageBuffer):
* GPUProcess/graphics/RemoteRenderingBackend.h:
* GPUProcess/graphics/RemoteRenderingBackend.messages.in:
* WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
* WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:
* WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
* WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
(WebKit::RemoteRenderingBackendProxy::gpuProcessConnectionDidClose):
(WebKit::RemoteRenderingBackendProxy::getPixelBufferForImageBuffer):
(WebKit::RemoteRenderingBackendProxy::putPixelBufferForImageBuffer):
(WebKit::RemoteRenderingBackendProxy::updateSharedMemoryForGetPixelBuffer):
(WebKit::RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory):
* WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (289579 => 289580)


--- trunk/Source/WebCore/ChangeLog	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/ChangeLog	2022-02-10 22:48:55 UTC (rev 289580)
@@ -1,3 +1,43 @@
+2022-02-10  Kimmo Kinnunen  <[email protected]>
+
+        ImageBuffer::get/putPixelBuffer should not go through DisplayList
+        https://bugs.webkit.org/show_bug.cgi?id=236305
+
+        Reviewed by Geoffrey Garen.
+
+        Remove GetPixelBuffer / PutPixelBuffer from display list implementation.
+        Display lists are about GraphicsContext commands.
+        GetPixelBuffer and PutPixelBuffer are ImageBuffer operations.
+        Especially GetPixelBuffer does not make sense as a display list item,
+        and in its current form it does not have parameters to propagate the information
+        other than to a global variables, like the WebKit side GPUP implementation does.
+        It is undefined what would two GetPixelBuffer commands one after another mean
+        in a display list.
+
+        The operations in the wrong layer make the correct implementation harder than
+        neccessary. In this case, GetPixelBuffer is a read operation, but in current
+        implementation it was invoked by Flush, e.g. GetPixelBuffer would be inside
+        a section of commands being flushed. Flush is a write operation. As such
+        it would create a get of unflushed content.
+
+        * platform/graphics/displaylists/DisplayList.cpp:
+        (WebCore::DisplayList::DisplayList::append):
+        * platform/graphics/displaylists/DisplayListItemBuffer.cpp:
+        (WebCore::DisplayList::ItemHandle::apply):
+        (WebCore::DisplayList::ItemHandle::destroy):
+        (WebCore::DisplayList::ItemHandle::safeCopy const):
+        * platform/graphics/displaylists/DisplayListItemType.cpp:
+        (WebCore::DisplayList::sizeOfItemInBytes):
+        (WebCore::DisplayList::isDrawingItem):
+        (WebCore::DisplayList::isInlineItem):
+        * platform/graphics/displaylists/DisplayListItemType.h:
+        * platform/graphics/displaylists/DisplayListItems.cpp:
+        (WebCore::DisplayList::operator<<):
+        * platform/graphics/displaylists/DisplayListItems.h:
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * platform/graphics/displaylists/DisplayListRecorderImpl.cpp:
+        * platform/graphics/displaylists/DisplayListRecorderImpl.h:
+
 2022-02-10  Devin Rousso  <[email protected]>
 
         Permit simultaneous Apple Pay and script injection

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -298,10 +298,6 @@
         return append<FillEllipse>(item.get<FillEllipse>());
     case ItemType::FlushContext:
         return append<FlushContext>(item.get<FlushContext>());
-    case ItemType::GetPixelBuffer:
-        return append<GetPixelBuffer>(item.get<GetPixelBuffer>());
-    case ItemType::PutPixelBuffer:
-        return append<PutPixelBuffer>(item.get<PutPixelBuffer>());
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia:
         return append<PaintFrameForMedia>(item.get<PaintFrameForMedia>());

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemBuffer.cpp (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemBuffer.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemBuffer.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -195,11 +195,6 @@
     case ItemType::FlushContext:
         get<FlushContext>().apply(context);
         return;
-    case ItemType::GetPixelBuffer:
-    case ItemType::PutPixelBuffer:
-        // Should already be handled by the delegate.
-        ASSERT_NOT_REACHED();
-        return;
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia:
         get<PaintFrameForMedia>().apply(context);
@@ -296,12 +291,6 @@
     case ItemType::FillRoundedRect:
         get<FillRoundedRect>().~FillRoundedRect();
         return;
-    case ItemType::GetPixelBuffer:
-        get<GetPixelBuffer>().~GetPixelBuffer();
-        return;
-    case ItemType::PutPixelBuffer:
-        get<PutPixelBuffer>().~PutPixelBuffer();
-        return;
     case ItemType::SetLineDash:
         get<SetLineDash>().~SetLineDash();
         return;
@@ -528,10 +517,6 @@
         return copyInto<FillRectWithRoundedHole>(itemOffset, *this);
     case ItemType::FillRoundedRect:
         return copyInto<FillRoundedRect>(itemOffset, *this);
-    case ItemType::GetPixelBuffer:
-        return copyInto<GetPixelBuffer>(itemOffset, *this);
-    case ItemType::PutPixelBuffer:
-        return copyInto<PutPixelBuffer>(itemOffset, *this);
     case ItemType::SetLineDash:
         return copyInto<SetLineDash>(itemOffset, *this);
     case ItemType::SetState:

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemType.cpp (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemType.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemType.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -134,10 +134,6 @@
         return sizeof(FillEllipse);
     case ItemType::FlushContext:
         return sizeof(FlushContext);
-    case ItemType::GetPixelBuffer:
-        return sizeof(GetPixelBuffer);
-    case ItemType::PutPixelBuffer:
-        return sizeof(PutPixelBuffer);
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia:
         return sizeof(PaintFrameForMedia);
@@ -212,7 +208,6 @@
     case ItemType::SetState:
     case ItemType::SetStrokeThickness:
     case ItemType::Translate:
-    case ItemType::GetPixelBuffer:
         return false;
     case ItemType::BeginTransparencyLayer:
     case ItemType::ClearRect:
@@ -247,7 +242,6 @@
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia:
 #endif
-    case ItemType::PutPixelBuffer:
     case ItemType::StrokeEllipse:
 #if ENABLE(INLINE_PATH_DATA)
     case ItemType::StrokeArc:
@@ -304,8 +298,6 @@
     case ItemType::FillRectWithGradient:
     case ItemType::FillRectWithRoundedHole:
     case ItemType::FillRoundedRect:
-    case ItemType::GetPixelBuffer:
-    case ItemType::PutPixelBuffer:
     case ItemType::SetLineDash:
     case ItemType::SetState:
     case ItemType::StrokePath:

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemType.h (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemType.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItemType.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -80,8 +80,6 @@
     FillPath,
     FillEllipse,
     FlushContext,
-    GetPixelBuffer,
-    PutPixelBuffer,
 #if ENABLE(VIDEO)
     PaintFrameForMedia,
 #endif

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -759,61 +759,6 @@
     return ts;
 }
 
-static TextStream& operator<<(TextStream& ts, const GetPixelBuffer& item)
-{
-    ts.dumpProperty("outputFormat", item.outputFormat());
-    ts.dumpProperty("srcRect", item.srcRect());
-    return ts;
-}
-
-PutPixelBuffer::PutPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
-    : m_srcRect(srcRect)
-    , m_destPoint(destPoint)
-    , m_pixelBuffer(pixelBuffer.deepClone()) // This copy is actually required to preserve the semantics of putPixelBuffer().
-    , m_destFormat(destFormat)
-{
-}
-
-PutPixelBuffer::PutPixelBuffer(PixelBuffer&& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
-    : m_srcRect(srcRect)
-    , m_destPoint(destPoint)
-    , m_pixelBuffer(WTFMove(pixelBuffer))
-    , m_destFormat(destFormat)
-{
-}
-
-PutPixelBuffer::PutPixelBuffer(const PutPixelBuffer& other)
-    : m_srcRect(other.m_srcRect)
-    , m_destPoint(other.m_destPoint)
-    , m_pixelBuffer(other.m_pixelBuffer.deepClone())
-    , m_destFormat(other.m_destFormat)
-{
-}
-
-PutPixelBuffer& PutPixelBuffer::operator=(const PutPixelBuffer& other)
-{
-    PutPixelBuffer copy { other };
-    swap(copy);
-    return *this;
-}
-
-void PutPixelBuffer::swap(PutPixelBuffer& other)
-{
-    std::swap(m_srcRect, other.m_srcRect);
-    std::swap(m_destPoint, other.m_destPoint);
-    std::swap(m_pixelBuffer, other.m_pixelBuffer);
-    std::swap(m_destFormat, other.m_destFormat);
-}
-
-static TextStream& operator<<(TextStream& ts, const PutPixelBuffer& item)
-{
-    ts.dumpProperty("pixelBufferSize", item.pixelBuffer().size());
-    ts.dumpProperty("srcRect", item.srcRect());
-    ts.dumpProperty("destPoint", item.destPoint());
-    ts.dumpProperty("destFormat", item.destFormat());
-    return ts;
-}
-
 #if ENABLE(VIDEO)
 PaintFrameForMedia::PaintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
     : m_identifier(player.identifier())
@@ -1106,8 +1051,6 @@
     case ItemType::FillPath: ts << "fill-path"; break;
     case ItemType::FillEllipse: ts << "fill-ellipse"; break;
     case ItemType::FlushContext: ts << "flush-context"; break;
-    case ItemType::GetPixelBuffer: ts << "get-pixel-buffer"; break;
-    case ItemType::PutPixelBuffer: ts << "put-pixel-buffer"; break;
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia: ts << "paint-frame-for-media"; break;
 #endif
@@ -1278,12 +1221,6 @@
     case ItemType::FlushContext:
         ts << item.get<FlushContext>();
         break;
-    case ItemType::GetPixelBuffer:
-        ts << item.get<GetPixelBuffer>();
-        break;
-    case ItemType::PutPixelBuffer:
-        ts << item.get<PutPixelBuffer>();
-        break;
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia:
         ts << item.get<PaintFrameForMedia>();

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -1968,127 +1968,6 @@
     FloatRect m_rect;
 };
 
-class GetPixelBuffer {
-public:
-    static constexpr ItemType itemType = ItemType::GetPixelBuffer;
-    static constexpr bool isInlineItem = false;
-    static constexpr bool isDrawingItem = false;
-
-    GetPixelBuffer(PixelBufferFormat outputFormat, const IntRect& srcRect)
-        : m_srcRect(srcRect)
-        , m_outputFormat(WTFMove(outputFormat))
-    {
-    }
-
-    // Explicit destructor added to force non-trivial destructor on all platforms
-    // as the encoding logic currently hardcodes which display list item types need
-    // out of line treatment rather than using the isInlineItem constant.
-    ~GetPixelBuffer() { }
-
-    const PixelBufferFormat& outputFormat() const { return m_outputFormat; }
-    IntRect srcRect() const { return m_srcRect; }
-
-    template<class Encoder> void encode(Encoder&) const;
-    template<class Decoder> static std::optional<GetPixelBuffer> decode(Decoder&);
-
-private:
-    IntRect m_srcRect;
-    PixelBufferFormat m_outputFormat;
-};
-
-template<class Encoder>
-void GetPixelBuffer::encode(Encoder& encoder) const
-{
-    encoder << m_srcRect;
-    encoder << m_outputFormat;
-}
-
-template<class Decoder>
-std::optional<GetPixelBuffer> GetPixelBuffer::decode(Decoder& decoder)
-{
-    std::optional<IntRect> srcRect;
-    decoder >> srcRect;
-    if (!srcRect)
-        return std::nullopt;
-
-    std::optional<PixelBufferFormat> outputFormat;
-    decoder >> outputFormat;
-    if (!outputFormat)
-        return std::nullopt;
-
-    return {{ WTFMove(*outputFormat), *srcRect }};
-}
-
-class PutPixelBuffer {
-public:
-    static constexpr ItemType itemType = ItemType::PutPixelBuffer;
-    static constexpr bool isInlineItem = false;
-    static constexpr bool isDrawingItem = true;
-
-    WEBCORE_EXPORT PutPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
-    WEBCORE_EXPORT PutPixelBuffer(PixelBuffer&&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
-
-    PutPixelBuffer(const PutPixelBuffer&);
-    PutPixelBuffer(PutPixelBuffer&&) = default;
-    PutPixelBuffer& operator=(const PutPixelBuffer&);
-    PutPixelBuffer& operator=(PutPixelBuffer&&) = default;
-
-    void swap(PutPixelBuffer&);
-
-    const PixelBuffer& pixelBuffer() const { return m_pixelBuffer; }
-    IntRect srcRect() const { return m_srcRect; }
-    IntPoint destPoint() const { return m_destPoint; }
-    AlphaPremultiplication destFormat() const { return m_destFormat; }
-
-    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return std::nullopt; }
-    std::optional<FloatRect> globalBounds() const { return {{ m_destPoint, m_srcRect.size() }}; }
-
-    template<class Encoder> void encode(Encoder&) const;
-    template<class Decoder> static std::optional<PutPixelBuffer> decode(Decoder&);
-
-private:
-    IntRect m_srcRect;
-    IntPoint m_destPoint;
-    PixelBuffer m_pixelBuffer;
-    AlphaPremultiplication m_destFormat;
-};
-
-template<class Encoder>
-void PutPixelBuffer::encode(Encoder& encoder) const
-{
-    encoder << m_pixelBuffer;
-    encoder << m_srcRect;
-    encoder << m_destPoint;
-    encoder << m_destFormat;
-}
-
-template<class Decoder>
-std::optional<PutPixelBuffer> PutPixelBuffer::decode(Decoder& decoder)
-{
-    std::optional<PixelBuffer> pixelBuffer;
-    std::optional<IntRect> srcRect;
-    std::optional<IntPoint> destPoint;
-    std::optional<AlphaPremultiplication> destFormat;
-
-    decoder >> pixelBuffer;
-    if (!pixelBuffer)
-        return std::nullopt;
-
-    decoder >> srcRect;
-    if (!srcRect)
-        return std::nullopt;
-
-    decoder >> destPoint;
-    if (!destPoint)
-        return std::nullopt;
-
-    decoder >> destFormat;
-    if (!destFormat)
-        return std::nullopt;
-
-    return {{ WTFMove(*pixelBuffer), *srcRect, *destPoint, *destFormat }};
-}
-
 #if ENABLE(VIDEO)
 class PaintFrameForMedia {
 public:
@@ -2423,8 +2302,6 @@
     , FillRectWithRoundedHole
     , FillRoundedRect
     , FlushContext
-    , GetPixelBuffer
-    , PutPixelBuffer
     , Restore
     , Rotate
     , Save
@@ -2527,8 +2404,6 @@
     WebCore::DisplayList::ItemType::FillPath,
     WebCore::DisplayList::ItemType::FillEllipse,
     WebCore::DisplayList::ItemType::FlushContext,
-    WebCore::DisplayList::ItemType::GetPixelBuffer,
-    WebCore::DisplayList::ItemType::PutPixelBuffer,
 #if ENABLE(VIDEO)
     WebCore::DisplayList::ItemType::PaintFrameForMedia,
 #endif

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -36,18 +36,13 @@
 
 namespace WebCore {
 
-enum class AlphaPremultiplication : uint8_t;
-
 class FloatPoint;
-class FloatPoint;
 class FloatRect;
 class Font;
 class GlyphBuffer;
 class Image;
-class PixelBuffer;
 class SourceImage;
 
-struct GraphicsContextState;
 struct ImagePaintingOptions;
 
 namespace DisplayList {
@@ -59,8 +54,6 @@
     WEBCORE_EXPORT Recorder(const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform&, DrawGlyphsRecorder::DeconstructDrawGlyphs = DrawGlyphsRecorder::DeconstructDrawGlyphs::Yes);
     WEBCORE_EXPORT virtual ~Recorder();
 
-    virtual void getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect) = 0;
-    virtual void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) = 0;
     virtual void convertToLuminanceMask() = 0;
     virtual void transformToColorSpace(const DestinationColorSpace&) = 0;
     virtual void flushContext(GraphicsContextFlushIdentifier) = 0;

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -63,16 +63,6 @@
         LOG(DisplayLists, "Recorded display list:\n%s", m_displayList.description().data());
 }
 
-void RecorderImpl::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect)
-{
-    append<GetPixelBuffer>(outputFormat, sourceRect);
-}
-
-void RecorderImpl::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
-{
-    append<PutPixelBuffer>(pixelBuffer, srcRect, destPoint, destFormat);
-}
-
 std::unique_ptr<GraphicsContext> RecorderImpl::createNestedContext(const FloatRect& initialClip, const AffineTransform& initialCTM)
 {
     return makeUnique<RecorderImpl>(*this, GraphicsContextState { }, initialClip, initialCTM);

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h (289579 => 289580)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -42,8 +42,6 @@
 
     bool isEmpty() const { return m_displayList.isEmpty(); }
 
-    void getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect) final;
-    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) final;
     void convertToLuminanceMask() final { }
     void transformToColorSpace(const DestinationColorSpace&) final { }
     void flushContext(GraphicsContextFlushIdentifier identifier) final { append<FlushContext>(identifier); }

Modified: trunk/Source/WebKit/ChangeLog (289579 => 289580)


--- trunk/Source/WebKit/ChangeLog	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/ChangeLog	2022-02-10 22:48:55 UTC (rev 289580)
@@ -1,3 +1,56 @@
+2022-02-10  Kimmo Kinnunen  <[email protected]>
+
+        ImageBuffer::get/putPixelBuffer should not go through DisplayList
+        https://bugs.webkit.org/show_bug.cgi?id=236305
+
+        Reviewed by Geoffrey Garen.
+
+        Move code that carries out RemoteImageBufferProxy GetPixelBuffer, PutPixelBuffer
+        from the display list playback to RemoteImageBuffer implementation
+        in RemoteRenderingBackend, the same place that hosts other
+        RemoteImageBuffer function invocations.
+
+        This makes it possible in the future to mark GetPixelBuffer as a read operation
+        depending on the previous write operations. Previously GetPixelBuffer was recorded
+        to the display list before the display list was flushed, which is semantically wrong
+        and in practice would cause inverted references.
+
+        Simplify the protocol to implement the GetPixelBuffer. Previously it was:
+         - If GPUP does not have the semaphore and the shm, ask for GPUP to send them,  sync
+         - Else if GPUP does not have the semaphore, ask for GPUP to send it, sync
+         - Else if GPUP does not have the shm send, ask for GPUP to send it, sync
+         - Send the GetPixelBuffer message via stream async
+         - Wait for the semaphore
+
+        After it is:
+         - If GPUP does not have the shm send GetPixelBuffer with the shm, sync
+         - Else send the GetPixelBuffer via stream sync
+
+        There's no point in sending a semaphore, the stream sync message is
+        just a wait on the stream semaphore. Also, since semaphores
+        might have spurious wakeups, it is not enough of a protocol to wait a
+        plain semaphore.
+
+        * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
+        * GPUProcess/graphics/RemoteDisplayListRecorder.h:
+        * GPUProcess/graphics/RemoteDisplayListRecorder.messages.in:
+        * GPUProcess/graphics/RemoteRenderingBackend.cpp:
+        (WebKit::RemoteRenderingBackend::getPixelBufferForImageBuffer):
+        (WebKit::RemoteRenderingBackend::getPixelBufferForImageBufferWithNewMemory):
+        (WebKit::RemoteRenderingBackend::putPixelBufferForImageBuffer):
+        * GPUProcess/graphics/RemoteRenderingBackend.h:
+        * GPUProcess/graphics/RemoteRenderingBackend.messages.in:
+        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
+        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:
+        * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
+        * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:
+        (WebKit::RemoteRenderingBackendProxy::gpuProcessConnectionDidClose):
+        (WebKit::RemoteRenderingBackendProxy::getPixelBufferForImageBuffer):
+        (WebKit::RemoteRenderingBackendProxy::putPixelBufferForImageBuffer):
+        (WebKit::RemoteRenderingBackendProxy::updateSharedMemoryForGetPixelBuffer):
+        (WebKit::RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory):
+        * WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
+
 2022-02-10  Devin Rousso  <[email protected]>
 
         Permit simultaneous Apple Pay and script injection

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp (289579 => 289580)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -431,16 +431,6 @@
     handleItem(DisplayList::FillEllipse(rect));
 }
 
-void RemoteDisplayListRecorder::getPixelBuffer(const IntRect& srcRect, const PixelBufferFormat& outputFormat)
-{
-    m_renderingBackend->populateGetPixelBufferSharedMemory(m_imageBuffer->getPixelBuffer(outputFormat, srcRect));
-}
-
-void RemoteDisplayListRecorder::putPixelBuffer(const IntRect& srcRect, const IntPoint& destPoint, const PixelBuffer& pixelBuffer, AlphaPremultiplication destFormat)
-{
-    m_imageBuffer->putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
-}
-
 void RemoteDisplayListRecorder::convertToLuminanceMask()
 {
     m_imageBuffer->convertToLuminanceMask();

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h (289579 => 289580)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -109,8 +109,6 @@
 #endif
     void fillPath(const WebCore::Path&);
     void fillEllipse(const WebCore::FloatRect&);
-    void getPixelBuffer(const WebCore::IntRect& srcRect, const WebCore::PixelBufferFormat& outputFormat);
-    void putPixelBuffer(const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, const WebCore::PixelBuffer&, WebCore::AlphaPremultiplication destFormat);
     void convertToLuminanceMask();
     void transformToColorSpace(const WebCore::DestinationColorSpace&);
     void paintFrameForMedia(WebCore::MediaPlayerIdentifier, const WebCore::FloatRect& destination);

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.messages.in (289579 => 289580)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.messages.in	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.messages.in	2022-02-10 22:48:55 UTC (rev 289580)
@@ -75,8 +75,6 @@
 #endif
     FillPath(WebCore::Path path)
     FillEllipse(WebCore::FloatRect rect)
-    GetPixelBuffer(WebCore::IntRect srcRect, struct WebCore::PixelBufferFormat outputFormat)
-    PutPixelBuffer(WebCore::IntRect srcRect, WebCore::IntPoint destPoint, WebCore::PixelBuffer pixelBuffer, enum:uint8_t WebCore::AlphaPremultiplication destFormat)
     ConvertToLuminanceMask()
     TransformToColorSpace(WebCore::DestinationColorSpace colorSpace)
     PaintFrameForMedia(WebCore::MediaPlayerIdentifier identifier, WebCore::FloatRect destination)

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (289579 => 289580)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -195,65 +195,41 @@
     updateRenderingResourceRequest();
 }
 
-std::optional<SharedMemory::IPCHandle> RemoteRenderingBackend::updateSharedMemoryForGetPixelBufferHelper(size_t byteCount)
+void RemoteRenderingBackend::getPixelBufferForImageBuffer(RenderingResourceIdentifier imageBuffer, WebCore::PixelBufferFormat&& destinationFormat, WebCore::IntRect&& srcRect, CompletionHandler<void()>&& completionHandler)
 {
-    MESSAGE_CHECK_WITH_RETURN_VALUE(!m_getPixelBufferSharedMemory || byteCount > m_getPixelBufferSharedMemory->size(), std::nullopt, "The existing Shmem for getPixelBuffer() is already big enough to handle the request");
-
-    if (byteCount > HTMLCanvasElement::maxActivePixelMemory()) {
-        // Just a sanity check.
-        return std::nullopt;
+    MESSAGE_CHECK(m_getPixelBufferSharedMemory, "No shared memory for getPixelBufferForImageBuffer");
+    QualifiedRenderingResourceIdentifier qualifiedImageBuffer { imageBuffer, m_gpuConnectionToWebProcess->webProcessIdentifier() };
+    if (auto imageBuffer = m_remoteResourceCache.cachedImageBuffer(qualifiedImageBuffer)) {
+        auto pixelBuffer = imageBuffer->getPixelBuffer(destinationFormat, srcRect);
+        if (pixelBuffer) {
+            MESSAGE_CHECK(pixelBuffer->data().byteLength() <= m_getPixelBufferSharedMemory->size(), "Shmem for return of getPixelBuffer is too small");
+            memcpy(m_getPixelBufferSharedMemory->data(), pixelBuffer->data().data(), pixelBuffer->data().byteLength());
+        } else
+            memset(m_getPixelBufferSharedMemory->data(), 0, m_getPixelBufferSharedMemory->size());
     }
-
-    destroyGetPixelBufferSharedMemory();
-    m_getPixelBufferSharedMemory = SharedMemory::allocate(byteCount);
-    SharedMemory::Handle handle;
-    if (m_getPixelBufferSharedMemory)
-        m_getPixelBufferSharedMemory->createHandle(handle, SharedMemory::Protection::ReadOnly);
-    return SharedMemory::IPCHandle { WTFMove(handle), m_getPixelBufferSharedMemory ? m_getPixelBufferSharedMemory->size() : 0 };
+    completionHandler();
 }
 
-void RemoteRenderingBackend::updateSharedMemoryForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&)>&& completionHandler)
+void RemoteRenderingBackend::getPixelBufferForImageBufferWithNewMemory(RenderingResourceIdentifier imageBuffer, SharedMemory::IPCHandle&& handle, WebCore::PixelBufferFormat&& destinationFormat, WebCore::IntRect&& srcRect, CompletionHandler<void()>&& completionHandler)
 {
-    ASSERT(!RunLoop::isMain());
-
-    if (auto handle = updateSharedMemoryForGetPixelBufferHelper(byteCount))
-        completionHandler(WTFMove(handle.value()));
-    else
-        completionHandler({ });
+    m_getPixelBufferSharedMemory = nullptr;
+    auto sharedMemory = WebKit::SharedMemory::map(handle.handle, WebKit::SharedMemory::Protection::ReadWrite);
+    MESSAGE_CHECK(sharedMemory, "Shared memory could not be mapped.");
+    MESSAGE_CHECK(sharedMemory->size() <= HTMLCanvasElement::maxActivePixelMemory(), "Shared memory too big.");
+    m_getPixelBufferSharedMemory = WTFMove(sharedMemory);
+    getPixelBufferForImageBuffer(imageBuffer, WTFMove(destinationFormat), WTFMove(srcRect), WTFMove(completionHandler));
 }
 
-void RemoteRenderingBackend::semaphoreForGetPixelBuffer(CompletionHandler<void(const IPC::Semaphore&)>&& completionHandler)
-{
-    ASSERT(!RunLoop::isMain());
-    completionHandler(m_getPixelBufferSemaphore);
-}
-
-void RemoteRenderingBackend::updateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&, const IPC::Semaphore&)>&& completionHandler)
-{
-    ASSERT(!RunLoop::isMain());
-
-    if (auto handle = updateSharedMemoryForGetPixelBufferHelper(byteCount))
-        completionHandler(WTFMove(handle.value()), m_getPixelBufferSemaphore);
-    else
-        completionHandler({ }, m_getPixelBufferSemaphore);
-}
-
 void RemoteRenderingBackend::destroyGetPixelBufferSharedMemory()
 {
     m_getPixelBufferSharedMemory = nullptr;
 }
 
-void RemoteRenderingBackend::populateGetPixelBufferSharedMemory(std::optional<WebCore::PixelBuffer>&& pixelBuffer)
+void RemoteRenderingBackend::putPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, WebCore::PixelBuffer&& pixelBuffer, WebCore::IntRect&& srcRect, WebCore::IntPoint&& destPoint, WebCore::AlphaPremultiplication destFormat)
 {
-    MESSAGE_CHECK(m_getPixelBufferSharedMemory, "We can't run getPixelBuffer without a buffer to write into");
-
-    if (pixelBuffer) {
-        MESSAGE_CHECK(pixelBuffer->data().byteLength() <= m_getPixelBufferSharedMemory->size(), "Shmem for return of getPixelBuffer is too small");
-        memcpy(m_getPixelBufferSharedMemory->data(), pixelBuffer->data().data(), pixelBuffer->data().byteLength());
-    } else
-        memset(m_getPixelBufferSharedMemory->data(), 0, m_getPixelBufferSharedMemory->size());
-
-    m_getPixelBufferSemaphore.signal();
+    QualifiedRenderingResourceIdentifier qualifiedImageBuffer { imageBuffer, m_gpuConnectionToWebProcess->webProcessIdentifier() };
+    if (auto imageBuffer = m_remoteResourceCache.cachedImageBuffer(qualifiedImageBuffer))
+        imageBuffer->putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
 }
 
 void RemoteRenderingBackend::getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution preserveResolution, WebCore::RenderingResourceIdentifier renderingResourceIdentifier, CompletionHandler<void(String&&)>&& completionHandler)

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h (289579 => 289580)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -83,8 +83,6 @@
     void didCreateImageBufferBackend(ImageBufferBackendHandle, QualifiedRenderingResourceIdentifier, RemoteDisplayListRecorder&);
     void didFlush(WebCore::GraphicsContextFlushIdentifier, QualifiedRenderingResourceIdentifier);
 
-    void populateGetPixelBufferSharedMemory(std::optional<WebCore::PixelBuffer>&&);
-
     bool allowsExitUnderMemoryPressure() const;
 
     // Runs Function in RemoteRenderingBackend task queue.
@@ -106,10 +104,10 @@
 
     // Messages to be received.
     void createImageBuffer(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, WebCore::RenderingResourceIdentifier);
-    void updateSharedMemoryForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&)>&&);
-    void semaphoreForGetPixelBuffer(CompletionHandler<void(const IPC::Semaphore&)>&&);
-    void updateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount, CompletionHandler<void(const SharedMemory::IPCHandle&, const IPC::Semaphore&)>&&);
+    void getPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier, WebCore::PixelBufferFormat&&, WebCore::IntRect&& srcRect, CompletionHandler<void()>&&);
+    void getPixelBufferForImageBufferWithNewMemory(WebCore::RenderingResourceIdentifier, SharedMemory::IPCHandle&&, WebCore::PixelBufferFormat&& destinationFormat, WebCore::IntRect&& srcRect, CompletionHandler<void()>&&);
     void destroyGetPixelBufferSharedMemory();
+    void putPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier, WebCore::PixelBuffer&&, WebCore::IntRect&& srcRect, WebCore::IntPoint&& destPoint, WebCore::AlphaPremultiplication destFormat);
     void getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, WebCore::RenderingResourceIdentifier, CompletionHandler<void(String&&)>&&);
     void getDataForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier, CompletionHandler<void(Vector<uint8_t>&&)>&&);
     void getShareableBitmapForImageBuffer(WebCore::RenderingResourceIdentifier, WebCore::PreserveResolution, CompletionHandler<void(ShareableBitmap::Handle&&)>&&);
@@ -136,7 +134,6 @@
     Ref<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
     WebCore::ProcessIdentity m_resourceOwner;
     RenderingBackendIdentifier m_renderingBackendIdentifier;
-    IPC::Semaphore m_getPixelBufferSemaphore;
     RefPtr<SharedMemory> m_getPixelBufferSharedMemory;
     ScopedRenderingResourcesRequest m_renderingResourcesRequest;
 

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


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in	2022-02-10 22:48:55 UTC (rev 289580)
@@ -24,10 +24,10 @@
 
 messages -> RemoteRenderingBackend NotRefCounted Stream {
     CreateImageBuffer(WebCore::FloatSize logicalSize, WebCore::RenderingMode renderingMode, float resolutionScale, WebCore::DestinationColorSpace colorSpace, enum:uint8_t WebCore::PixelFormat pixelFormat, WebCore::RenderingResourceIdentifier renderingResourceIdentifier)
-    UpdateSharedMemoryForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle) Synchronous NotStreamEncodableReply
-    SemaphoreForGetPixelBuffer() -> (IPC::Semaphore semaphore) Synchronous NotStreamEncodableReply
-    UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(uint32_t byteCount) -> (WebKit::SharedMemory::IPCHandle handle, IPC::Semaphore semaphore) Synchronous NotStreamEncodableReply
+    GetPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, struct WebCore::PixelBufferFormat outputFormat, WebCore::IntRect srcRect) -> () Synchronous
+    GetPixelBufferForImageBufferWithNewMemory(WebCore::RenderingResourceIdentifier imageBuffer, WebKit::SharedMemory::IPCHandle handle, struct WebCore::PixelBufferFormat outputFormat, WebCore::IntRect srcRect) -> () Synchronous NotStreamEncodable
     DestroyGetPixelBufferSharedMemory()
+    PutPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, WebCore::PixelBuffer pixelBuffer,  WebCore::IntRect srcRect, WebCore::IntPoint destPoint, enum:uint8_t WebCore::AlphaPremultiplication destFormat)
     GetDataURLForImageBuffer(String mimeType, std::optional<double> quality, enum:uint8_t WebCore::PreserveResolution preserveResolution, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (String urlString) Synchronous
     GetDataForImageBuffer(String mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier renderingResourceIdentifier) -> (Vector<uint8_t> data) Synchronous
     GetShareableBitmapForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, enum:uint8_t WebCore::PreserveResolution preserveResolution) -> (WebKit::ShareableBitmap::Handle handle) Synchronous NotStreamEncodableReply

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp (289579 => 289580)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -60,16 +60,6 @@
 {
 }
 
-void RemoteDisplayListRecorderProxy::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect)
-{
-    send(Messages::RemoteDisplayListRecorder::GetPixelBuffer(sourceRect, outputFormat));
-}
-
-void RemoteDisplayListRecorderProxy::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
-{
-    send(Messages::RemoteDisplayListRecorder::PutPixelBuffer(srcRect, destPoint, pixelBuffer, destFormat));
-}
-
 void RemoteDisplayListRecorderProxy::convertToLuminanceMask()
 {
     send(Messages::RemoteDisplayListRecorder::ConvertToLuminanceMask());

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h (289579 => 289580)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -47,8 +47,6 @@
     void resetNeedsFlush() { m_needsFlush = false; }
     bool needsFlush() const { return m_needsFlush; }
 
-    void getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect& sourceRect) final;
-    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) final;
     void convertToLuminanceMask() final;
     void transformToColorSpace(const WebCore::DestinationColorSpace&) final;
     void flushContext(WebCore::GraphicsContextFlushIdentifier) final;

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h (289579 => 289580)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -210,24 +210,14 @@
     {
         if (UNLIKELY(!m_remoteRenderingBackendProxy))
             return std::nullopt;
-
+        auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
+        mutableThis.flushDrawingContextAsync();
         auto pixelBuffer = WebCore::PixelBuffer::tryCreate(destinationFormat, srcRect.size());
         if (!pixelBuffer)
             return std::nullopt;
-        size_t dataSize = pixelBuffer->data().byteLength();
-
-        SharedMemory* sharedMemory = m_remoteRenderingBackendProxy->sharedMemoryForGetPixelBuffer(dataSize);
-        if (!sharedMemory)
+        auto& data = ""
+        if (!m_remoteRenderingBackendProxy->getPixelBufferForImageBuffer(m_renderingResourceIdentifier, destinationFormat, srcRect, { data.data(), data.byteLength() }))
             return std::nullopt;
-
-        auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
-        mutableThis.m_remoteDisplayList.getPixelBuffer(destinationFormat, srcRect);
-        mutableThis.flushDrawingContextAsync();
-
-        if (m_remoteRenderingBackendProxy->waitForGetPixelBufferToComplete())
-            memcpy(pixelBuffer->data().data(), sharedMemory->data(), dataSize);
-        else
-            memset(pixelBuffer->data().data(), 0, dataSize);
         return pixelBuffer;
     }
 
@@ -249,12 +239,16 @@
 
     void putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) final
     {
+        if (UNLIKELY(!m_remoteRenderingBackendProxy))
+            return;
         // The math inside PixelBuffer::create() doesn't agree with the math inside ImageBufferBackend::putPixelBuffer() about how m_resolutionScale interacts with the data in the ImageBuffer.
         // This means that putPixelBuffer() is only called when resolutionScale() == 1.
         ASSERT(resolutionScale() == 1);
-        m_remoteDisplayList.putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
+        auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
+        mutableThis.flushDrawingContextAsync();
+        m_remoteRenderingBackendProxy->putPixelBufferForImageBuffer(m_renderingResourceIdentifier, pixelBuffer, srcRect, destPoint, destFormat);
     }
-    
+
     void convertToLuminanceMask() final
     {
         m_remoteDisplayList.convertToLuminanceMask();

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


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp	2022-02-10 22:48:55 UTC (rev 289580)
@@ -33,7 +33,6 @@
 #include "PlatformRemoteImageBufferProxy.h"
 #include "RemoteRenderingBackendMessages.h"
 #include "RemoteRenderingBackendProxyMessages.h"
-#include "SharedMemory.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebPage.h"
 #include "WebProcess.h"
@@ -98,10 +97,7 @@
 
     if (m_destroyGetPixelBufferSharedMemoryTimer.isActive())
         m_destroyGetPixelBufferSharedMemoryTimer.stop();
-    m_getPixelBufferSemaphore = std::nullopt;
-    m_getPixelBufferSharedMemoryLength = 0;
     m_getPixelBufferSharedMemory = nullptr;
-    
     m_renderingUpdateID = { };
     m_didRenderingUpdateID = { };
 }
@@ -149,47 +145,59 @@
     return nullptr;
 }
 
-SharedMemory* RemoteRenderingBackendProxy::sharedMemoryForGetPixelBuffer(size_t dataSize)
+bool RemoteRenderingBackendProxy::getPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, const WebCore::PixelBufferFormat& destinationFormat, const WebCore::IntRect& srcRect, Span<uint8_t> result)
 {
-    bool needsSharedMemory = !m_getPixelBufferSharedMemory || dataSize > m_getPixelBufferSharedMemoryLength;
-    bool needsSemaphore = !m_getPixelBufferSemaphore;
+    if (auto handle = updateSharedMemoryForGetPixelBuffer(result.size())) {
+        SharedMemory::IPCHandle ipcHandle { WTFMove(*handle), m_getPixelBufferSharedMemory->size() };
+        auto sendResult = sendSyncToStream(Messages::RemoteRenderingBackend::GetPixelBufferForImageBufferWithNewMemory(imageBuffer, ipcHandle, destinationFormat, srcRect),
+            Messages::RemoteRenderingBackend::GetPixelBufferForImageBufferWithNewMemory::Reply());
+        if (!sendResult)
+            return false;
+    } else {
+        if (!m_getPixelBufferSharedMemory)
+            return false;
+        auto sendResult = sendSyncToStream(Messages::RemoteRenderingBackend::GetPixelBufferForImageBuffer(imageBuffer, destinationFormat, srcRect), Messages::RemoteRenderingBackend::GetPixelBufferForImageBuffer::Reply());
+        if (!sendResult)
+            return false;
+    }
+    memcpy(result.data(), m_getPixelBufferSharedMemory->data(), result.size());
+    return true;
+}
 
-    if (needsSharedMemory)
-        m_getPixelBufferSharedMemory = nullptr;
+void RemoteRenderingBackendProxy::putPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier imageBuffer, const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
+{
+    sendToStream(Messages::RemoteRenderingBackend::PutPixelBufferForImageBuffer(imageBuffer, pixelBuffer, srcRect, destPoint, destFormat));
+}
 
-    SharedMemory::IPCHandle handle;
-    IPC::Semaphore semaphore;
+std::optional<SharedMemory::Handle> RemoteRenderingBackendProxy::updateSharedMemoryForGetPixelBuffer(size_t dataSize)
+{
+    if (m_destroyGetPixelBufferSharedMemoryTimer.isActive())
+        m_destroyGetPixelBufferSharedMemoryTimer.stop();
 
-    if (needsSharedMemory && needsSemaphore)
-        sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryAndSemaphoreForGetPixelBuffer::Reply(handle, semaphore));
-    else if (needsSharedMemory)
-        sendSyncToStream(Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer(dataSize), Messages::RemoteRenderingBackend::UpdateSharedMemoryForGetPixelBuffer::Reply(handle));
-    else if (needsSemaphore)
-        sendSyncToStream(Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer(), Messages::RemoteRenderingBackend::SemaphoreForGetPixelBuffer::Reply(semaphore));
-
-    if (!handle.handle.isNull()) {
-        handle.handle.takeOwnershipOfMemory(MemoryLedger::Graphics);
-        m_getPixelBufferSharedMemory = SharedMemory::map(handle.handle, SharedMemory::Protection::ReadOnly);
-        m_getPixelBufferSharedMemoryLength = handle.dataSize;
+    if (m_getPixelBufferSharedMemory && dataSize <= m_getPixelBufferSharedMemory->size()) {
+        m_destroyGetPixelBufferSharedMemoryTimer.startOneShot(5_s);
+        return std::nullopt;
     }
-    if (needsSemaphore)
-        m_getPixelBufferSemaphore = WTFMove(semaphore);
+    destroyGetPixelBufferSharedMemory();
+    auto memory = SharedMemory::allocate(dataSize);
+    if (!memory)
+        return std::nullopt;
+    SharedMemory::Handle handle;
+    if (!memory->createHandle(handle, SharedMemory::Protection::ReadWrite))
+        return std::nullopt;
+    if (handle.isNull())
+        return std::nullopt;
 
-    if (m_destroyGetPixelBufferSharedMemoryTimer.isActive())
-        m_destroyGetPixelBufferSharedMemoryTimer.stop();
+    m_getPixelBufferSharedMemory = WTFMove(memory);
+    handle.takeOwnershipOfMemory(MemoryLedger::Graphics);
     m_destroyGetPixelBufferSharedMemoryTimer.startOneShot(5_s);
-
-    return m_getPixelBufferSharedMemory.get();
+    return handle;
 }
 
-bool RemoteRenderingBackendProxy::waitForGetPixelBufferToComplete()
-{
-    ASSERT(m_getPixelBufferSemaphore);
-    return m_getPixelBufferSemaphore->wait();
-}
-
 void RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory()
 {
+    if (!m_getPixelBufferSharedMemory)
+        return;
     m_getPixelBufferSharedMemory = nullptr;
     sendToStream(Messages::RemoteRenderingBackend::DestroyGetPixelBufferSharedMemory());
 }

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


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h	2022-02-10 22:34:33 UTC (rev 289579)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h	2022-02-10 22:48:55 UTC (rev 289580)
@@ -38,10 +38,12 @@
 #include "RemoteResourceCacheProxy.h"
 #include "RenderingBackendIdentifier.h"
 #include "RenderingUpdateID.h"
+#include "SharedMemory.h"
 #include "StreamClientConnection.h"
 #include <WebCore/RenderingResourceIdentifier.h>
 #include <WebCore/Timer.h>
 #include <wtf/Deque.h>
+#include <wtf/Span.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
@@ -73,10 +75,6 @@
 
     RemoteResourceCacheProxy& remoteResourceCacheProxy() { return m_remoteResourceCacheProxy; }
 
-    SharedMemory* sharedMemoryForGetPixelBuffer(size_t dataSize);
-    bool waitForGetPixelBufferToComplete();
-    void destroyGetPixelBufferSharedMemory();
-
     void createRemoteImageBuffer(WebCore::ImageBuffer&);
     bool isCached(const WebCore::ImageBuffer&) const;
 
@@ -85,6 +83,8 @@
 
     // Messages to be sent.
     RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat);
+    bool getPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier, const WebCore::PixelBufferFormat& destinationFormat, const WebCore::IntRect& srcRect, Span<uint8_t> result);
+    void putPixelBufferForImageBuffer(WebCore::RenderingResourceIdentifier, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat);
     String getDataURLForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::PreserveResolution, WebCore::RenderingResourceIdentifier);
     Vector<uint8_t> getDataForImageBuffer(const String& mimeType, std::optional<double> quality, WebCore::RenderingResourceIdentifier);
     RefPtr<ShareableBitmap> getShareableBitmap(WebCore::RenderingResourceIdentifier, WebCore::PreserveResolution);
@@ -143,6 +143,11 @@
     GPUProcessConnection& ensureGPUProcessConnection();
     IPC::Connection& gpuProcessConnection();
 
+    // Returns std::nullopt if no update is needed or allocation failed.
+    // Returns handle if that should be sent to the receiver process.
+    std::optional<SharedMemory::Handle> updateSharedMemoryForGetPixelBuffer(size_t dataSize);
+    void destroyGetPixelBufferSharedMemory();
+
     // Messages to be received.
     void didCreateImageBufferBackend(ImageBufferBackendHandle, WebCore::RenderingResourceIdentifier);
     void didFlush(WebCore::GraphicsContextFlushIdentifier, WebCore::RenderingResourceIdentifier);
@@ -152,10 +157,7 @@
     RemoteRenderingBackendCreationParameters m_parameters;
     WeakPtr<GPUProcessConnection> m_gpuProcessConnection;
     RemoteResourceCacheProxy m_remoteResourceCacheProxy { *this };
-
-    std::optional<IPC::Semaphore> m_getPixelBufferSemaphore;
     RefPtr<SharedMemory> m_getPixelBufferSharedMemory;
-    uint64_t m_getPixelBufferSharedMemoryLength { 0 };
     WebCore::Timer m_destroyGetPixelBufferSharedMemoryTimer { *this, &RemoteRenderingBackendProxy::destroyGetPixelBufferSharedMemory };
 
     RenderingUpdateID m_renderingUpdateID;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to