Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PathSegments cannot be used with anything else than PathImpl #20819

Conversation

kkinnunen-apple
Copy link
Contributor

@kkinnunen-apple kkinnunen-apple commented Nov 22, 2023

d132cc1

PathSegments cannot be used with anything else than PathImpl
https://bugs.webkit.org/show_bug.cgi?id=265247
rdar://118717060

Reviewed by Said Abou-Hallawa.

PathImpl and PathSegment were coupled:
PathImpl::appendSegment would call into PathSegment::addToImpl
PathSegment::addToImpl would call into PathImpl

This would be more complex than needed and also limit the PathSegments
to be only used with PathImpl.

Instead:
  - PathSegment is the data that is being held -- no actions toward any
    class that does actual work on the data.
  - PathImpl knows how to use the path segment types: PathImpl::add()
    for each path segment type.
  - PathImpl knows how to use the PathSegment variant:
    PathImpl::addSegment() for the PathSegment, doing generic add() over
    the variants.
  - Make each member function for adding segments PathImpl::add(). This
    way generic algorithms over the variants are consistent to write.
  - The PathImpl::add() parameters are by-value to avoid introducing
    indirection, the arguments are always used.

Construct PathCG, PathCairo from PathStream without applySegments, as
the PathStream segment list can be just iterated.

This works towards being able to play back a PathSegment list to a
CGContext.

* Source/WebCore/platform/graphics/PathImpl.cpp:
(WebCore::PathImpl::appendSegment): Deleted.
* Source/WebCore/platform/graphics/PathImpl.h:
(WebCore::addPathSegment):
* Source/WebCore/platform/graphics/PathSegment.cpp:
(WebCore::PathSegment::addToImpl const): Deleted.
* Source/WebCore/platform/graphics/PathSegment.h:
(WebCore::PathSegment::addTo const):
* Source/WebCore/platform/graphics/PathSegmentData.cpp:
(WebCore::PathMoveTo::addToImpl const): Deleted.
(WebCore::PathLineTo::addToImpl const): Deleted.
(WebCore::PathQuadCurveTo::addToImpl const): Deleted.
(WebCore::PathBezierCurveTo::addToImpl const): Deleted.
(WebCore::PathArcTo::addToImpl const): Deleted.
(WebCore::PathArc::addToImpl const): Deleted.
(WebCore::PathEllipse::addToImpl const): Deleted.
(WebCore::PathEllipseInRect::addToImpl const): Deleted.
(WebCore::PathRect::addToImpl const): Deleted.
(WebCore::PathRoundedRect::addToImpl const): Deleted.
(WebCore::PathDataLine::addToImpl const): Deleted.
(WebCore::PathDataQuadCurve::addToImpl const): Deleted.
(WebCore::PathDataBezierCurve::addToImpl const): Deleted.
(WebCore::PathDataArc::addToImpl const): Deleted.
(WebCore::PathCloseSubpath::addToImpl const): Deleted.
* Source/WebCore/platform/graphics/PathSegmentData.h:
* Source/WebCore/platform/graphics/cairo/PathCairo.cpp:
(WebCore::PathCairo::create):
* Source/WebCore/platform/graphics/cg/PathCG.cpp:
(WebCore::PathCG::create):

Canonical link: https://commits.webkit.org/271199@main

8b87147

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ›  gtk
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv-sim
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch
βœ… πŸ›  watch-sim

@kkinnunen-apple kkinnunen-apple self-assigned this Nov 22, 2023
@kkinnunen-apple kkinnunen-apple added the Canvas Bugs related to the canvas element. label Nov 22, 2023
@kkinnunen-apple kkinnunen-apple force-pushed the paths-to-cgcontext-refactor-only-1 branch from 4aa2d57 to 80181a8 Compare November 24, 2023 08:58
@kkinnunen-apple kkinnunen-apple force-pushed the paths-to-cgcontext-refactor-only-1 branch from 80181a8 to 25b11c9 Compare November 24, 2023 09:01
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Nov 24, 2023
@kkinnunen-apple kkinnunen-apple removed the merging-blocked Applied to prevent a change from being merged label Nov 24, 2023
@kkinnunen-apple kkinnunen-apple force-pushed the paths-to-cgcontext-refactor-only-1 branch from 25b11c9 to 3e3ce5e Compare November 24, 2023 09:47
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Nov 24, 2023
@kkinnunen-apple kkinnunen-apple removed the merging-blocked Applied to prevent a change from being merged label Nov 24, 2023
@kkinnunen-apple kkinnunen-apple force-pushed the paths-to-cgcontext-refactor-only-1 branch from 3e3ce5e to ae45f40 Compare November 24, 2023 15:00
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Nov 24, 2023
@kkinnunen-apple kkinnunen-apple removed the merging-blocked Applied to prevent a change from being merged label Nov 24, 2023
@kkinnunen-apple kkinnunen-apple force-pushed the paths-to-cgcontext-refactor-only-1 branch from ae45f40 to 8b87147 Compare November 24, 2023 15:25
Comment on lines +53 to +64
void addSegment(PathSegment);
virtual void add(PathMoveTo) = 0;
virtual void add(PathLineTo) = 0;
virtual void add(PathQuadCurveTo) = 0;
virtual void add(PathBezierCurveTo) = 0;
virtual void add(PathArcTo) = 0;
virtual void add(PathArc) = 0;
virtual void add(PathEllipse) = 0;
virtual void add(PathEllipseInRect) = 0;
virtual void add(PathRect) = 0;
virtual void add(PathRoundedRect) = 0;
virtual void add(PathCloseSubpath) = 0;
Copy link
Contributor

@shallawa shallawa Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it okay to pass the PathSegment and the PathSegment data structures by value? PathRoundedRect has 12 floats and an enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think so -- the PathSegment is only passed when it's a syntactic sugar over the individual calls. So no callframe should be generated, rather the switch should operate on the caller's value.
The individual PathSegment::Data types, especially small ones, should mostly be neutral when passed as a value:
For example, add(PathMoveTo) is two floats, where as moveTo(const FloatPoint&) passes the two simple values with a pointer indirection. Here the PathMoveTo variant should be a progression.

However, very big ones like PathRoundedRect, the ones that might have unread, redundant values, is a bit of a question mark. I would imagine that the effect is neutral, but I have not benchmarked it extensively.

Mostly I think the pass-by-value is progression if:

  • There is not many call layers that just forward the parameters (there is not)
  • There is not many variables that are passed redundantly and never read by the payload function (all except rounded rect variant)

At least if the problem is the latter, redundant values being passed, this would mean that the command is overloaded: two different methods in one. This is the case with "add rounded rect with platform strategy", "add rounded rect with webkit strategy". So a better, more consistent approach to fix that particular problem would be tahat these two could be split into two separate methods, if they mean different things.

Comment on lines -155 to +138
ensureImpl().addLineTo(point);
ensureImpl().add(PathLineTo { point });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the Impl is PathCG, this adds the overhead of copying the point to structure here. Then getting the address of the point in the structure in PathCG::add(PathMoveTo).

So I do not see the benefit of this change so far. Maybe in #10594, I will see the benefit of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the Impl is PathCG, this adds the overhead of copying the point to structure here.

No, I don't think there's an additional overhead.
Before, the pointer read to registers happened in PathCG::moveTo.
After, the pointer read to registers happens in Path::addLineTo.
It's the same amount of reads.

Then getting the address of the point in the structure in PathCG::add(PathMoveTo).

No, there's no pointers anymore in PathCG::add. It's pass by value.
I think the values are already in the registers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I do not see the benefit of this change so far. Maybe in #10594, I will see the benefit of it.

The intended benefit of having uniform name and passing the PathSegment::Data values as values:
It is done to be able to write polymorphic functions (==templates) over PathSegment.

For PathImpl::add over moveTo,bezierCurveTo,arcTo, it's evident: we are able to deconstruct PathSegment and apply the deconstructed variants in uniform fashion, and we don't need to further deconstruct the various PathMoveTo, ..., structs into moveTo(a,b,c,) calls redundantly.

@kkinnunen-apple kkinnunen-apple added the merge-queue Applied to send a pull request to merge-queue label Nov 28, 2023
https://bugs.webkit.org/show_bug.cgi?id=265247
rdar://118717060

Reviewed by Said Abou-Hallawa.

PathImpl and PathSegment were coupled:
PathImpl::appendSegment would call into PathSegment::addToImpl
PathSegment::addToImpl would call into PathImpl

This would be more complex than needed and also limit the PathSegments
to be only used with PathImpl.

Instead:
  - PathSegment is the data that is being held -- no actions toward any
    class that does actual work on the data.
  - PathImpl knows how to use the path segment types: PathImpl::add()
    for each path segment type.
  - PathImpl knows how to use the PathSegment variant:
    PathImpl::addSegment() for the PathSegment, doing generic add() over
    the variants.
  - Make each member function for adding segments PathImpl::add(). This
    way generic algorithms over the variants are consistent to write.
  - The PathImpl::add() parameters are by-value to avoid introducing
    indirection, the arguments are always used.

Construct PathCG, PathCairo from PathStream without applySegments, as
the PathStream segment list can be just iterated.

This works towards being able to play back a PathSegment list to a
CGContext.

* Source/WebCore/platform/graphics/PathImpl.cpp:
(WebCore::PathImpl::appendSegment): Deleted.
* Source/WebCore/platform/graphics/PathImpl.h:
(WebCore::addPathSegment):
* Source/WebCore/platform/graphics/PathSegment.cpp:
(WebCore::PathSegment::addToImpl const): Deleted.
* Source/WebCore/platform/graphics/PathSegment.h:
(WebCore::PathSegment::addTo const):
* Source/WebCore/platform/graphics/PathSegmentData.cpp:
(WebCore::PathMoveTo::addToImpl const): Deleted.
(WebCore::PathLineTo::addToImpl const): Deleted.
(WebCore::PathQuadCurveTo::addToImpl const): Deleted.
(WebCore::PathBezierCurveTo::addToImpl const): Deleted.
(WebCore::PathArcTo::addToImpl const): Deleted.
(WebCore::PathArc::addToImpl const): Deleted.
(WebCore::PathEllipse::addToImpl const): Deleted.
(WebCore::PathEllipseInRect::addToImpl const): Deleted.
(WebCore::PathRect::addToImpl const): Deleted.
(WebCore::PathRoundedRect::addToImpl const): Deleted.
(WebCore::PathDataLine::addToImpl const): Deleted.
(WebCore::PathDataQuadCurve::addToImpl const): Deleted.
(WebCore::PathDataBezierCurve::addToImpl const): Deleted.
(WebCore::PathDataArc::addToImpl const): Deleted.
(WebCore::PathCloseSubpath::addToImpl const): Deleted.
* Source/WebCore/platform/graphics/PathSegmentData.h:
* Source/WebCore/platform/graphics/cairo/PathCairo.cpp:
(WebCore::PathCairo::create):
* Source/WebCore/platform/graphics/cg/PathCG.cpp:
(WebCore::PathCG::create):

Canonical link: https://commits.webkit.org/271199@main
@webkit-commit-queue
Copy link
Collaborator

Committed 271199@main (d132cc1): https://commits.webkit.org/271199@main

Reviewed commits have been landed. Closing PR #20819 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit d132cc1 into WebKit:main Nov 28, 2023
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Canvas Bugs related to the canvas element.
Projects
None yet
5 participants