SixLabors / ImageSharp.Drawing

:pen: Extensions to ImageSharp containing a cross-platform 2D polygon manipulation API and drawing operations.
https://sixlabors.com/products/imagesharp-drawing/
Other
285 stars 39 forks source link

Cache ScanEdgeCollection in InternalPath #104

Open antonfirsov opened 3 years ago

antonfirsov commented 3 years ago

Creation of ScanEdgeCollection can take up to ~7% according to profiler results, so this seems to be a reasonable optimization. Instances shall be keyed by subsampling since y values in ScanEdge-s are rounded to subpixel scanlines.

Related: #103

JimBobSquarePants commented 1 year ago

Do you have any pointers here. I don't really follow the issue.

antonfirsov commented 1 year ago

Most (all?) IPath implementations cache their tessellation data as an InternalPath member. Whenever we render an IPath (InternalPath) with a given subsampling, we first convert the InternalPath to a TessellatedMultipolygon (which is just a more efficient storage for the points in InternalPath), then create a ScanEdgeCollection which is a data structure that already depends on the value of subsampling.

Assuming it's a common use case to render an IPath multiple times (which might be a wrong assumption! ... we should analyze use-cases), we could create a cache of ScanEdgeCollections inside InternalPath, so we don't need to recreate it on each render run. Since ScanEdgeCollection depends on subsampling, we should cache (int, ScanEdgeCollection) pairs. In fact one pair should be enough, since we don't expect users to switch the subsampling ratio between render runs.

JimBobSquarePants commented 1 year ago

Just had a read of the code there. You're on your own. Bit too complicated for me just now! 😆