Merge branch 'cache-optimize'

This commit is contained in:
Daniel Eklöf 2019-07-10 19:21:49 +02:00
commit 1a21a5fb29
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 78 additions and 68 deletions

61
csi.c
View file

@ -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
View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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
View file

@ -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;