render: merge wl surface damage for consecutive dirty rows

This commit is contained in:
Daniel Eklöf 2020-07-13 13:44:52 +02:00
parent 09bdf20aa0
commit 9f21799cb2
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

103
render.c
View file

@ -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]);