From 6a1e74feaeed85042f6da590dc5aaaf19124d1f1 Mon Sep 17 00:00:00 2001 From: nick black Date: Fri, 2 Apr 2021 00:54:45 -0400 Subject: [PATCH] [bitmaps] clear out ncvisual link on hide --- src/lib/internal.h | 7 +++++-- src/lib/sprite.c | 16 +++++++++++++--- src/lib/visual.c | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/lib/internal.h b/src/lib/internal.h index c0bf1acf5..4fd3d27d8 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -69,7 +69,10 @@ typedef struct sprixel { char* glyph; // glyph; can be quite large int glyphlen; // length of the glyph in bytes uint32_t id; // embedded into glusters field of nccell, 24 bits + // both the plane and visual can die before the sprixel does. they are + // responsible in such a case for NULLing out this link themselves. struct ncplane* n; // associated ncplane + struct ncvisual* ncv; // associated ncvisual sprixel_e invalidated;// sprixel invalidation state struct sprixel* next; int y, x; @@ -811,8 +814,8 @@ 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, int dimy, int dimx); -sprixel* sprixel_recycle(ncplane* n); +sprixel* sprixel_alloc(ncplane* n, struct ncvisual* ncv, int dimy, int dimx); +sprixel* sprixel_recycle(ncplane* n, struct ncvisual* ncv); 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); diff --git a/src/lib/sprite.c b/src/lib/sprite.c index e40d73589..4e32b991e 100644 --- a/src/lib/sprite.c +++ b/src/lib/sprite.c @@ -1,22 +1,29 @@ #include "internal.h" +#include "visual-details.h" // FIXME needs be atomic static uint32_t sprixelid_nonce; void sprixel_free(sprixel* s){ if(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){ +sprixel* sprixel_recycle(ncplane* n, ncvisual* ncv){ const notcurses* nc = ncplane_notcurses(n); if(nc->tcache.pixel_destroy == sprite_kitty_annihilate){ int dimy = n->sprite->dimy; int dimx = n->sprite->dimx; sprixel_hide(n->sprite); - return sprixel_alloc(n, dimy, dimx); + return sprixel_alloc(n, ncv, dimy, dimx); } return n->sprite; } @@ -40,6 +47,8 @@ void sprixel_hide(sprixel* s){ s->invalidated = SPRIXEL_HIDE; s->movedfromy = ncplane_abs_y(s->n); s->movedfromx = ncplane_abs_x(s->n); + s->ncv->spx = NULL; + s->ncv = NULL; s->n->sprite = NULL; s->n = NULL; } @@ -60,11 +69,12 @@ sprixel* sprixel_by_id(const notcurses* nc, uint32_t id){ return NULL; } -sprixel* sprixel_alloc(ncplane* n, int dimy, int dimx){ +sprixel* sprixel_alloc(ncplane* n, ncvisual* ncv, int dimy, int dimx){ 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->id = ++sprixelid_nonce; diff --git a/src/lib/visual.c b/src/lib/visual.c index 4dca586fb..f54a4109c 100644 --- a/src/lib/visual.c +++ b/src/lib/visual.c @@ -605,11 +605,11 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits if(ncv->spx == 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_alloc(n, rows, cols)) == NULL){ + if((ncv->spx = sprixel_alloc(n, ncv, rows, cols)) == NULL){ goto err; } }else{ - ncv->spx = sprixel_recycle(n); + ncv->spx = sprixel_recycle(n, ncv); } bargs.u.pixel.spx = ncv->spx; if(ncvisual_blit(ncv, disprows, dispcols, n, bset, disprows, dispcols, &bargs)){