vello_common: move subpath closing logic into flatten#1340
vello_common: move subpath closing logic into flatten#1340tomcur merged 1 commit intolinebender:mainfrom
flatten#1340Conversation
This is just a logic change and slight simplification of the lines
representation. By moving the burden of closing input subpaths to
flattening itself, this will allow to, e.g., cull geometry at the level
of Bèziers. Before, the closing of subpaths lived as a post-processing
step after flattening.
The actual change that starts using this for something more exciting is
in a follow-up PR.
This by itself does not really bring down timings (plus noise makes it
hard to measure).
```
flatten/Ghostscript_Tiger
time: [203.93 µs 204.28 µs 204.68 µs]
change: [-2.1022% -1.8481% -1.5684%] (p = 0.00 < 0.05)
Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
10 (10.00%) high mild
2 (2.00%) high severe
flatten/paris-30k time: [12.222 ms 12.298 ms 12.384 ms]
change: [+0.7747% +1.3966% +2.2290%] (p = 0.00 < 0.05)
Change within noise threshold.
Found 13 outliers among 100 measurements (13.00%)
13 (13.00%) high severe
```
LaurenzV
left a comment
There was a problem hiding this comment.
Not seeing anything that speaks against this, but it's not entirely clear to me why it's necessary. If culling of cubic's happens before flattening, why does it matter whether we close unclosed sub-paths during flattening or afterwards? 🤔
We need to ensure open input subpaths get closed at some point (as we've been doing before), but then want to allow open subpaths later in rendering for culling reasons. Say we we have a path like the following, with the box describing the viewport and The two elements of that path that matter for rendering are the diagonal line and the left-of-viewport vertical line, and we'd want to render as follows. If we cull the three elements that do not matter, and as a post-processing step enforce paths to be closed, we instead get |
|
I've added the above as docstrings to #1341. |
On top of #1340. tldr: If only some of Tiger's whiskers are visible, this results in -90% and -60% timings on flattening and tiling. This conservatively checks whether Bézier path elements we're about to flatten are outside the viewport. If they are fully to the right, top, or bottom of the viewport, the Bézier does not impact pixel coverage or coarse winding at all, and can be ignored. If it is fully to the left, it does impact pixel coverage and coarse winding, but only the element's start and endpoint y-values matter, not the exact shape, meaning we can just yield a line rather than finely flattening. The following two Ghostscript Tigers have their viewboxes reduced to `50 50 100 100` and `90 90 20 20`, down from `0 0 200 200`. Their flattening time is reduced by 52% and 90% respectively, and their tiling time by 22% and 60%. <details> <summary>Expand for the Tiger files</summary> `Ghostscript_Tiger-viewboxed.svg`  `Ghostscript_Tiger-viewboxed-extreme.svg`  </details> If more or less everything ends up being in the viewport, the additional calculation is wasted and increases flattening time by ~3%. This is of course workload-dependent. Flattening timings: ``` flatten/Ghostscript_Tiger time: [209.94 µs 210.21 µs 210.51 µs] change: [+2.6850% +3.1753% +3.6309%] (p = 0.00 < 0.05) Performance has regressed. Found 5 outliers among 100 measurements (5.00%) 4 (4.00%) high mild 1 (1.00%) high severe flatten/Ghostscript_Tiger-viewboxed time: [97.189 µs 97.287 µs 97.399 µs] change: [-52.787% -52.650% -52.514%] (p = 0.00 < 0.05) Performance has improved. Found 8 outliers among 100 measurements (8.00%) 6 (6.00%) high mild 2 (2.00%) high severe flatten/Ghostscript_Tiger-viewboxed-extreme time: [19.722 µs 19.741 µs 19.761 µs] change: [-90.311% -90.280% -90.255%] (p = 0.00 < 0.05) Performance has improved. Found 8 outliers among 100 measurements (8.00%) 7 (7.00%) high mild 1 (1.00%) high severe flatten/paris-30k time: [12.740 ms 12.764 ms 12.788 ms] change: [+2.6014% +3.3631% +4.0837%] (p = 0.00 < 0.05) Performance has regressed. Found 3 outliers among 100 measurements (3.00%) 3 (3.00%) high mild ``` Tiling timings: ``` tile/Ghostscript_Tiger time: [175.39 µs 175.79 µs 176.28 µs] change: [-0.4403% -0.0016% +0.4400%] (p = 1.00 > 0.05) No change in performance detected. Found 1 outliers among 50 measurements (2.00%) 1 (2.00%) high mild tile/Ghostscript_Tiger-viewboxed time: [78.932 µs 79.147 µs 79.409 µs] change: [-23.209% -22.803% -22.369%] (p = 0.00 < 0.05) Performance has improved. Found 5 outliers among 50 measurements (10.00%) 1 (2.00%) high mild 4 (8.00%) high severe tile/Ghostscript_Tiger-viewboxed-extreme time: [13.378 µs 13.390 µs 13.405 µs] change: [-60.417% -60.306% -60.199%] (p = 0.00 < 0.05) Performance has improved. Found 6 outliers among 50 measurements (12.00%) 2 (4.00%) high mild 4 (8.00%) high severe tile/paris-30k time: [20.970 ms 21.001 ms 21.034 ms] change: [-0.4881% -0.2397% +0.0108%] (p = 0.07 > 0.05) No change in performance detected. Found 1 outliers among 50 measurements (2.00%) 1 (2.00%) high mild ```
This is just a logic change and slight simplification of the lines representation. By moving the burden of closing input subpaths to flattening itself, this will allow, e.g., culling geometry at the level of Béziers. Before, the closing of subpaths lived as a post-processing step after flattening.
The actual change that starts using this for something more exciting is in #1341.
This by itself does not really bring down timings (plus noise makes it hard to measure).