term: performance: use a bitfield to track which ascii printer to use

The things affecting which ASCII printer we use have grown...

Instead of checking everything inside term_update_ascii_printer(), use
a bitfield.

Anything affecting the printer used, must now set a bit in this
bitfield. This makes term_update_ascii_printer() much faster, since
all it needs to do is check if the bitfield is zero or not.
This commit is contained in:
Daniel Eklöf 2024-06-24 01:26:57 +02:00
parent 22302d8bcc
commit 48cf57818d
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 63 additions and 13 deletions

19
csi.c
View file

@ -33,13 +33,12 @@ static void
sgr_reset(struct terminal *term)
{
/* TODO: can we drop this check? */
const enum curly_style curly_style = term->vt.curly.style;
memset(&term->vt.attrs, 0, sizeof(term->vt.attrs));
memset(&term->vt.curly, 0, sizeof(term->vt.curly));
if (unlikely(curly_style > CURLY_SINGLE))
term_update_ascii_printer(term);
term->bits_affecting_ascii_printer.curly_style = false;
term->bits_affecting_ascii_printer.curly_color = false;
term_update_ascii_printer(term);
}
static const char *
@ -107,6 +106,7 @@ csi_sgr(struct terminal *term)
case CURLY_NONE:
term->vt.attrs.underline = false;
term->vt.curly.style = CURLY_NONE;
term->bits_affecting_ascii_printer.curly_style = false;
break;
case CURLY_SINGLE:
@ -114,7 +114,9 @@ csi_sgr(struct terminal *term)
case CURLY_CURLY:
case CURLY_DOTTED:
case CURLY_DASHED:
term->vt.curly.style = style; break;
term->vt.curly.style = style;
term->bits_affecting_ascii_printer.curly_style =
style > CURLY_SINGLE;
break;
}
@ -134,6 +136,7 @@ csi_sgr(struct terminal *term)
case 24: {
term->vt.attrs.underline = false;
term->vt.curly.style = CURLY_NONE;
term->bits_affecting_ascii_printer.curly_style = false;
term_update_ascii_printer(term);
break;
}
@ -236,6 +239,7 @@ csi_sgr(struct terminal *term)
if (unlikely(param == 58)) {
term->vt.curly.color_src = src;
term->vt.curly.color = color;
term->bits_affecting_ascii_printer.curly_color = true;
term_update_ascii_printer(term);
} else if (param == 38) {
term->vt.attrs.fg_src = src;
@ -272,6 +276,7 @@ csi_sgr(struct terminal *term)
case 59:
term->vt.curly.color_src = COLOR_DEFAULT;
term->vt.curly.color = 0;
term->bits_affecting_ascii_printer.curly_color = false;
term_update_ascii_printer(term);
break;
@ -527,6 +532,9 @@ decset_decrst(struct terminal *term, unsigned param, bool enable)
tll_free(term->alt.scroll_damage);
term_damage_view(term);
}
term->bits_affecting_ascii_printer.sixels =
tll_length(term->grid->sixel_images) > 0;
term_update_ascii_printer(term);
break;
@ -1165,6 +1173,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
if (param == 4) {
/* Insertion Replacement Mode (IRM) */
term->insert_mode = sm;
term->bits_affecting_ascii_printer.insert_mode = sm;
term_update_ascii_printer(term);
break;
}

11
sixel.c
View file

@ -420,6 +420,8 @@ sixel_scroll_up(struct terminal *term, int rows)
}
}
term->bits_affecting_ascii_printer.sixels =
tll_length(term->grid->sixel_images) > 0;
term_update_ascii_printer(term);
verify_sixels(term);
}
@ -444,6 +446,8 @@ sixel_scroll_down(struct terminal *term, int rows)
break;
}
term->bits_affecting_ascii_printer.sixels =
tll_length(term->grid->sixel_images) > 0;
term_update_ascii_printer(term);
verify_sixels(term);
}
@ -852,6 +856,8 @@ sixel_overwrite_by_rectangle(
} else
_sixel_overwrite_by_rectangle(term, start, col, height, width, NULL, NULL);
term->bits_affecting_ascii_printer.sixels =
tll_length(term->grid->sixel_images) > 0;
term_update_ascii_printer(term);
}
@ -908,6 +914,8 @@ sixel_overwrite_by_row(struct terminal *term, int _row, int col, int width)
}
}
term->bits_affecting_ascii_printer.sixels =
tll_length(term->grid->sixel_images) > 0;
term_update_ascii_printer(term);
}
@ -1387,6 +1395,9 @@ sixel_unhook(struct terminal *term)
LOG_DBG("you now have %zu sixels in current grid",
tll_length(term->grid->sixel_images));
term->bits_affecting_ascii_printer.sixels =
tll_length(term->grid->sixel_images) > 0;
term_update_ascii_printer(term);
render_refresh(term);
}

View file

@ -2023,6 +2023,7 @@ term_reset(struct terminal *term, bool hard)
term_ime_enable(term);
#endif
term->bits_affecting_ascii_printer.value = 0;
term_update_ascii_printer(term);
if (!hard)
@ -3021,6 +3022,9 @@ term_restore_cursor(struct terminal *term, const struct cursor *cursor)
term->vt.attrs = term->vt.saved_attrs;
term->charsets = term->saved_charsets;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
}
@ -3801,21 +3805,21 @@ ascii_printer_single_shift(struct terminal *term, char32_t wc)
{
ascii_printer_generic(term, wc);
term->charsets.selected = term->charsets.saved;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
}
void
term_update_ascii_printer(struct terminal *term)
{
_Static_assert(sizeof(term->bits_affecting_ascii_printer) == sizeof(uint8_t), "bad size");
void (*new_printer)(struct terminal *term, char32_t wc) =
unlikely(tll_length(term->grid->sixel_images) > 0 ||
term->vt.osc8.uri != NULL ||
term->vt.curly.style > CURLY_SINGLE ||
term->vt.curly.color_src != COLOR_DEFAULT ||
term->charsets.set[term->charsets.selected] == CHARSET_GRAPHIC ||
term->insert_mode)
? &ascii_printer_generic
: &ascii_printer_fast;
unlikely(term->bits_affecting_ascii_printer.value != 0)
? &ascii_printer_generic
: &ascii_printer_fast;
#if defined(_DEBUG) && LOG_ENABLE_DBG
if (term->ascii_printer != new_printer) {
@ -4108,6 +4112,8 @@ term_osc8_open(struct terminal *term, uint64_t id, const char *uri)
term->vt.osc8.id = id;
term->vt.osc8.uri = xstrdup(uri);
term->bits_affecting_ascii_printer.osc8 = true;
term_update_ascii_printer(term);
}
@ -4117,6 +4123,7 @@ term_osc8_close(struct terminal *term)
free(term->vt.osc8.uri);
term->vt.osc8.uri = NULL;
term->vt.osc8.id = 0;
term->bits_affecting_ascii_printer.osc8 = false;
term_update_ascii_printer(term);
}

View file

@ -393,6 +393,17 @@ struct terminal {
const struct config *conf;
void (*ascii_printer)(struct terminal *term, char32_t c);
union {
struct {
bool sixels:1;
bool osc8:1;
bool curly_style:1;
bool curly_color:1;
bool insert_mode:1;
bool charset:1;
};
uint8_t value;
} bits_affecting_ascii_printer;
pid_t slave;
int ptmx;

12
vt.c
View file

@ -243,12 +243,16 @@ action_execute(struct terminal *term, uint8_t c)
case '\x0e':
/* SO - shift out */
term->charsets.selected = G1;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
break;
case '\x0f':
/* SI - shift in */
term->charsets.selected = G0;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
break;
@ -482,12 +486,16 @@ action_esc_dispatch(struct terminal *term, uint8_t final)
case 'n':
/* LS2 - Locking Shift 2 */
term->charsets.selected = G2;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
break;
case 'o':
/* LS3 - Locking Shift 3 */
term->charsets.selected = G3;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
break;
@ -546,6 +554,8 @@ action_esc_dispatch(struct terminal *term, uint8_t final)
size_t idx = term->vt.private - '(';
xassert(idx <= G3);
term->charsets.set[idx] = CHARSET_GRAPHIC;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
break;
}
@ -554,6 +564,8 @@ action_esc_dispatch(struct terminal *term, uint8_t final)
size_t idx = term->vt.private - '(';
xassert(idx <= G3);
term->charsets.set[idx] = CHARSET_ASCII;
term->bits_affecting_ascii_printer.charset =
term->charsets.set[term->charsets.selected] != CHARSET_ASCII;
term_update_ascii_printer(term);
break;
}