Title: [270002] trunk
Revision
270002
Author
[email protected]
Date
2020-11-18 17:20:48 -0800 (Wed, 18 Nov 2020)

Log Message

[Concurrent display lists] Add a way for display lists to partially replay
https://bugs.webkit.org/show_bug.cgi?id=219067

Reviewed by Simon Fraser.

Source/WebCore:

Make it possble for a display list replayer to stop early in the middle of processing a display list. This
capability is a prerequisite to three items:

-   Allow display list processing in the GPU process to pause when encountering missing cached resources.
-   Allow the GPU process to replay display list item buffers that contain display list data targeting different
    destination image buffers.
-   Allow the GPU process to prematurely halt display list processing and perform a MESSAGE_CHECK to terminate
    the web content process, in the case of an invalid display list item (e.g. decoding failure).

See below for more details.

Test: DisplayListTests.ReplayWithMissingResource

* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::flushDrawingContextAndCommit):
(WebCore::ImageBuffer::submitDisplayList): Deleted.

Remove the generic `submitDisplayList` method on `ImageBuffer`; instead, call directly into
`RemoteImageBuffer::submitDisplayList` to replay display lists.

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::platformCALayerPaintContents):

Adjust several call sites of `replay()` to grab the tracked display list from the `ReplayResult`.

* platform/graphics/displaylists/DisplayList.cpp:
(WebCore::DisplayList::DisplayList::asText const):
(WebCore::DisplayList::DisplayList::dump const):
* platform/graphics/displaylists/DisplayList.h:
(WebCore::DisplayList::DisplayList::iterator::operator* const):

Pull the iterator value out into a separate `Value` struct, and include the size of the current display list
item in the item buffer.

* platform/graphics/displaylists/DisplayListDrawingContext.cpp:
(WebCore::DisplayList::DrawingContext::replayDisplayList):
* platform/graphics/displaylists/DisplayListReplayer.cpp:
(WebCore::DisplayList::applyImageBufferItem):
(WebCore::DisplayList::applyNativeImageItem):
(WebCore::DisplayList::Replayer::applyItem):

Make this private helper method return an optional flag indicating whether display list replay should stop.

(WebCore::DisplayList::Replayer::replay):

Make replay() return a `ReplayResult`, which contains the tracked display list (if tracking is enabled), as well
as the number of bytes of display list item data that were consumed, and the reason why display list replay
stopped (the default reason being `ReplayedAllItems`).

* platform/graphics/displaylists/DisplayListReplayer.h:
(WebCore::DisplayList::Replayer::replay):

Source/WebKit:

See WebCore ChangeLog for more details.

* GPUProcess/graphics/RemoteImageBuffer.h:

Make `submitDisplayList` on `RemoteImageBuffer` return a `ReplayResult`.

(WebKit::RemoteImageBuffer::submitDisplayList):
* GPUProcess/graphics/RemoteRenderingBackend.cpp:
(WebKit::RemoteRenderingBackend::applyDisplayListsFromHandle):
* WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
(WebKit::RemoteImageBufferProxy::submitDisplayList):

Tools:

Add a test that exercises partial display list replay.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp: Added.
(TestWebKitAPI::TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (270001 => 270002)


--- trunk/Source/WebCore/ChangeLog	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/ChangeLog	2020-11-19 01:20:48 UTC (rev 270002)
@@ -1,3 +1,62 @@
+2020-11-18  Wenson Hsieh  <[email protected]>
+
+        [Concurrent display lists] Add a way for display lists to partially replay
+        https://bugs.webkit.org/show_bug.cgi?id=219067
+
+        Reviewed by Simon Fraser.
+
+        Make it possble for a display list replayer to stop early in the middle of processing a display list. This
+        capability is a prerequisite to three items:
+
+        -   Allow display list processing in the GPU process to pause when encountering missing cached resources.
+        -   Allow the GPU process to replay display list item buffers that contain display list data targeting different
+            destination image buffers.
+        -   Allow the GPU process to prematurely halt display list processing and perform a MESSAGE_CHECK to terminate
+            the web content process, in the case of an invalid display list item (e.g. decoding failure).
+
+        See below for more details.
+
+        Test: DisplayListTests.ReplayWithMissingResource
+
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::flushDrawingContextAndCommit):
+        (WebCore::ImageBuffer::submitDisplayList): Deleted.
+
+        Remove the generic `submitDisplayList` method on `ImageBuffer`; instead, call directly into
+        `RemoteImageBuffer::submitDisplayList` to replay display lists.
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::platformCALayerPaintContents):
+
+        Adjust several call sites of `replay()` to grab the tracked display list from the `ReplayResult`.
+
+        * platform/graphics/displaylists/DisplayList.cpp:
+        (WebCore::DisplayList::DisplayList::asText const):
+        (WebCore::DisplayList::DisplayList::dump const):
+        * platform/graphics/displaylists/DisplayList.h:
+        (WebCore::DisplayList::DisplayList::iterator::operator* const):
+
+        Pull the iterator value out into a separate `Value` struct, and include the size of the current display list
+        item in the item buffer.
+
+        * platform/graphics/displaylists/DisplayListDrawingContext.cpp:
+        (WebCore::DisplayList::DrawingContext::replayDisplayList):
+        * platform/graphics/displaylists/DisplayListReplayer.cpp:
+        (WebCore::DisplayList::applyImageBufferItem):
+        (WebCore::DisplayList::applyNativeImageItem):
+        (WebCore::DisplayList::Replayer::applyItem):
+
+        Make this private helper method return an optional flag indicating whether display list replay should stop.
+
+        (WebCore::DisplayList::Replayer::replay):
+
+        Make replay() return a `ReplayResult`, which contains the tracked display list (if tracking is enabled), as well
+        as the number of bytes of display list item data that were consumed, and the reason why display list replay
+        stopped (the default reason being `ReplayedAllItems`).
+
+        * platform/graphics/displaylists/DisplayListReplayer.h:
+        (WebCore::DisplayList::Replayer::replay):
+
 2020-11-18  Tim Horton  <[email protected]>
 
         REGRESSION (r269895): Google Maps expanded route options are missing background color

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (270001 => 270002)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-11-19 01:20:48 UTC (rev 270002)
@@ -73,7 +73,6 @@
     virtual bool prefersPreparationForDisplay() { return false; }
     virtual void flushDrawingContext() { }
     virtual void flushDrawingContextAndCommit() { }
-    virtual void submitDisplayList(const DisplayList::DisplayList&) { }
 
     virtual AffineTransform baseTransform() const = 0;
     virtual IntSize logicalSize() const = 0;

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (270001 => 270002)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -1691,7 +1691,7 @@
         DisplayList::Replayer replayer(context, *m_displayList);
         
         if (UNLIKELY(isTrackingDisplayListReplay())) {
-            auto replayList = replayer.replay(clip, isTrackingDisplayListReplay());
+            auto replayList = replayer.replay(clip, isTrackingDisplayListReplay()).trackedDisplayList;
             layerDisplayListMap().add(this, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>(clip, WTFMove(replayList)));
         } else
             replayer.replay(clip);

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -114,7 +114,7 @@
 String DisplayList::asText(AsTextFlags flags) const
 {
     TextStream stream(TextStream::LineMode::MultipleLine, TextStream::Formatting::SVGStyleRect);
-    for (auto [item, extent] : *this) {
+    for (auto [item, extent, itemSizeInBuffer] : *this) {
         if (!shouldDumpForFlags(flags, item))
             continue;
 
@@ -131,7 +131,7 @@
     TextStream::GroupScope group(ts);
     ts << "display list";
 
-    for (auto [item, extent] : *this) {
+    for (auto [item, extent, itemSizeInBuffer] : *this) {
         TextStream::GroupScope group(ts);
         ts << item;
         if (item.isDrawingItem())

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h (270001 => 270002)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h	2020-11-19 01:20:48 UTC (rev 270002)
@@ -117,8 +117,22 @@
         bool operator==(const iterator& other) { return &m_displayList == &other.m_displayList && m_cursor == other.m_cursor; }
         bool operator!=(const iterator& other) { return !(*this == other); }
         void operator++() { advance(); }
-        std::pair<ItemHandle, Optional<FloatRect>> operator*() const { return { ItemHandle { m_currentBufferForItem }, m_currentExtent }; }
 
+        struct Value {
+            ItemHandle item;
+            Optional<FloatRect> extent;
+            size_t itemSizeInBuffer { 0 };
+        };
+
+        Value operator*() const
+        {
+            return {
+                ItemHandle { m_currentBufferForItem },
+                m_currentExtent,
+                m_currentItemSizeInBuffer
+            };
+        }
+
     private:
         static constexpr size_t sizeOfFixedBufferForCurrentItem = 256;
 

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp (270001 => 270002)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -60,7 +60,7 @@
 
     Replayer replayer(destContext, m_displayList);
     if (m_tracksDisplayListReplay)
-        m_replayedDisplayList = replayer.replay({ }, m_tracksDisplayListReplay);
+        m_replayedDisplayList = replayer.replay({ }, m_tracksDisplayListReplay).trackedDisplayList;
     else
         replayer.replay();
     m_displayList.clear();

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp (270001 => 270002)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -46,46 +46,53 @@
 Replayer::~Replayer() = default;
 
 template<class T>
-inline static bool applyImageBufferItem(GraphicsContext& context, const ImageBufferHashMap& imageBuffers, ItemHandle item)
+inline static Optional<StopReplayReason> applyImageBufferItem(GraphicsContext& context, const ImageBufferHashMap& imageBuffers, ItemHandle item)
 {
     if (!item.is<T>())
-        return false;
+        return WTF::nullopt;
     auto& imageBufferItem = item.get<T>();
-    if (auto* imageBuffer = imageBuffers.get(imageBufferItem.imageBufferIdentifier()))
+    if (auto* imageBuffer = imageBuffers.get(imageBufferItem.imageBufferIdentifier())) {
         imageBufferItem.apply(context, *imageBuffer);
-    return true;
+        return WTF::nullopt;
+    }
+    return StopReplayReason::MissingCachedResource;
 }
 
 template<class T>
-inline static bool applyNativeImageItem(GraphicsContext& context, const NativeImageHashMap& nativeImages, ItemHandle item)
+inline static Optional<StopReplayReason> applyNativeImageItem(GraphicsContext& context, const NativeImageHashMap& nativeImages, ItemHandle item)
 {
     if (!item.is<T>())
-        return false;
+        return WTF::nullopt;
     auto& nativeImageItem = item.get<T>();
-    if (auto* image = nativeImages.get(nativeImageItem.imageIdentifier()))
+    if (auto* image = nativeImages.get(nativeImageItem.imageIdentifier())) {
         nativeImageItem.apply(context, *image);
-    return true;
+        return WTF::nullopt;
+    }
+    return StopReplayReason::MissingCachedResource;
 }
 
-void Replayer::applyItem(ItemHandle item)
+Optional<StopReplayReason> Replayer::applyItem(ItemHandle item)
 {
     if (m_delegate && m_delegate->apply(item, m_context))
-        return;
+        return WTF::nullopt;
 
-    if (applyImageBufferItem<DrawImageBuffer>(m_context, m_imageBuffers, item))
-        return;
-    if (applyImageBufferItem<ClipToImageBuffer>(m_context, m_imageBuffers, item))
-        return;
+    if (auto reasonForStopping = applyImageBufferItem<DrawImageBuffer>(m_context, m_imageBuffers, item))
+        return reasonForStopping;
 
-    if (applyNativeImageItem<DrawNativeImage>(m_context, m_nativeImages, item))
-        return;
-    if (applyNativeImageItem<DrawPattern>(m_context, m_nativeImages, item))
-        return;
+    if (auto reasonForStopping = applyImageBufferItem<ClipToImageBuffer>(m_context, m_imageBuffers, item))
+        return reasonForStopping;
 
+    if (auto reasonForStopping = applyNativeImageItem<DrawNativeImage>(m_context, m_nativeImages, item))
+        return reasonForStopping;
+
+    if (auto reasonForStopping = applyNativeImageItem<DrawPattern>(m_context, m_nativeImages, item))
+        return reasonForStopping;
+
     item.apply(m_context);
+    return WTF::nullopt;
 }
 
-std::unique_ptr<DisplayList> Replayer::replay(const FloatRect& initialClip, bool trackReplayList)
+ReplayResult Replayer::replay(const FloatRect& initialClip, bool trackReplayList)
 {
     LOG_WITH_STREAM(DisplayLists, stream << "\nReplaying with clip " << initialClip);
     UNUSED_PARAM(initialClip);
@@ -97,15 +104,22 @@
 #if !LOG_DISABLED
     size_t i = 0;
 #endif
-    for (auto [item, extent] : m_displayList) {
+    ReplayResult result;
+    for (auto [item, extent, itemSizeInBuffer] : m_displayList) {
         if (!initialClip.isZero() && extent && !extent->intersects(initialClip)) {
             LOG_WITH_STREAM(DisplayLists, stream << "skipping " << i++ << " " << item);
+            result.numberOfBytesRead += itemSizeInBuffer;
             continue;
         }
 
         LOG_WITH_STREAM(DisplayLists, stream << "applying " << i++ << " " << item);
-        applyItem(item);
+        if (auto reasonForStopping = applyItem(item)) {
+            result.reasonForStopping = *reasonForStopping;
+            break;
+        }
 
+        result.numberOfBytesRead += itemSizeInBuffer;
+
         if (UNLIKELY(trackReplayList)) {
             replayList->append(item);
             if (item.isDrawingItem())
@@ -113,7 +127,8 @@
         }
     }
 
-    return replayList;
+    result.trackedDisplayList = WTFMove(replayList);
+    return result;
 }
 
 } // namespace DisplayList

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h (270001 => 270002)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h	2020-11-19 01:20:48 UTC (rev 270002)
@@ -38,6 +38,18 @@
 
 namespace DisplayList {
 
+enum class StopReplayReason : uint8_t {
+    ReplayedAllItems,
+    MissingCachedResource,
+    DecodingFailure // FIXME: Propagate decoding errors to display list replay clients through this enum as well.
+};
+
+struct ReplayResult {
+    std::unique_ptr<DisplayList> trackedDisplayList;
+    size_t numberOfBytesRead { 0 };
+    StopReplayReason reasonForStopping { StopReplayReason::ReplayedAllItems };
+};
+
 class Replayer {
     WTF_MAKE_NONCOPYABLE(Replayer);
 public:
@@ -45,7 +57,7 @@
     WEBCORE_EXPORT Replayer(GraphicsContext&, const DisplayList&, const ImageBufferHashMap* = nullptr, const NativeImageHashMap* = nullptr, Delegate* = nullptr);
     WEBCORE_EXPORT ~Replayer();
 
-    WEBCORE_EXPORT std::unique_ptr<DisplayList> replay(const FloatRect& initialClip = { }, bool trackReplayList = false);
+    WEBCORE_EXPORT ReplayResult replay(const FloatRect& initialClip = { }, bool trackReplayList = false);
 
     class Delegate {
     public:
@@ -54,8 +66,8 @@
     };
     
 private:
-    void applyItem(ItemHandle);
-    
+    Optional<StopReplayReason> applyItem(ItemHandle);
+
     GraphicsContext& m_context;
     const DisplayList& m_displayList;
     const ImageBufferHashMap& m_imageBuffers;

Modified: trunk/Source/WebKit/ChangeLog (270001 => 270002)


--- trunk/Source/WebKit/ChangeLog	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebKit/ChangeLog	2020-11-19 01:20:48 UTC (rev 270002)
@@ -1,3 +1,22 @@
+2020-11-18  Wenson Hsieh  <[email protected]>
+
+        [Concurrent display lists] Add a way for display lists to partially replay
+        https://bugs.webkit.org/show_bug.cgi?id=219067
+
+        Reviewed by Simon Fraser.
+
+        See WebCore ChangeLog for more details.
+
+        * GPUProcess/graphics/RemoteImageBuffer.h:
+
+        Make `submitDisplayList` on `RemoteImageBuffer` return a `ReplayResult`.
+
+        (WebKit::RemoteImageBuffer::submitDisplayList):
+        * GPUProcess/graphics/RemoteRenderingBackend.cpp:
+        (WebKit::RemoteRenderingBackend::applyDisplayListsFromHandle):
+        * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
+        (WebKit::RemoteImageBufferProxy::submitDisplayList):
+
 2020-11-18  Chris Dumez  <[email protected]>
 
         Drop redundant code that tries to bump the QoS of the WebContent main thread of UserInteractive when handling a sync IPC

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h (270001 => 270002)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h	2020-11-19 01:20:48 UTC (rev 270002)
@@ -65,17 +65,18 @@
             context().restore();
     }
 
-private:
-    void submitDisplayList(const WebCore::DisplayList::DisplayList& displayList) override
+    WebCore::DisplayList::ReplayResult submitDisplayList(const WebCore::DisplayList::DisplayList& displayList)
     {
-        if (!displayList.isEmpty()) {
-            const auto& imageBuffers = m_remoteRenderingBackend.remoteResourceCache().imageBuffers();
-            const auto& nativeImages = m_remoteRenderingBackend.remoteResourceCache().nativeImages();
-            WebCore::DisplayList::Replayer replayer { BaseConcreteImageBuffer::context(), displayList, &imageBuffers, &nativeImages, this };
-            replayer.replay();
-        }
+        if (displayList.isEmpty())
+            return { };
+
+        const auto& imageBuffers = m_remoteRenderingBackend.remoteResourceCache().imageBuffers();
+        const auto& nativeImages = m_remoteRenderingBackend.remoteResourceCache().nativeImages();
+        WebCore::DisplayList::Replayer replayer { BaseConcreteImageBuffer::context(), displayList, &imageBuffers, &nativeImages, this };
+        return replayer.replay();
     }
 
+private:
     bool apply(WebCore::DisplayList::ItemHandle item, WebCore::GraphicsContext& context) override
     {
         if (item.is<WebCore::DisplayList::PutImageData>()) {

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (270001 => 270002)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -148,7 +148,10 @@
             return;
         }
 
-        destination.submitDisplayList(*displayList);
+        if (destination.isAccelerated())
+            static_cast<AcceleratedRemoteImageBuffer&>(destination).submitDisplayList(*displayList);
+        else
+            static_cast<UnacceleratedRemoteImageBuffer&>(destination).submitDisplayList(*displayList);
 
         CheckedSize checkedOffset = offset;
         checkedOffset += sizeToRead;

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


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2020-11-19 01:20:48 UTC (rev 270002)
@@ -34,6 +34,7 @@
 #include <WebCore/DisplayListImageBuffer.h>
 #include <WebCore/DisplayListItems.h>
 #include <WebCore/DisplayListRecorder.h>
+#include <WebCore/DisplayListReplayer.h>
 #include <wtf/Condition.h>
 #include <wtf/Lock.h>
 #include <wtf/SystemTracing.h>
@@ -204,7 +205,7 @@
         displayList.clear();
     }
 
-    void submitDisplayList(const WebCore::DisplayList::DisplayList& displayList) override
+    void submitDisplayList(const WebCore::DisplayList::DisplayList& displayList)
     {
         if (!m_remoteRenderingBackendProxy || displayList.isEmpty())
             return;

Modified: trunk/Tools/ChangeLog (270001 => 270002)


--- trunk/Tools/ChangeLog	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Tools/ChangeLog	2020-11-19 01:20:48 UTC (rev 270002)
@@ -1,3 +1,18 @@
+2020-11-18  Wenson Hsieh  <[email protected]>
+
+        [Concurrent display lists] Add a way for display lists to partially replay
+        https://bugs.webkit.org/show_bug.cgi?id=219067
+
+        Reviewed by Simon Fraser.
+
+        Add a test that exercises partial display list replay.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp: Added.
+        (TestWebKitAPI::TEST):
+
 2020-11-17  Yusuke Suzuki  <[email protected]>
 
         [JSC] Improve Wasm binary test coverage

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (270001 => 270002)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-11-19 01:20:48 UTC (rev 270002)
@@ -1145,6 +1145,7 @@
 		F4517B672054C49500C26721 /* TestWKWebViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4517B662054C49500C26721 /* TestWKWebViewController.mm */; };
 		F4538EF71E8473E600B5C953 /* large-red-square.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4538EF01E846B4100B5C953 /* large-red-square.png */; };
 		F456AB1C213EDBA300CB2CEF /* FontManagerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F456AB1B213EDBA300CB2CEF /* FontManagerTests.mm */; };
+		F457275E25578D06007ACA34 /* DisplayListTestsCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F457275D25578D06007ACA34 /* DisplayListTestsCG.cpp */; };
 		F457A9B8202D5CDC00F7E9D5 /* PasteMixedContent.mm in Sources */ = {isa = PBXBuildFile; fileRef = F457A9B6202D5CDC00F7E9D5 /* PasteMixedContent.mm */; };
 		F457A9D6202D68AF00F7E9D5 /* DataTransfer.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F457A9B3202D535300F7E9D5 /* DataTransfer.html */; };
 		F45B63FB1F197F4A009D38B9 /* image-map.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F45B63FA1F197F33009D38B9 /* image-map.html */; };
@@ -2889,6 +2890,7 @@
 		F4517B662054C49500C26721 /* TestWKWebViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestWKWebViewController.mm; sourceTree = "<group>"; };
 		F4538EF01E846B4100B5C953 /* large-red-square.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "large-red-square.png"; sourceTree = "<group>"; };
 		F456AB1B213EDBA300CB2CEF /* FontManagerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FontManagerTests.mm; sourceTree = "<group>"; };
+		F457275D25578D06007ACA34 /* DisplayListTestsCG.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListTestsCG.cpp; path = cg/DisplayListTestsCG.cpp; sourceTree = "<group>"; };
 		F457A9B3202D535300F7E9D5 /* DataTransfer.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DataTransfer.html; sourceTree = "<group>"; };
 		F457A9B6202D5CDC00F7E9D5 /* PasteMixedContent.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteMixedContent.mm; sourceTree = "<group>"; };
 		F45B63FA1F197F33009D38B9 /* image-map.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "image-map.html"; sourceTree = "<group>"; };
@@ -3484,6 +3486,7 @@
 		440A1D3614A01000008A66F2 /* WebCore */ = {
 			isa = PBXGroup;
 			children = (
+				F457275B25578C9E007ACA34 /* cg */,
 				CD89D0371C4EDB1300040A04 /* cocoa */,
 				A1EC11851F4253D900D0146E /* ios */,
 				ABF510632A19B8AC7EC40E17 /* AbortableTaskQueue.cpp */,
@@ -4692,6 +4695,14 @@
 			path = cocoa;
 			sourceTree = "<group>";
 		};
+		F457275B25578C9E007ACA34 /* cg */ = {
+			isa = PBXGroup;
+			children = (
+				F457275D25578D06007ACA34 /* DisplayListTestsCG.cpp */,
+			);
+			name = cg;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -5150,6 +5161,7 @@
 				AD57AC211DA7465B00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache.cpp in Sources */,
 				FEC2A85424CE975F00ADBC35 /* DisallowVMEntry.cpp in Sources */,
 				F4094CC725545BD5003D73E3 /* DisplayListTests.cpp in Sources */,
+				F457275E25578D06007ACA34 /* DisplayListTestsCG.cpp in Sources */,
 				73BD731823A846500020F450 /* DisplayName.mm in Sources */,
 				518EE51B20A78D0000E024F3 /* DoAfterNextPresentationUpdateAfterCrash.mm in Sources */,
 				2D7FD19322419087007887F1 /* DocumentEditingContext.mm in Sources */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp (270001 => 270002)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp	2020-11-19 00:31:52 UTC (rev 270001)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -78,7 +78,7 @@
     EXPECT_FALSE(list.isEmpty());
 
     bool observedUnexpectedItem = false;
-    for (auto [handle, extent] : list) {
+    for (auto [handle, extent, size] : list) {
         switch (handle.type()) {
         case ItemType::SetStrokeThickness: {
             EXPECT_FALSE(handle.isDrawingItem());
@@ -147,7 +147,7 @@
 
     list.append<FillRectWithColor>(FloatRect { 0, 0, 100, 100 }, Color::black);
 
-    for (auto [handle, extent] : list) {
+    for (auto [handle, extent, size] : list) {
         EXPECT_EQ(handle.type(), ItemType::FillRectWithColor);
         EXPECT_TRUE(handle.is<FillRectWithColor>());
 
@@ -223,7 +223,7 @@
     shallowCopy.setItemBufferClient(&reader);
 
     Vector<ItemType> itemTypes;
-    for (auto [handle, extent] : shallowCopy)
+    for (auto [handle, extent, size] : shallowCopy)
         itemTypes.append(handle.type());
 
     EXPECT_FALSE(shallowCopy.isEmpty());

Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp (0 => 270002)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/cg/DisplayListTestsCG.cpp	2020-11-19 01:20:48 UTC (rev 270002)
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#if USE(CG)
+
+#include <WebCore/DisplayList.h>
+#include <WebCore/DisplayListItems.h>
+#include <WebCore/DisplayListReplayer.h>
+#include <WebCore/Gradient.h>
+
+namespace TestWebKitAPI {
+using namespace WebCore;
+using DisplayList::DisplayList;
+using namespace DisplayList;
+
+TEST(DisplayListTests, ReplayWithMissingResource)
+{
+    constexpr CGFloat contextWidth = 100;
+    constexpr CGFloat contextHeight = 100;
+
+    FloatRect contextBounds { 0, 0, contextWidth, contextHeight };
+
+    auto colorSpace = adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceSRGB));
+    auto cgContext = adoptCF(CGBitmapContextCreate(nullptr, contextWidth, contextHeight, 8, 4 * contextWidth, colorSpace.get(), kCGImageAlphaPremultipliedLast));
+    GraphicsContext context { cgContext.get() };
+
+    auto imageBufferIdentifier = RenderingResourceIdentifier::generate();
+
+    DisplayList list;
+
+    list.append<SetInlineFillColor>(Color::green);
+    list.append<FillRect>(contextBounds);
+    list.append<DrawImageBuffer>(imageBufferIdentifier, contextBounds, contextBounds, ImagePaintingOptions { });
+    list.append<SetInlineStrokeColor>(Color::red);
+    list.append<StrokeLine>(FloatPoint { 0, contextHeight }, FloatPoint { contextWidth, 0 });
+
+    {
+        Replayer replayer { context, list };
+        auto result = replayer.replay();
+        EXPECT_LT(result.numberOfBytesRead, list.sizeInBytes());
+        EXPECT_EQ(result.reasonForStopping, StopReplayReason::MissingCachedResource);
+    }
+
+    {
+        auto imageBuffer = ImageBuffer::create({ 100, 100 }, RenderingMode::Unaccelerated);
+        ImageBufferHashMap imageBufferMap;
+        imageBufferMap.set(imageBufferIdentifier, imageBuffer.releaseNonNull());
+
+        Replayer replayer { context, list, &imageBufferMap };
+        auto result = replayer.replay();
+        EXPECT_EQ(result.numberOfBytesRead, list.sizeInBytes());
+        EXPECT_EQ(result.reasonForStopping, StopReplayReason::ReplayedAllItems);
+    }
+}
+
+} // namespace TestWebKitAPI
+
+#endif // USE(CG)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to