[GPU Process] Simplify DisplayList::Iterator part 6: Migrate ItemBufferWritingClient...
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 May 2021 09:52:48 +0000 (09:52 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 May 2021 09:52:48 +0000 (09:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=224270

Reviewed by Wenson Hsieh.

Source/WebCore:

This patch adds a new Variant that contains all the DisplayList item types, named DisplayListItem. It also migrates
ItemBufferWritingClient from ItemHandle to this new Variant.

There are two benefits to this:
1. The templated overload of ItemBuffer::append() is way simpler now. Previously, we used to allocate a byte buffer
       on the stack and run a placement new of the display list item type into it. Now, we can just run the DisplayListItem
       constructor instead. Using the Variant does require more stack space, but we only will ever have one of these objects
       on the stack at a time.
2. The big table inside RemoteImageBufferProxy::encodeItemOutOfLine() is gone, and is replaced with just 7 lines. This is
       one fewer place where we'll have to make sure the DisplayListItem types match a function in an entirely different
       framework.

No new tests, because there is no behavior change.

* platform/graphics/displaylists/DisplayListItemBuffer.cpp:
(WebCore::DisplayList::copyInto):
(WebCore::DisplayList::safeCopyHelper):
(WebCore::DisplayList::safeCopy):
(WebCore::DisplayList::ItemBuffer::append):
* platform/graphics/displaylists/DisplayListItemBuffer.h:
(WebCore::DisplayList::ItemBufferWritingClient::requiredSizeForItem const):
(WebCore::DisplayList::ItemBufferWritingClient::encodeItemOutOfLine const):
(WebCore::DisplayList::ItemBufferWritingClient::encodeItemInline const):
(WebCore::DisplayList::ItemBuffer::append):
* platform/graphics/displaylists/DisplayListItemType.cpp:
(WebCore::DisplayList::paddedSizeOfTypeAndItemInBytes):
(WebCore::DisplayList::displayListItemType):
* platform/graphics/displaylists/DisplayListItems.h:
* platform/graphics/displaylists/InMemoryDisplayList.cpp:
(WebCore::DisplayList::InMemoryDisplayList::WritingClient::requiredSizeForItem const):
(WebCore::DisplayList::InMemoryDisplayList::WritingClient::encodeItemInline const):
* platform/graphics/displaylists/InMemoryDisplayList.h:

Source/WebKit:

* WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
(WebKit::RemoteImageBufferProxy::encodeItemOutOfLineHelper):

Tools:

* TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/displaylists/DisplayListItemBuffer.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListItemBuffer.h
Source/WebCore/platform/graphics/displaylists/DisplayListItemType.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListItems.h
Source/WebCore/platform/graphics/displaylists/InMemoryDisplayList.cpp
Source/WebCore/platform/graphics/displaylists/InMemoryDisplayList.h
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp
Tools/TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp

index 3cecbc2..5ff4bd0 100644 (file)
@@ -1,5 +1,45 @@
 2021-05-09  Myles C. Maxfield  <mmaxfield@apple.com>
 
+        [GPU Process] Simplify DisplayList::Iterator part 6: Migrate ItemBufferWritingClient from ItemHandle to a const Variant&
+        https://bugs.webkit.org/show_bug.cgi?id=224270
+
+        Reviewed by Wenson Hsieh.
+
+        This patch adds a new Variant that contains all the DisplayList item types, named DisplayListItem. It also migrates
+        ItemBufferWritingClient from ItemHandle to this new Variant.
+
+        There are two benefits to this:
+        1. The templated overload of ItemBuffer::append() is way simpler now. Previously, we used to allocate a byte buffer
+               on the stack and run a placement new of the display list item type into it. Now, we can just run the DisplayListItem
+               constructor instead. Using the Variant does require more stack space, but we only will ever have one of these objects
+               on the stack at a time.
+        2. The big table inside RemoteImageBufferProxy::encodeItemOutOfLine() is gone, and is replaced with just 7 lines. This is
+               one fewer place where we'll have to make sure the DisplayListItem types match a function in an entirely different
+               framework.
+
+        No new tests, because there is no behavior change.
+
+        * platform/graphics/displaylists/DisplayListItemBuffer.cpp:
+        (WebCore::DisplayList::copyInto):
+        (WebCore::DisplayList::safeCopyHelper):
+        (WebCore::DisplayList::safeCopy):
+        (WebCore::DisplayList::ItemBuffer::append):
+        * platform/graphics/displaylists/DisplayListItemBuffer.h:
+        (WebCore::DisplayList::ItemBufferWritingClient::requiredSizeForItem const):
+        (WebCore::DisplayList::ItemBufferWritingClient::encodeItemOutOfLine const):
+        (WebCore::DisplayList::ItemBufferWritingClient::encodeItemInline const):
+        (WebCore::DisplayList::ItemBuffer::append):
+        * platform/graphics/displaylists/DisplayListItemType.cpp:
+        (WebCore::DisplayList::paddedSizeOfTypeAndItemInBytes):
+        (WebCore::DisplayList::displayListItemType):
+        * platform/graphics/displaylists/DisplayListItems.h:
+        * platform/graphics/displaylists/InMemoryDisplayList.cpp:
+        (WebCore::DisplayList::InMemoryDisplayList::WritingClient::requiredSizeForItem const):
+        (WebCore::DisplayList::InMemoryDisplayList::WritingClient::encodeItemInline const):
+        * platform/graphics/displaylists/InMemoryDisplayList.h:
+
+2021-05-09  Myles C. Maxfield  <mmaxfield@apple.com>
+
         [Cocoa] Unify last resort fallback font between all Cocoa ports
         https://bugs.webkit.org/show_bug.cgi?id=225569
 
index b85aa70..5a72501 100644 (file)
@@ -442,17 +442,28 @@ template<typename, typename = void> inline constexpr bool HasIsValid = false;
 template<typename T> inline constexpr bool HasIsValid<T, std::void_t<decltype(std::declval<T>().isValid())>> = true;
 
 template<typename Item>
-static typename std::enable_if_t<!HasIsValid<Item>, bool> copyInto(const ItemHandle& itemHandle, uint8_t* destinationWithOffset)
+static inline typename std::enable_if_t<!HasIsValid<Item>, bool> isValid(const Item&)
 {
-    new (destinationWithOffset) Item(itemHandle.get<Item>());
     return true;
 }
 
 template<typename Item>
-static typename std::enable_if_t<HasIsValid<Item>, bool> copyInto(const ItemHandle& itemHandle, uint8_t* destinationWithOffset)
+static inline typename std::enable_if_t<HasIsValid<Item>, bool> isValid(const Item& item)
 {
-    auto* newItem = new (destinationWithOffset) Item(itemHandle.get<Item>());
-    return newItem->isValid();
+    return item.isValid();
+}
+
+template<typename Item>
+static inline bool copyInto(uint8_t* destinationWithOffset, const Item& item)
+{
+    auto* newItem = new (destinationWithOffset) Item(item);
+    return isValid(*newItem);
+}
+
+template<typename Item>
+static inline bool copyInto(uint8_t* destinationWithOffset, const ItemHandle& itemHandle)
+{
+    return copyInto(destinationWithOffset, itemHandle.get<Item>());
 }
 
 bool ItemHandle::safeCopy(ItemHandle destination) const
@@ -462,141 +473,152 @@ bool ItemHandle::safeCopy(ItemHandle destination) const
     auto itemOffset = destination.data + sizeof(uint64_t);
     switch (itemType) {
     case ItemType::ClipOutToPath:
-        return copyInto<ClipOutToPath>(*this, itemOffset);
+        return copyInto<ClipOutToPath>(itemOffset, *this);
     case ItemType::ClipPath:
-        return copyInto<ClipPath>(*this, itemOffset);
+        return copyInto<ClipPath>(itemOffset, *this);
     case ItemType::DrawFocusRingPath:
-        return copyInto<DrawFocusRingPath>(*this, itemOffset);
+        return copyInto<DrawFocusRingPath>(itemOffset, *this);
     case ItemType::DrawFocusRingRects:
-        return copyInto<DrawFocusRingRects>(*this, itemOffset);
+        return copyInto<DrawFocusRingRects>(itemOffset, *this);
     case ItemType::DrawGlyphs:
-        return copyInto<DrawGlyphs>(*this, itemOffset);
+        return copyInto<DrawGlyphs>(itemOffset, *this);
     case ItemType::DrawImageBuffer:
-        return copyInto<DrawImageBuffer>(*this, itemOffset);
+        return copyInto<DrawImageBuffer>(itemOffset, *this);
     case ItemType::DrawLinesForText:
-        return copyInto<DrawLinesForText>(*this, itemOffset);
+        return copyInto<DrawLinesForText>(itemOffset, *this);
     case ItemType::DrawNativeImage:
-        return copyInto<DrawNativeImage>(*this, itemOffset);
+        return copyInto<DrawNativeImage>(itemOffset, *this);
     case ItemType::DrawPattern:
-        return copyInto<DrawPattern>(*this, itemOffset);
+        return copyInto<DrawPattern>(itemOffset, *this);
     case ItemType::DrawPath:
-        return copyInto<DrawPath>(*this, itemOffset);
+        return copyInto<DrawPath>(itemOffset, *this);
     case ItemType::FillCompositedRect:
-        return copyInto<FillCompositedRect>(*this, itemOffset);
+        return copyInto<FillCompositedRect>(itemOffset, *this);
     case ItemType::FillPath:
-        return copyInto<FillPath>(*this, itemOffset);
+        return copyInto<FillPath>(itemOffset, *this);
     case ItemType::FillRectWithColor:
-        return copyInto<FillRectWithColor>(*this, itemOffset);
+        return copyInto<FillRectWithColor>(itemOffset, *this);
     case ItemType::FillRectWithGradient:
-        return copyInto<FillRectWithGradient>(*this, itemOffset);
+        return copyInto<FillRectWithGradient>(itemOffset, *this);
     case ItemType::FillRectWithRoundedHole:
-        return copyInto<FillRectWithRoundedHole>(*this, itemOffset);
+        return copyInto<FillRectWithRoundedHole>(itemOffset, *this);
     case ItemType::FillRoundedRect:
-        return copyInto<FillRoundedRect>(*this, itemOffset);
+        return copyInto<FillRoundedRect>(itemOffset, *this);
     case ItemType::GetImageData:
-        return copyInto<GetImageData>(*this, itemOffset);
+        return copyInto<GetImageData>(itemOffset, *this);
     case ItemType::PutImageData:
-        return copyInto<PutImageData>(*this, itemOffset);
+        return copyInto<PutImageData>(itemOffset, *this);
     case ItemType::SetLineDash:
-        return copyInto<SetLineDash>(*this, itemOffset);
+        return copyInto<SetLineDash>(itemOffset, *this);
     case ItemType::SetState:
-        return copyInto<SetState>(*this, itemOffset);
+        return copyInto<SetState>(itemOffset, *this);
     case ItemType::StrokePath:
-        return copyInto<StrokePath>(*this, itemOffset);
+        return copyInto<StrokePath>(itemOffset, *this);
     case ItemType::ApplyDeviceScaleFactor:
-        return copyInto<ApplyDeviceScaleFactor>(*this, itemOffset);
+        return copyInto<ApplyDeviceScaleFactor>(itemOffset, *this);
 #if USE(CG)
     case ItemType::ApplyFillPattern:
-        return copyInto<ApplyFillPattern>(*this, itemOffset);
+        return copyInto<ApplyFillPattern>(itemOffset, *this);
     case ItemType::ApplyStrokePattern:
-        return copyInto<ApplyStrokePattern>(*this, itemOffset);
+        return copyInto<ApplyStrokePattern>(itemOffset, *this);
 #endif
     case ItemType::BeginClipToDrawingCommands:
-        return copyInto<BeginClipToDrawingCommands>(*this, itemOffset);
+        return copyInto<BeginClipToDrawingCommands>(itemOffset, *this);
     case ItemType::BeginTransparencyLayer:
-        return copyInto<BeginTransparencyLayer>(*this, itemOffset);
+        return copyInto<BeginTransparencyLayer>(itemOffset, *this);
     case ItemType::ClearRect:
-        return copyInto<ClearRect>(*this, itemOffset);
+        return copyInto<ClearRect>(itemOffset, *this);
     case ItemType::ClearShadow:
-        return copyInto<ClearShadow>(*this, itemOffset);
+        return copyInto<ClearShadow>(itemOffset, *this);
     case ItemType::Clip:
-        return copyInto<Clip>(*this, itemOffset);
+        return copyInto<Clip>(itemOffset, *this);
     case ItemType::ClipOut:
-        return copyInto<ClipOut>(*this, itemOffset);
+        return copyInto<ClipOut>(itemOffset, *this);
     case ItemType::ClipToImageBuffer:
-        return copyInto<ClipToImageBuffer>(*this, itemOffset);
+        return copyInto<ClipToImageBuffer>(itemOffset, *this);
     case ItemType::ConcatenateCTM:
-        return copyInto<ConcatenateCTM>(*this, itemOffset);
+        return copyInto<ConcatenateCTM>(itemOffset, *this);
     case ItemType::DrawDotsForDocumentMarker:
-        return copyInto<DrawDotsForDocumentMarker>(*this, itemOffset);
+        return copyInto<DrawDotsForDocumentMarker>(itemOffset, *this);
     case ItemType::DrawEllipse:
-        return copyInto<DrawEllipse>(*this, itemOffset);
+        return copyInto<DrawEllipse>(itemOffset, *this);
     case ItemType::DrawLine:
-        return copyInto<DrawLine>(*this, itemOffset);
+        return copyInto<DrawLine>(itemOffset, *this);
     case ItemType::DrawRect:
-        return copyInto<DrawRect>(*this, itemOffset);
+        return copyInto<DrawRect>(itemOffset, *this);
     case ItemType::EndClipToDrawingCommands:
-        return copyInto<EndClipToDrawingCommands>(*this, itemOffset);
+        return copyInto<EndClipToDrawingCommands>(itemOffset, *this);
     case ItemType::EndTransparencyLayer:
-        return copyInto<EndTransparencyLayer>(*this, itemOffset);
+        return copyInto<EndTransparencyLayer>(itemOffset, *this);
     case ItemType::FillEllipse:
-        return copyInto<FillEllipse>(*this, itemOffset);
+        return copyInto<FillEllipse>(itemOffset, *this);
 #if ENABLE(INLINE_PATH_DATA)
     case ItemType::FillInlinePath:
-        return copyInto<FillInlinePath>(*this, itemOffset);
+        return copyInto<FillInlinePath>(itemOffset, *this);
 #endif
     case ItemType::FillRect:
-        return copyInto<FillRect>(*this, itemOffset);
+        return copyInto<FillRect>(itemOffset, *this);
     case ItemType::FlushContext:
-        return copyInto<FlushContext>(*this, itemOffset);
+        return copyInto<FlushContext>(itemOffset, *this);
     case ItemType::MetaCommandChangeDestinationImageBuffer:
-        return copyInto<MetaCommandChangeDestinationImageBuffer>(*this, itemOffset);
+        return copyInto<MetaCommandChangeDestinationImageBuffer>(itemOffset, *this);
     case ItemType::MetaCommandChangeItemBuffer:
-        return copyInto<MetaCommandChangeItemBuffer>(*this, itemOffset);
+        return copyInto<MetaCommandChangeItemBuffer>(itemOffset, *this);
 #if ENABLE(VIDEO)
     case ItemType::PaintFrameForMedia:
-        return copyInto<PaintFrameForMedia>(*this, itemOffset);
+        return copyInto<PaintFrameForMedia>(itemOffset, *this);
 #endif
     case ItemType::Restore:
-        return copyInto<Restore>(*this, itemOffset);
+        return copyInto<Restore>(itemOffset, *this);
     case ItemType::Rotate:
-        return copyInto<Rotate>(*this, itemOffset);
+        return copyInto<Rotate>(itemOffset, *this);
     case ItemType::Save:
-        return copyInto<Save>(*this, itemOffset);
+        return copyInto<Save>(itemOffset, *this);
     case ItemType::Scale:
-        return copyInto<Scale>(*this, itemOffset);
+        return copyInto<Scale>(itemOffset, *this);
     case ItemType::SetCTM:
-        return copyInto<SetCTM>(*this, itemOffset);
+        return copyInto<SetCTM>(itemOffset, *this);
     case ItemType::SetInlineFillColor:
-        return copyInto<SetInlineFillColor>(*this, itemOffset);
+        return copyInto<SetInlineFillColor>(itemOffset, *this);
     case ItemType::SetInlineFillGradient:
-        return copyInto<SetInlineFillGradient>(*this, itemOffset);
+        return copyInto<SetInlineFillGradient>(itemOffset, *this);
     case ItemType::SetInlineStrokeColor:
-        return copyInto<SetInlineStrokeColor>(*this, itemOffset);
+        return copyInto<SetInlineStrokeColor>(itemOffset, *this);
     case ItemType::SetLineCap:
-        return copyInto<SetLineCap>(*this, itemOffset);
+        return copyInto<SetLineCap>(itemOffset, *this);
     case ItemType::SetLineJoin:
-        return copyInto<SetLineJoin>(*this, itemOffset);
+        return copyInto<SetLineJoin>(itemOffset, *this);
     case ItemType::SetMiterLimit:
-        return copyInto<SetMiterLimit>(*this, itemOffset);
+        return copyInto<SetMiterLimit>(itemOffset, *this);
     case ItemType::SetStrokeThickness:
-        return copyInto<SetStrokeThickness>(*this, itemOffset);
+        return copyInto<SetStrokeThickness>(itemOffset, *this);
     case ItemType::StrokeEllipse:
-        return copyInto<StrokeEllipse>(*this, itemOffset);
+        return copyInto<StrokeEllipse>(itemOffset, *this);
 #if ENABLE(INLINE_PATH_DATA)
     case ItemType::StrokeInlinePath:
-        return copyInto<StrokeInlinePath>(*this, itemOffset);
+        return copyInto<StrokeInlinePath>(itemOffset, *this);
 #endif
     case ItemType::StrokeRect:
-        return copyInto<StrokeRect>(*this, itemOffset);
+        return copyInto<StrokeRect>(itemOffset, *this);
     case ItemType::StrokeLine:
-        return copyInto<StrokeLine>(*this, itemOffset);
+        return copyInto<StrokeLine>(itemOffset, *this);
     case ItemType::Translate:
-        return copyInto<Translate>(*this, itemOffset);
+        return copyInto<Translate>(itemOffset, *this);
     }
     return false;
 }
 
+bool safeCopy(ItemHandle destination, const DisplayListItem& source)
+{
+    return WTF::visit([&](const auto& source) {
+        using DisplayListItemType = typename WTF::RemoveCVAndReference<decltype(source)>::type;
+        constexpr auto itemType = DisplayListItemType::itemType;
+        destination.data[0] = static_cast<uint8_t>(itemType);
+        auto itemOffset = destination.data + sizeof(uint64_t);
+        return copyInto<DisplayListItemType>(itemOffset, source);
+    }, source);
+}
+
 ItemBuffer::ItemBuffer(ItemBufferHandles&& handles)
     : m_readOnlyBuffers(WTFMove(handles))
 {
@@ -687,7 +709,7 @@ DidChangeItemBuffer ItemBuffer::swapWritableBufferIfNeeded(size_t numberOfBytes)
     return hadPreviousBuffer ? DidChangeItemBuffer::Yes : DidChangeItemBuffer::No;
 }
 
-void ItemBuffer::append(ItemHandle temporaryItem)
+void ItemBuffer::append(const DisplayListItem& temporaryItem)
 {
     auto requiredSizeForItem = m_writingClient->requiredSizeForItem(temporaryItem);
     RefPtr<SharedBuffer> outOfLineItem;
@@ -705,7 +727,7 @@ void ItemBuffer::append(ItemHandle temporaryItem)
 
     auto bufferChanged = swapWritableBufferIfNeeded(additionalCapacityForEncodedItem);
 
-    m_writableBuffer.data[m_writtenNumberOfBytes] = static_cast<uint8_t>(temporaryItem.type());
+    m_writableBuffer.data[m_writtenNumberOfBytes] = static_cast<uint8_t>(displayListItemType(temporaryItem));
     reinterpret_cast<uint64_t*>(m_writableBuffer.data + m_writtenNumberOfBytes)[1] = dataLength;
     auto* location = m_writableBuffer.data + m_writtenNumberOfBytes + 2 * sizeof(uint64_t);
 
index c441ac3..b991757 100644 (file)
@@ -82,6 +82,8 @@ struct ItemHandle {
     bool safeCopy(ItemHandle destination) const;
 };
 
+bool safeCopy(ItemHandle destination, const DisplayListItem& source);
+
 enum class DidChangeItemBuffer : bool { No, Yes };
 
 class ItemBufferWritingClient {
@@ -95,17 +97,17 @@ public:
         return { };
     }
 
-    virtual Optional<std::size_t> requiredSizeForItem(ItemHandle) const
+    virtual Optional<std::size_t> requiredSizeForItem(const DisplayListItem&) const
     {
         return WTF::nullopt;
     }
 
-    virtual RefPtr<SharedBuffer> encodeItemOutOfLine(ItemHandle) const
+    virtual RefPtr<SharedBuffer> encodeItemOutOfLine(const DisplayListItem&) const
     {
         return nullptr;
     }
 
-    virtual void encodeItemInline(ItemHandle, uint8_t*) const
+    virtual void encodeItemInline(const DisplayListItem&, uint8_t*) const
     {
     }
 
@@ -175,18 +177,9 @@ public:
     {
         static_assert(std::is_trivially_destructible<T>::value == T::isInlineItem);
 
-        if (!T::isInlineItem) {
+        if constexpr (!T::isInlineItem) {
             RELEASE_ASSERT(m_writingClient);
-#if COMPILER(MSVC)
-            __declspec(align(8)) typedef uint8_t EncodingBuffer[sizeof(uint64_t) + sizeof(T)];
-#else
-            using EncodingBuffer __attribute__((aligned (8))) = uint8_t[sizeof(uint64_t) + sizeof(T)];
-#endif
-            static EncodingBuffer temporaryItemBuffer;
-            temporaryItemBuffer[0] = static_cast<uint8_t>(T::itemType);
-            new (temporaryItemBuffer + sizeof(uint64_t)) T(std::forward<Args>(args)...);
-            append({ temporaryItemBuffer });
-            ItemHandle { temporaryItemBuffer }.destroy();
+            append(DisplayListItem(T(std::forward<Args>(args)...)));
             return;
         }
 
@@ -205,7 +198,7 @@ private:
     WEBCORE_EXPORT void didAppendData(size_t numberOfBytes, DidChangeItemBuffer);
 
     WEBCORE_EXPORT DidChangeItemBuffer swapWritableBufferIfNeeded(size_t numberOfBytes);
-    WEBCORE_EXPORT void append(ItemHandle);
+    WEBCORE_EXPORT void append(const DisplayListItem&);
     template<typename T, class... Args> void uncheckedAppend(DidChangeItemBuffer didChangeItemBuffer, Args&&... args)
     {
         auto* startOfItem = &m_writableBuffer.data[m_writtenNumberOfBytes];
index 4a663af..a1e091e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -259,6 +259,21 @@ size_t paddedSizeOfTypeAndItemInBytes(ItemType type)
     return sizeof(uint64_t) + roundUpToMultipleOf(alignof(uint64_t), sizeOfItemInBytes(type));
 }
 
+size_t paddedSizeOfTypeAndItemInBytes(const DisplayListItem& displayListItem)
+{
+    auto itemSize = WTF::visit([](const auto& item) {
+        return sizeof(item);
+    }, displayListItem);
+    return sizeof(uint64_t) + roundUpToMultipleOf(alignof(uint64_t), itemSize);
+}
+
+ItemType displayListItemType(const DisplayListItem& displayListItem)
+{
+    return WTF::visit([](const auto& item) {
+        return item.itemType;
+    }, displayListItem);
+}
+
 bool isInlineItem(ItemType type)
 {
     /* See the comment at the top of DisplayListItems.h for what this means.
index bb3775a..1eb8156 100644 (file)
@@ -2282,6 +2282,83 @@ private:
     RenderingResourceIdentifier m_identifier;
 };
 
+using DisplayListItem = Variant
+    < ApplyDeviceScaleFactor
+    , BeginClipToDrawingCommands
+    , BeginTransparencyLayer
+    , ClearRect
+    , ClearShadow
+    , Clip
+    , ClipOut
+    , ClipOutToPath
+    , ClipPath
+    , ClipToImageBuffer
+    , ConcatenateCTM
+    , DrawDotsForDocumentMarker
+    , DrawEllipse
+    , DrawFocusRingPath
+    , DrawFocusRingRects
+    , DrawGlyphs
+    , DrawImageBuffer
+    , DrawLine
+    , DrawLinesForText
+    , DrawNativeImage
+    , DrawPath
+    , DrawPattern
+    , DrawRect
+    , EndClipToDrawingCommands
+    , EndTransparencyLayer
+    , FillCompositedRect
+    , FillEllipse
+    , FillPath
+    , FillRect
+    , FillRectWithColor
+    , FillRectWithGradient
+    , FillRectWithRoundedHole
+    , FillRoundedRect
+    , FlushContext
+    , GetImageData
+    , MetaCommandChangeDestinationImageBuffer
+    , MetaCommandChangeItemBuffer
+    , PutImageData
+    , Restore
+    , Rotate
+    , Save
+    , Scale
+    , SetCTM
+    , SetInlineFillColor
+    , SetInlineFillGradient
+    , SetInlineStrokeColor
+    , SetLineCap
+    , SetLineDash
+    , SetLineJoin
+    , SetMiterLimit
+    , SetState
+    , SetStrokeThickness
+    , StrokeEllipse
+    , StrokeLine
+    , StrokePath
+    , StrokeRect
+    , Translate
+
+#if ENABLE(INLINE_PATH_DATA)
+    , FillInlinePath
+    , StrokeInlinePath
+#endif
+
+#if ENABLE(VIDEO)
+    , PaintFrameForMedia
+#endif
+
+#if USE(CG)
+    , ApplyFillPattern
+    , ApplyStrokePattern
+#endif
+>;
+
+size_t paddedSizeOfTypeAndItemInBytes(const DisplayListItem&);
+ItemType displayListItemType(const DisplayListItem&);
+
 TextStream& operator<<(TextStream&, ItemHandle);
 
 } // namespace DisplayList
@@ -2363,6 +2440,7 @@ template<> struct EnumTraits<WebCore::DisplayList::ItemType> {
 #endif
     WebCore::DisplayList::ItemType::ApplyDeviceScaleFactor
     >;
+
 };
 
 } // namespace WTF
index 26e6253..707818b 100644 (file)
 namespace WebCore {
 namespace DisplayList {
 
-Optional<std::size_t> InMemoryDisplayList::WritingClient::requiredSizeForItem(ItemHandle itemHandle) const
+Optional<std::size_t> InMemoryDisplayList::WritingClient::requiredSizeForItem(const DisplayListItem& displayListItem) const
 {
-    return paddedSizeOfTypeAndItemInBytes(itemHandle.type());
+    return paddedSizeOfTypeAndItemInBytes(displayListItem);
 }
 
-void InMemoryDisplayList::WritingClient::encodeItemInline(ItemHandle itemHandle, uint8_t* location) const
+void InMemoryDisplayList::WritingClient::encodeItemInline(const DisplayListItem& displayListItem, uint8_t* location) const
 {
-    itemHandle.safeCopy({ location });
+    safeCopy({ location }, displayListItem);
 }
 
 Optional<ItemHandle> WARN_UNUSED_RETURN InMemoryDisplayList::ReadingClient::decodeItem(const uint8_t* data, size_t dataLength, ItemType type, uint8_t* handleLocation)
index 4e8f990..1cc08af 100644 (file)
@@ -40,8 +40,8 @@ public:
     class WEBCORE_EXPORT WritingClient : public ItemBufferWritingClient {
         WTF_MAKE_FAST_ALLOCATED;
     private:
-        Optional<std::size_t> requiredSizeForItem(ItemHandle) const final;
-        void encodeItemInline(ItemHandle, uint8_t*) const final;
+        Optional<std::size_t> requiredSizeForItem(const DisplayListItem&) const final;
+        void encodeItemInline(const DisplayListItem&, uint8_t*) const final;
     };
 
     class WEBCORE_EXPORT ReadingClient : public ItemBufferReadingClient {
index 49788f3..12efa3f 100644 (file)
@@ -1,3 +1,13 @@
+2021-05-09  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [GPU Process] Simplify DisplayList::Iterator part 6: Migrate ItemBufferWritingClient from ItemHandle to a const Variant&
+        https://bugs.webkit.org/show_bug.cgi?id=224270
+
+        Reviewed by Wenson Hsieh.
+
+        * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
+        (WebKit::RemoteImageBufferProxy::encodeItemOutOfLineHelper):
+
 2021-05-08  Peng Liu  <peng.liu6@apple.com>
 
         [GPUP] A small video element enters fullscreen with strange animations
index 63a4f50..7e8daac 100644 (file)
@@ -322,105 +322,15 @@ protected:
         return { };
     }
 
-    RefPtr<WebCore::SharedBuffer> encodeItemOutOfLine(WebCore::DisplayList::ItemHandle item) const final
+    RefPtr<WebCore::SharedBuffer> encodeItemOutOfLine(const WebCore::DisplayList::DisplayListItem& item) const final
     {
-        /* This needs to match (1) isInlineItem() in DisplayListItemType.cpp, (2) RemoteRenderingBackend::decodeItem(),
-         * and (3) all the "static constexpr bool isInlineItem"s inside the individual item classes.
-         * See the comment at the top of DisplayListItems.h for why. */
-
-        switch (item.type()) {
-        case WebCore::DisplayList::ItemType::ClipOutToPath:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::ClipOutToPath>(item.get<WebCore::DisplayList::ClipOutToPath>());
-        case WebCore::DisplayList::ItemType::ClipPath:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::ClipPath>(item.get<WebCore::DisplayList::ClipPath>());
-        case WebCore::DisplayList::ItemType::DrawFocusRingPath:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::DrawFocusRingPath>(item.get<WebCore::DisplayList::DrawFocusRingPath>());
-        case WebCore::DisplayList::ItemType::DrawFocusRingRects:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::DrawFocusRingRects>(item.get<WebCore::DisplayList::DrawFocusRingRects>());
-        case WebCore::DisplayList::ItemType::DrawGlyphs:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::DrawGlyphs>(item.get<WebCore::DisplayList::DrawGlyphs>());
-        case WebCore::DisplayList::ItemType::DrawLinesForText:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::DrawLinesForText>(item.get<WebCore::DisplayList::DrawLinesForText>());
-        case WebCore::DisplayList::ItemType::DrawPath:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::DrawPath>(item.get<WebCore::DisplayList::DrawPath>());
-        case WebCore::DisplayList::ItemType::FillCompositedRect:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::FillCompositedRect>(item.get<WebCore::DisplayList::FillCompositedRect>());
-        case WebCore::DisplayList::ItemType::FillPath:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::FillPath>(item.get<WebCore::DisplayList::FillPath>());
-        case WebCore::DisplayList::ItemType::FillRectWithColor:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::FillRectWithColor>(item.get<WebCore::DisplayList::FillRectWithColor>());
-        case WebCore::DisplayList::ItemType::FillRectWithGradient:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::FillRectWithGradient>(item.get<WebCore::DisplayList::FillRectWithGradient>());
-        case WebCore::DisplayList::ItemType::FillRectWithRoundedHole:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::FillRectWithRoundedHole>(item.get<WebCore::DisplayList::FillRectWithRoundedHole>());
-        case WebCore::DisplayList::ItemType::FillRoundedRect:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::FillRoundedRect>(item.get<WebCore::DisplayList::FillRoundedRect>());
-        case WebCore::DisplayList::ItemType::PutImageData:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::PutImageData>(item.get<WebCore::DisplayList::PutImageData>());
-        case WebCore::DisplayList::ItemType::SetLineDash:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::SetLineDash>(item.get<WebCore::DisplayList::SetLineDash>());
-        case WebCore::DisplayList::ItemType::SetState:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::SetState>(item.get<WebCore::DisplayList::SetState>());
-        case WebCore::DisplayList::ItemType::StrokePath:
-            return IPC::Encoder::encodeSingleObject<WebCore::DisplayList::StrokePath>(item.get<WebCore::DisplayList::StrokePath>());
-        case WebCore::DisplayList::ItemType::ApplyDeviceScaleFactor:
-#if USE(CG)
-        case WebCore::DisplayList::ItemType::ApplyFillPattern:
-        case WebCore::DisplayList::ItemType::ApplyStrokePattern:
-#endif
-        case WebCore::DisplayList::ItemType::BeginTransparencyLayer:
-        case WebCore::DisplayList::ItemType::ClearRect:
-        case WebCore::DisplayList::ItemType::ClearShadow:
-        case WebCore::DisplayList::ItemType::Clip:
-        case WebCore::DisplayList::ItemType::ClipOut:
-        case WebCore::DisplayList::ItemType::ClipToImageBuffer:
-        case WebCore::DisplayList::ItemType::BeginClipToDrawingCommands:
-        case WebCore::DisplayList::ItemType::EndClipToDrawingCommands:
-        case WebCore::DisplayList::ItemType::ConcatenateCTM:
-        case WebCore::DisplayList::ItemType::DrawDotsForDocumentMarker:
-        case WebCore::DisplayList::ItemType::DrawEllipse:
-        case WebCore::DisplayList::ItemType::DrawImageBuffer:
-        case WebCore::DisplayList::ItemType::DrawNativeImage:
-        case WebCore::DisplayList::ItemType::DrawPattern:
-        case WebCore::DisplayList::ItemType::DrawLine:
-        case WebCore::DisplayList::ItemType::DrawRect:
-        case WebCore::DisplayList::ItemType::EndTransparencyLayer:
-        case WebCore::DisplayList::ItemType::FillEllipse:
-#if ENABLE(INLINE_PATH_DATA)
-        case WebCore::DisplayList::ItemType::FillInlinePath:
-#endif
-        case WebCore::DisplayList::ItemType::FillRect:
-        case WebCore::DisplayList::ItemType::FlushContext:
-        case WebCore::DisplayList::ItemType::MetaCommandChangeDestinationImageBuffer:
-        case WebCore::DisplayList::ItemType::MetaCommandChangeItemBuffer:
-#if ENABLE(VIDEO)
-        case WebCore::DisplayList::ItemType::PaintFrameForMedia:
-#endif
-        case WebCore::DisplayList::ItemType::Restore:
-        case WebCore::DisplayList::ItemType::Rotate:
-        case WebCore::DisplayList::ItemType::Save:
-        case WebCore::DisplayList::ItemType::Scale:
-        case WebCore::DisplayList::ItemType::SetCTM:
-        case WebCore::DisplayList::ItemType::SetInlineFillColor:
-        case WebCore::DisplayList::ItemType::SetInlineFillGradient:
-        case WebCore::DisplayList::ItemType::SetInlineStrokeColor:
-        case WebCore::DisplayList::ItemType::SetLineCap:
-        case WebCore::DisplayList::ItemType::SetLineJoin:
-        case WebCore::DisplayList::ItemType::SetMiterLimit:
-        case WebCore::DisplayList::ItemType::SetStrokeThickness:
-        case WebCore::DisplayList::ItemType::StrokeEllipse:
-#if ENABLE(INLINE_PATH_DATA)
-        case WebCore::DisplayList::ItemType::StrokeInlinePath:
-#endif
-        case WebCore::DisplayList::ItemType::StrokeRect:
-        case WebCore::DisplayList::ItemType::StrokeLine:
-        case WebCore::DisplayList::ItemType::Translate:
+        return WTF::visit([](const auto& displayListItem) -> RefPtr<WebCore::SharedBuffer> {
+            using DisplayListItemType = typename WTF::RemoveCVAndReference<decltype(displayListItem)>::type;
+            if constexpr (!DisplayListItemType::isInlineItem)
+                return IPC::Encoder::encodeSingleObject<DisplayListItemType>(displayListItem);
             RELEASE_ASSERT_NOT_REACHED();
             return nullptr;
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return nullptr;
-        }
+        }, item);
     }
 
     std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> createFlusher() override
index a22ccd4..f7f1b43 100644 (file)
@@ -1,3 +1,14 @@
+2021-05-09  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [GPU Process] Simplify DisplayList::Iterator part 6: Migrate ItemBufferWritingClient from ItemHandle to a const Variant&
+        https://bugs.webkit.org/show_bug.cgi?id=224270
+
+        Reviewed by Wenson Hsieh.
+
+        * TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp:
+
 2021-05-08  Alex Christensen  <achristensen@webkit.org>
 
         REGRESSION (r276797?): [ macOS/iOS ] TestWebKitAPI.URLSchemeHandler.Exceptions is flakey crashing
index 41077ce..bc7a849 100644 (file)
@@ -202,10 +202,10 @@ TEST(DisplayListTests, ItemBufferClient)
             return { globalBufferIdentifier, globalItemBuffer, globalItemBufferCapacity };
         }
 
-        RefPtr<SharedBuffer> encodeItemOutOfLine(ItemHandle handle) const final
+        RefPtr<SharedBuffer> encodeItemOutOfLine(const DisplayListItem& displayListItem) const final
         {
             auto index = m_items.size();
-            m_items.append(handle.get<StrokePath>());
+            m_items.append(WTF::get<StrokePath>(displayListItem));
             return SharedBuffer::create(reinterpret_cast<uint8_t*>(&index), sizeof(size_t));
         }
 
index eef716d..41ac39e 100644 (file)
@@ -100,7 +100,7 @@ private:
         return { globalBufferIdentifier, globalItemBuffer, globalItemBufferCapacity };
     }
 
-    RefPtr<SharedBuffer> encodeItemOutOfLine(ItemHandle) const final
+    RefPtr<SharedBuffer> encodeItemOutOfLine(const DisplayListItem&) const final
     {
         return SharedBuffer::create();
     }