⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 258118 in webkit


Ignore:
Timestamp:
Mar 8, 2020, 4:13:45 PM (6 years ago)
Author:
Wenson Hsieh
Message:

Lazily generate CGPaths for some simple types of paths, such as arcs and lines
https://bugs.webkit.org/show_bug.cgi?id=208464
<rdar://problem/59963226>

Reviewed by Daniel Bates, Darin Adler and Tim Horton.

Source/WebCore:

When the GPU process is enabled and used to render the canvas element, some canvas-related subtests in
MotionMark see significant performance regressions. One of the reasons for this is that in the process of
decoding display list items that contain WebCore::Paths in the GPU process, we end up allocating a new CGPath
for each WebCore::Path. This dramatically increases page demand and memory usage in the GPU process in contrast
to shipping WebKit, due to the fact that all of these CGPaths allocated up-front, and must all exist somewhere
in the heap upon decoding the display list.

In contrast, in shipping WebKit, each call to stroke the current canvas path (i.e. invoking
GraphicsContext::strokePath) is succeeded by clearing the path, which deallocates the CGPath backing the WebCore
Path. The next time a CGPath needs to be created, CoreGraphics is free to then allocate the new CGPath at the
address of the previous CGPath which was just destroyed, which prevents us from dirtying more pages than
necessary. This phenomenon affects most of the canvas-related MotionMark subtests to some degree, though the
impact is most noticeable with Canvas Lines.

On top of all this, a significant portion of time is also spent calling CGPathApply and converting the resulting
CGPathElements into serializable data when encoding each WebCore Path.

To mitigate these two issues and restore the wins we get from memory locality when drawing paths in large
quantities, we can:

  1. In the case of simple paths, stuff some information about how each path was created as inline data on

WebCore::Path itself, as a new data member. For now, this only encompasses lines, arcs, and moves (Paths
where only Path::moveTo was invoked), but may be expanded in the future to include ellipses and rects.
This allows us to achieve two things: (a) make encoding cheaper by not requiring a walk through all of
CGPath's elements, and (b) make decoding cheaper by just initializing the Path using inline data, rather
than having to create a new CGPath.

  1. When painting the StrokePath display list item, just discard m_path after we're done painting with it.

This, in conjunction with (1), means that the CGPath backing the WebCore::Path in the GPU process is only
created when we're just about to paint (i.e. when calling into strokePath()), and destroyed right after
we're done painting with it.

See below for details. There should be no change in behavior.

  • Headers.cmake:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/InlinePathData.h: Added.

(WebCore::MoveData::encode const):
(WebCore::MoveData::decode):
(WebCore::LineData::encode const):
(WebCore::LineData::decode):
(WebCore::ArcData::encode const):
(WebCore::ArcData::decode):

Introduce InlinePathData, a Variant of several different inline data types, each of which represents one simple
path type that is stored using only inline data. This includes line segments (a start point and an end point),
as well as arcs (which, in addition to a center and start and end angles) also includes an optional offset,
which represents the current position of the path at the time "addArc" was called.

For instance, in the following scenario, the path would have an arc that is offset by (100, 0); if filled, it
would result in a composite shape resembling a semicircle on top of a triangle:

path.moveTo(100, 0);
path.addArc(100, 100, 50, 0, PI, false);
context.fill(path);

When a Path is initialized (or after it is cleared), it starts off with neither a CGPath nor inline data. Moving
the path causes it to store inline MoveData; calling calling addLineTo or addArc then replaces the inline
data with either LineData or ArcData.

If, at any point, the path changes in a different way (i.e. neither line, arc, nor move), we clear out the
inline data and fall back to just representing the path data using the CGPath (m_path).

  • platform/graphics/Path.cpp:

Refactor the following 10 methods: moveTo, addLineTo, addArc, isEmpty, currentPoint, apply, elementCount,
hasCurrentPoint, fastBoundingRect, and boundingRect such that their implementations are now in platform-agnostic
code in Path.cpp. Logic in this platform-agnostic code will generally attempt to use inline path data to compute
an answer (or apply the requested mutations) without having to initialize the platform path representation.
Failing this, we fall back to calling -SlowCase versions of these methods, which will exercise the appropriate
APIs on each platform.

(WebCore::Path::elementCountSlowCase const):
(WebCore::Path::apply const):
(WebCore::Path::isEmpty const):
(WebCore::Path::hasCurrentPoint const):
(WebCore::Path::currentPoint const):
(WebCore::Path::elementCount const):
(WebCore::Path::addArc):
(WebCore::Path::addLineTo):
(WebCore::Path::moveTo):

In the case of these three methods for mutating a path, if we've either only moved the path or haven't touched
it at all, we can get away with only updating our inline path data, and avoid creating a CGPath.

(WebCore::Path::boundingRect const):
(WebCore::Path::fastBoundingRect const):
(WebCore::Path::boundingRectFromInlineData const):
(WebCore::Path::polygonPathFromPoints):

  • platform/graphics/Path.h:

(WebCore::Path::encode const):
(WebCore::Path::decode):

Teach Path::encode and Path::decode to respectively serialize and deserialize WebCore::Path by consulting only
the inline data, if it is present. For simple types of paths, this decreases the cost of both IPC encoding and
decoding, but adds a negligible amount of overhead in the case where the path is non-inline.

(WebCore::Path::hasInlineData const):
(WebCore::Path::hasAnyInlineData const):
(WebCore::Path::isNull const): Deleted.

  • platform/graphics/cairo/PathCairo.cpp:

(WebCore::Path::isEmptySlowCase const):
(WebCore::Path::currentPointSlowCase const):
(WebCore::Path::moveToSlowCase):
(WebCore::Path::addLineToSlowCase):
(WebCore::Path::addArcSlowCase):
(WebCore::Path::boundingRectSlowCase const):
(WebCore::Path::applySlowCase const):
(WebCore::Path::fastBoundingRectSlowCase const):
(WebCore::Path::isNull const):
(WebCore::Path::isEmpty const): Deleted.
(WebCore::Path::hasCurrentPoint const): Deleted.
(WebCore::Path::currentPoint const): Deleted.
(WebCore::Path::moveTo): Deleted.
(WebCore::Path::addLineTo): Deleted.
(WebCore::Path::addArc): Deleted.
(WebCore::Path::boundingRect const): Deleted.
(WebCore::Path::apply const): Deleted.

  • platform/graphics/cg/PathCG.cpp:

(WebCore::Path::createCGPath const):

Add a helper method that is invoked when the Path is asked for a CGPath. In this case, if there is inline data,
we need to lazily create the path and apply any inline path data we've accumulated. Once we're done applying the
inline data, set a flag (m_needsToApplyInlineData) to false to avoid re-applying inline data to the path.

(WebCore::Path::platformPath const):
(WebCore::Path::ensurePlatformPath):

When ensurePlatformPath is invoked, we are about to mutate our CGPath in such a way that it can't be expressed
in terms of inline data (at least, not with the changes in this patch). Clear out the inline path data in this
case, and apply the CGPath mutations that were previously stashed away in inline path data.

(WebCore::Path::isNull const):

A path is now considered null if it is not only missing a CGPath, but also does not have any inline path data.
This maintains the invariant that isNull() is true iff the platformPath() returns 0x0.

(WebCore::Path::Path):
(WebCore::Path::swap):

Update the constructors and swap helper method (used by assignment operators) to account for the new members.

(WebCore::Path::contains const):
(WebCore::Path::transform):
(WebCore::zeroRectIfNull):
(WebCore::Path::boundingRectSlowCase const):
(WebCore::Path::fastBoundingRectSlowCase const):
(WebCore::Path::moveToSlowCase):
(WebCore::Path::addLineToSlowCase):
(WebCore::Path::addArcSlowCase):
(WebCore::Path::clear):

When clearing Path, instead of setting m_path to a newly allocated CGPath, simply reset it to null. This
ensures that if we then apply some changes that can be expressed using only inline path data, we avoid having to
update the CGPath, and instead just update the inline path data.

(WebCore::Path::isEmptySlowCase const):
(WebCore::Path::currentPointSlowCase const):
(WebCore::Path::applySlowCase const):
(WebCore::Path::elementCountSlowCase const):
(WebCore::Path::boundingRect const): Deleted.
(WebCore::Path::fastBoundingRect const): Deleted.
(WebCore::Path::moveTo): Deleted.
(WebCore::Path::addLineTo): Deleted.
(WebCore::Path::addArc): Deleted.
(WebCore::Path::isEmpty const): Deleted.
(WebCore::Path::hasCurrentPoint const): Deleted.
(WebCore::Path::currentPoint const): Deleted.
(WebCore::Path::apply const): Deleted.
(WebCore::Path::elementCount const): Deleted.

  • platform/graphics/displaylists/DisplayListItems.cpp:

(WebCore::DisplayList::StrokePath::apply const):

Throw out the current WebCore::Path after we're done painting with it (see (2) in the above ChangeLog entry).

  • platform/graphics/displaylists/DisplayListItems.h:
  • platform/graphics/win/PathDirect2D.cpp:

(WebCore::Path::boundingRectSlowCase const):
(WebCore::Path::fastBoundingRectSlowCase const):
(WebCore::Path::moveToSlowCase):
(WebCore::Path::addLineToSlowCase):
(WebCore::Path::addArcSlowCase):
(WebCore::Path::isEmptySlowCase const):
(WebCore::Path::currentPointSlowCase const):
(WebCore::Path::applySlowCase const):
(WebCore::Path::isNull const):
(WebCore::Path::boundingRect const): Deleted.
(WebCore::Path::fastBoundingRect const): Deleted.
(WebCore::Path::moveTo): Deleted.
(WebCore::Path::addLineTo): Deleted.
(WebCore::Path::addArc): Deleted.
(WebCore::Path::isEmpty const): Deleted.
(WebCore::Path::hasCurrentPoint const): Deleted.
(WebCore::Path::currentPoint const): Deleted.
(WebCore::Path::apply const): Deleted.

Source/WebKit:

Add argument coders for WTF::Monostate, so that Variants of the form: Variant<Monostate, Foo, Bar> can be
encoded and decoded over IPC.

  • Platform/IPC/ArgumentCoders.cpp:

(IPC::ArgumentCoder<Monostate>::encode):
(IPC::ArgumentCoder<Monostate>::decode):

  • Platform/IPC/ArgumentCoders.h:

Source/WTF:

Add a feature flag for INLINE_PATH_DATA. This feature flag exists to ensure that we can avoid having
m_inlineData on Path in ports that don't implement the necessary facilities for inline path data yet, since it
would just end up being wasted memory.

  • wtf/PlatformEnable.h:
Location:
trunk/Source
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r258089 r258118  
     12020-03-08  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Lazily generate CGPaths for some simple types of paths, such as arcs and lines
     4        https://bugs.webkit.org/show_bug.cgi?id=208464
     5        <rdar://problem/59963226>
     6
     7        Reviewed by Daniel Bates, Darin Adler and Tim Horton.
     8
     9        Add a feature flag for INLINE_PATH_DATA. This feature flag exists to ensure that we can avoid having
     10        m_inlineData on Path in ports that don't implement the necessary facilities for inline path data yet, since it
     11        would just end up being wasted memory.
     12
     13        * wtf/PlatformEnable.h:
     14
    1152020-03-07  Daniel Bates  <dabates@apple.com>
    216
  • trunk/Source/WTF/wtf/PlatformEnable.h

    r258076 r258118  
    818818#endif
    819819
     820#if !defined(ENABLE_INLINE_PATH_DATA) && USE(CG)
     821#define ENABLE_INLINE_PATH_DATA 1
     822#endif
    820823
    821824/* Disable SharedArrayBuffers until Spectre security concerns are mitigated. */
  • trunk/Source/WebCore/ChangeLog

    r258116 r258118  
     12020-03-08  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Lazily generate CGPaths for some simple types of paths, such as arcs and lines
     4        https://bugs.webkit.org/show_bug.cgi?id=208464
     5        <rdar://problem/59963226>
     6
     7        Reviewed by Daniel Bates, Darin Adler and Tim Horton.
     8
     9        When the GPU process is enabled and used to render the canvas element, some canvas-related subtests in
     10        MotionMark see significant performance regressions. One of the reasons for this is that in the process of
     11        decoding display list items that contain `WebCore::Path`s in the GPU process, we end up allocating a new CGPath
     12        for each WebCore::Path. This dramatically increases page demand and memory usage in the GPU process in contrast
     13        to shipping WebKit, due to the fact that all of these CGPaths allocated up-front, and must all exist somewhere
     14        in the heap upon decoding the display list.
     15
     16        In contrast, in shipping WebKit, each call to stroke the current canvas path (i.e. invoking
     17        GraphicsContext::strokePath) is succeeded by clearing the path, which deallocates the CGPath backing the WebCore
     18        Path. The next time a CGPath needs to be created, CoreGraphics is free to then allocate the new CGPath at the
     19        address of the previous CGPath which was just destroyed, which prevents us from dirtying more pages than
     20        necessary. This phenomenon affects most of the canvas-related MotionMark subtests to some degree, though the
     21        impact is most noticeable with Canvas Lines.
     22
     23        On top of all this, a significant portion of time is also spent calling CGPathApply and converting the resulting
     24        CGPathElements into serializable data when encoding each WebCore Path.
     25
     26        To mitigate these two issues and restore the wins we get from memory locality when drawing paths in large
     27        quantities, we can:
     28
     29        1.  In the case of simple paths, stuff some information about how each path was created as inline data on
     30            WebCore::Path itself, as a new data member. For now, this only encompasses lines, arcs, and moves (Paths
     31            where only `Path::moveTo` was invoked), but may be expanded in the future to include ellipses and rects.
     32            This allows us to achieve two things: (a) make encoding cheaper by not requiring a walk through all of
     33            CGPath's elements, and (b) make decoding cheaper by just initializing the Path using inline data, rather
     34            than having to create a new CGPath.
     35
     36        2.  When painting the StrokePath display list item, just discard `m_path` after we're done painting with it.
     37            This, in conjunction with (1), means that the CGPath backing the WebCore::Path in the GPU process is only
     38            created when we're just about to paint (i.e. when calling into strokePath()), and destroyed right after
     39            we're done painting with it.
     40
     41        See below for details. There should be no change in behavior.
     42
     43        * Headers.cmake:
     44        * WebCore.xcodeproj/project.pbxproj:
     45        * platform/graphics/InlinePathData.h: Added.
     46        (WebCore::MoveData::encode const):
     47        (WebCore::MoveData::decode):
     48        (WebCore::LineData::encode const):
     49        (WebCore::LineData::decode):
     50        (WebCore::ArcData::encode const):
     51        (WebCore::ArcData::decode):
     52
     53        Introduce InlinePathData, a Variant of several different inline data types, each of which represents one simple
     54        path type that is stored using only inline data. This includes line segments (a start point and an end point),
     55        as well as arcs (which, in addition to a center and start and end angles) also includes an optional offset,
     56        which represents the current position of the path at the time "addArc" was called.
     57
     58        For instance, in the following scenario, the path would have an arc that is offset by (100, 0); if filled, it
     59        would result in a composite shape resembling a semicircle on top of a triangle:
     60
     61        path.moveTo(100, 0);
     62        path.addArc(100, 100, 50, 0, PI, false);
     63        context.fill(path);
     64
     65        When a Path is initialized (or after it is cleared), it starts off with neither a CGPath nor inline data. Moving
     66        the path causes it to store inline MoveData; calling calling `addLineTo` or `addArc` then replaces the inline
     67        data with either LineData or ArcData.
     68
     69        If, at any point, the path changes in a different way (i.e. neither line, arc, nor move), we clear out the
     70        inline data and fall back to just representing the path data using the CGPath (m_path).
     71
     72        * platform/graphics/Path.cpp:
     73
     74        Refactor the following 10 methods: moveTo, addLineTo, addArc, isEmpty, currentPoint, apply, elementCount,
     75        hasCurrentPoint, fastBoundingRect, and boundingRect such that their implementations are now in platform-agnostic
     76        code in Path.cpp. Logic in this platform-agnostic code will generally attempt to use inline path data to compute
     77        an answer (or apply the requested mutations) without having to initialize the platform path representation.
     78        Failing this, we fall back to calling -SlowCase versions of these methods, which will exercise the appropriate
     79        APIs on each platform.
     80
     81        (WebCore::Path::elementCountSlowCase const):
     82        (WebCore::Path::apply const):
     83        (WebCore::Path::isEmpty const):
     84        (WebCore::Path::hasCurrentPoint const):
     85        (WebCore::Path::currentPoint const):
     86        (WebCore::Path::elementCount const):
     87        (WebCore::Path::addArc):
     88        (WebCore::Path::addLineTo):
     89        (WebCore::Path::moveTo):
     90
     91        In the case of these three methods for mutating a path, if we've either only moved the path or haven't touched
     92        it at all, we can get away with only updating our inline path data, and avoid creating a CGPath.
     93
     94        (WebCore::Path::boundingRect const):
     95        (WebCore::Path::fastBoundingRect const):
     96        (WebCore::Path::boundingRectFromInlineData const):
     97        (WebCore::Path::polygonPathFromPoints):
     98        * platform/graphics/Path.h:
     99        (WebCore::Path::encode const):
     100        (WebCore::Path::decode):
     101
     102        Teach Path::encode and Path::decode to respectively serialize and deserialize WebCore::Path by consulting only
     103        the inline data, if it is present. For simple types of paths, this decreases the cost of both IPC encoding and
     104        decoding, but adds a negligible amount of overhead in the case where the path is non-inline.
     105
     106        (WebCore::Path::hasInlineData const):
     107        (WebCore::Path::hasAnyInlineData const):
     108        (WebCore::Path::isNull const): Deleted.
     109        * platform/graphics/cairo/PathCairo.cpp:
     110        (WebCore::Path::isEmptySlowCase const):
     111        (WebCore::Path::currentPointSlowCase const):
     112        (WebCore::Path::moveToSlowCase):
     113        (WebCore::Path::addLineToSlowCase):
     114        (WebCore::Path::addArcSlowCase):
     115        (WebCore::Path::boundingRectSlowCase const):
     116        (WebCore::Path::applySlowCase const):
     117        (WebCore::Path::fastBoundingRectSlowCase const):
     118        (WebCore::Path::isNull const):
     119        (WebCore::Path::isEmpty const): Deleted.
     120        (WebCore::Path::hasCurrentPoint const): Deleted.
     121        (WebCore::Path::currentPoint const): Deleted.
     122        (WebCore::Path::moveTo): Deleted.
     123        (WebCore::Path::addLineTo): Deleted.
     124        (WebCore::Path::addArc): Deleted.
     125        (WebCore::Path::boundingRect const): Deleted.
     126        (WebCore::Path::apply const): Deleted.
     127        * platform/graphics/cg/PathCG.cpp:
     128        (WebCore::Path::createCGPath const):
     129
     130        Add a helper method that is invoked when the Path is asked for a CGPath. In this case, if there is inline data,
     131        we need to lazily create the path and apply any inline path data we've accumulated. Once we're done applying the
     132        inline data, set a flag (m_needsToApplyInlineData) to false to avoid re-applying inline data to the path.
     133
     134        (WebCore::Path::platformPath const):
     135        (WebCore::Path::ensurePlatformPath):
     136
     137        When ensurePlatformPath is invoked, we are about to mutate our CGPath in such a way that it can't be expressed
     138        in terms of inline data (at least, not with the changes in this patch). Clear out the inline path data in this
     139        case, and apply the CGPath mutations that were previously stashed away in inline path data.
     140
     141        (WebCore::Path::isNull const):
     142
     143        A path is now considered null if it is not only missing a CGPath, but also does not have any inline path data.
     144        This maintains the invariant that `isNull()` is true iff the `platformPath()` returns 0x0.
     145
     146        (WebCore::Path::Path):
     147        (WebCore::Path::swap):
     148
     149        Update the constructors and `swap` helper method (used by assignment operators) to account for the new members.
     150
     151        (WebCore::Path::contains const):
     152        (WebCore::Path::transform):
     153        (WebCore::zeroRectIfNull):
     154        (WebCore::Path::boundingRectSlowCase const):
     155        (WebCore::Path::fastBoundingRectSlowCase const):
     156        (WebCore::Path::moveToSlowCase):
     157        (WebCore::Path::addLineToSlowCase):
     158        (WebCore::Path::addArcSlowCase):
     159        (WebCore::Path::clear):
     160
     161        When clearing Path, instead of setting `m_path` to a newly allocated CGPath, simply reset it to null. This
     162        ensures that if we then apply some changes that can be expressed using only inline path data, we avoid having to
     163        update the CGPath, and instead just update the inline path data.
     164
     165        (WebCore::Path::isEmptySlowCase const):
     166        (WebCore::Path::currentPointSlowCase const):
     167        (WebCore::Path::applySlowCase const):
     168        (WebCore::Path::elementCountSlowCase const):
     169        (WebCore::Path::boundingRect const): Deleted.
     170        (WebCore::Path::fastBoundingRect const): Deleted.
     171        (WebCore::Path::moveTo): Deleted.
     172        (WebCore::Path::addLineTo): Deleted.
     173        (WebCore::Path::addArc): Deleted.
     174        (WebCore::Path::isEmpty const): Deleted.
     175        (WebCore::Path::hasCurrentPoint const): Deleted.
     176        (WebCore::Path::currentPoint const): Deleted.
     177        (WebCore::Path::apply const): Deleted.
     178        (WebCore::Path::elementCount const): Deleted.
     179        * platform/graphics/displaylists/DisplayListItems.cpp:
     180        (WebCore::DisplayList::StrokePath::apply const):
     181
     182        Throw out the current WebCore::Path after we're done painting with it (see (2) in the above ChangeLog entry).
     183
     184        * platform/graphics/displaylists/DisplayListItems.h:
     185        * platform/graphics/win/PathDirect2D.cpp:
     186        (WebCore::Path::boundingRectSlowCase const):
     187        (WebCore::Path::fastBoundingRectSlowCase const):
     188        (WebCore::Path::moveToSlowCase):
     189        (WebCore::Path::addLineToSlowCase):
     190        (WebCore::Path::addArcSlowCase):
     191        (WebCore::Path::isEmptySlowCase const):
     192        (WebCore::Path::currentPointSlowCase const):
     193        (WebCore::Path::applySlowCase const):
     194        (WebCore::Path::isNull const):
     195        (WebCore::Path::boundingRect const): Deleted.
     196        (WebCore::Path::fastBoundingRect const): Deleted.
     197        (WebCore::Path::moveTo): Deleted.
     198        (WebCore::Path::addLineTo): Deleted.
     199        (WebCore::Path::addArc): Deleted.
     200        (WebCore::Path::isEmpty const): Deleted.
     201        (WebCore::Path::hasCurrentPoint const): Deleted.
     202        (WebCore::Path::currentPoint const): Deleted.
     203        (WebCore::Path::apply const): Deleted.
     204
    12052020-03-08  Konstantin Tokarev  <annulen@yandex.ru>
    2206
  • trunk/Source/WebCore/Headers.cmake

    r258060 r258118  
    11281128    platform/graphics/InbandTextTrackPrivate.h
    11291129    platform/graphics/InbandTextTrackPrivateClient.h
     1130    platform/graphics/InlinePathData.h
    11301131    platform/graphics/IntPoint.h
    11311132    platform/graphics/IntPointHash.h
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r258115 r258118  
    49834983                F44A5F591FED38F2007F5944 /* LegacyNSPasteboardTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
    49844984                F44EBBD91DB5D21400277334 /* StaticRange.h in Headers */ = {isa = PBXBuildFile; fileRef = F44EBBD81DB5D21400277334 /* StaticRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
     4985                F45775CE241437D5002DF1A0 /* InlinePathData.h in Headers */ = {isa = PBXBuildFile; fileRef = F45775CD241437D5002DF1A0 /* InlinePathData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    49854986                F45C231E1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h in Headers */ = {isa = PBXBuildFile; fileRef = F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */; settings = {ATTRIBUTES = (Private, ); }; };
    49864987                F46729281E0DE68500ACC3D8 /* ScrollSnapOffsetsInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F46729251E0DE5AB00ACC3D8 /* ScrollSnapOffsetsInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1547415475                F44EBBD81DB5D21400277334 /* StaticRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticRange.h; sourceTree = "<group>"; };
    1547515476                F44EBBDA1DB5DD9D00277334 /* StaticRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticRange.cpp; sourceTree = "<group>"; };
     15477                F45775CD241437D5002DF1A0 /* InlinePathData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlinePathData.h; sourceTree = "<group>"; };
    1547615478                F45C231B1995B73B00A6E2E3 /* AxisScrollSnapOffsets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AxisScrollSnapOffsets.cpp; sourceTree = "<group>"; };
    1547715479                F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AxisScrollSnapOffsets.h; sourceTree = "<group>"; };
     
    2513825140                                07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */,
    2513925141                                07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */,
     25142                                F45775CD241437D5002DF1A0 /* InlinePathData.h */,
    2514025143                                2D46F04D17B96FBD005647F0 /* IntPoint.cpp */,
    2514125144                                B27535440B053814002CE64F /* IntPoint.h */,
     
    3042930432                                6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */,
    3043030433                                6F0CD695229ED32700C5994E /* InlineLineBuilder.h in Headers */,
     30434                                F45775CE241437D5002DF1A0 /* InlinePathData.h in Headers */,
    3043130435                                6F360E5023999421001512A7 /* InlineSoftLineBreakItem.h in Headers */,
    3043230436                                AA4C3A770B2B1679002334A2 /* InlineStyleSheetOwner.h in Headers */,
  • trunk/Source/WebCore/platform/graphics/Path.cpp

    r257918 r258118  
    5656#if !HAVE(CGPATH_GET_NUMBER_OF_ELEMENTS)
    5757
    58 size_t Path::elementCount() const
     58size_t Path::elementCountSlowCase() const
    5959{
    6060    size_t numPoints = 0;
     
    168168}
    169169
     170void Path::apply(const PathApplierFunction& function) const
     171{
     172    if (isNull())
     173        return;
     174
     175#if ENABLE(INLINE_PATH_DATA)
     176    if (hasInlineData<MoveData>()) {
     177        PathElement element;
     178        element.type = PathElement::Type::MoveToPoint;
     179        element.points[0] = WTF::get<MoveData>(m_inlineData).location;
     180        function(element);
     181        return;
     182    }
     183
     184    if (hasInlineData<LineData>()) {
     185        auto& line = WTF::get<LineData>(m_inlineData);
     186        PathElement element;
     187        element.type = PathElement::Type::MoveToPoint;
     188        element.points[0] = line.start;
     189        function(element);
     190        element.type = PathElement::Type::AddLineToPoint;
     191        element.points[0] = line.end;
     192        function(element);
     193        return;
     194    }
     195#endif
     196
     197    applySlowCase(function);
     198}
     199
     200bool Path::isEmpty() const
     201{
     202    if (isNull())
     203        return true;
     204
     205#if ENABLE(INLINE_PATH_DATA)
     206    if (hasAnyInlineData())
     207        return false;
     208#endif
     209
     210    return isEmptySlowCase();
     211}
     212
     213bool Path::hasCurrentPoint() const
     214{
     215    return !isEmpty();
     216}
     217
     218FloatPoint Path::currentPoint() const
     219{
     220    if (isNull())
     221        return { };
     222
     223#if ENABLE(INLINE_PATH_DATA)
     224    if (hasInlineData<MoveData>())
     225        return WTF::get<MoveData>(m_inlineData).location;
     226
     227    if (hasInlineData<LineData>())
     228        return WTF::get<LineData>(m_inlineData).end;
     229#endif
     230
     231    return currentPointSlowCase();
     232}
     233
     234size_t Path::elementCount() const
     235{
     236#if ENABLE(INLINE_PATH_DATA)
     237    if (hasInlineData<MoveData>())
     238        return 1;
     239
     240    if (hasInlineData<LineData>())
     241        return 2;
     242#endif
     243
     244    return elementCountSlowCase();
     245}
     246
     247void Path::addArc(const FloatPoint& point, float radius, float startAngle, float endAngle, bool anticlockwise)
     248{
     249    // Workaround for <rdar://problem/5189233> CGPathAddArc hangs or crashes when passed inf as start or end angle,
     250    // as well as http://bugs.webkit.org/show_bug.cgi?id=16449, since cairo_arc() functions hang or crash when
     251    // passed inf as radius or start/end angle.
     252    if (!std::isfinite(radius) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
     253        return;
     254
     255#if ENABLE(INLINE_PATH_DATA)
     256    if (isNull() || hasInlineData<MoveData>()) {
     257        ArcData arc;
     258        if (hasAnyInlineData()) {
     259            arc.hasOffset = true;
     260            arc.offset = WTF::get<MoveData>(m_inlineData).location;
     261        }
     262        arc.center = point;
     263        arc.radius = radius;
     264        arc.startAngle = startAngle;
     265        arc.endAngle = endAngle;
     266        // FIXME: Either ArcData::clockwise needs to be renamed to anticlockwise, or the last argument to
     267        // Path::addArc needs to be renamed to clockwise.
     268        arc.clockwise = anticlockwise;
     269        m_inlineData = { WTFMove(arc) };
     270        return;
     271    }
     272#endif
     273
     274    addArcSlowCase(point, radius, startAngle, endAngle, anticlockwise);
     275}
     276
     277void Path::addLineTo(const FloatPoint& point)
     278{
     279#if ENABLE(INLINE_PATH_DATA)
     280    if (isNull() || hasInlineData<MoveData>()) {
     281        LineData line;
     282        line.start = hasAnyInlineData() ? WTF::get<MoveData>(m_inlineData).location : FloatPoint();
     283        line.end = point;
     284        m_inlineData = { WTFMove(line) };
     285        return;
     286    }
     287#endif
     288
     289    addLineToSlowCase(point);
     290}
     291
     292void Path::moveTo(const FloatPoint& point)
     293{
     294#if ENABLE(INLINE_PATH_DATA)
     295    if (isNull() || hasInlineData<MoveData>()) {
     296        m_inlineData = MoveData { point };
     297        return;
     298    }
     299#endif
     300
     301    moveToSlowCase(point);
     302}
     303
     304FloatRect Path::boundingRect() const
     305{
     306    if (isNull())
     307        return { };
     308
     309#if ENABLE(INLINE_PATH_DATA)
     310    if (auto rect = boundingRectFromInlineData())
     311        return *rect;
     312#endif
     313
     314    return boundingRectSlowCase();
     315}
     316
     317FloatRect Path::fastBoundingRect() const
     318{
     319    if (isNull())
     320        return { };
     321
     322#if ENABLE(INLINE_PATH_DATA)
     323    if (auto rect = boundingRectFromInlineData())
     324        return *rect;
     325#endif
     326
     327    return fastBoundingRectSlowCase();
     328}
     329
     330#if ENABLE(INLINE_PATH_DATA)
     331
     332Optional<FloatRect> Path::boundingRectFromInlineData() const
     333{
     334    if (hasInlineData<MoveData>())
     335        return FloatRect { };
     336
     337    if (hasInlineData<LineData>()) {
     338        FloatRect result;
     339        auto& line = WTF::get<LineData>(m_inlineData);
     340        result.fitToPoints(line.start, line.end);
     341        return result;
     342    }
     343
     344    return WTF::nullopt;
     345}
     346
     347#endif
     348
    170349#if !USE(CG) && !USE(DIRECT2D)
    171350Path Path::polygonPathFromPoints(const Vector<FloatPoint>& points)
     
    181360    path.closeSubpath();
    182361    return path;
    183 }
    184 
    185 FloatRect Path::fastBoundingRect() const
    186 {
    187     return boundingRect();
    188362}
    189363#endif
  • trunk/Source/WebCore/platform/graphics/Path.h

    r257918 r258118  
    2626 */
    2727
    28 #ifndef Path_h
    29 #define Path_h
     28#pragma once
    3029
    3130#include "FloatRect.h"
     31#include "InlinePathData.h"
    3232#include "WindRule.h"
    3333#include <wtf/FastMalloc.h>
     
    148148
    149149    WEBCORE_EXPORT void clear();
    150     bool isNull() const { return !m_path; }
     150    WEBCORE_EXPORT bool isNull() const;
    151151    bool isEmpty() const;
    152152    // Gets the current point of the current path, which is conceptually the final point reached by the path so far.
    153153    // Note the Path can be empty (isEmpty() == true) and still have a current point.
     154    // FIXME: The above comment might need to be updated; on all supported platforms, the result of hasCurrentPoint() is identical
     155    // to !isEmpty().
    154156    bool hasCurrentPoint() const;
    155157    FloatPoint currentPoint() const;
     
    186188    PlatformPathPtr platformPath() const { return m_path.get(); }
    187189#elif USE(CG)
    188     PlatformPathPtr platformPath() const { return m_path.get(); }
     190    WEBCORE_EXPORT PlatformPathPtr platformPath() const;
    189191#else
    190192    PlatformPathPtr platformPath() const { return m_path; }
     
    226228
    227229private:
     230#if ENABLE(INLINE_PATH_DATA)
     231    template<typename DataType> bool hasInlineData() const;
     232    bool hasAnyInlineData() const;
     233    Optional<FloatRect> boundingRectFromInlineData() const;
     234#endif
     235
     236    void moveToSlowCase(const FloatPoint&);
     237    void addLineToSlowCase(const FloatPoint&);
     238    void addArcSlowCase(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
     239
     240    FloatRect boundingRectSlowCase() const;
     241    FloatRect fastBoundingRectSlowCase() const;
     242    bool isEmptySlowCase() const;
     243    FloatPoint currentPointSlowCase() const;
     244    size_t elementCountSlowCase() const;
     245    void applySlowCase(const PathApplierFunction&) const;
     246
    228247#if USE(CG)
     248    void createCGPath() const;
    229249    void swap(Path&);
    230250#endif
     
    238258#endif
    239259
     260#if ENABLE(INLINE_PATH_DATA)
     261    InlinePathData m_inlineData;
     262#endif
    240263#if USE(CG)
    241264    mutable bool m_copyPathBeforeMutation { false };
     
    247270template<class Encoder> void Path::encode(Encoder& encoder) const
    248271{
     272#if ENABLE(INLINE_PATH_DATA)
     273    bool hasInlineData = hasAnyInlineData();
     274    encoder << hasInlineData;
     275    if (hasInlineData) {
     276        encoder << m_inlineData;
     277        return;
     278    }
     279#endif
     280
    249281    encoder << static_cast<uint64_t>(elementCount());
    250282
     
    277309{
    278310    Path path;
     311
     312#if ENABLE(INLINE_PATH_DATA)
     313    bool hasInlineData;
     314    if (!decoder.decode(hasInlineData))
     315        return WTF::nullopt;
     316
     317    if (hasInlineData) {
     318        if (!decoder.decode(path.m_inlineData))
     319            return WTF::nullopt;
     320
     321        return path;
     322    }
     323#endif
     324
    279325    uint64_t numPoints;
    280326    if (!decoder.decode(numPoints))
     
    340386}
    341387
    342 }
    343 
    344 #endif
     388#if ENABLE(INLINE_PATH_DATA)
     389
     390template <typename DataType> inline bool Path::hasInlineData() const
     391{
     392    return WTF::holds_alternative<DataType>(m_inlineData);
     393}
     394
     395inline bool Path::hasAnyInlineData() const
     396{
     397    return !hasInlineData<Monostate>();
     398}
     399
     400#endif
     401
     402} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/cairo/PathCairo.cpp

    r255559 r258118  
    118118}
    119119
    120 bool Path::isEmpty() const
    121 {
    122     return isNull() || !cairo_has_current_point(platformPath()->context());
    123 }
    124 
    125 bool Path::hasCurrentPoint() const
    126 {
    127     return !isEmpty();
    128 }
    129 
    130 FloatPoint Path::currentPoint() const
    131 {
    132     if (isNull())
    133         return FloatPoint();
    134 
     120bool Path::isEmptySlowCase() const
     121{
     122    return !cairo_has_current_point(platformPath()->context());
     123}
     124
     125FloatPoint Path::currentPointSlowCase() const
     126{
    135127    // FIXME: Is this the correct way?
    136128    double x;
     
    146138}
    147139
    148 void Path::moveTo(const FloatPoint& p)
     140void Path::moveToSlowCase(const FloatPoint& p)
    149141{
    150142    cairo_t* cr = ensurePlatformPath()->context();
     
    152144}
    153145
    154 void Path::addLineTo(const FloatPoint& p)
     146void Path::addLineToSlowCase(const FloatPoint& p)
    155147{
    156148    cairo_t* cr = ensurePlatformPath()->context();
     
    190182}
    191183
    192 void Path::addArc(const FloatPoint& p, float r, float startAngle, float endAngle, bool anticlockwise)
    193 {
    194     // http://bugs.webkit.org/show_bug.cgi?id=16449
    195     // cairo_arc() functions hang or crash when passed inf as radius or start/end angle
    196     if (!std::isfinite(r) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
    197         return;
    198 
     184void Path::addArcSlowCase(const FloatPoint& p, float r, float startAngle, float endAngle, bool anticlockwise)
     185{
    199186    cairo_t* cr = ensurePlatformPath()->context();
    200187    float sweep = endAngle - startAngle;
     
    354341}
    355342
    356 FloatRect Path::boundingRect() const
    357 {
    358     // Should this be isEmpty() or can an empty path have a non-zero origin?
    359     if (isNull())
    360         return FloatRect();
    361 
     343FloatRect Path::boundingRectSlowCase() const
     344{
    362345    cairo_t* cr = platformPath()->context();
    363346    double x0, x1, y0, y1;
     
    409392}
    410393
    411 void Path::apply(const PathApplierFunction& function) const
    412 {
    413     if (isNull())
    414         return;
    415 
     394void Path::applySlowCase(const PathApplierFunction& function) const
     395{
    416396    cairo_t* cr = platformPath()->context();
    417397    auto pathCopy = cairo_copy_path(cr);
     
    448428}
    449429
     430FloatRect Path::fastBoundingRectSlowCase() const
     431{
     432    return boundingRect();
     433}
     434
    450435void Path::transform(const AffineTransform& transform)
    451436{
     
    456441}
    457442
     443bool Path::isNull() const
     444{
     445    return !m_path;
     446}
     447
    458448} // namespace WebCore
    459449
  • trunk/Source/WebCore/platform/graphics/cg/PathCG.cpp

    r257918 r258118  
    8282}
    8383
     84void Path::createCGPath() const
     85{
     86    if (m_path)
     87        return;
     88
     89    m_path = adoptCF(CGPathCreateMutable());
     90
     91    WTF::switchOn(m_inlineData,
     92        [&](Monostate) { }, // Start with an empty path.
     93        [&](const MoveData& move) {
     94            CGPathMoveToPoint(m_path.get(), nullptr, move.location.x(), move.location.y());
     95        },
     96        [&](const LineData& line) {
     97            CGPathMoveToPoint(m_path.get(), nullptr, line.start.x(), line.start.y());
     98            CGPathAddLineToPoint(m_path.get(), nullptr, line.end.x(), line.end.y());
     99        },
     100        [&](const ArcData& arc) {
     101            if (arc.hasOffset)
     102                CGPathMoveToPoint(m_path.get(), nullptr, arc.offset.x(), arc.offset.y());
     103            CGPathAddArc(m_path.get(), nullptr, arc.center.x(), arc.center.y(), arc.radius, arc.startAngle, arc.endAngle, arc.clockwise);
     104        }
     105    );
     106}
     107
    84108Path::Path(RetainPtr<CGMutablePathRef>&& path)
    85109    : m_path(WTFMove(path))
     
    90114Path::~Path() = default;
    91115
     116PlatformPathPtr Path::platformPath() const
     117{
     118    if (!m_path && hasAnyInlineData())
     119        createCGPath();
     120    return m_path.get();
     121}
     122
    92123PlatformPathPtr Path::ensurePlatformPath()
    93124{
    94     if (!m_path)
    95         m_path = adoptCF(CGPathCreateMutable());
    96     else if (m_copyPathBeforeMutation) {
     125    createCGPath();
     126    if (m_copyPathBeforeMutation) {
    97127        if (CFGetRetainCount(m_path.get()) > 1)
    98128            m_path = adoptCF(CGPathCreateMutableCopy(m_path.get()));
    99129        m_copyPathBeforeMutation = false;
    100130    }
     131    m_inlineData = Monostate { };
    101132    return m_path.get();
    102133}
    103134
     135bool Path::isNull() const
     136{
     137    return !m_path && !hasAnyInlineData();
     138}
     139
    104140Path::Path(const Path& other)
    105141{
    106142    m_path = { other.m_path };
     143    m_inlineData = other.m_inlineData;
    107144    if (m_path) {
    108145        m_copyPathBeforeMutation = true;
     
    113150Path::Path(Path&& other)
    114151    : m_path(std::exchange(other.m_path, nullptr))
     152    , m_inlineData(std::exchange(other.m_inlineData, Monostate { }))
    115153    , m_copyPathBeforeMutation(std::exchange(other.m_copyPathBeforeMutation, false))
    116154{
     
    120158{
    121159    std::swap(m_path, otherPath.m_path);
     160    std::swap(m_inlineData, otherPath.m_inlineData);
    122161    std::swap(m_copyPathBeforeMutation, otherPath.m_copyPathBeforeMutation);
    123162}
     
    180219
    181220    // CGPathContainsPoint returns false for non-closed paths, as a work-around, we copy and close the path first.  Radar 4758998 asks for a better CG API to use
    182     auto path = adoptCF(copyCGPathClosingSubpaths(m_path.get()));
     221    auto path = adoptCF(copyCGPathClosingSubpaths(platformPath()));
    183222    bool ret = CGPathContainsPoint(path.get(), 0, point, rule == WindRule::EvenOdd ? true : false);
    184223    return ret;
     
    218257#if PLATFORM(WIN)
    219258    auto path = adoptCF(CGPathCreateMutable());
    220     CGPathAddPath(path.get(), &transformCG, m_path.get());
     259    CGPathAddPath(path.get(), &transformCG, platformPath());
    221260#else
    222     auto path = adoptCF(CGPathCreateMutableCopyByTransformingPath(m_path.get(), &transformCG));
     261    auto path = adoptCF(CGPathCreateMutableCopyByTransformingPath(platformPath(), &transformCG));
    223262#endif
    224263    m_path = WTFMove(path);
    225264    m_copyPathBeforeMutation = false;
    226 }
    227 
    228 FloatRect Path::boundingRect() const
    229 {
    230     if (isNull())
    231         return CGRectZero;
    232 
     265    m_inlineData = Monostate { };
     266}
     267
     268static inline FloatRect zeroRectIfNull(CGRect rect)
     269{
     270    if (CGRectIsNull(rect))
     271        return { };
     272    return rect;
     273}
     274
     275FloatRect Path::boundingRectSlowCase() const
     276{
    233277    // CGPathGetBoundingBox includes the path's control points, CGPathGetPathBoundingBox does not.
    234 
    235     CGRect bound = CGPathGetPathBoundingBox(m_path.get());
    236     return CGRectIsNull(bound) ? CGRectZero : bound;
    237 }
    238 
    239 FloatRect Path::fastBoundingRect() const
    240 {
    241     if (isNull())
    242         return CGRectZero;
    243     CGRect bound = CGPathGetBoundingBox(m_path.get());
    244     return CGRectIsNull(bound) ? CGRectZero : bound;
     278    return zeroRectIfNull(CGPathGetPathBoundingBox(platformPath()));
     279}
     280
     281FloatRect Path::fastBoundingRectSlowCase() const
     282{
     283    return zeroRectIfNull(CGPathGetBoundingBox(platformPath()));
    245284}
    246285
     
    268307}
    269308
    270 void Path::moveTo(const FloatPoint& point)
     309void Path::moveToSlowCase(const FloatPoint& point)
    271310{
    272311    CGPathMoveToPoint(ensurePlatformPath(), nullptr, point.x(), point.y());
    273312}
    274313
    275 void Path::addLineTo(const FloatPoint& p)
     314void Path::addLineToSlowCase(const FloatPoint& p)
    276315{
    277316    CGPathAddLineToPoint(ensurePlatformPath(), nullptr, p.x(), p.y());
     
    351390}
    352391
    353 void Path::addArc(const FloatPoint& p, float radius, float startAngle, float endAngle, bool clockwise)
    354 {
    355     // Workaround for <rdar://problem/5189233> CGPathAddArc hangs or crashes when passed inf as start or end angle
    356     if (!std::isfinite(startAngle) || !std::isfinite(endAngle))
    357         return;
    358 
     392void Path::addArcSlowCase(const FloatPoint& p, float radius, float startAngle, float endAngle, bool clockwise)
     393{
    359394    CGPathAddArc(ensurePlatformPath(), nullptr, p.x(), p.y(), radius, startAngle, endAngle, clockwise);
    360395}
     
    403438        return;
    404439
    405     m_path = adoptCF(CGPathCreateMutable());
     440    m_path.clear();
     441    m_inlineData = Monostate { };
    406442    m_copyPathBeforeMutation = false;
    407443}
    408444
    409 bool Path::isEmpty() const
    410 {
    411     return isNull() || CGPathIsEmpty(m_path.get());
    412 }
    413 
    414 bool Path::hasCurrentPoint() const
    415 {
    416     return !isEmpty();
    417 }
    418    
    419 FloatPoint Path::currentPoint() const
    420 {
    421     if (isNull())
    422         return FloatPoint();
    423     return CGPathGetCurrentPoint(m_path.get());
     445bool Path::isEmptySlowCase() const
     446{
     447    return CGPathIsEmpty(m_path.get());
     448}
     449
     450FloatPoint Path::currentPointSlowCase() const
     451{
     452    return CGPathGetCurrentPoint(platformPath());
    424453}
    425454
     
    450479}
    451480
    452 void Path::apply(const PathApplierFunction& function) const
    453 {
    454     if (isNull())
    455         return;
    456 
    457     CGPathApply(m_path.get(), (void*)&function, CGPathApplierToPathApplier);
     481void Path::applySlowCase(const PathApplierFunction& function) const
     482{
     483    CGPathApply(platformPath(), (void*)&function, CGPathApplierToPathApplier);
    458484}
    459485
    460486#if HAVE(CGPATH_GET_NUMBER_OF_ELEMENTS)
    461487
    462 size_t Path::elementCount() const
    463 {
    464     return CGPathGetNumberOfElements(m_path);
     488size_t Path::elementCountSlowCase() const
     489{
     490    return CGPathGetNumberOfElements(platformPath());
    465491}
    466492
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp

    r258051 r258118  
    12291229void StrokePath::apply(GraphicsContext& context) const
    12301230{
    1231     context.strokePath(m_path);
     1231    context.strokePath(WTFMove(m_path));
    12321232}
    12331233
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h

    r258051 r258118  
    25902590    Optional<FloatRect> localBounds(const GraphicsContext&) const override;
    25912591
    2592     const Path m_path;
     2592    mutable Path m_path;
    25932593};
    25942594
  • trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp

    r254087 r258118  
    302302}
    303303
    304 FloatRect Path::boundingRect() const
    305 {
    306     if (isNull())
    307         return FloatRect();
    308 
     304FloatRect Path::boundingRectSlowCase() const
     305{
    309306    D2D1_RECT_F bounds = { };
    310307    if (!SUCCEEDED(m_path->GetBounds(nullptr, &bounds)))
     
    314311}
    315312
    316 FloatRect Path::fastBoundingRect() const
    317 {
    318     if (isNull())
    319         return FloatRect();
    320 
     313FloatRect Path::fastBoundingRectSlowCase() const
     314{
    321315    D2D1_RECT_F bounds = { };
    322316    if (!SUCCEEDED(m_path->GetBounds(nullptr, &bounds)))
     
    375369}
    376370
    377 void Path::moveTo(const FloatPoint& point)
     371void Path::moveToSlowCase(const FloatPoint& point)
    378372{
    379373    if (m_activePath)
     
    395389}
    396390
    397 void Path::addLineTo(const FloatPoint& point)
     391void Path::addLineToSlowCase(const FloatPoint& point)
    398392{
    399393    openFigureAtCurrentPointIfNecessary();
     
    526520}
    527521
    528 void Path::addArc(const FloatPoint& center, float radius, float startAngle, float endAngle, bool anticlockwise)
     522void Path::addArcSlowCase(const FloatPoint& center, float radius, float startAngle, float endAngle, bool anticlockwise)
    529523{
    530524    auto arcStartPoint = arcStart(center, radius, startAngle);
     
    622616}
    623617
    624 bool Path::isEmpty() const
    625 {
    626     if (isNull())
    627         return true;
    628 
     618bool Path::isEmptySlowCase() const
     619{
    629620    if (!m_path->GetSourceGeometryCount())
    630621        return true;
     
    635626}
    636627
    637 bool Path::hasCurrentPoint() const
    638 {
    639     return !isEmpty();
    640 }
    641    
    642 FloatPoint Path::currentPoint() const
    643 {
    644     if (isNull())
    645         return FloatPoint();
    646 
     628FloatPoint Path::currentPointSlowCase() const
     629{
    647630    float length = 0;
    648631    HRESULT hr = m_path->ComputeLength(nullptr, &length);
     
    669652}
    670653
    671 void Path::apply(const PathApplierFunction& function) const
    672 {
    673     if (isNull())
    674         return;
    675 
     654void Path::applySlowCase(const PathApplierFunction&) const
     655{
    676656    notImplemented();
    677657}
    678658
     659bool Path::isNull() const
     660{
     661    return !m_path;
     662}
     663
    679664}
    680665
  • trunk/Source/WebKit/ChangeLog

    r258117 r258118  
     12020-03-08  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Lazily generate CGPaths for some simple types of paths, such as arcs and lines
     4        https://bugs.webkit.org/show_bug.cgi?id=208464
     5        <rdar://problem/59963226>
     6
     7        Reviewed by Daniel Bates, Darin Adler and Tim Horton.
     8
     9        Add argument coders for `WTF::Monostate`, so that Variants of the form: `Variant<Monostate, Foo, Bar>` can be
     10        encoded and decoded over IPC.
     11
     12        * Platform/IPC/ArgumentCoders.cpp:
     13        (IPC::ArgumentCoder<Monostate>::encode):
     14        (IPC::ArgumentCoder<Monostate>::decode):
     15        * Platform/IPC/ArgumentCoders.h:
     16
    1172020-03-08  Brady Eidson  <beidson@apple.com>
    218
  • trunk/Source/WebKit/Platform/IPC/ArgumentCoders.cpp

    r250673 r258118  
    206206#endif
    207207
     208void ArgumentCoder<Monostate>::encode(Encoder&, const Monostate&)
     209{
     210}
     211
     212Optional<Monostate> ArgumentCoder<Monostate>::decode(Decoder&)
     213{
     214    return Monostate { };
     215}
     216
    208217} // namespace IPC
  • trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h

    r256632 r258118  
    3434#include <wtf/SHA1.h>
    3535#include <wtf/Unexpected.h>
     36#include <wtf/Variant.h>
    3637#include <wtf/WallTime.h>
    3738
     
    692693#endif
    693694
     695template<> struct ArgumentCoder<Monostate> {
     696    static void encode(Encoder&, const Monostate&);
     697    static Optional<Monostate> decode(Decoder&);
     698};
     699
    694700} // namespace IPC
Note: See TracChangeset for help on using the changeset viewer.