mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
terminal: scrolling: prefetch cells of scrolled in lines
Since newly scrolled in lines will be erased, we want them in the cache. So, allocate and prefetch new lines, then repair non-scrolling regions (to give the prefetch time to actually fetch the data). Finally, erase the newly scrolled in lines. This also fixes a bug where the fixup for the non-scrolling regions could crash on an unallocated row (we were accessing rows that would be, but hadn't yet been, scrolled in).
This commit is contained in:
parent
1d7bf3fbca
commit
e4a631f7f0
1 changed files with 28 additions and 17 deletions
45
terminal.c
45
terminal.c
|
|
@ -151,15 +151,6 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
|||
|
||||
assert(rows < term->rows && "unimplemented");
|
||||
|
||||
/* Top non-scrolling region */
|
||||
for (int i = region.start - 1; i >= 0; i--)
|
||||
grid_swap_row(term->grid, i, i + rows);
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
for (int i = term->rows - 1; i >= region.end; i--)
|
||||
grid_swap_row(term->grid, i, i + rows);
|
||||
|
||||
/* Offset grid origin */
|
||||
bool view_follows = term->grid->view == term->grid->offset;
|
||||
term->grid->offset += rows;
|
||||
term->grid->offset %= term->grid->num_rows;
|
||||
|
|
@ -167,11 +158,28 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
|||
if (view_follows)
|
||||
term->grid->view = term->grid->offset;
|
||||
|
||||
for (int r = max(region.end - rows, 0); r < region.end; r++) {
|
||||
struct row *row = grid_row(term->grid, r);
|
||||
erase_line(term, row);
|
||||
/*
|
||||
* This loop serves two purposes:
|
||||
* 1) ensure all visible lines are *allocated*
|
||||
* 2) prefetch the cells - this makes life easier for erase_line() below
|
||||
*/
|
||||
for (int r = max(region.end - rows, 0); r < term->rows; r++) {
|
||||
struct row *row = grid_row(term->grid, r);
|
||||
__builtin_prefetch(row->cells, 1, 3);
|
||||
}
|
||||
|
||||
/* Top non-scrolling region. */
|
||||
for (int i = region.start - 1; i >= 0; i--)
|
||||
grid_swap_row(term->grid, i - rows, i);
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
for (int i = term->rows - 1; i >= region.end; i--)
|
||||
grid_swap_row(term->grid, i - rows, i);
|
||||
|
||||
/* Erase scrolled in lines */
|
||||
for (int r = max(region.end - rows, 0); r < region.end; r++)
|
||||
erase_line(term, grid_row(term->grid, r));
|
||||
|
||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
||||
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
|
||||
}
|
||||
|
|
@ -192,13 +200,17 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
assert(rows < term->rows && "unimplemented");
|
||||
|
||||
bool view_follows = term->grid->view == term->grid->offset;
|
||||
|
||||
term->grid->offset += term->grid->num_rows - rows;
|
||||
term->grid->offset %= term->grid->num_rows;
|
||||
|
||||
if (view_follows)
|
||||
term->grid->view = term->grid->offset;
|
||||
|
||||
for (int r = 0; r < min(region.start + rows, region.end); r++) {
|
||||
struct row *row = grid_row(term->grid, r);
|
||||
__builtin_prefetch(row->cells, 1, 3);
|
||||
}
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
for (int i = region.end + rows; i < term->rows + rows; i++)
|
||||
grid_swap_row(term->grid, i, i - rows);
|
||||
|
|
@ -207,10 +219,9 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
for (int i = 0 + rows; i < region.start + rows; i++)
|
||||
grid_swap_row(term->grid, i, i - rows);
|
||||
|
||||
term_erase(
|
||||
term,
|
||||
&(struct coord){0, region.start},
|
||||
&(struct coord){term->cols - 1, min(region.start + rows, region.end) - 1});
|
||||
/* Erase scrolled in lines */
|
||||
for (int r = region.start; r < min(region.start + rows, region.end); r++)
|
||||
erase_line(term, grid_row(term->grid, r));
|
||||
|
||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue