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)