terminal: foreground/background in cell attributes are now uint32_t

This reduces the cell size, and thus improves the cache behavour
This commit is contained in:
Daniel Eklöf 2019-07-16 13:17:51 +02:00
parent 2a1c4d29e9
commit ccc8ef9606
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 123 additions and 62 deletions

88
csi.c
View file

@ -18,6 +18,7 @@
#define min(x, y) ((x) < (y) ? (x) : (y))
#if 0
static const struct rgb colors_regular[] = {
{0.000000, 0.000000, 0.000000}, /* 0x000000 */
{0.800000, 0.576471, 0.576471}, /* 0xcc9393 */
@ -41,6 +42,31 @@ static const struct rgb colors_bright[] = {
};
static struct rgb colors256[256];
#else
static const uint32_t colors_regular[] = {
0x000000,
0xcc9393,
0x7f9f7f,
0xd0bf8f,
0x6ca0a3,
0xdc8cc3,
0x93e0e3,
0xdcdccc,
};
static const uint32_t colors_bright[] = {
0x000000,
0xdca3a3,
0xbfebbf,
0xf0dfaf,
0x8cd0d3,
0xdc8cc3,
0x93e0e3,
0xffffff,
};
static uint32_t colors256[256];
#endif
static void __attribute__((constructor))
initialize_colors256(void)
@ -53,21 +79,31 @@ initialize_colors256(void)
for (size_t r = 0; r < 6; r++) {
for (size_t g = 0; g < 6; g++) {
for (size_t b = 0; b < 6; b++) {
#if 0
colors256[16 + r * 6 * 6 + g * 6 + b] = (struct rgb) {
r * 51 / 255.0,
g * 51 / 255.0,
b * 51 / 255.0,
};
#else
colors256[16 + r * 6 * 6 + g * 6 + b]
= r * 51 << 16 | g * 51 << 8 | b * 51;
#endif
}
}
}
for (size_t i = 0; i < 24; i++){
#if 0
colors256[232 + i] = (struct rgb) {
i * 11 / 255.0,
i * 11 / 255.0,
i * 11 / 255.0,
};
#else
/* TODO: i + 1? */
colors256[232 + i] = i * 11 << 16 | i * 11 << 8 | i * 11;
#endif
}
}
@ -152,8 +188,7 @@ csi_sgr(struct terminal *term)
case 35:
case 36:
case 37:
term->vt.attrs.have_foreground = true;
term->vt.attrs.foreground = colors_regular[param - 30];
term->vt.attrs.foreground = 1 << 31 | colors_regular[param - 30];
break;
case 38: {
@ -161,8 +196,7 @@ csi_sgr(struct terminal *term)
term->vt.params.v[i + 1].value == 5)
{
size_t idx = term->vt.params.v[i + 2].value;
term->vt.attrs.foreground = colors256[idx];
term->vt.attrs.have_foreground = true;
term->vt.attrs.foreground = 1 << 31 | colors256[idx];
i += 2;
}
@ -173,12 +207,7 @@ csi_sgr(struct terminal *term)
uint8_t r = term->vt.params.v[i + 2].value;
uint8_t g = term->vt.params.v[i + 3].value;
uint8_t b = term->vt.params.v[i + 4].value;
term->vt.attrs.foreground = (struct rgb) {
r / 255.0,
g / 255.0,
b / 255.0,
};
term->vt.attrs.have_foreground = true;
term->vt.attrs.foreground = 1 << 31 | r << 16 | g << 8 | b;
i += 4;
}
@ -194,12 +223,7 @@ csi_sgr(struct terminal *term)
/* 6 - CS tolerance */
/* 7 - color space associated with tolerance */
term->vt.attrs.foreground = (struct rgb) {
r / 255.0,
g / 255.0,
b / 255.0,
};
term->vt.attrs.have_foreground = true;
term->vt.attrs.foreground = 1 << 31 | r << 16 | g << 8 | b;
} else {
LOG_ERR("invalid CSI SGR sequence");
abort();
@ -214,8 +238,7 @@ csi_sgr(struct terminal *term)
}
case 39:
term->vt.attrs.foreground = term->foreground;
term->vt.attrs.have_foreground = false;
term->vt.attrs.foreground = 0;
break;
/* Regular background colors */
@ -227,8 +250,7 @@ csi_sgr(struct terminal *term)
case 45:
case 46:
case 47:
term->vt.attrs.background = colors_regular[param - 40];
term->vt.attrs.have_background = true;
term->vt.attrs.background = 1 << 31 | colors_regular[param - 40];
break;
case 48: {
@ -236,8 +258,7 @@ csi_sgr(struct terminal *term)
term->vt.params.v[i + 1].value == 5)
{
size_t idx = term->vt.params.v[i + 2].value;
term->vt.attrs.background = colors256[idx];
term->vt.attrs.have_background = true;
term->vt.attrs.background = 1 << 31 | colors256[idx];
i += 2;
}
@ -247,12 +268,7 @@ csi_sgr(struct terminal *term)
uint8_t r = term->vt.params.v[i + 2].value;
uint8_t g = term->vt.params.v[i + 3].value;
uint8_t b = term->vt.params.v[i + 4].value;
term->vt.attrs.background = (struct rgb) {
r / 255.0,
g / 255.0,
b / 255.0,
};
term->vt.attrs.have_background = true;
term->vt.attrs.background = 1 << 31 | r << 16 | g << 8 | b;
i += 4;
}
@ -269,12 +285,7 @@ csi_sgr(struct terminal *term)
/* 6 - CS tolerance */
/* 7 - color space associated with tolerance */
term->vt.attrs.background = (struct rgb) {
r / 255.0,
g / 255.0,
b / 255.0,
};
term->vt.attrs.have_background = true;
term->vt.attrs.background = 1 << 31 | r << 16 | g << 8 | b;
} else {
LOG_ERR("invalid CSI SGR sequence");
abort();
@ -289,8 +300,7 @@ csi_sgr(struct terminal *term)
break;
}
case 49:
term->vt.attrs.background = term->background;
term->vt.attrs.have_background = false;
term->vt.attrs.background = 0;
break;
/* Bright foreground colors */
@ -302,8 +312,7 @@ csi_sgr(struct terminal *term)
case 95:
case 96:
case 97:
term->vt.attrs.foreground = colors_bright[param - 90];
term->vt.attrs.have_foreground = true;
term->vt.attrs.foreground = 1 << 31 | colors_bright[param - 90];
break;
/* Regular background colors */
@ -315,8 +324,7 @@ csi_sgr(struct terminal *term)
case 105:
case 106:
case 107:
term->vt.attrs.background = colors_bright[param - 100];
term->vt.attrs.have_background = true;
term->vt.attrs.background = 1 << 31 | colors_bright[param - 100];
break;
default:

5
main.c
View file

@ -33,8 +33,13 @@
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
#if 0
static const struct rgb default_foreground = {0.86, 0.86, 0.86};
static const struct rgb default_background = {0.067, 0.067, 0.067};
#else
static const uint32_t default_foreground = 0xdcdccc;
static const uint32_t default_background = 0x111111;
#endif
static void
shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)

View file

@ -28,7 +28,11 @@ struct glyph_sequence {
int count;
struct attributes attrs;
#if 0
struct rgb foreground;
#else
uint32_t foreground;
#endif
};
static struct glyph_sequence gseq;
@ -68,22 +72,48 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
}
}
#if 0
const struct rgb *foreground = cell->attrs.have_foreground
? &cell->attrs.foreground
: !term->reverse ? &term->foreground : &term->background;
const struct rgb *background = cell->attrs.have_background
? &cell->attrs.background
: !term->reverse ? &term->background : &term->foreground;
#else
uint32_t _foreground = cell->attrs.foreground >> 31
? cell->attrs.foreground
: !term->reverse ? term->foreground : term->background;
uint32_t _background = cell->attrs.background >> 31
? cell->attrs.background
: !term->reverse ? term->background : term->foreground;
#endif
/* If *one* is set, we reverse */
if (has_cursor ^ cell->attrs.reverse ^ is_selected) {
#if 0
const struct rgb *swap = foreground;
foreground = background;
background = swap;
#else
uint32_t swap = _foreground;
#endif
_foreground = _background;
_background = swap;
}
#if 0
struct rgb foreground = {
((_foreground >> 16) & 0xff) / 255.0,
((_foreground >> 8) & 0xff) / 255.0,
((_foreground >> 0) & 0xff) / 255.0,
};
#endif
struct rgb background = {
((_background >> 16) & 0xff) / 255.0,
((_background >> 8) & 0xff) / 255.0,
((_background >> 0) & 0xff) / 255.0,
};
/* Background */
cairo_set_source_rgb(buf->cairo, background->r, background->g, background->b);
cairo_set_source_rgb(buf->cairo, background.r, background.g, background.b);
cairo_rectangle(buf->cairo, x, y, width, height);
cairo_fill(buf->cairo);
@ -104,22 +134,30 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
if (memcmp(&cell->attrs, &gseq.attrs, sizeof(cell->attrs)) != 0 ||
gseq.count >= sizeof(gseq.glyphs) / sizeof(gseq.glyphs[0]) - 10 ||
memcmp(&gseq.foreground, foreground, sizeof(*foreground)) != 0)
#if 0
memcmp(&gseq.foreground, foreground, sizeof(*foreground)) != 0
#else
gseq.foreground != _foreground
#endif
)
{
if (gseq.count >= sizeof(gseq.glyphs) / sizeof(gseq.glyphs[0]) - 10)
LOG_WARN("hit glyph limit");
cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs));
cairo_set_source_rgb(
buf->cairo, gseq.foreground.r, gseq.foreground.g,
gseq.foreground.b);
struct rgb fg = {
((gseq.foreground >> 16) & 0xff) / 255.0,
((gseq.foreground >> 8) & 0xff) / 255.0,
((gseq.foreground >> 0) & 0xff) / 255.0,
};
cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs));
cairo_set_source_rgb(buf->cairo, fg.r, fg.g, fg.b);
cairo_show_glyphs(buf->cairo, gseq.glyphs, gseq.count);
gseq.g = gseq.glyphs;
gseq.count = 0;
gseq.attrs = cell->attrs;
gseq.foreground = *foreground;
gseq.foreground = _foreground;
}
int new_glyphs
@ -225,9 +263,18 @@ grid_render(struct terminal *term)
int rmargin_width = term->width - rmargin;
int bmargin_height = term->height - bmargin;
#if 0
const struct rgb *bg = !term->reverse ?
&term->background : &term->foreground;
cairo_set_source_rgb(buf->cairo, bg->r, bg->g, bg->b);
#else
uint32_t _bg = !term->reverse ? term->background : term->foreground;
struct rgb bg = {
((_bg >> 16) & 0xff) / 255.0,
((_bg >> 8) & 0xff) / 255.0,
((_bg >> 0) & 0xff) / 255.0,
};
#endif
cairo_set_source_rgb(buf->cairo, bg.r, bg.g, bg.b);
cairo_rectangle(buf->cairo, rmargin, 0, rmargin_width, term->height);
cairo_rectangle(buf->cairo, 0, bmargin, term->width, bmargin_height);
@ -332,10 +379,14 @@ grid_render(struct terminal *term)
}
if (gseq.count > 0) {
struct rgb fg = {
((gseq.foreground >> 16) & 0xff) / 255.0,
((gseq.foreground >> 8) & 0xff) / 255.0,
((gseq.foreground >> 0) & 0xff) / 255.0,
};
cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs));
cairo_set_source_rgb(
buf->cairo, gseq.foreground.r, gseq.foreground.g,
gseq.foreground.b);
cairo_set_source_rgb(buf->cairo, fg.r, fg.g, fg.b);
cairo_show_glyphs(buf->cairo, gseq.glyphs, gseq.count);
}

View file

@ -72,10 +72,9 @@ erase_cell_range(struct terminal *term, struct row *row, int start, int end)
assert(start < term->cols);
assert(end < term->cols);
if (unlikely(term->vt.attrs.have_background)) {
if (unlikely(term->vt.attrs.background >> 31)) {
for (int col = start; col <= end; col++) {
row->cells[col].c[0] = '\0';
row->cells[col].attrs.have_background = true;
row->cells[col].attrs.background = term->vt.attrs.background;
}
} else {

View file

@ -55,14 +55,12 @@ struct attributes {
uint8_t italic:1;
uint8_t underline:1;
uint8_t strikethrough:1;
//uint8_t blink:1; /* Not supported yet, and removing it means all other attributes fit in a single uint8_t */
uint8_t blink:1;
uint8_t conceal:1;
uint8_t reverse:1;
uint8_t have_foreground:1;
uint8_t have_background:1;
struct rgb foreground; /* Only valid when have_foreground == true */
struct rgb background; /* Only valid when have_background == true */
uint32_t foreground;
uint32_t background;
} __attribute__((packed));
struct cell {
@ -236,8 +234,8 @@ struct terminal {
bool print_needs_wrap;
struct scroll_region scroll_region;
struct rgb foreground;
struct rgb background;
uint32_t foreground;
uint32_t background;
struct {
int col;