mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
sixel: add: add sixel_add_many(), improving performance of DECGRI
DECGRI, i.e. repeat sixel character, only need to do image resizing, and updating the current ‘column’ value *once*. By adding sixel_add_many(), and doing the size/resize checking there, the performance of sixel_add() is made much simpler. This boosts performance quite noticeably when the application is emitting many and/or long repeat sequences.
This commit is contained in:
parent
6e963dbf68
commit
6d208fa5e0
1 changed files with 27 additions and 24 deletions
51
sixel.c
51
sixel.c
|
|
@ -988,26 +988,17 @@ resize(struct terminal *term, int new_width, int new_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sixel_add(struct terminal *term, uint32_t color, uint8_t sixel)
|
sixel_add(struct terminal *term, int col, int width, uint32_t color, uint8_t sixel)
|
||||||
{
|
{
|
||||||
//LOG_DBG("adding sixel %02hhx using color 0x%06x", sixel, color);
|
xassert(term->sixel.pos.col < term->sixel.image.width);
|
||||||
|
|
||||||
int width = term->sixel.image.width;
|
|
||||||
|
|
||||||
if (unlikely(term->sixel.pos.col >= width)) {
|
|
||||||
width = term->sixel.pos.col + 1;
|
|
||||||
if (unlikely(!resize_horizontally(term, width)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Height adjustment done while processing ‘-’ */
|
|
||||||
xassert(term->sixel.pos.row < term->sixel.image.height);
|
xassert(term->sixel.pos.row < term->sixel.image.height);
|
||||||
|
|
||||||
size_t ofs = term->sixel.row_byte_ofs + term->sixel.pos.col;
|
size_t ofs = term->sixel.row_byte_ofs + col;
|
||||||
uint32_t *data = &term->sixel.image.data[ofs];
|
uint32_t *data = &term->sixel.image.data[ofs];
|
||||||
|
|
||||||
int max_non_empty_row = 0;
|
int max_non_empty_row = 0;
|
||||||
int row = term->sixel.pos.row;
|
int row = term->sixel.pos.row;
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++, sixel >>= 1, data += width) {
|
for (int i = 0; i < 6; i++, sixel >>= 1, data += width) {
|
||||||
if (sixel & 1) {
|
if (sixel & 1) {
|
||||||
*data = color;
|
*data = color;
|
||||||
|
|
@ -1016,13 +1007,32 @@ sixel_add(struct terminal *term, uint32_t color, uint8_t sixel)
|
||||||
}
|
}
|
||||||
|
|
||||||
xassert(sixel == 0);
|
xassert(sixel == 0);
|
||||||
term->sixel.pos.col++;
|
|
||||||
|
|
||||||
term->sixel.max_non_empty_row_no = max(
|
term->sixel.max_non_empty_row_no = max(
|
||||||
term->sixel.max_non_empty_row_no,
|
term->sixel.max_non_empty_row_no,
|
||||||
max_non_empty_row);
|
max_non_empty_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sixel_add_many(struct terminal *term, uint8_t c, unsigned count)
|
||||||
|
{
|
||||||
|
uint32_t color = term->sixel.palette[term->sixel.color_idx];
|
||||||
|
|
||||||
|
int col = term->sixel.pos.col;
|
||||||
|
int width = term->sixel.image.width;
|
||||||
|
|
||||||
|
if (unlikely(col + count - 1 >= width)) {
|
||||||
|
width = col + count;
|
||||||
|
if (unlikely(!resize_horizontally(term, width)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < count; i++, col++)
|
||||||
|
sixel_add(term, col, width, color, c);
|
||||||
|
|
||||||
|
term->sixel.pos.col = col;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
decsixel(struct terminal *term, uint8_t c)
|
decsixel(struct terminal *term, uint8_t c)
|
||||||
{
|
{
|
||||||
|
|
@ -1079,7 +1089,7 @@ decsixel(struct terminal *term, uint8_t c)
|
||||||
case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v':
|
case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v':
|
||||||
case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}':
|
case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}':
|
||||||
case '~':
|
case '~':
|
||||||
sixel_add(term, term->sixel.palette[term->sixel.color_idx], c - 63);
|
sixel_add_many(term, c - 63, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ' ':
|
case ' ':
|
||||||
|
|
@ -1157,18 +1167,11 @@ decgri(struct terminal *term, uint8_t c)
|
||||||
case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o':
|
case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o':
|
||||||
case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v':
|
case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v':
|
||||||
case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}':
|
case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}':
|
||||||
case '~': {
|
case '~':
|
||||||
//LOG_DBG("repeating '%c' %u times", c, term->sixel.param);
|
sixel_add_many(term, c - 63, term->sixel.param);
|
||||||
unsigned count = term->sixel.param;
|
|
||||||
uint32_t color = term->sixel.palette[term->sixel.color_idx];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; i++)
|
|
||||||
sixel_add(term, color, c - 63);
|
|
||||||
|
|
||||||
term->sixel.state = SIXEL_DECSIXEL;
|
term->sixel.state = SIXEL_DECSIXEL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue