mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-18 05:34:02 -04:00
render: add a 'clean' bit to each cell; only render cells that aren't clean
This patch takes a bit from the foreground color value in a cell (todo: split up foreground/background into bitfields with a separate field for 'foreground/background' has been set), and only re-renders cells that aren't marked as clean. Note: we use a 'clean' bit rather than a 'dirty' bit to make it easy to erase cells - we can (keep doing) do that by simply memsetting a cell range to 0.
This commit is contained in:
parent
c531795b83
commit
85ef9df586
7 changed files with 52 additions and 33 deletions
25
csi.c
25
csi.c
|
|
@ -126,7 +126,7 @@ csi_sgr(struct terminal *term)
|
||||||
case 35:
|
case 35:
|
||||||
case 36:
|
case 36:
|
||||||
case 37:
|
case 37:
|
||||||
term->vt.attrs.foreground = 1 << 31 | term->colors.regular[param - 30];
|
term->vt.attrs.foreground = 1 << 30 | term->colors.regular[param - 30];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 38: {
|
case 38: {
|
||||||
|
|
@ -141,7 +141,7 @@ csi_sgr(struct terminal *term)
|
||||||
color = term->colors.bright[idx - 8];
|
color = term->colors.bright[idx - 8];
|
||||||
else
|
else
|
||||||
color = colors256[idx];
|
color = colors256[idx];
|
||||||
term->vt.attrs.foreground = 1 << 31 | color;
|
term->vt.attrs.foreground = 1 << 30 | color;
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +152,7 @@ csi_sgr(struct terminal *term)
|
||||||
uint8_t r = term->vt.params.v[i + 2].value;
|
uint8_t r = term->vt.params.v[i + 2].value;
|
||||||
uint8_t g = term->vt.params.v[i + 3].value;
|
uint8_t g = term->vt.params.v[i + 3].value;
|
||||||
uint8_t b = term->vt.params.v[i + 4].value;
|
uint8_t b = term->vt.params.v[i + 4].value;
|
||||||
term->vt.attrs.foreground = 1 << 31 | r << 16 | g << 8 | b;
|
term->vt.attrs.foreground = 1 << 30 | r << 16 | g << 8 | b;
|
||||||
i += 4;
|
i += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +168,7 @@ csi_sgr(struct terminal *term)
|
||||||
/* 6 - CS tolerance */
|
/* 6 - CS tolerance */
|
||||||
/* 7 - color space associated with tolerance */
|
/* 7 - color space associated with tolerance */
|
||||||
|
|
||||||
term->vt.attrs.foreground = 1 << 31 | r << 16 | g << 8 | b;
|
term->vt.attrs.foreground = 1 << 30 | r << 16 | g << 8 | b;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERR("invalid CSI SGR sequence");
|
LOG_ERR("invalid CSI SGR sequence");
|
||||||
abort();
|
abort();
|
||||||
|
|
@ -195,7 +195,7 @@ csi_sgr(struct terminal *term)
|
||||||
case 45:
|
case 45:
|
||||||
case 46:
|
case 46:
|
||||||
case 47:
|
case 47:
|
||||||
term->vt.attrs.background = 1 << 31 | term->colors.regular[param - 40];
|
term->vt.attrs.background = 1 << 30 | term->colors.regular[param - 40];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 48: {
|
case 48: {
|
||||||
|
|
@ -211,7 +211,7 @@ csi_sgr(struct terminal *term)
|
||||||
color = term->colors.bright[idx - 8];
|
color = term->colors.bright[idx - 8];
|
||||||
else
|
else
|
||||||
color = colors256[idx];
|
color = colors256[idx];
|
||||||
term->vt.attrs.background = 1 << 31 | color;
|
term->vt.attrs.background = 1 << 30 | color;
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ csi_sgr(struct terminal *term)
|
||||||
uint8_t r = term->vt.params.v[i + 2].value;
|
uint8_t r = term->vt.params.v[i + 2].value;
|
||||||
uint8_t g = term->vt.params.v[i + 3].value;
|
uint8_t g = term->vt.params.v[i + 3].value;
|
||||||
uint8_t b = term->vt.params.v[i + 4].value;
|
uint8_t b = term->vt.params.v[i + 4].value;
|
||||||
term->vt.attrs.background = 1 << 31 | r << 16 | g << 8 | b;
|
term->vt.attrs.background = 1 << 30 | r << 16 | g << 8 | b;
|
||||||
i += 4;
|
i += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -238,7 +238,7 @@ csi_sgr(struct terminal *term)
|
||||||
/* 6 - CS tolerance */
|
/* 6 - CS tolerance */
|
||||||
/* 7 - color space associated with tolerance */
|
/* 7 - color space associated with tolerance */
|
||||||
|
|
||||||
term->vt.attrs.background = 1 << 31 | r << 16 | g << 8 | b;
|
term->vt.attrs.background = 1 << 30 | r << 16 | g << 8 | b;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERR("invalid CSI SGR sequence");
|
LOG_ERR("invalid CSI SGR sequence");
|
||||||
abort();
|
abort();
|
||||||
|
|
@ -265,7 +265,7 @@ csi_sgr(struct terminal *term)
|
||||||
case 95:
|
case 95:
|
||||||
case 96:
|
case 96:
|
||||||
case 97:
|
case 97:
|
||||||
term->vt.attrs.foreground = 1 << 31 | term->colors.bright[param - 90];
|
term->vt.attrs.foreground = 1 << 30 | term->colors.bright[param - 90];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Regular background colors */
|
/* Regular background colors */
|
||||||
|
|
@ -277,7 +277,7 @@ csi_sgr(struct terminal *term)
|
||||||
case 105:
|
case 105:
|
||||||
case 106:
|
case 106:
|
||||||
case 107:
|
case 107:
|
||||||
term->vt.attrs.background = 1 << 31 | term->colors.bright[param - 100];
|
term->vt.attrs.background = 1 << 30 | term->colors.bright[param - 100];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -487,6 +487,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
memmove(&term->grid->cur_row->cells[term->cursor.col],
|
memmove(&term->grid->cur_row->cells[term->cursor.col],
|
||||||
&term->grid->cur_row->cells[term->cursor.col + count],
|
&term->grid->cur_row->cells[term->cursor.col + count],
|
||||||
remaining * sizeof(term->grid->cur_row->cells[0]));
|
remaining * sizeof(term->grid->cur_row->cells[0]));
|
||||||
|
|
||||||
|
for (size_t c = 0; c < remaining; c++)
|
||||||
|
term->grid->cur_row->cells[term->cursor.col + c].attrs.clean = 0;
|
||||||
term->grid->cur_row->dirty = true;
|
term->grid->cur_row->dirty = true;
|
||||||
|
|
||||||
/* Erase the remainder of the line */
|
/* Erase the remainder of the line */
|
||||||
|
|
@ -511,6 +514,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
memmove(&term->grid->cur_row->cells[term->cursor.col + count],
|
memmove(&term->grid->cur_row->cells[term->cursor.col + count],
|
||||||
&term->grid->cur_row->cells[term->cursor.col],
|
&term->grid->cur_row->cells[term->cursor.col],
|
||||||
remaining * sizeof(term->grid->cur_row->cells[0]));
|
remaining * sizeof(term->grid->cur_row->cells[0]));
|
||||||
|
for (size_t c = 0; c < remaining; c++)
|
||||||
|
term->grid->cur_row->cells[term->cursor.col + count + c].attrs.clean = 0;
|
||||||
term->grid->cur_row->dirty = true;
|
term->grid->cur_row->dirty = true;
|
||||||
|
|
||||||
/* Erase (insert space characters) */
|
/* Erase (insert space characters) */
|
||||||
|
|
|
||||||
2
grid.c
2
grid.c
|
|
@ -29,6 +29,8 @@ grid_row_alloc(int cols)
|
||||||
{
|
{
|
||||||
struct row *row = malloc(sizeof(*row));
|
struct row *row = malloc(sizeof(*row));
|
||||||
row->cells = calloc(cols, sizeof(row->cells[0]));
|
row->cells = calloc(cols, sizeof(row->cells[0]));
|
||||||
|
for (size_t c = 0; c < cols; c++)
|
||||||
|
row->cells[c].attrs.clean = 1;
|
||||||
row->dirty = false; /* TODO: parameter? */
|
row->dirty = false; /* TODO: parameter? */
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
main.c
6
main.c
|
|
@ -831,9 +831,11 @@ main(int argc, char *const *argv)
|
||||||
for (int r = 0; r < term.rows; r++) {
|
for (int r = 0; r < term.rows; r++) {
|
||||||
struct row *row = grid_row_in_view(term.grid, r);
|
struct row *row = grid_row_in_view(term.grid, r);
|
||||||
for (int col = 0; col < term.cols; col++) {
|
for (int col = 0; col < term.cols; col++) {
|
||||||
if (row->cells[col].attrs.blink) {
|
struct cell *cell = &row->cells[col];
|
||||||
|
|
||||||
|
if (cell->attrs.blink) {
|
||||||
|
cell->attrs.clean = 0;
|
||||||
row->dirty = true;
|
row->dirty = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
render.c
11
render.c
|
|
@ -174,8 +174,13 @@ arm_blink_timer(struct terminal *term)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
render_cell(struct terminal *term, struct buffer *buf, size_t buf_idx,
|
render_cell(struct terminal *term, struct buffer *buf, size_t buf_idx,
|
||||||
const struct cell *cell, int col, int row, bool has_cursor)
|
struct cell *cell, int col, int row, bool has_cursor)
|
||||||
{
|
{
|
||||||
|
if (cell->attrs.clean)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cell->attrs.clean = 1;
|
||||||
|
|
||||||
cairo_t *cr = buf->cairo[buf_idx];
|
cairo_t *cr = buf->cairo[buf_idx];
|
||||||
double width = term->cell_width;
|
double width = term->cell_width;
|
||||||
double height = term->cell_height;
|
double height = term->cell_height;
|
||||||
|
|
@ -185,10 +190,10 @@ render_cell(struct terminal *term, struct buffer *buf, size_t buf_idx,
|
||||||
bool block_cursor = has_cursor && term->cursor_style == CURSOR_BLOCK;
|
bool block_cursor = has_cursor && term->cursor_style == CURSOR_BLOCK;
|
||||||
bool is_selected = coord_is_selected(term, col, row);
|
bool is_selected = coord_is_selected(term, col, row);
|
||||||
|
|
||||||
uint32_t _fg = cell->attrs.foreground >> 31
|
uint32_t _fg = cell->attrs.foreground >> 30
|
||||||
? cell->attrs.foreground
|
? cell->attrs.foreground
|
||||||
: !term->reverse ? term->colors.fg : term->colors.bg;
|
: !term->reverse ? term->colors.fg : term->colors.bg;
|
||||||
uint32_t _bg = cell->attrs.background >> 31
|
uint32_t _bg = cell->attrs.background >> 30
|
||||||
? cell->attrs.background
|
? cell->attrs.background
|
||||||
: !term->reverse ? term->colors.bg : term->colors.fg;
|
: !term->reverse ? term->colors.bg : term->colors.fg;
|
||||||
|
|
||||||
|
|
|
||||||
24
terminal.c
24
terminal.c
|
|
@ -20,29 +20,36 @@ void
|
||||||
term_damage_rows(struct terminal *term, int start, int end)
|
term_damage_rows(struct terminal *term, int start, int end)
|
||||||
{
|
{
|
||||||
assert(start <= end);
|
assert(start <= end);
|
||||||
for (int r = start; r <= end; r++)
|
for (int r = start; r <= end; r++) {
|
||||||
grid_row(term->grid, r)->dirty = true;
|
struct row *row = grid_row(term->grid, r);
|
||||||
|
row->dirty = true;
|
||||||
|
for (int c = 0; c < term->grid->num_cols; c++)
|
||||||
|
row->cells[c].attrs.clean = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_damage_rows_in_view(struct terminal *term, int start, int end)
|
term_damage_rows_in_view(struct terminal *term, int start, int end)
|
||||||
{
|
{
|
||||||
assert(start <= end);
|
assert(start <= end);
|
||||||
for (int r = start; r <= end; r++)
|
for (int r = start; r <= end; r++) {
|
||||||
grid_row_in_view(term->grid, r)->dirty = true;
|
struct row *row = grid_row_in_view(term->grid, r);
|
||||||
|
row->dirty = true;
|
||||||
|
for (int c = 0; c < term->grid->num_cols; c++)
|
||||||
|
row->cells[c].attrs.clean = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_damage_all(struct terminal *term)
|
term_damage_all(struct terminal *term)
|
||||||
{
|
{
|
||||||
term_damage_rows(term, 0, term->rows);
|
term_damage_rows(term, 0, term->rows - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_damage_view(struct terminal *term)
|
term_damage_view(struct terminal *term)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < term->rows; i++)
|
term_damage_rows_in_view(term, 0, term->rows - 1);
|
||||||
grid_row_in_view(term->grid, i)->dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -73,9 +80,10 @@ erase_cell_range(struct terminal *term, struct row *row, int start, int end)
|
||||||
assert(start < term->cols);
|
assert(start < term->cols);
|
||||||
assert(end < term->cols);
|
assert(end < term->cols);
|
||||||
|
|
||||||
if (unlikely(term->vt.attrs.background >> 31)) {
|
if (unlikely(term->vt.attrs.background >> 30)) {
|
||||||
for (int col = start; col <= end; col++) {
|
for (int col = start; col <= end; col++) {
|
||||||
row->cells[col].c[0] = '\0';
|
row->cells[col].c[0] = '\0';
|
||||||
|
row->cells[col].attrs.clean = 0;
|
||||||
row->cells[col].attrs.background = term->vt.attrs.background;
|
row->cells[col].attrs.background = term->vt.attrs.background;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,11 @@ struct attributes {
|
||||||
uint8_t conceal:1;
|
uint8_t conceal:1;
|
||||||
uint8_t reverse:1;
|
uint8_t reverse:1;
|
||||||
|
|
||||||
uint32_t foreground;
|
uint32_t clean:1;
|
||||||
uint32_t background;
|
uint32_t foreground:31;
|
||||||
|
|
||||||
|
uint32_t reserved:1;
|
||||||
|
uint32_t background:31;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct cell {
|
struct cell {
|
||||||
|
|
|
||||||
10
vt.c
10
vt.c
|
|
@ -698,7 +698,6 @@ pre_print(struct terminal *term)
|
||||||
static inline void
|
static inline void
|
||||||
post_print(struct terminal *term)
|
post_print(struct terminal *term)
|
||||||
{
|
{
|
||||||
term->grid->cur_row->dirty = true;
|
|
||||||
if (term->cursor.col < term->cols - 1)
|
if (term->cursor.col < term->cols - 1)
|
||||||
term_cursor_right(term, 1);
|
term_cursor_right(term, 1);
|
||||||
else
|
else
|
||||||
|
|
@ -716,13 +715,6 @@ print_insert(struct terminal *term)
|
||||||
&row[term->cursor.col + 1],
|
&row[term->cursor.col + 1],
|
||||||
&row[term->cursor.col],
|
&row[term->cursor.col],
|
||||||
term->cols - term->cursor.col - 1);
|
term->cols - term->cursor.col - 1);
|
||||||
|
|
||||||
#if 0
|
|
||||||
term_damage_update(
|
|
||||||
term, term->cursor.linear + 1, term->cols - term->cursor.col - 1);
|
|
||||||
#else
|
|
||||||
row->dirty = true;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -737,6 +729,7 @@ action_print_utf8(struct terminal *term)
|
||||||
term_damage_update(term, term->cursor.linear, 1);
|
term_damage_update(term, term->cursor.linear, 1);
|
||||||
#else
|
#else
|
||||||
row->dirty = true;
|
row->dirty = true;
|
||||||
|
cell->attrs.clean = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
print_insert(term);
|
print_insert(term);
|
||||||
|
|
@ -761,6 +754,7 @@ action_print(struct terminal *term, uint8_t c)
|
||||||
term_damage_update(term, term->cursor.linear, 1);
|
term_damage_update(term, term->cursor.linear, 1);
|
||||||
#else
|
#else
|
||||||
row->dirty = true;
|
row->dirty = true;
|
||||||
|
cell->attrs.clean = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
print_insert(term);
|
print_insert(term);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue