selection: rework how we update a selection

Before this patch, each selection update would result in grid covered
by the selection being walked *three* times. First to “premark” the
area that *will* be selected after the update, then again to unmark
the previous selection (excluding the cells that were premarked - but
the cells are still iterated), and then one more time to finalize the
selection state in the grid.

Furthermore, each time a frame is rendered, the entire selection were
iterated again, to ensure all the cells have their ‘selected’ bit
set.

This quickly gets *very* slow.

This patch takes a completely different approach. Instead of looking
at the selection as a range of cells to iterate, we view it as an
area, or region. Thus, on each update, we have to regions: the region
representing the previous selection, and the region representing the
to-be selection.

By diffing these two regions, we get two new regions: one that
represents the cells that were selected, but aren’t any more, and one
that represents the cells that previously were not selected, but now
will be.

We implement the regions using pixman regions. By subtracting the
current selection from the previous selection, we get the region
representing the cells that are no longer selected, and that should be
unmarked.

By subtracting the previous selection from the current, we get the
region representing the cells that was added to the selection in this
update, and that should be marked.

selection_dirty_cells() is rewritten in a similar manner. We create
pixman regions for the selection, and the current scrollback view. The
intersection represents the (selected) cells that are visible. These
need to iterated and marked as being selected.

Closes #1114
This commit is contained in:
Daniel Eklöf 2022-07-28 18:45:25 +02:00
parent b8506bbea0
commit fa2d9f8699
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 196 additions and 110 deletions

View file

@ -98,12 +98,14 @@
highlighted correctly.
* Selection not being cancelled correctly when scrolled out.
* Extending a multi-page selection behaving inconsistently.
* Poor performance when making very large selections ([#1114][1114]).
[1055]: https://codeberg.org/dnkl/foot/issues/1055
[1092]: https://codeberg.org/dnkl/foot/issues/1092
[1097]: https://codeberg.org/dnkl/foot/issues/1097
[1111]: https://codeberg.org/dnkl/foot/issues/1111
[1120]: https://codeberg.org/dnkl/foot/issues/1120
[1114]: https://codeberg.org/dnkl/foot/issues/1114
### Security