mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-10-31 15:20:13 +00:00
Elide unnecessary sprixel invalidations
When the damaged cell of a sprixel is actually entirely transparent (or annihilated), there's no need to invalidate it. Check for this in the TAM in sprixel_invalidate(). Good optimization, and eliminates a lot of the flicker in `xray` on Kitty described in #1522.
This commit is contained in:
parent
9d516d8c8c
commit
529972d16b
@ -56,7 +56,8 @@ typedef enum {
|
||||
typedef enum {
|
||||
SPRIXCELL_NORMAL, // no transparent pixels in this cell
|
||||
SPRIXCELL_CONTAINS_TRANS, // this cell has transparent pixels
|
||||
SPRIXCELL_ANNIHILATED, // this cell has been wiped
|
||||
SPRIXCELL_ALL_TRANS, // all pixels are naturally transparent
|
||||
SPRIXCELL_ANNIHILATED, // this cell has been wiped (all trans)
|
||||
} sprixcell_e;
|
||||
|
||||
// there is a context-wide set of displayed pixel glyphs ("sprixels"); i.e.
|
||||
@ -831,7 +832,7 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int y, int x);
|
||||
int sixel_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell);
|
||||
int sprite_destroy(const struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s);
|
||||
void sprixel_free(sprixel* s);
|
||||
void sprixel_invalidate(sprixel* s);
|
||||
void sprixel_invalidate(sprixel* s, int y, int x);
|
||||
void sprixel_movefrom(sprixel* s, int y, int x);
|
||||
void sprixel_hide(sprixel* s);
|
||||
int sprite_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out);
|
||||
@ -848,7 +849,6 @@ int sprite_kitty_annihilate(const notcurses* nc, const ncpile* p, FILE* out, spr
|
||||
int sprite_kitty_init(int fd);
|
||||
int sprite_sixel_init(int fd);
|
||||
int sprite_init(const notcurses* nc);
|
||||
void sprixel_invalidate(sprixel* s);
|
||||
int kitty_shutdown(int fd);
|
||||
int sixel_shutdown(int fd);
|
||||
sprixel* sprixel_by_id(const notcurses* nc, uint32_t id);
|
||||
|
@ -153,6 +153,7 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
|
||||
//fprintf(stderr, "CACHED WIPE %d %d/%d\n", s->id, ycell, xcell);
|
||||
return 0; // already annihilated, needn't draw glyph in kitty
|
||||
}
|
||||
//fprintf(stderr, "NEW WIPE %d %d/%d\n", s->id, ycell, xcell);
|
||||
const int totalpixels = s->pixy * s->pixx;
|
||||
const int xpixels = nc->tcache.cellpixx;
|
||||
const int ypixels = nc->tcache.cellpixy;
|
||||
@ -271,13 +272,21 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx,
|
||||
const uint32_t* line = data + (linesize / sizeof(*data)) * y;
|
||||
source[e] = line[x];
|
||||
//fprintf(stderr, "%u/%u/%u -> %c%c%c%c %u %u %u %u\n", r, g, b, b64[0], b64[1], b64[2], b64[3], b64[0], b64[1], b64[2], b64[3]);
|
||||
int tyx = (x / cdimx) + (y / cdimy) * cols;
|
||||
int xcell = x / cdimx;
|
||||
int ycell = y / cdimy;
|
||||
int tyx = xcell + ycell * cols;
|
||||
//fprintf(stderr, "Tyx: %d y: %d (%d) * %d x: %d (%d)\n", tyx, y, y / cdimy, cols, x, x / cdimx);
|
||||
if(tacache[tyx] == SPRIXCELL_ANNIHILATED){
|
||||
wipe[e] = 1;
|
||||
}else{
|
||||
wipe[e] = 0;
|
||||
if(rgba_trans_p(source[e], transcolor)){
|
||||
if(x % cdimx == 0 && y % cdimy == 0){
|
||||
tacache[tyx] = SPRIXCELL_ALL_TRANS;
|
||||
}else if(tacache[tyx] == SPRIXCELL_NORMAL){
|
||||
tacache[tyx] = SPRIXCELL_CONTAINS_TRANS;
|
||||
}
|
||||
}else if(tacache[tyx] == SPRIXCELL_ALL_TRANS){
|
||||
tacache[tyx] = SPRIXCELL_CONTAINS_TRANS;
|
||||
}
|
||||
}
|
||||
|
@ -1084,7 +1084,7 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
|
||||
}
|
||||
//fprintf(stderr, "RAST %08x [%s] to %d/%d cols: %u %016lx\n", srccell->gcluster, pool_extended_gcluster(&nc->pool, srccell), y, x, srccell->width, srccell->channels);
|
||||
if(rvec[damageidx].sprixel){
|
||||
sprixel_invalidate(rvec[damageidx].sprixel);
|
||||
sprixel_invalidate(rvec[damageidx].sprixel, y, x);
|
||||
}
|
||||
if(term_putc(out, &nc->pool, srccell)){
|
||||
return -1;
|
||||
|
@ -60,9 +60,17 @@ void sprixel_hide(sprixel* s){
|
||||
}
|
||||
}
|
||||
|
||||
void sprixel_invalidate(sprixel* s){
|
||||
if(s->invalidated != SPRIXEL_HIDE){
|
||||
s->invalidated = SPRIXEL_INVALIDATED;
|
||||
// y and x are absolute coordinates
|
||||
void sprixel_invalidate(sprixel* s, int y, int x){
|
||||
//fprintf(stderr, "INVALIDATING AT %d/%d\n", y, x);
|
||||
if(s->invalidated != SPRIXEL_HIDE && s->n){
|
||||
int localy = y - s->n->absy;
|
||||
int localx = x - s->n->absx;
|
||||
//fprintf(stderr, "INVALIDATING AT %d/%d (%d/%d) TAM: %d\n", y, x, localy, localx, s->n->tacache[localy * s->dimx + localx]);
|
||||
if(s->n->tacache[localy * s->dimx + localx] != SPRIXCELL_ALL_TRANS &&
|
||||
s->n->tacache[localy * s->dimx + localx] != SPRIXCELL_ALL_TRANS){
|
||||
s->invalidated = SPRIXEL_INVALIDATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user