mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-02 07:15:31 -04: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;
|
struct buffer *buf = term->render.workers.buf;
|
||||||
bool frame_done = false;
|
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) {
|
while (!frame_done) {
|
||||||
mtx_lock(lock);
|
mtx_lock(lock);
|
||||||
assert(tll_length(term->render.workers.queue) > 0);
|
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);
|
int row_no = tll_pop_front(term->render.workers.queue);
|
||||||
mtx_unlock(lock);
|
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) {
|
switch (row_no) {
|
||||||
default: {
|
default: {
|
||||||
assert(buf != NULL);
|
assert(buf != NULL);
|
||||||
|
|
||||||
struct row *row = grid_row_in_view(term->grid, row_no);
|
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);
|
render_row(term, buf->pix[my_id], row, row_no, cursor_col);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1412,31 +1415,67 @@ grid_render(struct terminal *term)
|
||||||
row->dirty = true;
|
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) {
|
if (term->render.workers.count > 0) {
|
||||||
|
|
||||||
mtx_lock(&term->render.workers.lock);
|
mtx_lock(&term->render.workers.lock);
|
||||||
|
|
||||||
term->render.workers.buf = buf;
|
term->render.workers.buf = buf;
|
||||||
for (size_t i = 0; i < term->render.workers.count; i++)
|
for (size_t i = 0; i < term->render.workers.count; i++)
|
||||||
sem_post(&term->render.workers.start);
|
sem_post(&term->render.workers.start);
|
||||||
|
|
||||||
assert(tll_length(term->render.workers.queue) == 0);
|
assert(tll_length(term->render.workers.queue) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (int r = 0; r < term->rows; r++) {
|
int first_dirty_row = -1;
|
||||||
struct row *row = grid_row_in_view(term->grid, r);
|
for (int r = 0; r < term->rows; r++) {
|
||||||
|
struct row *row = grid_row_in_view(term->grid, r);
|
||||||
|
|
||||||
if (!row->dirty)
|
if (!row->dirty) {
|
||||||
continue;
|
if (first_dirty_row >= 0) {
|
||||||
|
wl_surface_damage_buffer(
|
||||||
tll_push_back(term->render.workers.queue, r);
|
term->window->surface,
|
||||||
row->dirty = false;
|
term->margins.left,
|
||||||
|
term->margins.top + first_dirty_row * term->cell_height,
|
||||||
wl_surface_damage_buffer(
|
term->width - term->margins.left - term->margins.right,
|
||||||
term->window->surface,
|
(r - first_dirty_row) * term->cell_height);
|
||||||
term->margins.left, term->margins.top + r * term->cell_height,
|
}
|
||||||
term->width - term->margins.left - term->margins.right, 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++)
|
for (size_t i = 0; i < term->render.workers.count; i++)
|
||||||
tll_push_back(term->render.workers.queue, -1);
|
tll_push_back(term->render.workers.queue, -1);
|
||||||
mtx_unlock(&term->render.workers.lock);
|
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++)
|
for (size_t i = 0; i < term->render.workers.count; i++)
|
||||||
sem_wait(&term->render.workers.done);
|
sem_wait(&term->render.workers.done);
|
||||||
term->render.workers.buf = NULL;
|
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]);
|
render_sixel_images(term, buf->pix[0]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue