mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-14 08:21:27 -04:00
render: get rid of 'all-clean' detection
Instead of trying to figure out if we had to render something (i.e. something in the grid was dirty), and using that to determine whether to post a callback or not, we now let render_refresh() set a flag indication we need to render another frame. This simplifies render_grid(), which now _always_ renders, and pushes it to the compositor. The callback handler checks the pending flag and simply doesn't call render_grid() when there's no more pending state to render. This ends up reducing the number of wakeups when e.g. having a blinking cursor.
This commit is contained in:
parent
418ff5bcd9
commit
c22ae98729
3 changed files with 13 additions and 22 deletions
31
render.c
31
render.c
|
|
@ -294,7 +294,6 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Glyph surface is an alpha mask */
|
/* Glyph surface is an alpha mask */
|
||||||
/* TODO: cache */
|
|
||||||
pixman_image_t *src = pixman_image_create_solid_fill(&fg);
|
pixman_image_t *src = pixman_image_create_solid_fill(&fg);
|
||||||
pixman_image_composite32(
|
pixman_image_composite32(
|
||||||
PIXMAN_OP_OVER, src, glyph->pix, pix, 0, 0, 0, 0,
|
PIXMAN_OP_OVER, src, glyph->pix, pix, 0, 0, 0, 0,
|
||||||
|
|
@ -457,7 +456,6 @@ grid_render(struct terminal *term)
|
||||||
wl_surface_attach(term->window->surface, buf->wl_buf, 0, 0);
|
wl_surface_attach(term->window->surface, buf->wl_buf, 0, 0);
|
||||||
|
|
||||||
pixman_image_t *pix = buf->pix;
|
pixman_image_t *pix = buf->pix;
|
||||||
bool all_clean = tll_length(term->grid->scroll_damage) == 0;
|
|
||||||
|
|
||||||
/* If we resized the window, or is flashing, or just stopped flashing */
|
/* If we resized the window, or is flashing, or just stopped flashing */
|
||||||
if (term->render.last_buf != buf ||
|
if (term->render.last_buf != buf ||
|
||||||
|
|
@ -521,9 +519,12 @@ grid_render(struct terminal *term)
|
||||||
|
|
||||||
/* Erase old cursor (if we rendered a cursor last time) */
|
/* Erase old cursor (if we rendered a cursor last time) */
|
||||||
if (term->render.last_cursor.cell != NULL) {
|
if (term->render.last_cursor.cell != NULL) {
|
||||||
|
|
||||||
struct cell *cell = term->render.last_cursor.cell;
|
struct cell *cell = term->render.last_cursor.cell;
|
||||||
struct coord at = term->render.last_cursor.in_view;
|
struct coord at = term->render.last_cursor.in_view;
|
||||||
|
term->render.last_cursor.cell = NULL;
|
||||||
|
|
||||||
|
/* If cell already is dirty, it will be rendered anyway */
|
||||||
if (cell->attrs.clean) {
|
if (cell->attrs.clean) {
|
||||||
cell->attrs.clean = 0;
|
cell->attrs.clean = 0;
|
||||||
render_cell(term, pix, cell, at.col, at.row, false);
|
render_cell(term, pix, cell, at.col, at.row, false);
|
||||||
|
|
@ -534,15 +535,6 @@ grid_render(struct terminal *term)
|
||||||
term->y_margin + at.row * term->cell_height,
|
term->y_margin + at.row * term->cell_height,
|
||||||
term->cell_width, term->cell_height);
|
term->cell_width, term->cell_height);
|
||||||
}
|
}
|
||||||
term->render.last_cursor.cell = NULL;
|
|
||||||
|
|
||||||
if (term->render.last_cursor.actual.col != term->cursor.point.col ||
|
|
||||||
term->render.last_cursor.actual.row != term->cursor.point.row)
|
|
||||||
{
|
|
||||||
/* Detect cursor movement - we don't dirty cells touched
|
|
||||||
* by the cursor, since only the final cell matters. */
|
|
||||||
all_clean = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tll_foreach(term->grid->scroll_damage, it) {
|
tll_foreach(term->grid->scroll_damage, it) {
|
||||||
|
|
@ -589,7 +581,6 @@ grid_render(struct terminal *term)
|
||||||
mtx_unlock(&term->render.workers.lock);
|
mtx_unlock(&term->render.workers.lock);
|
||||||
|
|
||||||
row->dirty = false;
|
row->dirty = false;
|
||||||
all_clean = false;
|
|
||||||
|
|
||||||
wl_surface_damage_buffer(
|
wl_surface_damage_buffer(
|
||||||
term->window->surface,
|
term->window->surface,
|
||||||
|
|
@ -610,9 +601,7 @@ grid_render(struct terminal *term)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
render_row(term, pix, row, r);
|
render_row(term, pix, row, r);
|
||||||
|
|
||||||
row->dirty = false;
|
row->dirty = false;
|
||||||
all_clean = false;
|
|
||||||
|
|
||||||
wl_surface_damage_buffer(
|
wl_surface_damage_buffer(
|
||||||
term->window->surface,
|
term->window->surface,
|
||||||
|
|
@ -674,12 +663,6 @@ grid_render(struct terminal *term)
|
||||||
cols_updated * term->cell_width, term->cell_height);
|
cols_updated * term->cell_width, term->cell_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_clean) {
|
|
||||||
buf->busy = false;
|
|
||||||
wl_display_flush(term->wl->display);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (term->flash.active) {
|
if (term->flash.active) {
|
||||||
/* Note: alpha is pre-computed in each color component */
|
/* Note: alpha is pre-computed in each color component */
|
||||||
/* TODO: dim while searching */
|
/* TODO: dim while searching */
|
||||||
|
|
@ -722,7 +705,11 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
|
||||||
assert(term->window->frame_callback == wl_callback);
|
assert(term->window->frame_callback == wl_callback);
|
||||||
wl_callback_destroy(wl_callback);
|
wl_callback_destroy(wl_callback);
|
||||||
term->window->frame_callback = NULL;
|
term->window->frame_callback = NULL;
|
||||||
grid_render(term);
|
|
||||||
|
if (term->render.pending) {
|
||||||
|
term->render.pending = false;
|
||||||
|
grid_render(term);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -960,4 +947,6 @@ render_refresh(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (term->window->frame_callback == NULL)
|
if (term->window->frame_callback == NULL)
|
||||||
grid_render(term);
|
grid_render(term);
|
||||||
|
else
|
||||||
|
term->render.pending = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,8 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
||||||
NULL);
|
NULL);
|
||||||
term->delayed_render_timer.is_armed = true;
|
term->delayed_render_timer.is_armed = true;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
term->render.pending = true;
|
||||||
|
|
||||||
if (events & EPOLLHUP)
|
if (events & EPOLLHUP)
|
||||||
return term_shutdown(term);
|
return term_shutdown(term);
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,7 @@ struct terminal {
|
||||||
struct cell *cell; /* For easy access to content */
|
struct cell *cell; /* For easy access to content */
|
||||||
} last_cursor;
|
} last_cursor;
|
||||||
|
|
||||||
|
bool pending;
|
||||||
struct buffer *last_buf; /* Buffer we rendered to last time */
|
struct buffer *last_buf; /* Buffer we rendered to last time */
|
||||||
bool was_flashing; /* Flash was active last time we rendered */
|
bool was_flashing; /* Flash was active last time we rendered */
|
||||||
bool was_searching;
|
bool was_searching;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue