Title: [269092] trunk
Revision
269092
Author
wenson_hs...@apple.com
Date
2020-10-27 19:09:17 -0700 (Tue, 27 Oct 2020)

Log Message

[Concurrent display lists] Add alternate versions of existing display list items that only contain inline data
https://bugs.webkit.org/show_bug.cgi?id=218259

Reviewed by Tim Horton.

Source/WebCore:

In preparation for supporting concurrent generation and consumption of display list items in the GPU process,
add new variants of some existing display list items that contain only "inline data" (i.e. no pointers).

No change in behavior; see below for more details.

* platform/graphics/Path.cpp:
(WebCore::Path::isEmpty const):
(WebCore::Path::addQuadCurveTo):
(WebCore::Path::addBezierCurveTo):
(WebCore::Path::Path):
* platform/graphics/Path.h:

Add a helper method to convert `InlinePathData` to `Path`.

(WebCore::Path::inlineData const):
(WebCore::Path::encode const):
(WebCore::Path::hasInlineData const):

Rename `hasAnyInlineData` to just `hasInlineData`, and make it public.

(WebCore::Path::releasePlatformPathIfPossible const): Deleted.

Additionally, remove `releasePlatformPathIfPossible()` altogether. This method was used to ensure that
`StrokePath` and `FillPath` wouldn't keep their `Path`'s platform `CGPathRef`s around after applying the item in
the GPU process, which leads to accumulating a pool of unused `CGPathRef`s after playing back a display list
that contains many `Path` objects. However, since `StrokeInlinePath` and `FillInlinePath` now exist, the `Path`
object we create when applying those items is always going to be temporary, which allows us to avoid this
problem.

(WebCore::Path::hasAnyInlineData const): Deleted.
* platform/graphics/cg/PathCG.cpp:
(WebCore::Path::platformPath const):
(WebCore::Path::isNull const):
* platform/graphics/displaylists/DisplayList.h:
* platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::Item::sizeInBytes):
(WebCore::DisplayList::SetInlineFillGradient::SetInlineFillGradient):
(WebCore::DisplayList::SetInlineFillGradient::gradient const):
(WebCore::DisplayList::SetInlineFillGradient::create):
(WebCore::DisplayList::SetInlineFillGradient::apply const):
(WebCore::DisplayList::SetInlineFillGradient::isInline):

Introduce a new SetInlineFillGradient item to represent setting the fill gradient to a gradient with at most 4
color stops, with only inline colors. This inline data is pulled out of the `Gradient` upon construction, and
later used to reconstruct a `Gradient` during playback.

(WebCore::DisplayList::operator<<):
(WebCore::DisplayList::SetInlineFillColor::create):
(WebCore::DisplayList::SetInlineFillColor::apply const):

Change `SetFillColor` to `SetInlineFillColor`, and make it pass around an `SRGB<uint8_t>` instead of a `Color`,
since the latter could contain a pointer to an extended color.

(WebCore::DisplayList::SetInlineStrokeColor::create):
(WebCore::DisplayList::SetInlineStrokeColor::apply const):

Similar to the above, but when setting the stroke color to an inline (non-extended) color.

(WebCore::DisplayList::SetStrokeThickness::create):
(WebCore::DisplayList::SetStrokeThickness::apply const):
(WebCore::DisplayList::FillInlinePath::FillInlinePath):
(WebCore::DisplayList::FillInlinePath::apply const):
(WebCore::DisplayList::FillPath::apply const):
(WebCore::DisplayList::StrokePath::apply const):
(WebCore::DisplayList::StrokeInlinePath::localBounds const):
(WebCore::DisplayList::StrokeInlinePath::apply const):
(WebCore::DisplayList::StrokeInlinePath::StrokeInlinePath):

Add `StrokeInlinePath` and `FillInlinePath`, which contain `InlinePathData` instead of `Path` objects and only
construct `path()` objects when needed (i.e. when applying to a `GraphicsContext`).

(WebCore::DisplayList::SetFillColor::create): Deleted.
(WebCore::DisplayList::SetFillColor::apply const): Deleted.
(WebCore::DisplayList::SetStrokeState::create): Deleted.
(WebCore::DisplayList::SetStrokeState::apply const): Deleted.
* platform/graphics/displaylists/DisplayListItems.h:
(WebCore::DisplayList::SetInlineFillGradient::create):
(WebCore::DisplayList::SetInlineFillGradient::encode const):
(WebCore::DisplayList::SetInlineFillGradient::decode):
(WebCore::DisplayList::SetInlineFillColor::color const):
(WebCore::DisplayList::SetInlineFillColor::SetInlineFillColor):
(WebCore::DisplayList::SetInlineFillColor::encode const):
(WebCore::DisplayList::SetInlineFillColor::decode):
(WebCore::DisplayList::SetInlineStrokeColor::color const):
(WebCore::DisplayList::SetInlineStrokeColor::SetInlineStrokeColor):
(WebCore::DisplayList::SetInlineStrokeColor::encode const):
(WebCore::DisplayList::SetInlineStrokeColor::decode):
(WebCore::DisplayList::SetStrokeThickness::thickness const):
(WebCore::DisplayList::SetStrokeThickness::SetStrokeThickness):
(WebCore::DisplayList::SetStrokeThickness::encode const):
(WebCore::DisplayList::SetStrokeThickness::decode):

Pull stroke thickness out into its own display list item.

(WebCore::DisplayList::FillInlinePath::create):
(WebCore::DisplayList::FillInlinePath::path const):
(WebCore::DisplayList::FillInlinePath::encode const):
(WebCore::DisplayList::FillInlinePath::decode):
(WebCore::DisplayList::StrokeInlinePath::create):
(WebCore::DisplayList::StrokeInlinePath::path const):
(WebCore::DisplayList::StrokeInlinePath::encode const):
(WebCore::DisplayList::StrokeInlinePath::decode):
(WebCore::DisplayList::Item::encode const):
(WebCore::DisplayList::Item::decode):
(WebCore::DisplayList::SetFillColor::color const): Deleted.
(WebCore::DisplayList::SetFillColor::SetFillColor): Deleted.
(WebCore::DisplayList::SetFillColor::encode const): Deleted.
(WebCore::DisplayList::SetFillColor::decode): Deleted.
(WebCore::DisplayList::SetStrokeState::color const): Deleted.
(WebCore::DisplayList::SetStrokeState::hasColor const): Deleted.
(WebCore::DisplayList::SetStrokeState::thickness const): Deleted.
(WebCore::DisplayList::SetStrokeState::hasThickness const): Deleted.
(WebCore::DisplayList::SetStrokeState::SetStrokeState): Deleted.
(WebCore::DisplayList::SetStrokeState::encode const): Deleted.
(WebCore::DisplayList::SetStrokeState::decode): Deleted.

Split `SetStrokeState` out into separate items tracking thickness and stroke color.

* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::containsOnlyInlineStateChanges):

Refactor this code so that it emits multiple display list items if multiple inline states change. Previously,
this was only done for simultaneous stroke color and stroke thickness changes (via the `SetStrokeState` item);
this was done to avoid creating more display list items than needed. However, once all inline display list items
are constructed directly in shared memory, there will be (almost) zero overhead for splitting this into
separate items.

(WebCore::DisplayList::Recorder::appendStateChangeItem):
(WebCore::DisplayList::Recorder::willAppendItem):
(WebCore::DisplayList::Recorder::fillPath):
(WebCore::DisplayList::Recorder::strokePath):
(WebCore::DisplayList::containsOnlyStrokeColorOrThicknessChange): Deleted.
(WebCore::DisplayList::containsOnlyFillColorChange): Deleted.
(WebCore::DisplayList::createStateChangeItem): Deleted.

Additionally refactor this method so that it is now a private method that appends to `m_displayList`, instead of
returning a display list item to be appended. This will become important in a future patch, which will replace
the existing `append` method with a templated version that takes the display list item type as a template
argument.

* platform/graphics/displaylists/DisplayListRecorder.h:

LayoutTests:

Rebaseline an existing test.

* displaylists/canvas-display-list-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269091 => 269092)


--- trunk/LayoutTests/ChangeLog	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/LayoutTests/ChangeLog	2020-10-28 02:09:17 UTC (rev 269092)
@@ -1,3 +1,14 @@
+2020-10-27  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Concurrent display lists] Add alternate versions of existing display list items that only contain inline data
+        https://bugs.webkit.org/show_bug.cgi?id=218259
+
+        Reviewed by Tim Horton.
+
+        Rebaseline an existing test.
+
+        * displaylists/canvas-display-list-expected.txt:
+
 2020-10-27  Carlos Alberto Lopez Perez  <clo...@igalia.com>
 
         [GTK][WPE] Rebaseline tests after r269044 and r269036

Modified: trunk/LayoutTests/displaylists/canvas-display-list-expected.txt (269091 => 269092)


--- trunk/LayoutTests/displaylists/canvas-display-list-expected.txt	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/LayoutTests/displaylists/canvas-display-list-expected.txt	2020-10-28 02:09:17 UTC (rev 269092)
@@ -8,7 +8,7 @@
 (fill-rect
   (extent at (10,140) size 55x50)
   (rect at (10,10) size 55x50))
-(set-fill-color
+(set-inline-fill-color
   (color #0000C880))
 (fill-rect
   (extent at (30,120) size 55x50)

Modified: trunk/Source/WebCore/ChangeLog (269091 => 269092)


--- trunk/Source/WebCore/ChangeLog	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/ChangeLog	2020-10-28 02:09:17 UTC (rev 269092)
@@ -1,3 +1,152 @@
+2020-10-27  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Concurrent display lists] Add alternate versions of existing display list items that only contain inline data
+        https://bugs.webkit.org/show_bug.cgi?id=218259
+
+        Reviewed by Tim Horton.
+
+        In preparation for supporting concurrent generation and consumption of display list items in the GPU process,
+        add new variants of some existing display list items that contain only "inline data" (i.e. no pointers).
+
+        No change in behavior; see below for more details.
+
+        * platform/graphics/Path.cpp:
+        (WebCore::Path::isEmpty const):
+        (WebCore::Path::addQuadCurveTo):
+        (WebCore::Path::addBezierCurveTo):
+        (WebCore::Path::Path):
+        * platform/graphics/Path.h:
+
+        Add a helper method to convert `InlinePathData` to `Path`.
+
+        (WebCore::Path::inlineData const):
+        (WebCore::Path::encode const):
+        (WebCore::Path::hasInlineData const):
+
+        Rename `hasAnyInlineData` to just `hasInlineData`, and make it public.
+
+        (WebCore::Path::releasePlatformPathIfPossible const): Deleted.
+
+        Additionally, remove `releasePlatformPathIfPossible()` altogether. This method was used to ensure that
+        `StrokePath` and `FillPath` wouldn't keep their `Path`'s platform `CGPathRef`s around after applying the item in
+        the GPU process, which leads to accumulating a pool of unused `CGPathRef`s after playing back a display list
+        that contains many `Path` objects. However, since `StrokeInlinePath` and `FillInlinePath` now exist, the `Path`
+        object we create when applying those items is always going to be temporary, which allows us to avoid this
+        problem.
+
+        (WebCore::Path::hasAnyInlineData const): Deleted.
+        * platform/graphics/cg/PathCG.cpp:
+        (WebCore::Path::platformPath const):
+        (WebCore::Path::isNull const):
+        * platform/graphics/displaylists/DisplayList.h:
+        * platform/graphics/displaylists/DisplayListItems.cpp:
+        (WebCore::DisplayList::Item::sizeInBytes):
+        (WebCore::DisplayList::SetInlineFillGradient::SetInlineFillGradient):
+        (WebCore::DisplayList::SetInlineFillGradient::gradient const):
+        (WebCore::DisplayList::SetInlineFillGradient::create):
+        (WebCore::DisplayList::SetInlineFillGradient::apply const):
+        (WebCore::DisplayList::SetInlineFillGradient::isInline):
+
+        Introduce a new SetInlineFillGradient item to represent setting the fill gradient to a gradient with at most 4
+        color stops, with only inline colors. This inline data is pulled out of the `Gradient` upon construction, and
+        later used to reconstruct a `Gradient` during playback.
+
+        (WebCore::DisplayList::operator<<):
+        (WebCore::DisplayList::SetInlineFillColor::create):
+        (WebCore::DisplayList::SetInlineFillColor::apply const):
+
+        Change `SetFillColor` to `SetInlineFillColor`, and make it pass around an `SRGB<uint8_t>` instead of a `Color`,
+        since the latter could contain a pointer to an extended color.
+
+        (WebCore::DisplayList::SetInlineStrokeColor::create):
+        (WebCore::DisplayList::SetInlineStrokeColor::apply const):
+
+        Similar to the above, but when setting the stroke color to an inline (non-extended) color.
+
+        (WebCore::DisplayList::SetStrokeThickness::create):
+        (WebCore::DisplayList::SetStrokeThickness::apply const):
+        (WebCore::DisplayList::FillInlinePath::FillInlinePath):
+        (WebCore::DisplayList::FillInlinePath::apply const):
+        (WebCore::DisplayList::FillPath::apply const):
+        (WebCore::DisplayList::StrokePath::apply const):
+        (WebCore::DisplayList::StrokeInlinePath::localBounds const):
+        (WebCore::DisplayList::StrokeInlinePath::apply const):
+        (WebCore::DisplayList::StrokeInlinePath::StrokeInlinePath):
+
+        Add `StrokeInlinePath` and `FillInlinePath`, which contain `InlinePathData` instead of `Path` objects and only
+        construct `path()` objects when needed (i.e. when applying to a `GraphicsContext`).
+
+        (WebCore::DisplayList::SetFillColor::create): Deleted.
+        (WebCore::DisplayList::SetFillColor::apply const): Deleted.
+        (WebCore::DisplayList::SetStrokeState::create): Deleted.
+        (WebCore::DisplayList::SetStrokeState::apply const): Deleted.
+        * platform/graphics/displaylists/DisplayListItems.h:
+        (WebCore::DisplayList::SetInlineFillGradient::create):
+        (WebCore::DisplayList::SetInlineFillGradient::encode const):
+        (WebCore::DisplayList::SetInlineFillGradient::decode):
+        (WebCore::DisplayList::SetInlineFillColor::color const):
+        (WebCore::DisplayList::SetInlineFillColor::SetInlineFillColor):
+        (WebCore::DisplayList::SetInlineFillColor::encode const):
+        (WebCore::DisplayList::SetInlineFillColor::decode):
+        (WebCore::DisplayList::SetInlineStrokeColor::color const):
+        (WebCore::DisplayList::SetInlineStrokeColor::SetInlineStrokeColor):
+        (WebCore::DisplayList::SetInlineStrokeColor::encode const):
+        (WebCore::DisplayList::SetInlineStrokeColor::decode):
+        (WebCore::DisplayList::SetStrokeThickness::thickness const):
+        (WebCore::DisplayList::SetStrokeThickness::SetStrokeThickness):
+        (WebCore::DisplayList::SetStrokeThickness::encode const):
+        (WebCore::DisplayList::SetStrokeThickness::decode):
+
+        Pull stroke thickness out into its own display list item.
+
+        (WebCore::DisplayList::FillInlinePath::create):
+        (WebCore::DisplayList::FillInlinePath::path const):
+        (WebCore::DisplayList::FillInlinePath::encode const):
+        (WebCore::DisplayList::FillInlinePath::decode):
+        (WebCore::DisplayList::StrokeInlinePath::create):
+        (WebCore::DisplayList::StrokeInlinePath::path const):
+        (WebCore::DisplayList::StrokeInlinePath::encode const):
+        (WebCore::DisplayList::StrokeInlinePath::decode):
+        (WebCore::DisplayList::Item::encode const):
+        (WebCore::DisplayList::Item::decode):
+        (WebCore::DisplayList::SetFillColor::color const): Deleted.
+        (WebCore::DisplayList::SetFillColor::SetFillColor): Deleted.
+        (WebCore::DisplayList::SetFillColor::encode const): Deleted.
+        (WebCore::DisplayList::SetFillColor::decode): Deleted.
+        (WebCore::DisplayList::SetStrokeState::color const): Deleted.
+        (WebCore::DisplayList::SetStrokeState::hasColor const): Deleted.
+        (WebCore::DisplayList::SetStrokeState::thickness const): Deleted.
+        (WebCore::DisplayList::SetStrokeState::hasThickness const): Deleted.
+        (WebCore::DisplayList::SetStrokeState::SetStrokeState): Deleted.
+        (WebCore::DisplayList::SetStrokeState::encode const): Deleted.
+        (WebCore::DisplayList::SetStrokeState::decode): Deleted.
+
+        Split `SetStrokeState` out into separate items tracking thickness and stroke color.
+
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::containsOnlyInlineStateChanges):
+
+        Refactor this code so that it emits multiple display list items if multiple inline states change. Previously,
+        this was only done for simultaneous stroke color and stroke thickness changes (via the `SetStrokeState` item);
+        this was done to avoid creating more display list items than needed. However, once all inline display list items
+        are constructed directly in shared memory, there will be (almost) zero overhead for splitting this into
+        separate items.
+
+        (WebCore::DisplayList::Recorder::appendStateChangeItem):
+        (WebCore::DisplayList::Recorder::willAppendItem):
+        (WebCore::DisplayList::Recorder::fillPath):
+        (WebCore::DisplayList::Recorder::strokePath):
+        (WebCore::DisplayList::containsOnlyStrokeColorOrThicknessChange): Deleted.
+        (WebCore::DisplayList::containsOnlyFillColorChange): Deleted.
+        (WebCore::DisplayList::createStateChangeItem): Deleted.
+
+        Additionally refactor this method so that it is now a private method that appends to `m_displayList`, instead of
+        returning a display list item to be appended. This will become important in a future patch, which will replace
+        the existing `append` method with a templated version that takes the display list item type as a template
+        argument.
+
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+
 2020-10-27  Said Abou-Hallawa  <s...@apple.com>
 
         Make RenderingMode a bool enum and remove ShouldAccelerate

Modified: trunk/Source/WebCore/platform/graphics/Path.cpp (269091 => 269092)


--- trunk/Source/WebCore/platform/graphics/Path.cpp	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/Path.cpp	2020-10-28 02:09:17 UTC (rev 269092)
@@ -230,7 +230,7 @@
         return true;
 
 #if ENABLE(INLINE_PATH_DATA)
-    if (hasAnyInlineData())
+    if (hasInlineData())
         return false;
 #endif
 
@@ -348,7 +348,7 @@
 #if ENABLE(INLINE_PATH_DATA)
     if (isNull() || hasInlineData<MoveData>()) {
         QuadCurveData curve;
-        curve.startPoint = hasAnyInlineData() ? WTF::get<MoveData>(m_inlineData).location : FloatPoint();
+        curve.startPoint = hasInlineData() ? WTF::get<MoveData>(m_inlineData).location : FloatPoint();
         curve.controlPoint = controlPoint;
         curve.endPoint = endPoint;
         m_inlineData = { WTFMove(curve) };
@@ -364,7 +364,7 @@
 #if ENABLE(INLINE_PATH_DATA)
     if (isNull() || hasInlineData<MoveData>()) {
         BezierCurveData curve;
-        curve.startPoint = hasAnyInlineData() ? WTF::get<MoveData>(m_inlineData).location : FloatPoint();
+        curve.startPoint = hasInlineData() ? WTF::get<MoveData>(m_inlineData).location : FloatPoint();
         curve.controlPoint1 = controlPoint1;
         curve.controlPoint2 = controlPoint2;
         curve.endPoint = endPoint;

Modified: trunk/Source/WebCore/platform/graphics/Path.h (269091 => 269092)


--- trunk/Source/WebCore/platform/graphics/Path.h	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/Path.h	2020-10-28 02:09:17 UTC (rev 269092)
@@ -133,6 +133,15 @@
     WEBCORE_EXPORT Path& operator=(const Path&);
     WEBCORE_EXPORT Path& operator=(Path&&);
 
+#if ENABLE(INLINE_PATH_DATA)
+    static Path from(const InlinePathData& inlineData)
+    {
+        Path path;
+        path.m_inlineData = inlineData;
+        return path;
+    }
+#endif
+
     static Path polygonPathFromPoints(const Vector<FloatPoint>&);
 
     bool contains(const FloatPoint&, WindRule = WindRule::NonZero) const;
@@ -196,17 +205,6 @@
     PlatformPathPtr platformPath() const { return m_path; }
 #endif
 
-    void releasePlatformPathIfPossible() const
-    {
-#if ENABLE(INLINE_PATH_DATA)
-        if (!hasAnyInlineData() || !m_path)
-            return;
-
-        m_path = nullptr;
-        m_copyPathBeforeMutation = false;
-#endif
-    }
-
 #if !USE(CAIRO)
     // ensurePlatformPath() will allocate a PlatformPath if it has not yet been and will never return null.
     WEBCORE_EXPORT PlatformPathPtr ensurePlatformPath();
@@ -246,12 +244,13 @@
 
 #if ENABLE(INLINE_PATH_DATA)
     template<typename DataType> const DataType& inlineData() const;
+    InlinePathData inlineData() const { return m_inlineData; }
     template<typename DataType> bool hasInlineData() const;
+    bool hasInlineData() const;
 #endif
 
 private:
 #if ENABLE(INLINE_PATH_DATA)
-    bool hasAnyInlineData() const;
     template<typename DataType> DataType& inlineData();
     Optional<FloatRect> fastBoundingRectFromInlineData() const;
     Optional<FloatRect> boundingRectFromInlineData() const;
@@ -308,7 +307,7 @@
 template<class Encoder> void Path::encode(Encoder& encoder) const
 {
 #if ENABLE(INLINE_PATH_DATA)
-    bool hasInlineData = hasAnyInlineData();
+    bool hasInlineData = this->hasInlineData();
     encoder << hasInlineData;
     if (hasInlineData) {
         encoder << m_inlineData;
@@ -440,7 +439,7 @@
     return WTF::get<DataType>(m_inlineData);
 }
 
-inline bool Path::hasAnyInlineData() const
+inline bool Path::hasInlineData() const
 {
     return !hasInlineData<Monostate>();
 }

Modified: trunk/Source/WebCore/platform/graphics/cg/PathCG.cpp (269091 => 269092)


--- trunk/Source/WebCore/platform/graphics/cg/PathCG.cpp	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/cg/PathCG.cpp	2020-10-28 02:09:17 UTC (rev 269092)
@@ -125,7 +125,7 @@
 
 PlatformPathPtr Path::platformPath() const
 {
-    if (!m_path && hasAnyInlineData())
+    if (!m_path && hasInlineData())
         createCGPath();
     return m_path.get();
 }
@@ -144,7 +144,7 @@
 
 bool Path::isNull() const
 {
-    return !m_path && !hasAnyInlineData();
+    return !m_path && !hasInlineData();
 }
 
 Path::Path(const Path& other)

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h	2020-10-28 02:09:17 UTC (rev 269092)
@@ -47,8 +47,10 @@
     Scale,
     ConcatenateCTM,
     SetCTM,
-    SetFillColor,
-    SetStrokeState,
+    SetInlineFillGradient,
+    SetInlineFillColor,
+    SetInlineStrokeColor,
+    SetStrokeThickness,
     SetState,
     SetLineCap,
     SetLineDash,
@@ -81,11 +83,17 @@
     FillCompositedRect,
     FillRoundedRect,
     FillRectWithRoundedHole,
+#if ENABLE(INLINE_PATH_DATA)
+    FillInlinePath,
+#endif
     FillPath,
     FillEllipse,
     PutImageData,
     PaintFrameForMedia,
     StrokeRect,
+#if ENABLE(INLINE_PATH_DATA)
+    StrokeInlinePath,
+#endif
     StrokePath,
     StrokeEllipse,
     ClearRect,

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2020-10-28 02:09:17 UTC (rev 269092)
@@ -76,10 +76,14 @@
         return sizeof(downcast<SetCTM>(item));
     case ItemType::ConcatenateCTM:
         return sizeof(downcast<ConcatenateCTM>(item));
-    case ItemType::SetFillColor:
-        return sizeof(downcast<SetFillColor>(item));
-    case ItemType::SetStrokeState:
-        return sizeof(downcast<SetStrokeState>(item));
+    case ItemType::SetInlineFillGradient:
+        return sizeof(downcast<SetInlineFillGradient>(item));
+    case ItemType::SetInlineFillColor:
+        return sizeof(downcast<SetInlineFillColor>(item));
+    case ItemType::SetInlineStrokeColor:
+        return sizeof(downcast<SetInlineStrokeColor>(item));
+    case ItemType::SetStrokeThickness:
+        return sizeof(downcast<SetStrokeThickness>(item));
     case ItemType::SetState:
         return sizeof(downcast<SetState>(item));
     case ItemType::SetLineCap:
@@ -144,6 +148,10 @@
         return sizeof(downcast<FillRoundedRect>(item));
     case ItemType::FillRectWithRoundedHole:
         return sizeof(downcast<FillRectWithRoundedHole>(item));
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::FillInlinePath:
+        return sizeof(downcast<FillInlinePath>(item));
+#endif
     case ItemType::FillPath:
         return sizeof(downcast<FillPath>(item));
     case ItemType::FillEllipse:
@@ -154,6 +162,10 @@
         return sizeof(downcast<PaintFrameForMedia>(item));
     case ItemType::StrokeRect:
         return sizeof(downcast<StrokeRect>(item));
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::StrokeInlinePath:
+        return sizeof(downcast<StrokeInlinePath>(item));
+#endif
     case ItemType::StrokePath:
         return sizeof(downcast<StrokePath>(item));
     case ItemType::StrokeEllipse:
@@ -322,46 +334,127 @@
     return ts;
 }
 
-Ref<SetFillColor> SetFillColor::create(Color color)
+SetInlineFillGradient::SetInlineFillGradient(const Gradient& gradient)
+    : Item(ItemType::SetInlineFillGradient)
+    , m_data(gradient.data())
+    , m_gradientSpaceTransformation(gradient.gradientSpaceTransform())
+    , m_spreadMethod(gradient.spreadMethod())
+    , m_colorStopCount(static_cast<uint8_t>(gradient.stops().size()))
 {
-    return adoptRef(*new SetFillColor(color));
+    RELEASE_ASSERT(m_colorStopCount <= maxColorStopCount);
+    for (uint8_t i = 0; i < m_colorStopCount; ++i) {
+        m_offsets[i] = gradient.stops()[i].offset;
+        m_colors[i] = gradient.stops()[i].color.asInline();
+    }
 }
 
-SetFillColor::~SetFillColor() = default;
+Ref<Gradient> SetInlineFillGradient::gradient() const
+{
+    auto gradient = Gradient::create(Gradient::Data(m_data));
+    for (uint8_t i = 0; i < m_colorStopCount; ++i)
+        gradient->addColorStop({ m_offsets[i], Color(m_colors[i]) });
+    gradient->setSpreadMethod(m_spreadMethod);
+    gradient->setGradientSpaceTransform(m_gradientSpaceTransformation);
+    return gradient;
+}
 
-void SetFillColor::apply(GraphicsContext& context) const
+Ref<SetInlineFillGradient> SetInlineFillGradient::create(const Gradient& gradient)
 {
-    context.setFillColor(m_color);
+    return adoptRef(*new SetInlineFillGradient(gradient));
 }
 
-static TextStream& operator<<(TextStream& ts, const SetFillColor& state)
+SetInlineFillGradient::SetInlineFillGradient(float offsets[maxColorStopCount], SRGBA<uint8_t> colors[maxColorStopCount], const Gradient::Data& data, const AffineTransform& gradientSpaceTransformation, GradientSpreadMethod spreadMethod, uint8_t colorStopCount)
+    : Item(ItemType::SetInlineFillGradient)
+    , m_data(data)
+    , m_gradientSpaceTransformation(gradientSpaceTransformation)
+    , m_spreadMethod(spreadMethod)
+    , m_colorStopCount(colorStopCount)
 {
+    RELEASE_ASSERT(m_colorStopCount <= maxColorStopCount);
+    for (uint8_t i = 0; i < m_colorStopCount; ++i) {
+        m_offsets[i] = offsets[i];
+        m_colors[i] = colors[i];
+    }
+}
+
+SetInlineFillGradient::~SetInlineFillGradient() = default;
+
+void SetInlineFillGradient::apply(GraphicsContext& context) const
+{
+    if (m_colorStopCount <= maxColorStopCount)
+        context.setFillGradient(gradient());
+}
+
+bool SetInlineFillGradient::isInline(const Gradient& gradient)
+{
+    if (gradient.stops().size() > SetInlineFillGradient::maxColorStopCount)
+        return false;
+
+    for (auto& colorStop : gradient.stops()) {
+        if (!colorStop.color.isInline())
+            return false;
+    }
+
+    return true;
+}
+
+static TextStream& operator<<(TextStream& ts, const SetInlineFillGradient&)
+{
+    // FIXME: Dump gradient data.
+    return ts;
+}
+
+Ref<SetInlineFillColor> SetInlineFillColor::create(SRGBA<uint8_t> colorData)
+{
+    return adoptRef(*new SetInlineFillColor(colorData));
+}
+
+SetInlineFillColor::~SetInlineFillColor() = default;
+
+void SetInlineFillColor::apply(GraphicsContext& context) const
+{
+    context.setFillColor(color());
+}
+
+static TextStream& operator<<(TextStream& ts, const SetInlineFillColor& state)
+{
     ts.dumpProperty("color", state.color());
     return ts;
 }
 
-Ref<SetStrokeState> SetStrokeState::create(Optional<Color>&& color, Optional<float>&& thickness)
+Ref<SetInlineStrokeColor> SetInlineStrokeColor::create(SRGBA<uint8_t> colorData)
 {
-    return adoptRef(*new SetStrokeState(WTFMove(color), WTFMove(thickness)));
+    return adoptRef(*new SetInlineStrokeColor(colorData));
 }
 
-SetStrokeState::~SetStrokeState() = default;
+SetInlineStrokeColor::~SetInlineStrokeColor() = default;
 
-void SetStrokeState::apply(GraphicsContext& context) const
+void SetInlineStrokeColor::apply(GraphicsContext& context) const
 {
-    if (m_hasColor)
-        context.setStrokeColor(m_color);
+    context.setStrokeColor(color());
+}
 
-    if (m_hasThickness)
-        context.setStrokeThickness(m_thickness);
+static TextStream& operator<<(TextStream& ts, const SetInlineStrokeColor& state)
+{
+    ts.dumpProperty("color", state.color());
+    return ts;
 }
 
-static TextStream& operator<<(TextStream& ts, const SetStrokeState& state)
+Ref<SetStrokeThickness> SetStrokeThickness::create(float thickness)
 {
-    if (state.hasColor())
-        ts.dumpProperty("color", state.color());
-    if (state.hasThickness())
-        ts.dumpProperty("thickness", state.thickness());
+    return adoptRef(*new SetStrokeThickness(thickness));
+}
+
+SetStrokeThickness::~SetStrokeThickness() = default;
+
+void SetStrokeThickness::apply(GraphicsContext& context) const
+{
+    context.setStrokeThickness(m_thickness);
+}
+
+static TextStream& operator<<(TextStream& ts, const SetStrokeThickness& state)
+{
+    ts.dumpProperty("thickness", state.thickness());
     return ts;
 }
 
@@ -1193,6 +1286,30 @@
     return ts;
 }
 
+#if ENABLE(INLINE_PATH_DATA)
+
+FillInlinePath::FillInlinePath(const InlinePathData& pathData)
+    : DrawingItem(ItemType::FillInlinePath)
+    , m_pathData(pathData)
+{
+}
+
+FillInlinePath::~FillInlinePath() = default;
+
+void FillInlinePath::apply(GraphicsContext& context) const
+{
+    context.fillPath(path());
+}
+
+static TextStream& operator<<(TextStream& ts, const FillInlinePath& item)
+{
+    ts << static_cast<const DrawingItem&>(item);
+    ts.dumpProperty("path", item.path());
+    return ts;
+}
+
+#endif // ENABLE(INLINE_PATH_DATA)
+
 FillPath::FillPath(const Path& path)
     : DrawingItem(ItemType::FillPath)
     , m_path(path)
@@ -1204,7 +1321,6 @@
 void FillPath::apply(GraphicsContext& context) const
 {
     context.fillPath(m_path);
-    m_path.releasePlatformPathIfPossible();
 }
 
 static TextStream& operator<<(TextStream& ts, const FillPath& item)
@@ -1354,7 +1470,6 @@
 void StrokePath::apply(GraphicsContext& context) const
 {
     context.strokePath(m_path);
-    m_path.releasePlatformPathIfPossible();
 }
 
 static TextStream& operator<<(TextStream& ts, const StrokePath& item)
@@ -1393,6 +1508,40 @@
     return ts;
 }
 
+#if ENABLE(INLINE_PATH_DATA)
+
+Optional<FloatRect> StrokeInlinePath::localBounds(const GraphicsContext& context) const
+{
+    // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
+    float strokeThickness = context.strokeThickness();
+
+    FloatRect bounds = path().fastBoundingRect();
+    bounds.expand(strokeThickness, strokeThickness);
+    return bounds;
+}
+
+void StrokeInlinePath::apply(GraphicsContext& context) const
+{
+    context.strokePath(path());
+}
+
+static TextStream& operator<<(TextStream& ts, const StrokeInlinePath& item)
+{
+    ts << static_cast<const DrawingItem&>(item);
+    ts.dumpProperty("path", item.path());
+    return ts;
+}
+
+StrokeInlinePath::StrokeInlinePath(const InlinePathData& pathData)
+    : DrawingItem(ItemType::StrokeInlinePath)
+    , m_pathData(pathData)
+{
+}
+
+StrokeInlinePath::~StrokeInlinePath() = default;
+
+#endif // ENABLE(INLINE_PATH_DATA)
+
 StrokePath::StrokePath(const Path& path)
     : DrawingItem(ItemType::StrokePath)
     , m_path(path)
@@ -1508,8 +1657,10 @@
     case ItemType::Scale: ts << "scale"; break;
     case ItemType::SetCTM: ts << "set-ctm"; break;
     case ItemType::ConcatenateCTM: ts << "concatentate-ctm"; break;
-    case ItemType::SetFillColor: ts << "set-fill-color"; break;
-    case ItemType::SetStrokeState: ts << "set-stroke-state"; break;
+    case ItemType::SetInlineFillGradient: ts << "set-inline-fill-gradient"; break;
+    case ItemType::SetInlineFillColor: ts << "set-inline-fill-color"; break;
+    case ItemType::SetInlineStrokeColor: ts << "set-inline-stroke-color"; break;
+    case ItemType::SetStrokeThickness: ts << "set-stroke-thickness"; break;
     case ItemType::SetState: ts << "set-state"; break;
     case ItemType::SetLineCap: ts << "set-line-cap"; break;
     case ItemType::SetLineDash: ts << "set-line-dash"; break;
@@ -1541,11 +1692,17 @@
     case ItemType::FillCompositedRect: ts << "fill-composited-rect"; break;
     case ItemType::FillRoundedRect: ts << "fill-rounded-rect"; break;
     case ItemType::FillRectWithRoundedHole: ts << "fill-rect-with-rounded-hole"; break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::FillInlinePath: ts << "fill-inline-path"; break;
+#endif
     case ItemType::FillPath: ts << "fill-path"; break;
     case ItemType::FillEllipse: ts << "fill-ellipse"; break;
     case ItemType::PutImageData: ts << "put-image-data"; break;
     case ItemType::PaintFrameForMedia: ts << "paint-frame-for-media"; break;
     case ItemType::StrokeRect: ts << "stroke-rect"; break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::StrokeInlinePath: ts << "stroke-inline-path"; break;
+#endif
     case ItemType::StrokePath: ts << "stroke-path"; break;
     case ItemType::StrokeEllipse: ts << "stroke-ellipse"; break;
     case ItemType::ClearRect: ts << "clear-rect"; break;
@@ -1583,12 +1740,18 @@
     case ItemType::ConcatenateCTM:
         ts << downcast<ConcatenateCTM>(item);
         break;
-    case ItemType::SetFillColor:
-        ts << downcast<SetFillColor>(item);
+    case ItemType::SetInlineFillGradient:
+        ts << downcast<SetInlineFillGradient>(item);
         break;
-    case ItemType::SetStrokeState:
-        ts << downcast<SetStrokeState>(item);
+    case ItemType::SetInlineFillColor:
+        ts << downcast<SetInlineFillColor>(item);
         break;
+    case ItemType::SetInlineStrokeColor:
+        ts << downcast<SetInlineStrokeColor>(item);
+        break;
+    case ItemType::SetStrokeThickness:
+        ts << downcast<SetStrokeThickness>(item);
+        break;
     case ItemType::SetState:
         ts << downcast<SetState>(item);
         break;
@@ -1682,6 +1845,11 @@
     case ItemType::FillRectWithRoundedHole:
         ts << downcast<FillRectWithRoundedHole>(item);
         break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::FillInlinePath:
+        ts << downcast<FillInlinePath>(item);
+        break;
+#endif
     case ItemType::FillPath:
         ts << downcast<FillPath>(item);
         break;
@@ -1697,6 +1865,11 @@
     case ItemType::StrokeRect:
         ts << downcast<StrokeRect>(item);
         break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::StrokeInlinePath:
+        ts << downcast<StrokeInlinePath>(item);
+        break;
+#endif
     case ItemType::StrokePath:
         ts << downcast<StrokePath>(item);
         break;

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2020-10-28 02:09:17 UTC (rev 269092)
@@ -337,121 +337,221 @@
     return ConcatenateCTM::create(*transform);
 }
 
-class SetFillColor : public Item {
+class SetInlineFillGradient : public Item {
 public:
-    WEBCORE_EXPORT static Ref<SetFillColor> create(Color);
+    static constexpr uint8_t maxColorStopCount = 4;
 
-    WEBCORE_EXPORT virtual ~SetFillColor();
+    static Ref<SetInlineFillGradient> create(const Gradient&);
+    static bool isInline(const Gradient&);
 
-    Color color() const { return m_color; }
+    virtual ~SetInlineFillGradient();
 
+    Ref<Gradient> gradient() const;
+
     template<class Encoder> void encode(Encoder&) const;
-    template<class Decoder> static Optional<Ref<SetFillColor>> decode(Decoder&);
+    template<class Decoder> static Optional<Ref<SetInlineFillGradient>> decode(Decoder&);
 
 private:
-    SetFillColor(Color color)
-        : Item(ItemType::SetFillColor)
-        , m_color(color)
+    static Ref<SetInlineFillGradient> create(float offsets[maxColorStopCount], SRGBA<uint8_t> colors[maxColorStopCount],
+        const Gradient::Data& data, const AffineTransform& gradientSpaceTransformation, GradientSpreadMethod spreadMethod, uint8_t colorStopCount)
     {
+        return adoptRef(*new SetInlineFillGradient(offsets, colors, data, gradientSpaceTransformation, spreadMethod, colorStopCount));
     }
 
+    WEBCORE_EXPORT SetInlineFillGradient(float offsets[maxColorStopCount], SRGBA<uint8_t> colors[maxColorStopCount], const Gradient::Data&,
+        const AffineTransform& gradientSpaceTransformation, GradientSpreadMethod, uint8_t colorStopCount);
+
+    SetInlineFillGradient(const Gradient&);
+
     void apply(GraphicsContext&) const override;
 
-    Color m_color;
+    float m_offsets[maxColorStopCount];
+    SRGBA<uint8_t> m_colors[maxColorStopCount];
+    Gradient::Data m_data;
+    AffineTransform m_gradientSpaceTransformation;
+    GradientSpreadMethod m_spreadMethod { GradientSpreadMethod::Pad };
+    uint8_t m_colorStopCount { 0 };
 };
 
 template<class Encoder>
-void SetFillColor::encode(Encoder& encoder) const
+void SetInlineFillGradient::encode(Encoder& encoder) const
 {
-    encoder << m_color;
+    encoder << m_colorStopCount;
+    for (uint8_t i = 0; i < m_colorStopCount; ++i) {
+        encoder << m_offsets[i];
+        encoder << PackedColor::RGBA { m_colors[i] }.value;
+    }
+    encoder << m_data;
+    encoder << m_gradientSpaceTransformation;
+    encoder << m_spreadMethod;
 }
 
 template<class Decoder>
-Optional<Ref<SetFillColor>> SetFillColor::decode(Decoder& decoder)
+Optional<Ref<SetInlineFillGradient>> SetInlineFillGradient::decode(Decoder& decoder)
 {
-    Optional<Color> color;
-    decoder >> color;
-    if (!color)
+    Optional<uint8_t> colorStopCount;
+    decoder >> colorStopCount;
+    if (!colorStopCount)
         return WTF::nullopt;
 
-    return SetFillColor::create(*color);
+    if (*colorStopCount > maxColorStopCount)
+        return WTF::nullopt;
+
+    float offsets[maxColorStopCount];
+    SRGBA<uint8_t> colors[maxColorStopCount];
+    for (uint8_t i = 0; i < *colorStopCount; ++i) {
+        Optional<float> offset;
+        decoder >> offset;
+        if (!offset)
+            return WTF::nullopt;
+
+        Optional<uint32_t> color;
+        decoder >> color;
+        if (!color)
+            return WTF::nullopt;
+
+        colors[i] = asSRGBA(PackedColor::RGBA { *color });
+        offsets[i] = *offset;
+    }
+
+    Optional<Gradient::Data> data;
+    decoder >> data;
+    if (!data)
+        return WTF::nullopt;
+
+    Optional<AffineTransform> gradientSpaceTransformation;
+    decoder >> gradientSpaceTransformation;
+    if (!gradientSpaceTransformation)
+        return WTF::nullopt;
+
+    Optional<GradientSpreadMethod> spreadMethod;
+    decoder >> spreadMethod;
+    if (!spreadMethod)
+        return WTF::nullopt;
+
+    return { SetInlineFillGradient::create(offsets, colors, *data, *gradientSpaceTransformation, *spreadMethod, *colorStopCount) };
 }
 
-class SetStrokeState : public Item {
+class SetInlineFillColor : public Item {
 public:
-    WEBCORE_EXPORT static Ref<SetStrokeState> create(Optional<Color>&&, Optional<float>&& thickness);
+    WEBCORE_EXPORT static Ref<SetInlineFillColor> create(SRGBA<uint8_t>);
 
-    WEBCORE_EXPORT virtual ~SetStrokeState();
+    WEBCORE_EXPORT virtual ~SetInlineFillColor();
 
-    Color color() const { return m_color; }
-    bool hasColor() const { return m_hasColor; }
+    Color color() const { return { m_colorData }; }
 
-    float thickness() const { return m_thickness; }
-    bool hasThickness() const { return m_hasThickness; }
-
     template<class Encoder> void encode(Encoder&) const;
-    template<class Decoder> static Optional<Ref<SetStrokeState>> decode(Decoder&);
+    template<class Decoder> static Optional<Ref<SetInlineFillColor>> decode(Decoder&);
 
 private:
-    SetStrokeState(Optional<Color>&& color, Optional<float>&& thickness)
-        : Item(ItemType::SetStrokeState)
-        , m_color(color.valueOr(Color()))
-        , m_thickness(thickness.valueOr(0))
-        , m_hasColor(color.hasValue())
-        , m_hasThickness(thickness.hasValue())
+    SetInlineFillColor(SRGBA<uint8_t> colorData)
+        : Item(ItemType::SetInlineFillColor)
+        , m_colorData(colorData)
     {
     }
 
     void apply(GraphicsContext&) const override;
 
-    Color m_color;
-    float m_thickness { 0 };
-    bool m_hasColor { false };
-    bool m_hasThickness { false };
+    SRGBA<uint8_t> m_colorData;
 };
 
 template<class Encoder>
-void SetStrokeState::encode(Encoder& encoder) const
+void SetInlineFillColor::encode(Encoder& encoder) const
 {
-    encoder << m_hasColor;
-    if (m_hasColor)
-        encoder << m_color;
-
-    encoder << m_hasThickness;
-    if (m_hasThickness)
-        encoder << m_thickness;
+    encoder << PackedColor::RGBA { m_colorData }.value;
 }
 
 template<class Decoder>
-Optional<Ref<SetStrokeState>> SetStrokeState::decode(Decoder& decoder)
+Optional<Ref<SetInlineFillColor>> SetInlineFillColor::decode(Decoder& decoder)
 {
-    Optional<bool> hasColor;
-    decoder >> hasColor;
-    if (!hasColor)
+    Optional<uint32_t> value;
+    decoder >> value;
+    if (!value)
         return WTF::nullopt;
 
-    Optional<Color> color;
-    if (*hasColor) {
-        decoder >> color;
-        if (!color)
-            return WTF::nullopt;
+    return SetInlineFillColor::create(asSRGBA(PackedColor::RGBA { *value }));
+}
+
+class SetInlineStrokeColor : public Item {
+public:
+    WEBCORE_EXPORT static Ref<SetInlineStrokeColor> create(SRGBA<uint8_t>);
+
+    WEBCORE_EXPORT virtual ~SetInlineStrokeColor();
+
+    Color color() const { return { m_colorData }; }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static Optional<Ref<SetInlineStrokeColor>> decode(Decoder&);
+
+private:
+    SetInlineStrokeColor(SRGBA<uint8_t> colorData)
+        : Item(ItemType::SetInlineStrokeColor)
+        , m_colorData(colorData)
+    {
     }
 
-    Optional<bool> hasThickness;
-    decoder >> hasThickness;
-    if (!hasThickness)
+    void apply(GraphicsContext&) const override;
+
+    SRGBA<uint8_t> m_colorData;
+};
+
+template<class Encoder>
+void SetInlineStrokeColor::encode(Encoder& encoder) const
+{
+    encoder << PackedColor::RGBA { m_colorData }.value;
+}
+
+template<class Decoder>
+Optional<Ref<SetInlineStrokeColor>> SetInlineStrokeColor::decode(Decoder& decoder)
+{
+    Optional<uint32_t> value;
+    decoder >> value;
+    if (!value)
         return WTF::nullopt;
 
-    Optional<float> thickness;
-    if (*hasThickness) {
-        decoder >> thickness;
-        if (!thickness)
-            return WTF::nullopt;
+    return SetInlineStrokeColor::create(asSRGBA(PackedColor::RGBA { *value }));
+}
+
+class SetStrokeThickness : public Item {
+public:
+    WEBCORE_EXPORT static Ref<SetStrokeThickness> create(float thickness);
+
+    WEBCORE_EXPORT virtual ~SetStrokeThickness();
+
+    float thickness() const { return m_thickness; }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static Optional<Ref<SetStrokeThickness>> decode(Decoder&);
+
+private:
+    SetStrokeThickness(float thickness)
+        : Item(ItemType::SetStrokeThickness)
+        , m_thickness(thickness)
+    {
     }
 
-    return SetStrokeState::create(WTFMove(color), WTFMove(thickness));
+    void apply(GraphicsContext&) const override;
+
+    float m_thickness { 0 };
+};
+
+template<class Encoder>
+void SetStrokeThickness::encode(Encoder& encoder) const
+{
+    encoder << m_thickness;
 }
 
+template<class Decoder>
+Optional<Ref<SetStrokeThickness>> SetStrokeThickness::decode(Decoder& decoder)
+{
+    Optional<float> thickness;
+    decoder >> thickness;
+    if (!thickness)
+        return WTF::nullopt;
+
+    return SetStrokeThickness::create(*thickness);
+}
+
 class SetState : public Item {
 public:
     static Ref<SetState> create(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
@@ -2577,6 +2677,50 @@
     return FillRectWithRoundedHole::create(*rect, *roundedHoleRect, *color);
 }
 
+#if ENABLE(INLINE_PATH_DATA)
+
+class FillInlinePath : public DrawingItem {
+public:
+    static Ref<FillInlinePath> create(const InlinePathData& pathData)
+    {
+        return adoptRef(*new FillInlinePath(pathData));
+    }
+
+    WEBCORE_EXPORT virtual ~FillInlinePath();
+
+    Path path() const { return Path::from(m_pathData); }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static Optional<Ref<FillInlinePath>> decode(Decoder&);
+
+private:
+    WEBCORE_EXPORT FillInlinePath(const InlinePathData&);
+
+    void apply(GraphicsContext&) const override;
+    Optional<FloatRect> localBounds(const GraphicsContext&) const override { return path().fastBoundingRect(); }
+
+    InlinePathData m_pathData;
+};
+
+template<class Encoder>
+void FillInlinePath::encode(Encoder& encoder) const
+{
+    encoder << m_pathData;
+}
+
+template<class Decoder>
+Optional<Ref<FillInlinePath>> FillInlinePath::decode(Decoder& decoder)
+{
+    Optional<InlinePathData> pathData;
+    decoder >> pathData;
+    if (!pathData)
+        return WTF::nullopt;
+
+    return FillInlinePath::create(WTFMove(*pathData));
+}
+
+#endif // ENABLE(INLINE_PATH_DATA)
+
 class FillPath : public DrawingItem {
 public:
     static Ref<FillPath> create(const Path& path)
@@ -2832,6 +2976,50 @@
     return StrokeRect::create(*rect, *lineWidth);
 }
 
+#if ENABLE(INLINE_PATH_DATA)
+
+class StrokeInlinePath : public DrawingItem {
+public:
+    static Ref<StrokeInlinePath> create(const InlinePathData& pathData)
+    {
+        return adoptRef(*new StrokeInlinePath(pathData));
+    }
+
+    WEBCORE_EXPORT virtual ~StrokeInlinePath();
+
+    Path path() const { return Path::from(m_pathData); }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static Optional<Ref<StrokeInlinePath>> decode(Decoder&);
+
+private:
+    WEBCORE_EXPORT StrokeInlinePath(const InlinePathData&);
+
+    void apply(GraphicsContext&) const override;
+    Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+    InlinePathData m_pathData;
+};
+
+template<class Encoder>
+void StrokeInlinePath::encode(Encoder& encoder) const
+{
+    encoder << m_pathData;
+}
+
+template<class Decoder>
+Optional<Ref<StrokeInlinePath>> StrokeInlinePath::decode(Decoder& decoder)
+{
+    Optional<InlinePathData> pathData;
+    decoder >> pathData;
+    if (!pathData)
+        return WTF::nullopt;
+
+    return StrokeInlinePath::create(WTFMove(*pathData));
+}
+
+#endif // ENABLE(INLINE_PATH_DATA)
+
 class StrokePath : public DrawingItem {
 public:
     static Ref<StrokePath> create(const Path& path)
@@ -3081,12 +3269,18 @@
     case ItemType::ConcatenateCTM:
         encoder << downcast<ConcatenateCTM>(*this);
         break;
-    case ItemType::SetFillColor:
-        encoder << downcast<SetFillColor>(*this);
+    case ItemType::SetInlineFillGradient:
+        encoder << downcast<SetInlineFillGradient>(*this);
         break;
-    case ItemType::SetStrokeState:
-        encoder << downcast<SetStrokeState>(*this);
+    case ItemType::SetInlineFillColor:
+        encoder << downcast<SetInlineFillColor>(*this);
         break;
+    case ItemType::SetInlineStrokeColor:
+        encoder << downcast<SetInlineStrokeColor>(*this);
+        break;
+    case ItemType::SetStrokeThickness:
+        encoder << downcast<SetStrokeThickness>(*this);
+        break;
     case ItemType::SetState:
         encoder << downcast<SetState>(*this);
         break;
@@ -3183,6 +3377,11 @@
     case ItemType::FillRectWithRoundedHole:
         encoder << downcast<FillRectWithRoundedHole>(*this);
         break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::FillInlinePath:
+        encoder << downcast<FillInlinePath>(*this);
+        break;
+#endif
     case ItemType::FillPath:
         encoder << downcast<FillPath>(*this);
         break;
@@ -3198,6 +3397,11 @@
     case ItemType::StrokeRect:
         encoder << downcast<StrokeRect>(*this);
         break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::StrokeInlinePath:
+        encoder << downcast<StrokeInlinePath>(*this);
+        break;
+#endif
     case ItemType::StrokePath:
         encoder << downcast<StrokePath>(*this);
         break;
@@ -3264,14 +3468,23 @@
         if (auto item = ConcatenateCTM::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
         break;
-    case ItemType::SetFillColor:
-        if (auto item = SetFillColor::decode(decoder))
+    case ItemType::SetInlineFillGradient: {
+        if (auto item = SetInlineFillGradient::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
         break;
-    case ItemType::SetStrokeState:
-        if (auto item = SetStrokeState::decode(decoder))
+    }
+    case ItemType::SetInlineFillColor:
+        if (auto item = SetInlineFillColor::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
         break;
+    case ItemType::SetInlineStrokeColor:
+        if (auto item = SetInlineStrokeColor::decode(decoder))
+            return static_reference_cast<Item>(WTFMove(*item));
+        break;
+    case ItemType::SetStrokeThickness:
+        if (auto item = SetStrokeThickness::decode(decoder))
+            return static_reference_cast<Item>(WTFMove(*item));
+        break;
     case ItemType::SetState:
         if (auto item = SetState::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
@@ -3400,6 +3613,12 @@
         if (auto item = FillRectWithRoundedHole::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
         break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::FillInlinePath:
+        if (auto item = FillInlinePath::decode(decoder))
+            return static_reference_cast<Item>(WTFMove(*item));
+        break;
+#endif
     case ItemType::FillPath:
         if (auto item = FillPath::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
@@ -3420,6 +3639,12 @@
         if (auto item = StrokeRect::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
         break;
+#if ENABLE(INLINE_PATH_DATA)
+    case ItemType::StrokeInlinePath:
+        if (auto item = StrokeInlinePath::decode(decoder))
+            return static_reference_cast<Item>(WTFMove(*item));
+        break;
+#endif
     case ItemType::StrokePath:
         if (auto item = StrokePath::decode(decoder))
             return static_reference_cast<Item>(WTFMove(*item));
@@ -3482,8 +3707,10 @@
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Scale)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetCTM)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ConcatenateCTM)
-SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetFillColor)
-SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetStrokeState)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetInlineFillGradient)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetInlineFillColor)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetInlineStrokeColor)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetStrokeThickness)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetState)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineCap)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineDash)
@@ -3515,11 +3742,17 @@
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillCompositedRect)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRoundedRect)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithRoundedHole)
+#if ENABLE(INLINE_PATH_DATA)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillInlinePath)
+#endif
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillPath)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillEllipse)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(PutImageData)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(PaintFrameForMedia)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeRect)
+#if ENABLE(INLINE_PATH_DATA)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeInlinePath)
+#endif
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokePath)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeEllipse)
 SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearRect)
@@ -3544,8 +3777,10 @@
     WebCore::DisplayList::ItemType::Scale,
     WebCore::DisplayList::ItemType::SetCTM,
     WebCore::DisplayList::ItemType::ConcatenateCTM,
-    WebCore::DisplayList::ItemType::SetFillColor,
-    WebCore::DisplayList::ItemType::SetStrokeState,
+    WebCore::DisplayList::ItemType::SetInlineFillGradient,
+    WebCore::DisplayList::ItemType::SetInlineFillColor,
+    WebCore::DisplayList::ItemType::SetInlineStrokeColor,
+    WebCore::DisplayList::ItemType::SetStrokeThickness,
     WebCore::DisplayList::ItemType::SetState,
     WebCore::DisplayList::ItemType::SetLineCap,
     WebCore::DisplayList::ItemType::SetLineDash,
@@ -3578,11 +3813,17 @@
     WebCore::DisplayList::ItemType::FillCompositedRect,
     WebCore::DisplayList::ItemType::FillRoundedRect,
     WebCore::DisplayList::ItemType::FillRectWithRoundedHole,
+#if ENABLE(INLINE_PATH_DATA)
+    WebCore::DisplayList::ItemType::FillInlinePath,
+#endif
     WebCore::DisplayList::ItemType::FillPath,
     WebCore::DisplayList::ItemType::FillEllipse,
     WebCore::DisplayList::ItemType::PutImageData,
     WebCore::DisplayList::ItemType::PaintFrameForMedia,
     WebCore::DisplayList::ItemType::StrokeRect,
+#if ENABLE(INLINE_PATH_DATA)
+    WebCore::DisplayList::ItemType::StrokeInlinePath,
+#endif
     WebCore::DisplayList::ItemType::StrokePath,
     WebCore::DisplayList::ItemType::StrokeEllipse,
     WebCore::DisplayList::ItemType::ClearRect,

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp (269091 => 269092)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2020-10-28 02:09:17 UTC (rev 269092)
@@ -58,38 +58,49 @@
     appendItem(WebCore::DisplayList::PutImageData::create(inputFormat, imageData, srcRect, destPoint, destFormat));
 }
 
-static bool containsOnlyStrokeColorOrThicknessChange(GraphicsContextState::StateChangeFlags changes)
+static bool containsOnlyInlineStateChanges(const GraphicsContextStateChange& changes, GraphicsContextState::StateChangeFlags changeFlags)
 {
-    static constexpr GraphicsContextState::StateChangeFlags strokeStateChangeFlags {
+    static constexpr GraphicsContextState::StateChangeFlags inlineStateChangeFlags {
         GraphicsContextState::StrokeThicknessChange,
-        GraphicsContextState::StrokeColorChange
+        GraphicsContextState::StrokeColorChange,
+        GraphicsContextState::FillColorChange,
+        GraphicsContextState::FillGradientChange,
     };
-    return changes == (changes & strokeStateChangeFlags);
-}
 
-static bool containsOnlyFillColorChange(GraphicsContextState::StateChangeFlags changes)
-{
-    return changes == (changes & GraphicsContextState::FillColorChange);
+    if (changeFlags != (changeFlags & inlineStateChangeFlags))
+        return false;
+
+    if (changeFlags.contains(GraphicsContextState::StrokeColorChange) && !changes.m_state.strokeColor.isInline())
+        return false;
+
+    if (changeFlags.contains(GraphicsContextState::FillColorChange) && !changes.m_state.fillColor.isInline())
+        return false;
+
+    if (changeFlags.contains(GraphicsContextState::FillGradientChange)
+        && (!changes.m_state.fillGradient || !SetInlineFillGradient::isInline(*changes.m_state.fillGradient)))
+        return false;
+
+    return true;
 }
 
-static Ref<Item> createStateChangeItem(const GraphicsContextStateChange& changes, GraphicsContextState::StateChangeFlags changeFlags)
+void Recorder::appendStateChangeItem(const GraphicsContextStateChange& changes, GraphicsContextState::StateChangeFlags changeFlags)
 {
-    if (containsOnlyFillColorChange(changeFlags))
-        return SetFillColor::create(changes.m_state.fillColor);
+    if (!containsOnlyInlineStateChanges(changes, changeFlags)) {
+        m_displayList.appendItem(SetState::create(changes.m_state, changeFlags));
+        return;
+    }
 
-    if (containsOnlyStrokeColorOrThicknessChange(changeFlags)) {
-        Optional<Color> strokeColor;
-        if (changeFlags.contains(GraphicsContextState::StrokeColorChange))
-            strokeColor = changes.m_state.strokeColor;
+    if (changeFlags.contains(GraphicsContextState::StrokeColorChange))
+        m_displayList.appendItem(SetInlineStrokeColor::create(changes.m_state.strokeColor.asInline()));
 
-        Optional<float> strokeThickness;
-        if (changeFlags.contains(GraphicsContextState::StrokeThicknessChange))
-            strokeThickness = changes.m_state.strokeThickness;
+    if (changeFlags.contains(GraphicsContextState::StrokeThicknessChange))
+        m_displayList.appendItem(SetStrokeThickness::create(changes.m_state.strokeThickness));
 
-        return SetStrokeState::create(WTFMove(strokeColor), WTFMove(strokeThickness));
-    }
+    if (changeFlags.contains(GraphicsContextState::FillColorChange))
+        m_displayList.appendItem(SetInlineFillColor::create(changes.m_state.fillColor.asInline()));
 
-    return SetState::create(changes.m_state, changeFlags);
+    if (changeFlags.contains(GraphicsContextState::FillGradientChange))
+        m_displayList.appendItem(SetInlineFillGradient::create(*changes.m_state.fillGradient));
 }
 
 void Recorder::willAppendItem(const Item& item)
@@ -106,7 +117,7 @@
         GraphicsContextState::StateChangeFlags changesFromLastState = stateChanges.changesFromState(currentState().lastDrawingState);
         if (changesFromLastState) {
             LOG_WITH_STREAM(DisplayLists, stream << "pre-drawing, saving state " << GraphicsContextStateChange(stateChanges.m_state, changesFromLastState));
-            m_displayList.append(createStateChangeItem(stateChanges, changesFromLastState));
+            appendStateChangeItem(stateChanges, changesFromLastState);
             stateChanges.m_changeFlags = { };
             currentState().lastDrawingState = stateChanges.m_state;
         }
@@ -324,6 +335,12 @@
 
 void Recorder::fillPath(const Path& path)
 {
+#if ENABLE(INLINE_PATH_DATA)
+    if (path.hasInlineData()) {
+        appendItemAndUpdateExtent(FillInlinePath::create(path.inlineData()));
+        return;
+    }
+#endif
     appendItemAndUpdateExtent(FillPath::create(path));
 }
 
@@ -339,6 +356,12 @@
 
 void Recorder::strokePath(const Path& path)
 {
+#if ENABLE(INLINE_PATH_DATA)
+    if (path.hasInlineData()) {
+        appendItemAndUpdateExtent(StrokeInlinePath::create(path.inlineData()));
+        return;
+    }
+#endif
     appendItemAndUpdateExtent(StrokePath::create(path));
 }
 

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2020-10-28 01:49:53 UTC (rev 269091)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2020-10-28 02:09:17 UTC (rev 269092)
@@ -151,6 +151,8 @@
     ItemType& appendItem(Ref<ItemType>&&);
     void willAppendItem(const Item&);
 
+    void appendStateChangeItem(const GraphicsContextStateChange&, GraphicsContextState::StateChangeFlags);
+
     FloatRect extentFromLocalBounds(const FloatRect&) const;
     void updateItemExtent(DrawingItem&) const;
     
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to