mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
Merge branch 'cache-optimize'
This commit is contained in:
commit
1a21a5fb29
6 changed files with 78 additions and 68 deletions
61
csi.c
61
csi.c
|
|
@ -79,6 +79,33 @@ sgr_reset(struct terminal *term)
|
|||
term->vt.attrs.background = term->background;
|
||||
}
|
||||
|
||||
static const char *
|
||||
csi_as_string(struct terminal *term, uint8_t final)
|
||||
{
|
||||
static char msg[1024];
|
||||
int c = snprintf(msg, sizeof(msg), "CSI: ");
|
||||
|
||||
if (term->vt.private != 0)
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%c", term->vt.private);
|
||||
|
||||
for (size_t i = 0; i < term->vt.params.idx; i++){
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%d",
|
||||
term->vt.params.v[i].value);
|
||||
|
||||
for (size_t j = 0; i < term->vt.params.v[i].sub.idx; j++) {
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, ":%d",
|
||||
term->vt.params.v[i].sub.value[j]);
|
||||
}
|
||||
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%s",
|
||||
i == term->vt.params.idx - 1 ? "" : ";");
|
||||
}
|
||||
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%c (%zu parameters)",
|
||||
final, term->vt.params.idx);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void
|
||||
csi_sgr(struct terminal *term)
|
||||
{
|
||||
|
|
@ -99,8 +126,8 @@ csi_sgr(struct terminal *term)
|
|||
case 2: term->vt.dim = true; break;
|
||||
case 3: term->vt.attrs.italic = true; break;
|
||||
case 4: term->vt.attrs.underline = true; break;
|
||||
case 5: term->vt.attrs.blink = true; break;
|
||||
case 6: term->vt.attrs.blink = true; break;
|
||||
case 5: LOG_WARN("unimplemented: %s (blink)", csi_as_string(term, 'm')); /*term->vt.attrs.blink = true; */break;
|
||||
case 6: break; /* rapid blink, ignored */
|
||||
case 7: term->vt.attrs.reverse = true; break;
|
||||
case 8: term->vt.attrs.conceal = true; break;
|
||||
case 9: term->vt.attrs.strikethrough = true; break;
|
||||
|
|
@ -108,7 +135,8 @@ csi_sgr(struct terminal *term)
|
|||
case 22: term->vt.attrs.bold = term->vt.dim = false; break;
|
||||
case 23: term->vt.attrs.italic = false; break;
|
||||
case 24: term->vt.attrs.underline = false; break;
|
||||
case 25: term->vt.attrs.blink = false; break;
|
||||
case 25: /*term->vt.attrs.blink = false; */break;
|
||||
case 26: break; /* rapid blink, ignored */
|
||||
case 27: term->vt.attrs.reverse = false; break;
|
||||
case 28: term->vt.attrs.conceal = false; break;
|
||||
case 29: term->vt.attrs.strikethrough = false; break;
|
||||
|
|
@ -239,33 +267,6 @@ csi_sgr(struct terminal *term)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
csi_as_string(struct terminal *term, uint8_t final)
|
||||
{
|
||||
static char msg[1024];
|
||||
int c = snprintf(msg, sizeof(msg), "CSI: ");
|
||||
|
||||
if (term->vt.private != 0)
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%c", term->vt.private);
|
||||
|
||||
for (size_t i = 0; i < term->vt.params.idx; i++){
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%d",
|
||||
term->vt.params.v[i].value);
|
||||
|
||||
for (size_t j = 0; i < term->vt.params.v[i].sub.idx; j++) {
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, ":%d",
|
||||
term->vt.params.v[i].sub.value[j]);
|
||||
}
|
||||
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%s",
|
||||
i == term->vt.params.idx - 1 ? "" : ";");
|
||||
}
|
||||
|
||||
c += snprintf(&msg[c], sizeof(msg) - c, "%c (%zu parameters)",
|
||||
final, term->vt.params.idx);
|
||||
return msg;
|
||||
}
|
||||
|
||||
void
|
||||
csi_dispatch(struct terminal *term, uint8_t final)
|
||||
{
|
||||
|
|
|
|||
5
grid.c
5
grid.c
|
|
@ -12,12 +12,13 @@ grid_swap_row(struct grid *grid, int row_a, int row_b)
|
|||
{
|
||||
assert(grid->offset >= 0);
|
||||
assert(row_a != row_b);
|
||||
assert(row_a >= 0);
|
||||
assert(row_b >= 0);
|
||||
|
||||
int real_a = (grid->offset + row_a + grid->num_rows) % grid->num_rows;
|
||||
int real_b = (grid->offset + row_b + grid->num_rows) % grid->num_rows;
|
||||
|
||||
assert(real_a >= 0);
|
||||
assert(real_b >= 0);
|
||||
|
||||
struct row *tmp = grid->rows[real_a];
|
||||
grid->rows[real_a] = grid->rows[real_b];
|
||||
grid->rows[real_b] = tmp;
|
||||
|
|
|
|||
4
render.c
4
render.c
|
|
@ -101,7 +101,7 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
|
||||
cairo_status_t status = cairo_scaled_font_text_to_glyphs(
|
||||
attrs_to_font(term, &cell->attrs), x, y + term->fextents.ascent,
|
||||
cell->c, strlen(cell->c), &gseq.g, &new_glyphs,
|
||||
cell->c, strnlen(cell->c, 4), &gseq.g, &new_glyphs,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
|
|
@ -379,7 +379,7 @@ render_resize(struct terminal *term, int width, int height)
|
|||
term->width = width;
|
||||
term->height = height;
|
||||
|
||||
const int scrollback_lines = 10000;
|
||||
const int scrollback_lines = 1000;
|
||||
|
||||
const int old_cols = term->cols;
|
||||
const int old_rows = term->rows;
|
||||
|
|
|
|||
51
terminal.c
51
terminal.c
|
|
@ -146,19 +146,11 @@ term_cursor_down(struct terminal *term, int count)
|
|||
void
|
||||
term_scroll_partial(struct terminal *term, struct scroll_region region, int rows)
|
||||
{
|
||||
LOG_DBG("scroll: %d rows", rows);
|
||||
LOG_DBG("scroll: rows=%d, region.start=%d, region.end=%d",
|
||||
rows, region.start, region.end);
|
||||
|
||||
assert(rows < term->rows && "unimplemented");
|
||||
|
||||
/* Top non-scrolling region */
|
||||
for (int i = region.start - 1; i >= 0; i--)
|
||||
grid_swap_row(term->grid, i, i + rows);
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
for (int i = term->rows - 1; i >= region.end; i--)
|
||||
grid_swap_row(term->grid, i, i + rows);
|
||||
|
||||
/* Offset grid origin */
|
||||
bool view_follows = term->grid->view == term->grid->offset;
|
||||
term->grid->offset += rows;
|
||||
term->grid->offset %= term->grid->num_rows;
|
||||
|
|
@ -166,11 +158,28 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
|||
if (view_follows)
|
||||
term->grid->view = term->grid->offset;
|
||||
|
||||
for (int r = max(region.end - rows, 0); r < region.end; r++) {
|
||||
struct row *row = grid_row(term->grid, r);
|
||||
erase_line(term, row);
|
||||
/*
|
||||
* This loop serves two purposes:
|
||||
* 1) ensure all visible lines are *allocated*
|
||||
* 2) prefetch the cells - this makes life easier for erase_line() below
|
||||
*/
|
||||
for (int r = max(region.end - rows, 0); r < term->rows; r++) {
|
||||
struct row *row = grid_row(term->grid, r);
|
||||
__builtin_prefetch(row->cells, 1, 3);
|
||||
}
|
||||
|
||||
/* Top non-scrolling region. */
|
||||
for (int i = region.start - 1; i >= 0; i--)
|
||||
grid_swap_row(term->grid, i - rows, i);
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
for (int i = term->rows - 1; i >= region.end; i--)
|
||||
grid_swap_row(term->grid, i - rows, i);
|
||||
|
||||
/* Erase scrolled in lines */
|
||||
for (int r = max(region.end - rows, 0); r < region.end; r++)
|
||||
erase_line(term, grid_row(term->grid, r));
|
||||
|
||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
||||
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
|
||||
}
|
||||
|
|
@ -185,16 +194,23 @@ void
|
|||
term_scroll_reverse_partial(struct terminal *term,
|
||||
struct scroll_region region, int rows)
|
||||
{
|
||||
LOG_DBG("scroll reverse: rows=%d, region.start=%d, region.end=%d",
|
||||
rows, region.start, region.end);
|
||||
|
||||
assert(rows < term->rows && "unimplemented");
|
||||
|
||||
bool view_follows = term->grid->view == term->grid->offset;
|
||||
|
||||
term->grid->offset += term->grid->num_rows - rows;
|
||||
term->grid->offset %= term->grid->num_rows;
|
||||
|
||||
if (view_follows)
|
||||
term->grid->view = term->grid->offset;
|
||||
|
||||
for (int r = 0; r < min(region.start + rows, region.end); r++) {
|
||||
struct row *row = grid_row(term->grid, r);
|
||||
__builtin_prefetch(row->cells, 1, 3);
|
||||
}
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
for (int i = region.end + rows; i < term->rows + rows; i++)
|
||||
grid_swap_row(term->grid, i, i - rows);
|
||||
|
|
@ -203,10 +219,9 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
for (int i = 0 + rows; i < region.start + rows; i++)
|
||||
grid_swap_row(term->grid, i, i - rows);
|
||||
|
||||
term_erase(
|
||||
term,
|
||||
&(struct coord){0, region.start},
|
||||
&(struct coord){term->cols - 1, min(region.start + rows, region.end) - 1});
|
||||
/* Erase scrolled in lines */
|
||||
for (int r = region.start; r < min(region.start + rows, region.end); r++)
|
||||
erase_line(term, grid_row(term->grid, r));
|
||||
|
||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
|
||||
|
|
|
|||
23
terminal.h
23
terminal.h
|
|
@ -38,37 +38,30 @@ struct wayland {
|
|||
bool have_argb8888;
|
||||
};
|
||||
|
||||
struct rgb { double r, g, b; } __attribute__((packed));
|
||||
struct rgb { float r, g, b; } __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Note: we want the cells to be as small as possible. Larger cells
|
||||
* means fewer scrollback lines (or performance drops due to cache
|
||||
* misses) */
|
||||
struct attributes {
|
||||
#if 0
|
||||
bool bold;
|
||||
bool italic;
|
||||
bool underline;
|
||||
bool strikethrough;
|
||||
bool blink;
|
||||
bool conceal;
|
||||
bool reverse;
|
||||
bool have_foreground;
|
||||
bool have_background;
|
||||
#else
|
||||
uint8_t bold:1;
|
||||
uint8_t italic:1;
|
||||
uint8_t underline:1;
|
||||
uint8_t strikethrough:1;
|
||||
uint8_t blink:1;
|
||||
//uint8_t blink:1; /* Not supported yet, and removing it means all other attributes fit in a single uint8_t */
|
||||
uint8_t conceal:1;
|
||||
uint8_t reverse:1;
|
||||
uint8_t have_foreground:1;
|
||||
uint8_t have_background:1;
|
||||
#endif
|
||||
|
||||
struct rgb foreground; /* Only valid when have_foreground == true */
|
||||
struct rgb background; /* Only valid when have_background == true */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct cell {
|
||||
struct attributes attrs;
|
||||
char c[5];
|
||||
char c[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct scroll_region {
|
||||
|
|
|
|||
2
vt.c
2
vt.c
|
|
@ -757,7 +757,7 @@ action_print(struct terminal *term, uint8_t c)
|
|||
if (unlikely(term->charset[term->selected_charset] == CHARSET_GRAPHIC) &&
|
||||
c >= 0x41 && c <= 0x7e)
|
||||
{
|
||||
strcpy(cell->c, vt100_0[c - 0x41]);
|
||||
strncpy(cell->c, vt100_0[c - 0x41], sizeof(cell->c));
|
||||
} else {
|
||||
//LOG_DBG("print: ASCII: %c", c);
|
||||
cell->c[0] = c;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue