For solid color fills (with alpha = 255), the rasterizer now tracks
spans of solid colors within a scanline and fills the entire span with
a single call to fast_u32_fill().
This gave up to a 1.5x speedup drawing the Ghostscript Tiger within
SerenityOS.
This avoids doing pointless plotting for scanlines that will never be
seen.
Note: This currently can only clip edges vertically. Horizontal clipping
is more tricky, since edges that are not visible can still change how
things accumulate across the scanline.
Fixes#22382
Sadly, this causes a bunch of LibWeb test churn as this change
imperceptibly changes the final rasterized output.
It seems for very narrow tall paths it is possible for the dxdy value
to round to a value (that after many repeated additions) overshoots
the desired end x. This caused a (rather rare) crash on this 3D canvas
demo: https://www.kevs3d.co.uk/dev/html5logo/. For now, lets just avoid
a crash here. This does not make any noticeable visual differences on
the demos I tired.
This was previously masked by sorting the edges on max_y, but if the
last added edge pointed to an edge that ended on the current scanline,
that edge (and what it points to) would also end up added to the active
edges. These edges would then never get removed, and break things very
badly!
Remove SplitLineSegment and replace it with a FloatLine, nobody was
interested in its extra fields anymore. Also, remove the sorting of
the split segments, this really should not have been done here
anyway, and is not required by the rasterizer anymore. Keeping the
segments in stroke order will also make it possible to generate
stroked path geometry (in future).
This is an implementation of the scanline edge-flag algorithm for
antialiased path filling described here:
https://mlab.taik.fi/~kkallio/antialiasing/EdgeFlagAA.pdf
The initial implementation does not try to implement every possible
optimization in favour of keeping things simple. However, it does
support:
- Both evenodd and nonzero fill rules
- Applying paint styles/gradients
- A range of samples per pixel (8, 16, 32)
- Very nice antialiasing :^)
This replaces the previous path filling code, that only really applied
antialiasing in the x-axis.
There's some very nice improvements around the web with this change,
especially for small icons. Strokes are still a bit wonky, as they don't
yet use this rasterizer, but I think it should be possible to convert
them to do so.