mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
[kitty] speed up kitty_null() with parse_start
This commit is contained in:
parent
889e81d648
commit
760ee94b04
@ -65,7 +65,8 @@ typedef struct sprixel {
|
||||
int y, x;
|
||||
int dimy, dimx; // cell geometry
|
||||
int pixy, pixx; // pixel geometry (might be smaller than cell geo)
|
||||
int* tacache; // transparency-annihilatin cache (dimy * dimx)
|
||||
int* tacache; // transparency-annihilatin cache (dimy * dimx)
|
||||
int parse_start; // where to start parsing for cell wipes
|
||||
} sprixel;
|
||||
|
||||
// A plane is memory for some rectilinear virtual window, plus current cursor
|
||||
@ -725,7 +726,8 @@ void sprixel_free(sprixel* s);
|
||||
void sprixel_hide(sprixel* s);
|
||||
// dimy and dimx are cell geometry, not pixel
|
||||
sprixel* sprixel_create(ncplane* n, const char* s, int bytes, int placey, int placex,
|
||||
int sprixelid, int dimy, int dimx, int pixy, int pixx);
|
||||
int sprixelid, int dimy, int dimx, int pixy, int pixx,
|
||||
int parse_start);
|
||||
API int sprite_wipe_cell(const notcurses* nc, sprixel* s, int y, int x);
|
||||
int sprite_kitty_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
|
||||
int sprite_kitty_clear_all(const notcurses* nc);
|
||||
@ -1126,8 +1128,10 @@ egc_rtl(const char* egc, int* bytes){
|
||||
// new, purpose-specific plane.
|
||||
static inline int
|
||||
plane_blit_sixel(ncplane* n, const char* s, int bytes, int placey, int placex,
|
||||
int leny, int lenx, int sprixelid, int dimy, int dimx){
|
||||
sprixel* spx = sprixel_create(n, s, bytes, placey, placex, sprixelid, leny, lenx, dimy, dimx);
|
||||
int leny, int lenx, int sprixelid, int dimy, int dimx,
|
||||
int parse_start){
|
||||
sprixel* spx = sprixel_create(n, s, bytes, placey, placex, sprixelid,
|
||||
leny, lenx, dimy, dimx, parse_start);
|
||||
if(spx == NULL){
|
||||
return -1;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
|
||||
if((ycell + 1) * ypixels > s->pixy){
|
||||
targy = s->pixy - ycell * ypixels;
|
||||
}
|
||||
char* c = s->glyph;
|
||||
char* c = s->glyph + s->parse_start;
|
||||
//fprintf(stderr, "TARGET AREA: %d x %d @ %dx%d of %d/%d (%d/%d) len %zu\n", targy, targx, ycell, xcell, s->dimy, s->dimx, s->pixy, s->pixx, strlen(c));
|
||||
// every pixel was 4 source bytes, 32 bits, 6.33 base64 bytes. every 3 input pixels is
|
||||
// 12 bytes (96 bits), an even 16 base64 bytes. there is chunking to worry about. there
|
||||
@ -142,11 +142,6 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
|
||||
int chunkedhandled = 0;
|
||||
const int chunks = totalpixels / RGBA_MAXLEN + !!(totalpixels % RGBA_MAXLEN);
|
||||
while(targy && chunkedhandled < chunks){ // need to null out |targy| rows of |targx| pixels, track with |thisrow|
|
||||
//fprintf(stderr, "CHUNK %d NEXTPIXEL: %d NEXTCHUNK: %d\n", chunkedhandled, nextpixel, nextchunk);
|
||||
while(*c != ';'){
|
||||
++c;
|
||||
}
|
||||
++c;
|
||||
//fprintf(stderr, "PLUCKING FROM [%s]\n", c);
|
||||
int inchunk = totalpixels - chunkedhandled * RGBA_MAXLEN;
|
||||
if(inchunk > RGBA_MAXLEN){
|
||||
@ -184,8 +179,13 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
|
||||
}
|
||||
}
|
||||
c += RGBA_MAXLEN * 4 * 4 / 3; // 4bpp * 4/3 for base64, 4096b per chunk
|
||||
c += 8; // new chunk header
|
||||
++chunkedhandled;
|
||||
//fprintf(stderr, "LOOKING NOW AT %u [%s]\n", c - s->glyph, c);
|
||||
while(*c != ';'){
|
||||
++c;
|
||||
}
|
||||
++c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -195,7 +195,7 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
|
||||
// 16 base64-encoded bytes. 4096 / 16 == 256 3-pixel groups, or 768 pixels.
|
||||
static int
|
||||
write_kitty_data(FILE* fp, int linesize, int leny, int lenx,
|
||||
const uint32_t* data, int sprixelid){
|
||||
const uint32_t* data, int sprixelid, int* parse_start){
|
||||
if(linesize % sizeof(*data)){
|
||||
return -1;
|
||||
}
|
||||
@ -209,7 +209,8 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx,
|
||||
//fprintf(stderr, "total: %d chunks = %d, s=%d,v=%d\n", total, chunks, lenx, leny);
|
||||
while(chunks--){
|
||||
if(totalout == 0){
|
||||
fprintf(fp, "\e_Gf=32,s=%d,v=%d,i=%d,a=T,%c=1;", lenx, leny, sprixelid, chunks ? 'm' : 'q');
|
||||
*parse_start = fprintf(fp, "\e_Gf=32,s=%d,v=%d,i=%d,a=T,%c=1;",
|
||||
lenx, leny, sprixelid, chunks ? 'm' : 'q');
|
||||
}else{
|
||||
fprintf(fp, "\e_G%sm=%d;", chunks ? "" : "q=1,", chunks ? 1 : 0);
|
||||
}
|
||||
@ -258,13 +259,16 @@ int kitty_blit_inner(ncplane* nc, int linesize, int leny, int lenx,
|
||||
if(fp == NULL){
|
||||
return -1;
|
||||
}
|
||||
if(write_kitty_data(fp, linesize, leny, lenx, data, bargs->pixel.sprixelid)){
|
||||
int parse_start = 0;
|
||||
if(write_kitty_data(fp, linesize, leny, lenx, data, bargs->pixel.sprixelid,
|
||||
&parse_start)){
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
if(plane_blit_sixel(nc, buf, size, bargs->pixel.placey, bargs->pixel.placex,
|
||||
rows, cols, bargs->pixel.sprixelid, leny, lenx) < 0){
|
||||
rows, cols, bargs->pixel.sprixelid, leny, lenx,
|
||||
parse_start) < 0){
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
@ -415,13 +415,12 @@ write_rle(int* printed, int color, FILE* fp, int seenrle, unsigned char crle){
|
||||
|
||||
// Emit the sprixel in its entirety, plus enable and disable pixel mode.
|
||||
static int
|
||||
write_sixel_data(FILE* fp, int lenx, sixeltable* stab){
|
||||
write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start){
|
||||
// \e[?80: DECSDM "sixel scrolling" mode (put output at cursor location)
|
||||
// \x90: 8-bit "device control sequence", lowercase q (start sixel)
|
||||
// doesn't seem to work with at least xterm; we instead use '\ePq'
|
||||
// FIXME i think we can print DESDM on the first one, and never again
|
||||
fprintf(fp, "\e[?80h\ePq");
|
||||
//fprintf(fp, "\ePq");
|
||||
*parse_start += fprintf(fp, "\e[?80h\ePq");
|
||||
|
||||
// Set Raster Attributes - pan/pad=1 (pixel aspect ratio), Ph=lenx, Pv=leny
|
||||
// using Ph/Pv causes a background to be drawn using color register 0 for all
|
||||
@ -434,10 +433,10 @@ write_sixel_data(FILE* fp, int lenx, sixeltable* stab){
|
||||
int count = stab->deets[idx].count;
|
||||
//fprintf(stderr, "RGB: %3u %3u %3u DT: %d SUMS: %3d %3d %3d COUNT: %d\n", rgb[0], rgb[1], rgb[2], idx, stab->deets[idx].sums[0] / count * 100 / 255, stab->deets[idx].sums[1] / count * 100 / 255, stab->deets[idx].sums[2] / count * 100 / 255, count);
|
||||
//fprintf(fp, "#%d;2;%u;%u;%u", i, rgb[0], rgb[1], rgb[2]);
|
||||
fprintf(fp, "#%d;2;%jd;%jd;%jd", i,
|
||||
(intmax_t)(stab->deets[idx].sums[0] * 100 / count / 255),
|
||||
(intmax_t)(stab->deets[idx].sums[1] * 100 / count / 255),
|
||||
(intmax_t)(stab->deets[idx].sums[2] * 100 / count / 255));
|
||||
*parse_start += fprintf(fp, "#%d;2;%jd;%jd;%jd", i,
|
||||
(intmax_t)(stab->deets[idx].sums[0] * 100 / count / 255),
|
||||
(intmax_t)(stab->deets[idx].sums[1] * 100 / count / 255),
|
||||
(intmax_t)(stab->deets[idx].sums[2] * 100 / count / 255));
|
||||
}
|
||||
int p = 0;
|
||||
while(p < stab->sixelcount){
|
||||
@ -498,7 +497,8 @@ int sixel_blit_inner(ncplane* nc, int leny, int lenx, sixeltable* stab,
|
||||
if(fp == NULL){
|
||||
return -1;
|
||||
}
|
||||
if(write_sixel_data(fp, lenx, stab)){
|
||||
int parse_start = 0;
|
||||
if(write_sixel_data(fp, lenx, stab, &parse_start)){
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
return -1;
|
||||
@ -506,7 +506,8 @@ int sixel_blit_inner(ncplane* nc, int leny, int lenx, sixeltable* stab,
|
||||
unsigned cols = lenx / bargs->pixel.celldimx + !!(lenx % bargs->pixel.celldimx);
|
||||
unsigned rows = leny / bargs->pixel.celldimy + !!(leny % bargs->pixel.celldimy);
|
||||
if(plane_blit_sixel(nc, buf, size, bargs->pixel.placey, bargs->pixel.placex,
|
||||
rows, cols, bargs->pixel.sprixelid, leny, lenx) < 0){
|
||||
rows, cols, bargs->pixel.sprixelid, leny, lenx,
|
||||
parse_start) < 0){
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ void sprixel_hide(sprixel* s){
|
||||
|
||||
// y and x are the cell geometry, not the pixel geometry
|
||||
sprixel* sprixel_create(ncplane* n, const char* s, int bytes, int placey, int placex,
|
||||
int sprixelid, int dimy, int dimx, int pixy, int pixx){
|
||||
int sprixelid, int dimy, int dimx, int pixy, int pixx,
|
||||
int parse_start){
|
||||
sprixel* ret = malloc(sizeof(sprixel));
|
||||
if(ret){
|
||||
if((ret->glyph = memdup(s, bytes + 1)) == NULL){
|
||||
@ -42,6 +43,7 @@ sprixel* sprixel_create(ncplane* n, const char* s, int bytes, int placey, int pl
|
||||
ret->pixy = pixy;
|
||||
ret->y = placey;
|
||||
ret->x = placex;
|
||||
ret->parse_start = parse_start;
|
||||
if(ncplane_pile(n)){
|
||||
notcurses* nc = ncplane_notcurses(n);
|
||||
ret->next = nc->sprixelcache;
|
||||
|
Loading…
x
Reference in New Issue
Block a user