Title: [269542] trunk/Tools
Revision
269542
Author
wenson_hs...@apple.com
Date
2020-11-06 14:01:25 -0800 (Fri, 06 Nov 2020)

Log Message

[Concurrent display lists] Add API tests for WebCore::DisplayList::DisplayList and related classes
https://bugs.webkit.org/show_bug.cgi?id=218425

Reviewed by Tim Horton.

Add two new API tests:
-   One that covers basic display list functionality (i.e. appending items, checking whether a display list is
    empty, clearing a display list and iterating over items).
-   Another that exercises the item buffer client hooks to provide data for writing and encode and decode out-
    of-line display list items. This test uses toy Reader/Writer classes that know how to "encode" and "decode"
    `StrokePath` items by storing and reading 8-byte indices into a shared `Vector<StrokePath>`.

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

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (269541 => 269542)


--- trunk/Tools/ChangeLog	2020-11-06 21:59:56 UTC (rev 269541)
+++ trunk/Tools/ChangeLog	2020-11-06 22:01:25 UTC (rev 269542)
@@ -1,3 +1,23 @@
+2020-11-06  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Concurrent display lists] Add API tests for WebCore::DisplayList::DisplayList and related classes
+        https://bugs.webkit.org/show_bug.cgi?id=218425
+
+        Reviewed by Tim Horton.
+
+        Add two new API tests:
+        -   One that covers basic display list functionality (i.e. appending items, checking whether a display list is
+            empty, clearing a display list and iterating over items).
+        -   Another that exercises the item buffer client hooks to provide data for writing and encode and decode out-
+            of-line display list items. This test uses toy Reader/Writer classes that know how to "encode" and "decode"
+            `StrokePath` items by storing and reading 8-byte indices into a shared `Vector<StrokePath>`.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp: Added.
+        (TestWebKitAPI::createGradient):
+        (TestWebKitAPI::createComplexPath):
+        (TestWebKitAPI::TEST):
+
 2020-11-06  Aakash Jain  <aakash_j...@apple.com>
 
         [build.webkit.org] Use workerEnvironment instead of slaveEnvironment for new Buildbot

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (269541 => 269542)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-11-06 21:59:56 UTC (rev 269541)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-11-06 22:01:25 UTC (rev 269542)
@@ -1098,6 +1098,7 @@
 		F4010B8324DA267F00A876E2 /* PoseAsClass.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4010B8124DA267F00A876E2 /* PoseAsClass.mm */; };
 		F402F56C23ECC2FB00865549 /* UIWKInteractionViewProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = F402F56B23ECC2FB00865549 /* UIWKInteractionViewProtocol.mm */; };
 		F407FE391F1D0DFC0017CF25 /* enormous.svg in Copy Resources */ = {isa = PBXBuildFile; fileRef = F407FE381F1D0DE60017CF25 /* enormous.svg */; };
+		F4094CC725545BD5003D73E3 /* DisplayListTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */; };
 		F4106C6921ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */; };
 		F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F415086C1DA040C10044BE9B /* play-audio-on-click.html */; };
 		F418BE151F71B7DC001970E6 /* RoundedRectTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */; };
@@ -1958,7 +1959,7 @@
 		44077BB0231449D200179E2D /* DataDetectorsTestIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsTestIOS.mm; sourceTree = "<group>"; };
 		442BBF681C91CAD90017087F /* RefLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefLogger.cpp; sourceTree = "<group>"; };
 		4433A395208044130091ED57 /* SynchronousTimeoutTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SynchronousTimeoutTests.mm; sourceTree = "<group>"; };
-		448110C1253F40240097FC33 /* WebPreferencesTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WebPreferencesTest.mm; path = WebPreferencesTest.mm; sourceTree = "<group>"; };
+		448110C1253F40240097FC33 /* WebPreferencesTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebPreferencesTest.mm; sourceTree = "<group>"; };
 		44817A2E1F0486BF00003810 /* WKRequestActivatedElementInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKRequestActivatedElementInfo.mm; sourceTree = "<group>"; };
 		448D7E451EA6C55500ECC756 /* EnvironmentUtilitiesTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EnvironmentUtilitiesTest.cpp; sourceTree = "<group>"; };
 		44A622C114A0E2B60048515B /* WTFStringUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFStringUtilities.h; sourceTree = "<group>"; };
@@ -2823,6 +2824,7 @@
 		F4010B8224DA267F00A876E2 /* PoseAsClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PoseAsClass.h; path = ../TestRunnerShared/cocoa/PoseAsClass.h; sourceTree = "<group>"; };
 		F402F56B23ECC2FB00865549 /* UIWKInteractionViewProtocol.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UIWKInteractionViewProtocol.mm; sourceTree = "<group>"; };
 		F407FE381F1D0DE60017CF25 /* enormous.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = enormous.svg; sourceTree = "<group>"; };
+		F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayListTests.cpp; sourceTree = "<group>"; };
 		F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewFirstResponderTests.mm; sourceTree = "<group>"; };
 		F415086C1DA040C10044BE9B /* play-audio-on-click.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "play-audio-on-click.html"; sourceTree = "<group>"; };
 		F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RoundedRectTests.cpp; sourceTree = "<group>"; };
@@ -3482,6 +3484,7 @@
 				260BA5781B1D2E7B004FA07C /* DFACombiner.cpp */,
 				260BA57A1B1D2EE2004FA07C /* DFAHelpers.h */,
 				26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
+				F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */,
 				93915A1624DB66C70019FF43 /* DocumentOrder.cpp */,
 				3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */,
 				579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */,
@@ -5121,6 +5124,7 @@
 				7CCE7EEA1A411AE600447C4C /* DidNotHandleKeyDown.cpp in Sources */,
 				AD57AC211DA7465B00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache.cpp in Sources */,
 				FEC2A85424CE975F00ADBC35 /* DisallowVMEntry.cpp in Sources */,
+				F4094CC725545BD5003D73E3 /* DisplayListTests.cpp in Sources */,
 				73BD731823A846500020F450 /* DisplayName.mm in Sources */,
 				518EE51B20A78D0000E024F3 /* DoAfterNextPresentationUpdateAfterCrash.mm in Sources */,
 				2D7FD19322419087007887F1 /* DocumentEditingContext.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp (0 => 269542)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp	2020-11-06 22:01:25 UTC (rev 269542)
@@ -0,0 +1,235 @@
+/*
+ * 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"
+
+#include <WebCore/DisplayList.h>
+#include <WebCore/DisplayListItems.h>
+#include <WebCore/Gradient.h>
+
+namespace TestWebKitAPI {
+using namespace WebCore;
+using DisplayList::DisplayList;
+using namespace DisplayList;
+
+constexpr size_t globalItemBufferCapacity = 1 << 12;
+static uint8_t globalItemBuffer[globalItemBufferCapacity];
+
+static Ref<Gradient> createGradient()
+{
+    auto gradient = Gradient::create(Gradient::ConicData { { 0., 0. }, 1.25 });
+    gradient->addColorStop({ 0.1, Color::red });
+    gradient->addColorStop({ 0.5, Color::green });
+    gradient->addColorStop({ 0.9, Color::blue });
+    return gradient;
+}
+
+static Path createComplexPath()
+{
+    Path path;
+    path.moveTo({ 10., 10. });
+    path.addLineTo({ 50., 50. });
+    path.addQuadCurveTo({ 100., 100. }, { 0., 200. });
+    path.addLineTo({ 10., 10. });
+    return path;
+}
+
+TEST(DisplayListTests, AppendItems)
+{
+    DisplayList list;
+
+    EXPECT_TRUE(list.isEmpty());
+
+    auto gradient = createGradient();
+    auto path = createComplexPath();
+
+    for (int i = 0; i < 50; ++i) {
+        list.append<SetStrokeThickness>(1.5);
+        list.append<FillPath>(path);
+        list.append<FillRectWithGradient>(FloatRect { 1., 1., 10., 10. }, gradient);
+        list.append<SetInlineFillColor>(Color::red);
+#if ENABLE(INLINE_PATH_DATA)
+        list.append<StrokeInlinePath>(InlinePathData { LineData {{ 0., 0. }, { 10., 15. }}});
+#endif
+    }
+
+    EXPECT_FALSE(list.isEmpty());
+
+    bool observedUnexpectedItem = false;
+    for (auto [handle, extent] : list) {
+        switch (handle.type()) {
+        case ItemType::SetStrokeThickness: {
+            EXPECT_FALSE(handle.isDrawingItem());
+            EXPECT_TRUE(handle.is<SetStrokeThickness>());
+            auto& item = handle.get<SetStrokeThickness>();
+            EXPECT_EQ(item.thickness(), 1.5);
+            break;
+        }
+        case ItemType::FillPath: {
+            EXPECT_TRUE(handle.isDrawingItem());
+            EXPECT_TRUE(handle.is<FillPath>());
+            auto& item = handle.get<FillPath>();
+            EXPECT_EQ(item.path().platformPath(), path.platformPath());
+            break;
+        }
+        case ItemType::FillRectWithGradient: {
+            EXPECT_TRUE(handle.isDrawingItem());
+            EXPECT_TRUE(handle.is<FillRectWithGradient>());
+            auto& item = handle.get<FillRectWithGradient>();
+            EXPECT_EQ(item.rect(), FloatRect(1., 1., 10., 10.));
+            EXPECT_EQ(&item.gradient(), gradient.ptr());
+            break;
+        }
+        case ItemType::SetInlineFillColor: {
+            EXPECT_FALSE(handle.isDrawingItem());
+            EXPECT_TRUE(handle.is<SetInlineFillColor>());
+            auto& item = handle.get<SetInlineFillColor>();
+            EXPECT_EQ(item.color(), Color::red);
+            break;
+        }
+#if ENABLE(INLINE_PATH_DATA)
+        case ItemType::StrokeInlinePath: {
+            EXPECT_TRUE(handle.isDrawingItem());
+            EXPECT_TRUE(handle.is<StrokeInlinePath>());
+            auto& item = handle.get<StrokeInlinePath>();
+            const auto path = item.path();
+            auto& line = path.inlineData<LineData>();
+            EXPECT_EQ(line.start, FloatPoint(0, 0));
+            EXPECT_EQ(line.end, FloatPoint(10., 15.));
+            break;
+        }
+#endif
+        default: {
+            observedUnexpectedItem = true;
+            break;
+        }
+        }
+    }
+
+    EXPECT_FALSE(observedUnexpectedItem);
+    EXPECT_GT(list.sizeInBytes(), 0U);
+
+    list.clear();
+
+    observedUnexpectedItem = false;
+    for (auto itemAndExtent : list) {
+        UNUSED_PARAM(itemAndExtent);
+        observedUnexpectedItem = true;
+    }
+
+    EXPECT_TRUE(list.isEmpty());
+    EXPECT_EQ(list.sizeInBytes(), 0U);
+    EXPECT_FALSE(observedUnexpectedItem);
+
+    list.append<FillRectWithColor>(FloatRect { 0, 0, 100, 100 }, Color::black);
+
+    for (auto [handle, extent] : list) {
+        EXPECT_EQ(handle.type(), ItemType::FillRectWithColor);
+        EXPECT_TRUE(handle.is<FillRectWithColor>());
+
+        auto& item = handle.get<FillRectWithColor>();
+        EXPECT_EQ(item.color().asInline(), Color::black);
+        EXPECT_EQ(item.rect(), FloatRect(0, 0, 100, 100));
+    }
+
+    EXPECT_FALSE(list.isEmpty());
+    EXPECT_GT(list.sizeInBytes(), 0U);
+}
+
+TEST(DisplayListTests, ItemBufferClient)
+{
+    Vector<StrokePath> strokePathItems;
+    static ItemBufferIdentifier globalBufferIdentifier = ItemBufferIdentifier::generate();
+
+    class StrokePathReader : public ItemBufferReadingClient {
+    public:
+        StrokePathReader(const Vector<StrokePath>& items)
+            : m_items(items)
+        {
+        }
+
+    private:
+        Optional<ItemHandle> WARN_UNUSED_RETURN decodeItem(const uint8_t* data, size_t dataLength, ItemType type, uint8_t* handleLocation)
+        {
+            EXPECT_EQ(type, ItemType::StrokePath);
+            EXPECT_EQ(dataLength, sizeof(size_t));
+            new (handleLocation + sizeof(ItemType)) StrokePath(m_items[*reinterpret_cast<const size_t*>(data)]);
+            return {{ handleLocation }};
+        }
+
+        const Vector<StrokePath>& m_items;
+    };
+
+    class StrokePathWriter : public ItemBufferWritingClient {
+    public:
+        StrokePathWriter(Vector<StrokePath>& items)
+            : m_items(items)
+        {
+        }
+
+    private:
+        ItemBufferHandle createItemBuffer(size_t capacity) final
+        {
+            EXPECT_LT(capacity, globalItemBufferCapacity);
+            return { globalBufferIdentifier, globalItemBuffer, globalItemBufferCapacity };
+        }
+
+        RefPtr<SharedBuffer> encodeItem(ItemHandle handle) const final
+        {
+            auto index = m_items.size();
+            m_items.append(handle.get<StrokePath>());
+            return SharedBuffer::create(reinterpret_cast<uint8_t*>(&index), sizeof(size_t));
+        }
+
+        Vector<StrokePath>& m_items;
+    };
+
+    DisplayList list;
+    StrokePathWriter writer { strokePathItems };
+    list.setItemBufferClient(&writer);
+
+    auto path = createComplexPath();
+    list.append<SetInlineStrokeColor>(Color::blue);
+    list.append<StrokePath>(path);
+    list.append<SetInlineStrokeColor>(Color::red);
+    list.append<StrokePath>(path);
+
+    DisplayList shallowCopy {{ ItemBufferHandle { globalBufferIdentifier, globalItemBuffer, list.sizeInBytes() } }};
+    StrokePathReader reader { strokePathItems };
+    shallowCopy.setItemBufferClient(&reader);
+
+    Vector<ItemType> itemTypes;
+    for (auto [handle, extent] : shallowCopy)
+        itemTypes.append(handle.type());
+
+    EXPECT_FALSE(shallowCopy.isEmpty());
+    EXPECT_EQ(itemTypes.size(), 4U);
+    EXPECT_EQ(itemTypes[0], ItemType::SetInlineStrokeColor);
+    EXPECT_EQ(itemTypes[1], ItemType::StrokePath);
+    EXPECT_EQ(itemTypes[2], ItemType::SetInlineStrokeColor);
+    EXPECT_EQ(itemTypes[3], ItemType::StrokePath);
+}
+
+} // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to