From 13bf7edad251df9943bd75665a3510535849b0ac Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Wed, 14 Oct 2026 17:36:22 +0300 Subject: Deduplicate scroll and SIMD paths while preserving performance --- src/screen.c | 128 ++++++++++++++++------------------------------------------- 1 file changed, 34 insertions(+), 94 deletions(-) (limited to 'src/screen.c') diff --git a/src/screen.c b/src/screen.c index d9dfe31..bd65564 100644 --- a/src/screen.c +++ b/src/screen.c @@ -560,6 +560,21 @@ void term_screen_erase(struct term *t, int mode) } } +/* Reset a recycled row's contents and identity; callers choose its version. */ +static inline void reset_scrolled_row(struct term *t, struct srow *row, bool def) +{ + row->kind = ROW_CELLS; + row->uid = ++t->next_row_uid; + if (def) { + row->len = 0; + row->flags = 0; + } else { + fill_cells(row->cells, t->cols, t->cur_fg, t->cur_bg); + row->len = (uint16_t)t->cols; + row->flags = RF_TAIL_PADDED; + } +} + static void rotate_and_clear_srows(struct term *t, struct srow *base, int height, int count, bool down, bool def) { @@ -568,50 +583,18 @@ static void rotate_and_clear_srows(struct term *t, struct srow *base, int height if (!saved) return; - if (!down) { - memcpy(saved, base, (size_t)count * sizeof(struct srow)); - memmove(base, base + count, (size_t)(height - count) * sizeof(struct srow)); - memcpy(base + height - count, saved, (size_t)count * sizeof(struct srow)); - - for (int i = 0; i < height - count; i++) - base[i].version++; - - for (int i = 0; i < count; i++) { - struct srow *dst = &base[height - count + i]; - dst->kind = ROW_CELLS; - dst->uid = ++t->next_row_uid; - dst->version = 1; - if (def) { - dst->len = 0; - dst->flags = 0; - } else { - fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg); - dst->len = (uint16_t)t->cols; - dst->flags = RF_TAIL_PADDED; - } - } - } else { - memcpy(saved, base + height - count, (size_t)count * sizeof(struct srow)); - memmove(base + count, base, (size_t)(height - count) * sizeof(struct srow)); - memcpy(base, saved, (size_t)count * sizeof(struct srow)); - - for (int i = 0; i < height - count; i++) - base[count + i].version++; - - for (int i = 0; i < count; i++) { - struct srow *dst = &base[i]; - dst->kind = ROW_CELLS; - dst->uid = ++t->next_row_uid; - dst->version = 1; - if (def) { - dst->len = 0; - dst->flags = 0; - } else { - fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg); - dst->len = (uint16_t)t->cols; - dst->flags = RF_TAIL_PADDED; - } - } + int kept = down ? count : 0; + int cleared = down ? 0 : height - count; + memcpy(saved, base + (down ? height - count : 0), (size_t)count * sizeof(struct srow)); + memmove(base + kept, base + (down ? 0 : count), + (size_t)(height - count) * sizeof(struct srow)); + memcpy(base + cleared, saved, (size_t)count * sizeof(struct srow)); + for (int i = 0; i < height - count; i++) + base[kept + i].version++; + for (int i = 0; i < count; i++) { + struct srow *dst = &base[cleared + i]; + reset_scrolled_row(t, dst, def); + dst->version = 1; } if (saved != tmp) free(saved); @@ -659,17 +642,8 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count, if (history) { screen_new_row(t, row); } else { - row->kind = ROW_CELLS; - row->uid = ++t->next_row_uid; + reset_scrolled_row(t, row, def); row->version++; - if (def) { - row->len = 0; - row->flags = 0; - } else { - fill_cells(row->cells, t->cols, t->cur_fg, t->cur_bg); - row->len = (uint16_t)t->cols; - row->flags = RF_TAIL_PADDED; - } } } int new_top = orig_top + count; @@ -696,17 +670,8 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count, int p = orig_top + (rows - count) + i; if (p >= rows) p -= rows; struct srow *row = &s->slot[p]; - row->kind = ROW_CELLS; - row->uid = ++t->next_row_uid; + reset_scrolled_row(t, row, def); row->version = 1; - if (def) { - row->len = 0; - row->flags = 0; - } else { - fill_cells(row->cells, t->cols, t->cur_fg, t->cur_bg); - row->len = (uint16_t)t->cols; - row->flags = RF_TAIL_PADDED; - } } int new_top = orig_top - count; if (new_top < 0) new_top += rows; @@ -730,36 +695,11 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count, if (count == height) { int start = phys_row(t, top); - if (start + height <= s->rows) { - for (int i = 0; i < height; i++) { - struct srow *dst = &s->slot[start + i]; - dst->kind = ROW_CELLS; - dst->uid = ++t->next_row_uid; - dst->version++; - if (def) { - dst->len = 0; - dst->flags = 0; - } else { - fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg); - dst->len = (uint16_t)t->cols; - dst->flags = RF_TAIL_PADDED; - } - } - } else { - for (int y = top; y <= bottom; y++) { - struct srow *dst = screen_get_row(s, y); - dst->kind = ROW_CELLS; - dst->uid = ++t->next_row_uid; - dst->version++; - if (def) { - dst->len = 0; - dst->flags = 0; - } else { - fill_cells(dst->cells, t->cols, t->cur_fg, t->cur_bg); - dst->len = (uint16_t)t->cols; - dst->flags = RF_TAIL_PADDED; - } - } + for (int i = 0; i < height; i++) { + int p = start + i; + struct srow *dst = &s->slot[p >= s->rows ? p - s->rows : p]; + reset_scrolled_row(t, dst, def); + dst->version++; } } else { int start = phys_row(t, top); -- cgit v1.2.3