mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-10-31 15:20:13 +00:00
Detach sprixel from ncvisual
The ncvisual can't own the sprixel -- we could very well blit it twice to two different planes, wipe cells from one and not the other, and not want those shared. Instead, it's owned by the plane. This clears up the ownership/lifetime story quite a bit, and closes #1548, where only the most recent of several blittings of a sprixel was visible.
This commit is contained in:
parent
8c6cd6a630
commit
2d73ba79e4
@ -547,7 +547,7 @@ ncdirect_render_visual(ncdirect* n, ncvisual* ncv, ncblitter_e blitfxn,
|
||||
bargs.u.pixel.colorregs = n->tcache.color_registers;
|
||||
int cols = lenx / bargs.u.pixel.celldimx + !!(lenx % bargs.u.pixel.celldimx);
|
||||
int rows = leny / bargs.u.pixel.celldimy + !!(leny % bargs.u.pixel.celldimy);
|
||||
if((bargs.u.pixel.spx = sprixel_alloc(ncdv, ncv, rows, cols, 0, 0)) == NULL){
|
||||
if((bargs.u.pixel.spx = sprixel_alloc(ncdv, rows, cols, 0, 0)) == NULL){
|
||||
free_plane(ncdv);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -922,10 +922,10 @@ void sprixel_hide(sprixel* s);
|
||||
int sprite_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out);
|
||||
int kitty_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out);
|
||||
int sixel_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out);
|
||||
// dimy and dimx are cell geometry, not pixel. takes ownership of s on success.
|
||||
sprixel* sprixel_alloc(ncplane* n, struct ncvisual* ncv, int dimy, int dimx,
|
||||
int placey, int placex);
|
||||
sprixel* sprixel_recycle(ncplane* n, struct ncvisual* ncv);
|
||||
// dimy and dimx are cell geometry, not pixel.
|
||||
sprixel* sprixel_alloc(ncplane* n, int dimy, int dimx, int placey, int placex);
|
||||
sprixel* sprixel_recycle(ncplane* n);
|
||||
// takes ownership of s on success.
|
||||
int sprixel_load(sprixel* spx, char* s, int bytes, int placey, int placex,
|
||||
int pixy, int pixx, int parse_start);
|
||||
int sprite_wipe_cell(const notcurses* nc, sprixel* s, int y, int x);
|
||||
|
@ -9,25 +9,22 @@ void sprixel_free(sprixel* s){
|
||||
if(s->n){
|
||||
s->n->sprite = NULL;
|
||||
}
|
||||
if(s->ncv){
|
||||
s->ncv->spx = NULL;
|
||||
}
|
||||
free(s->glyph);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
sprixel* sprixel_recycle(ncplane* n, ncvisual* ncv){
|
||||
sprixel* sprixel_recycle(ncplane* n){
|
||||
assert(n->sprite);
|
||||
const notcurses* nc = ncplane_notcurses_const(n);
|
||||
if(nc->tcache.pixel_destroy == sprite_kitty_annihilate){
|
||||
sprixel* hides = n->sprite ? n->sprite : ncv->spx;
|
||||
assert(hides);
|
||||
sprixel* hides = n->sprite;
|
||||
int dimy = hides->dimy;
|
||||
int dimx = hides->dimx;
|
||||
int y = hides->y;
|
||||
int x = hides->x;
|
||||
sprixel_hide(hides);
|
||||
return sprixel_alloc(n, ncv, dimy, dimx, y, x);
|
||||
return sprixel_alloc(n, dimy, dimx, y, x);
|
||||
}
|
||||
return n->sprite;
|
||||
}
|
||||
@ -52,10 +49,6 @@ void sprixel_hide(sprixel* s){
|
||||
s->invalidated = SPRIXEL_HIDE;
|
||||
s->movedfromy = ncplane_abs_y(s->n);
|
||||
s->movedfromx = ncplane_abs_x(s->n);
|
||||
if(s->ncv){
|
||||
s->ncv->spx = NULL;
|
||||
s->ncv = NULL;
|
||||
}
|
||||
if(s->n){
|
||||
s->n->sprite = NULL;
|
||||
s->n = NULL;
|
||||
@ -86,13 +79,11 @@ sprixel* sprixel_by_id(const notcurses* nc, uint32_t id){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sprixel* sprixel_alloc(ncplane* n, ncvisual* ncv, int dimy, int dimx,
|
||||
int placey, int placex){
|
||||
sprixel* sprixel_alloc(ncplane* n, int dimy, int dimx, int placey, int placex){
|
||||
sprixel* ret = malloc(sizeof(sprixel));
|
||||
if(ret){
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
ret->n = n;
|
||||
ret->ncv = ncv;
|
||||
ret->dimy = dimy;
|
||||
ret->dimx = dimx;
|
||||
ret->y = placey;
|
||||
|
@ -25,8 +25,6 @@ typedef struct ncvisual {
|
||||
// lines are sometimes padded. this many true bytes per row in data.
|
||||
int rowstride;
|
||||
bool owndata; // we own data iff owndata == true
|
||||
// FIXME this cannot live here! it breaks wiping. associate with plane.
|
||||
struct sprixel* spx; // non-NULL if this is NCBLIT_PIXEL
|
||||
} ncvisual;
|
||||
|
||||
static inline void
|
||||
|
@ -700,22 +700,17 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits
|
||||
bargs.u.pixel.celldimx = nc->tcache.cellpixx;
|
||||
bargs.u.pixel.celldimy = nc->tcache.cellpixy;
|
||||
bargs.u.pixel.colorregs = nc->tcache.color_registers;
|
||||
if(ncv->spx == NULL || n->sprite == NULL){
|
||||
if(n->sprite == NULL){
|
||||
int cols = dispcols / bargs.u.pixel.celldimx + !!(dispcols % bargs.u.pixel.celldimx);
|
||||
int rows = disprows / bargs.u.pixel.celldimy + !!(disprows % bargs.u.pixel.celldimy);
|
||||
if(ncv->spx){
|
||||
sprixel_hide(ncv->spx);
|
||||
}
|
||||
if(n->sprite){
|
||||
sprixel_hide(n->sprite);
|
||||
}
|
||||
if((ncv->spx = sprixel_alloc(n, ncv, rows, cols, placey, placex)) == NULL){
|
||||
goto err;
|
||||
if((n->sprite = sprixel_alloc(n, rows, cols, placey, placex)) == NULL){
|
||||
ncplane_destroy(createdn);
|
||||
return NULL;
|
||||
}
|
||||
}else{
|
||||
ncv->spx = sprixel_recycle(n, ncv);
|
||||
n->sprite = sprixel_recycle(n);
|
||||
}
|
||||
bargs.u.pixel.spx = ncv->spx;
|
||||
bargs.u.pixel.spx = n->sprite;
|
||||
// FIXME only set this if cursor is indeed hidden
|
||||
if(nc->tcache.sprixel_cursor_hack){
|
||||
bargs.u.pixel.cursor_hack = nc->tcache.civis;
|
||||
@ -723,16 +718,10 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits
|
||||
bargs.u.pixel.cursor_hack = NULL;
|
||||
}
|
||||
if(ncvisual_blit(ncv, disprows, dispcols, n, bset, disprows, dispcols, &bargs)){
|
||||
goto err;
|
||||
ncplane_destroy(createdn);
|
||||
return NULL;
|
||||
}
|
||||
return n;
|
||||
|
||||
err:
|
||||
if(ncv->spx){
|
||||
sprixel_free(ncv->spx);
|
||||
}
|
||||
ncplane_destroy(createdn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ncplane* ncvisual_render(notcurses* nc, ncvisual* ncv, const struct ncvisual_options* vopts){
|
||||
@ -788,9 +777,6 @@ ncvisual* ncvisual_from_plane(const ncplane* n, ncblitter_e blit, int begy, int
|
||||
}
|
||||
|
||||
void ncvisual_destroy(ncvisual* ncv){
|
||||
if(ncv->spx){
|
||||
ncv->spx->ncv = NULL;
|
||||
}
|
||||
if(visual_implementation){
|
||||
visual_implementation->visual_destroy(ncv);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user