mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
render: merge wl surface damage for consecutive dirty rows
This commit is contained in:
parent
09bdf20aa0
commit
9f21799cb2
1 changed files with 60 additions and 43 deletions
103
render.c
103
render.c
|
|
@ -865,6 +865,15 @@ render_worker_thread(void *_ctx)
|
|||
struct buffer *buf = term->render.workers.buf;
|
||||
bool frame_done = false;
|
||||
|
||||
/* Translate offset-relative cursor row to view-relative */
|
||||
struct coord cursor = {-1, -1};
|
||||
if (!term->hide_cursor) {
|
||||
cursor = term->grid->cursor.point;
|
||||
cursor.row += term->grid->offset;
|
||||
cursor.row -= term->grid->view;
|
||||
cursor.row &= term->grid->num_rows - 1;
|
||||
}
|
||||
|
||||
while (!frame_done) {
|
||||
mtx_lock(lock);
|
||||
assert(tll_length(term->render.workers.queue) > 0);
|
||||
|
|
@ -872,18 +881,12 @@ render_worker_thread(void *_ctx)
|
|||
int row_no = tll_pop_front(term->render.workers.queue);
|
||||
mtx_unlock(lock);
|
||||
|
||||
/* Translate offset-relative cursor row to view-relative */
|
||||
struct coord cursor = term->grid->cursor.point;
|
||||
cursor.row += term->grid->offset;
|
||||
cursor.row -= term->grid->view;
|
||||
cursor.row &= term->grid->num_rows - 1;
|
||||
|
||||
switch (row_no) {
|
||||
default: {
|
||||
assert(buf != NULL);
|
||||
|
||||
struct row *row = grid_row_in_view(term->grid, row_no);
|
||||
int cursor_col = !term->hide_cursor && cursor.row == row_no ? cursor.col : -1;
|
||||
int cursor_col = cursor.row == row_no ? cursor.col : -1;
|
||||
|
||||
render_row(term, buf->pix[my_id], row, row_no, cursor_col);
|
||||
break;
|
||||
|
|
@ -1412,31 +1415,67 @@ grid_render(struct terminal *term)
|
|||
row->dirty = true;
|
||||
}
|
||||
|
||||
/* Translate offset-relative row to view-relative, unless cursor
|
||||
* is hidden, then we just set it to -1 */
|
||||
struct coord cursor = {-1, -1};
|
||||
if (!term->hide_cursor) {
|
||||
cursor = term->grid->cursor.point;
|
||||
cursor.row += term->grid->offset;
|
||||
cursor.row -= term->grid->view;
|
||||
cursor.row &= term->grid->num_rows - 1;
|
||||
}
|
||||
|
||||
if (term->render.workers.count > 0) {
|
||||
|
||||
mtx_lock(&term->render.workers.lock);
|
||||
|
||||
term->render.workers.buf = buf;
|
||||
for (size_t i = 0; i < term->render.workers.count; i++)
|
||||
sem_post(&term->render.workers.start);
|
||||
|
||||
assert(tll_length(term->render.workers.queue) == 0);
|
||||
}
|
||||
|
||||
for (int r = 0; r < term->rows; r++) {
|
||||
struct row *row = grid_row_in_view(term->grid, r);
|
||||
int first_dirty_row = -1;
|
||||
for (int r = 0; r < term->rows; r++) {
|
||||
struct row *row = grid_row_in_view(term->grid, r);
|
||||
|
||||
if (!row->dirty)
|
||||
continue;
|
||||
|
||||
tll_push_back(term->render.workers.queue, r);
|
||||
row->dirty = false;
|
||||
|
||||
wl_surface_damage_buffer(
|
||||
term->window->surface,
|
||||
term->margins.left, term->margins.top + r * term->cell_height,
|
||||
term->width - term->margins.left - term->margins.right, term->cell_height);
|
||||
if (!row->dirty) {
|
||||
if (first_dirty_row >= 0) {
|
||||
wl_surface_damage_buffer(
|
||||
term->window->surface,
|
||||
term->margins.left,
|
||||
term->margins.top + first_dirty_row * term->cell_height,
|
||||
term->width - term->margins.left - term->margins.right,
|
||||
(r - first_dirty_row) * term->cell_height);
|
||||
}
|
||||
first_dirty_row = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (first_dirty_row < 0)
|
||||
first_dirty_row = r;
|
||||
|
||||
row->dirty = false;
|
||||
|
||||
if (term->render.workers.count > 0)
|
||||
tll_push_back(term->render.workers.queue, r);
|
||||
|
||||
else {
|
||||
int cursor_col = cursor.row == r ? cursor.col : -1;
|
||||
render_row(term, buf->pix[0], row, r, cursor_col);
|
||||
}
|
||||
|
||||
if (first_dirty_row >= 0) {
|
||||
wl_surface_damage_buffer(
|
||||
term->window->surface,
|
||||
term->margins.left,
|
||||
term->margins.top + first_dirty_row * term->cell_height,
|
||||
term->width - term->margins.left - term->margins.right,
|
||||
(term->rows - first_dirty_row) * term->cell_height);
|
||||
}
|
||||
}
|
||||
|
||||
/* Signal workers the frame is done */
|
||||
if (term->render.workers.count > 0) {
|
||||
for (size_t i = 0; i < term->render.workers.count; i++)
|
||||
tll_push_back(term->render.workers.queue, -1);
|
||||
mtx_unlock(&term->render.workers.lock);
|
||||
|
|
@ -1444,28 +1483,6 @@ grid_render(struct terminal *term)
|
|||
for (size_t i = 0; i < term->render.workers.count; i++)
|
||||
sem_wait(&term->render.workers.done);
|
||||
term->render.workers.buf = NULL;
|
||||
} else {
|
||||
for (int r = 0; r < term->rows; r++) {
|
||||
struct row *row = grid_row_in_view(term->grid, r);
|
||||
|
||||
if (!row->dirty)
|
||||
continue;
|
||||
|
||||
/* Translate offset-relative row to view-relative */
|
||||
struct coord cursor = term->grid->cursor.point;
|
||||
cursor.row += term->grid->offset;
|
||||
cursor.row -= term->grid->view;
|
||||
cursor.row &= term->grid->num_rows - 1;
|
||||
|
||||
int cursor_col = !term->hide_cursor && cursor.row == r ? cursor.col : -1;
|
||||
render_row(term, buf->pix[0], row, r, cursor_col);
|
||||
row->dirty = false;
|
||||
|
||||
wl_surface_damage_buffer(
|
||||
term->window->surface,
|
||||
term->margins.left, term->margins.top + r * term->cell_height,
|
||||
term->width - term->margins.left - term->margins.right, term->cell_height);
|
||||
}
|
||||
}
|
||||
|
||||
render_sixel_images(term, buf->pix[0]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue