mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-10-24 22:28:29 +00:00
Speed up CSI escape code parsing by ~30%
This commit is contained in:
parent
07ea7583ac
commit
82ae858a03
2 changed files with 25 additions and 5 deletions
|
|
@ -190,6 +190,8 @@ Detailed list of changes
|
|||
|
||||
- Speed up SIMD UTF-8 decoding: ~20% faster for ASCII and ~50% faster for multi-byte text on both x86 and ARM, by processing pairs of vectors of plain ASCII text at a time and compacting decoded codepoints within 128-bit lanes, avoiding expensive cross-lane operations. Also add an AVX-512 based decoder, another ~75% faster for multi-byte text, used automatically on CPUs that support it (Intel Ice Lake+, AMD Zen 4+). Additionally fix the SIMD decoders failing to emit U+FFFD for an incomplete UTF-8 sequence cut off by an escape code
|
||||
|
||||
- Improve throughput when processing escape code heavy input by ~30% by taking the input buffer lock once per buffer of input rather than once per escape code and using cheaper arithmetic to parse CSI parameters
|
||||
|
||||
- The :opt:`scrollbar` option now takes a new value ``scrolled-or-hovered`` to also show the scrollbar when the mouse moves over the scrollbar region (:pull:`10345`)
|
||||
|
||||
- A new :code:`kitten @ screenshot` remote control command to take a pixel perfect PNG screenshot of an OS Window, tab or window
|
||||
|
|
|
|||
|
|
@ -842,17 +842,28 @@ commit_csi_param(PS *self UNUSED, ParsedCSI *csi) {
|
|||
REPORT_ERROR("CSI escape code has too many parameters, ignoring it");
|
||||
return false;
|
||||
}
|
||||
csi->params[csi->num_params++] = csi->mult * (csi->accumulator / digit_multipliers[csi->num_digits - 1]);
|
||||
csi->params[csi->num_params++] = csi->mult * (int64_t)csi->accumulator;
|
||||
csi->num_digits = 0;
|
||||
csi->mult = 1;
|
||||
csi->accumulator = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MAX_CSI_DIGITS 16u
|
||||
|
||||
static void
|
||||
csi_add_digit(ParsedCSI *csi, uint8_t ch) {
|
||||
if (UNLIKELY(csi->num_digits >= arraysz(digit_multipliers))) return;
|
||||
csi->accumulator += (ch - '0') * digit_multipliers[csi->num_digits++];
|
||||
if (UNLIKELY(csi->num_digits >= MAX_CSI_DIGITS)) return;
|
||||
csi->num_digits++;
|
||||
csi->accumulator = csi->accumulator * 10 + (ch - '0');
|
||||
}
|
||||
|
||||
static void
|
||||
consume_csi_digit_run(ParsedCSI *csi, const uint8_t *buf, size_t *pos, const size_t sz) {
|
||||
// consume a run of parameter digits without re-entering the per-byte state machine
|
||||
size_t p = *pos;
|
||||
while (p < sz && (uint8_t)(buf[p] - '0') <= 9) csi_add_digit(csi, buf[p++]);
|
||||
*pos = p;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -870,6 +881,7 @@ csi_parse_loop(PS *self, ParsedCSI *csi, const uint8_t *buf, size_t *pos, const
|
|||
break;
|
||||
case DIGIT:
|
||||
csi_add_digit(csi, ch);
|
||||
consume_csi_digit_run(csi, buf, pos, sz);
|
||||
csi->state = CSI_BODY;
|
||||
break;
|
||||
case '?':
|
||||
|
|
@ -937,7 +949,10 @@ csi_parse_loop(PS *self, ParsedCSI *csi, const uint8_t *buf, size_t *pos, const
|
|||
if (!commit_csi_param(self, csi)) return true;
|
||||
csi->is_sub_param[csi->num_params] = false;
|
||||
break;
|
||||
case DIGIT: csi_add_digit(csi, ch); break;
|
||||
case DIGIT:
|
||||
csi_add_digit(csi, ch);
|
||||
consume_csi_digit_run(csi, buf, pos, sz);
|
||||
break;
|
||||
default: REPORT_ERROR("Invalid character in CSI: %s (0x%x), ignoring the sequence", csi_letter(ch), ch); return true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1594,7 +1609,10 @@ run_worker(void *p, ParseData *pd, bool flush) {
|
|||
self->read.consumed = 0;
|
||||
do {
|
||||
end_with_lock;
|
||||
{ consume_input(self, pd->dump_callback, screen->window_id); }
|
||||
// consume all already read input without lock cycling, the
|
||||
// writer thread only modifies write.pending and buffer space
|
||||
// beyond read.sz + write.pending
|
||||
do { consume_input(self, pd->dump_callback, screen->window_id); } while (self->read.pos < self->read.sz);
|
||||
with_lock;
|
||||
self->read.sz += self->write.pending;
|
||||
self->write.pending = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue