render: fix surface damage when rendering sixels.

Pass a damage region to render_row()/render_cell() when rendering
partially visible cells underneath a sixel.

This ensures the affected regions are later reported as 'damaged' to
the Wayland compositor.

Closes #1515
This commit is contained in:
Daniel Eklöf 2023-10-12 16:24:15 +02:00
parent 4aa67e464a
commit f5f2f5a954
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 13 additions and 9 deletions

View file

@ -53,9 +53,12 @@
### Deprecated
### Removed
### Fixed
* Foot not starting on linux kernels before 6.3 ([#1514][1514]).
* Cells underneath erased sixels not being repainted ([#1515][1515]).
[1514]: https://codeberg.org/dnkl/foot/issues/1514
[1515]: https://codeberg.org/dnkl/foot/issues/1515
### Security

View file

@ -1199,7 +1199,8 @@ render_sixel_chunk(struct terminal *term, pixman_image_t *pix, const struct sixe
static void
render_sixel(struct terminal *term, pixman_image_t *pix,
const struct coord *cursor, const struct sixel *sixel)
pixman_region32_t *damage, const struct coord *cursor,
const struct sixel *sixel)
{
xassert(sixel->pix != NULL);
xassert(sixel->width >= 0);
@ -1293,8 +1294,7 @@ render_sixel(struct terminal *term, pixman_image_t *pix,
*/
if (!sixel->opaque) {
/* TODO: multithreading */
int cursor_col = cursor->row == term_row_no ? cursor->col : -1;
render_row(term, pix, NULL, row, term_row_no, cursor_col);
render_row(term, pix, damage, row, term_row_no, cursor_col);
} else {
for (int col = sixel->pos.col;
col < min(sixel->pos.col + sixel->cols, term->cols);
@ -1309,7 +1309,7 @@ render_sixel(struct terminal *term, pixman_image_t *pix,
if ((last_row_needs_erase && last_row) ||
(last_col_needs_erase && last_col))
{
render_cell(term, pix, NULL, row, term_row_no, col, cursor_col == col);
render_cell(term, pix, damage, row, term_row_no, col, cursor_col);
} else {
cell->attrs.clean = 1;
cell->attrs.confined = 1;
@ -1333,6 +1333,7 @@ render_sixel(struct terminal *term, pixman_image_t *pix,
static void
render_sixel_images(struct terminal *term, pixman_image_t *pix,
pixman_region32_t *damage,
const struct coord *cursor)
{
if (likely(tll_length(term->grid->sixel_images)) == 0)
@ -1370,7 +1371,7 @@ render_sixel_images(struct terminal *term, pixman_image_t *pix,
}
sixel_sync_cache(term, &it->item);
render_sixel(term, pix, cursor, &it->item);
render_sixel(term, pix, damage, cursor, &it->item);
}
}
@ -2974,7 +2975,10 @@ grid_render(struct terminal *term)
}
}
render_sixel_images(term, buf->pix[0], &cursor);
pixman_region32_t damage;
pixman_region32_init(&damage);
render_sixel_images(term, buf->pix[0], &damage, &cursor);
if (term->render.workers.count > 0) {
mtx_lock(&term->render.workers.lock);
@ -2985,9 +2989,6 @@ grid_render(struct terminal *term)
xassert(tll_length(term->render.workers.queue) == 0);
}
pixman_region32_t damage;
pixman_region32_init(&damage);
for (int r = 0; r < term->rows; r++) {
struct row *row = grid_row_in_view(term->grid, r);