per-ncpile sprixel list #1462

pull/1573/head
nick black 3 years ago
parent d1a01e8fe8
commit 5e6862f34c
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -552,6 +552,7 @@ typedef struct ncpile {
struct ncpile *prev, *next; // circular list
size_t crenderlen; // size of crender vector
int dimy, dimx; // rows and cols at time of render
sprixel* sprixelcache; // list of sprixels
} ncpile;
// the standard pile can be reached through ->stdplane.
@ -585,8 +586,6 @@ typedef struct notcurses {
pthread_mutex_t pilelock; // guards pile list, locks resize in render
bool suppress_banner; // from notcurses_options
sprixel* sprixelcache; // list of pixel graphics currently displayed
// desired margins (best-effort only), copied in from notcurses_options
int margin_t, margin_b, margin_r, margin_l;
int loglevel;
@ -942,7 +941,7 @@ int sixel_init(int fd);
int sprite_init(const notcurses* nc);
int kitty_shutdown(int fd);
int sixel_shutdown(int fd);
sprixel* sprixel_by_id(const notcurses* nc, uint32_t id);
sprixel* sprixel_by_id(const ncpile* n, uint32_t id);
// these three all use absolute coordinates
void sprixel_invalidate(sprixel* s, int y, int x);
void sprixel_movefrom(sprixel* s, int y, int x);

@ -229,12 +229,23 @@ int update_term_dimensions(int fd, int* rows, int* cols, tinfo* tcache){
return 0;
}
// destroy the sprixels of an ncpile (this will not hide the sprixels)
static void
free_sprixels(ncpile* n){
while(n->sprixelcache){
sprixel* tmp = n->sprixelcache->next;
sprixel_free(n->sprixelcache);
n->sprixelcache = tmp;
}
}
// destroy an empty ncpile. only call with pilelock held.
static void
ncpile_destroy(ncpile* pile){
if(pile){
pile->prev->next = pile->next;
pile->next->prev = pile->prev;
free_sprixels(pile);
free(pile->crender);
free(pile);
}
@ -292,6 +303,7 @@ make_ncpile(notcurses* nc, ncplane* n){
ret->dimx = 0;
ret->crender = NULL;
ret->crenderlen = 0;
ret->sprixelcache = NULL;
}
return ret;
}
@ -968,7 +980,6 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
ret->margin_l = opts->margin_l;
ret->margin_r = opts->margin_r;
ret->cursory = ret->cursorx = -1;
ret->sprixelcache = NULL;
memset(&ret->stats, 0, sizeof(ret->stats));
memset(&ret->stashed_stats, 0, sizeof(ret->stashed_stats));
reset_stats(&ret->stats);
@ -1136,15 +1147,6 @@ ncpile_drop(notcurses* nc, ncpile** pile){
}
}
static void
free_sprixels(notcurses* nc){
while(nc->sprixelcache){
sprixel* tmp = nc->sprixelcache->next;
sprixel_free(nc->sprixelcache);
nc->sprixelcache = tmp;
}
}
// drop all piles and all planes, save the standard plane and its pile
void notcurses_drop_planes(notcurses* nc){
pthread_mutex_lock(&nc->pilelock);
@ -1179,7 +1181,6 @@ int notcurses_stop(notcurses* nc){
if(nc->ttyfd >= 0){
ret |= close(nc->ttyfd);
}
free_sprixels(nc);
egcpool_dump(&nc->pool);
free(nc->lastframe);
free(nc->rstate.mstream);

@ -159,8 +159,8 @@ paint_sprixel(const ncplane* p, const nccell* vis, struct crender* crender,
}else if(!crender->p){
// if we are a bitmap, and above a cell that has changed (and
// will thus be printed), we'll need redraw the sprixel.
if(crender->sprixel == NULL /*|| rvec->sprixel->invalidated == SPRIXEL_HIDE*/){
crender->sprixel = sprixel_by_id(nc, cell_sprixel_id(vis));
if(crender->sprixel == NULL){
crender->sprixel = sprixel_by_id(ncplane_pile_const(p), cell_sprixel_id(vis));
}
}
}
@ -858,9 +858,9 @@ emit_bg_palindex(notcurses* nc, FILE* out, const nccell* srccell){
// remove any sprixels which are no longer desired. for kitty, this will be
// a pure erase; for sixel, we must overwrite.
static int
clean_sprixels(notcurses* nc, const ncpile* p, FILE* out){
clean_sprixels(notcurses* nc, ncpile* p, FILE* out){
sprixel* s;
sprixel** parent = &nc->sprixelcache;
sprixel** parent = &p->sprixelcache;
int ret = 0;
while( (s = *parent) ){
if(s->invalidated == SPRIXEL_HIDE){
@ -900,9 +900,9 @@ clean_sprixels(notcurses* nc, const ncpile* p, FILE* out){
// returns -1 on error, 0 on success. draw any sprixels. any material
// underneath them has already been updated.
static int
rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){
rasterize_sprixels(notcurses* nc, ncpile* p, FILE* out){
int ret = 0;
for(sprixel* s = nc->sprixelcache ; s ; s = s->next){
for(sprixel* s = p->sprixelcache ; s ; s = s->next){
if(s->invalidated == SPRIXEL_INVALIDATED){
int y, x;
ncplane_yx(s->n, &y, &x);
@ -1056,7 +1056,7 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
}
static int
notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){
notcurses_rasterize_inner(notcurses* nc, ncpile* p, FILE* out){
fseeko(out, 0, SEEK_SET);
// we only need to emit a coordinate if it was damaged. the damagemap is a
// bit per coordinate, one per struct crender.
@ -1088,7 +1088,7 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){
// rasterize the rendered frame, and blockingly write it out to the terminal.
static int
raster_and_write(notcurses* nc, const ncpile* p, FILE* out){
raster_and_write(notcurses* nc, ncpile* p, FILE* out){
if(notcurses_rasterize_inner(nc, p, out) < 0){
return -1;
}
@ -1112,7 +1112,7 @@ raster_and_write(notcurses* nc, const ncpile* p, FILE* out){
// during rasterization, we'll get grotesque flicker. 'out' is a memstream
// used to collect a buffer.
static inline int
notcurses_rasterize(notcurses* nc, const ncpile* p, FILE* out){
notcurses_rasterize(notcurses* nc, ncpile* p, FILE* out){
const int cursory = nc->cursory;
const int cursorx = nc->cursorx;
if(cursory >= 0){ // either both are good, or neither is
@ -1154,7 +1154,7 @@ int notcurses_refresh(notcurses* nc, int* restrict dimy, int* restrict dimx){
if(home_cursor(nc, true)){
return -1;
}
ncpile p;
ncpile p = {};
p.dimy = nc->stdplane->leny;
p.dimx = nc->stdplane->lenx;
const int count = (nc->lfdimx > p.dimx ? nc->lfdimx : p.dimx) *
@ -1234,7 +1234,7 @@ ncpile_render_internal(ncplane* n, struct crender* rvec, int leny, int lenx,
int ncpile_rasterize(ncplane* n){
struct timespec start, rasterdone, writedone;
clock_gettime(CLOCK_MONOTONIC, &start);
const ncpile* pile = ncplane_pile(n);
ncpile* pile = ncplane_pile(n);
struct notcurses* nc = ncplane_notcurses(n);
const int miny = pile->dimy < nc->lfdimy ? pile->dimy : nc->lfdimy;
const int minx = pile->dimx < nc->lfdimx ? pile->dimx : nc->lfdimx;

@ -92,8 +92,8 @@ void sprixel_invalidate(sprixel* s, int y, int x){
}
}
sprixel* sprixel_by_id(const notcurses* nc, uint32_t id){
for(sprixel* cur = nc->sprixelcache ; cur ; cur = cur->next){
sprixel* sprixel_by_id(const ncpile* n, uint32_t id){
for(sprixel* cur = n->sprixelcache ; cur ; cur = cur->next){
if(cur->id == id){
return cur;
}
@ -114,9 +114,10 @@ sprixel* sprixel_alloc(ncplane* n, int dimy, int dimx, int placey, int placex){
ret->wipes_outstanding = false;
//fprintf(stderr, "LOOKING AT %p (p->n = %p)\n", ret, ret->n);
if(ncplane_pile(ret->n)){
notcurses* nc = ncplane_notcurses(ret->n);
ret->next = nc->sprixelcache;
nc->sprixelcache = ret;
ncpile* np = ncplane_pile(ret->n);
ret->next = np->sprixelcache;
np->sprixelcache = ret;
const notcurses* nc = ncplane_notcurses_const(ret->n);
ret->cellpxy = nc->tcache.cellpixy;
ret->cellpxx = nc->tcache.cellpixx;
//fprintf(stderr, "%p %p %p\n", nc->sprixelcache, ret, nc->sprixelcache->next);

Loading…
Cancel
Save