From fe61082c5cc3439083ea80fad19c0811cfd2683b Mon Sep 17 00:00:00 2001 From: nick black Date: Sun, 20 Jun 2021 08:41:32 -0400 Subject: [PATCH] account for sprixel bytes emitted in new stat #1801 --- src/lib/internal.h | 1 + src/lib/kitty.c | 3 ++- src/lib/render.c | 61 ++++++++++++++++++++++++++-------------------- src/lib/sixel.c | 3 ++- src/lib/stats.c | 8 ++++-- 5 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/lib/internal.h b/src/lib/internal.h index c88cc880a..7e9c0cfac 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -888,6 +888,7 @@ sprite_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ } // precondition: s->invalidated is SPRIXEL_INVALIDATED or SPRIXEL_MOVED. +// returns -1 on error, or the number of bytes written. static inline int sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ //sprixel_debug(stderr, s); diff --git a/src/lib/kitty.c b/src/lib/kitty.c index e2d3a411d..03c85cfe7 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -610,10 +610,11 @@ int kitty_destroy(const notcurses* nc __attribute__ ((unused)), return 0; } +// returns the number of bytes written int kitty_draw(const ncpile* p, sprixel* s, FILE* out){ //fprintf(stderr, "DRAWING %d\n", s->id); (void)p; - int ret = 0; + int ret = s->glyphlen; if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){ ret = -1; } diff --git a/src/lib/render.c b/src/lib/render.c index 6433a0bcd..8af96079a 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -898,23 +898,23 @@ 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 +// a pure erase; for sixel, we must overwrite. returns -1 on failure, and +// otherwise the number of bytes emitted redrawing sprixels. +static int64_t clean_sprixels(notcurses* nc, ncpile* p, FILE* out){ sprixel* s; sprixel** parent = &p->sprixelcache; - int ret = 0; + int64_t bytesemitted = 0; while( (s = *parent) ){ if(s->invalidated == SPRIXEL_HIDE){ //fprintf(stderr, "OUGHT HIDE %d [%dx%d] %p\n", s->id, s->dimy, s->dimx, s); - if(sprite_destroy(nc, p, out, s) == 0){ - if( (*parent = s->next) ){ - s->next->prev = s->prev; - } - sprixel_free(s); - }else{ - ret = -1; + if(sprite_destroy(nc, p, out, s)){ + return -1; } + if( (*parent = s->next) ){ + s->next->prev = s->prev; + } + sprixel_free(s); }else if(s->invalidated == SPRIXEL_MOVED || s->invalidated == SPRIXEL_INVALIDATED){ int y, x; ncplane_yx(s->n, &y, &x); @@ -925,9 +925,11 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){ sprite_destroy(nc, p, out, s); } if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l) == 0){ - if(sprite_draw(nc, p, s, out)){ + int r = sprite_draw(nc, p, s, out); + if(r < 0){ return -1; } + bytesemitted += r; nc->rstate.hardcursorpos = true; } parent = &s->next; @@ -937,31 +939,32 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){ parent = &s->next; } } - return ret; + return bytesemitted; } -// returns -1 on error, 0 on success. draw any sprixels. any material -// underneath them has already been updated. -static int +// draw any invalidated sprixels. returns -1 on error, number of bytes written +// on success. any material underneath them has already been updated. +static int64_t rasterize_sprixels(notcurses* nc, ncpile* p, FILE* out){ - int ret = 0; + int64_t bytesemitted = 0; for(sprixel* s = p->sprixelcache ; s ; s = s->next){ if(s->invalidated == SPRIXEL_INVALIDATED){ int y, x; ncplane_yx(s->n, &y, &x); //fprintf(stderr, "3 DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->margin_t, x + nc->margin_l, s->n); - if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l) == 0){ - if(sprite_draw(nc, p, s, out)){ - return -1; - } - nc->rstate.hardcursorpos = true; - }else{ - ret = -1; + if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l)){ + return -1; } + int r = sprite_draw(nc, p, s, out); + if(r < 0){ + return -1; + } + bytesemitted += r; + nc->rstate.hardcursorpos = true; ++nc->stats.sprixelemissions; } } - return ret; + return bytesemitted; } // Producing the frame requires three steps: @@ -1103,7 +1106,8 @@ notcurses_rasterize_inner(notcurses* nc, ncpile* p, FILE* out){ // we explicitly move the cursor at the beginning of each output line, so no // need to home it expliticly. //fprintf(stderr, "pile %p ymax: %d xmax: %d\n", p, p->dimy + nc->margin_t, p->dimx + nc->margin_l); - if(clean_sprixels(nc, p, out) < 0){ + int64_t sprixelbytes = clean_sprixels(nc, p, out); + if(sprixelbytes < 0){ return -1; } update_palette(nc, out); @@ -1112,9 +1116,14 @@ notcurses_rasterize_inner(notcurses* nc, ncpile* p, FILE* out){ return -1; } //fprintf(stderr, "RASTERIZE SPRIXELS\n"); - if(rasterize_sprixels(nc, p, out) < 0){ + int64_t rasprixelbytes = rasterize_sprixels(nc, p, out); + if(rasprixelbytes < 0){ return -1; } + sprixelbytes += rasprixelbytes; + pthread_mutex_lock(&nc->statlock); + nc->stats.sprixelbytes += sprixelbytes; + pthread_mutex_unlock(&nc->statlock); //fprintf(stderr, "RASTERIZE CORE\n"); if(rasterize_core(nc, p, out, 1)){ return -1; diff --git a/src/lib/sixel.c b/src/lib/sixel.c index fc1eea253..b1eed797f 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -831,6 +831,7 @@ int sixel_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ return 0; } +// returns the number of bytes written int sixel_draw(const ncpile* p, sprixel* s, FILE* out){ // if we've wiped or rebuilt any cells, effect those changes now, or else // we'll get flicker when we move to the new location. @@ -856,7 +857,7 @@ int sixel_draw(const ncpile* p, sprixel* s, FILE* out){ } s->invalidated = SPRIXEL_QUIESCENT; } - return 0; + return s->glyphlen; } int sixel_init(const tinfo* ti, int fd){ diff --git a/src/lib/stats.c b/src/lib/stats.c index 751848df5..67948fc3c 100644 --- a/src/lib/stats.c +++ b/src/lib/stats.c @@ -143,6 +143,7 @@ void notcurses_stats_reset(notcurses* nc, ncstats* stats){ stash->refreshes += nc->stats.refreshes; stash->sprixelemissions += nc->stats.sprixelemissions; stash->sprixelelisions += nc->stats.sprixelelisions; + stash->sprixelbytes += nc->stats.sprixelbytes; stash->fbbytes = nc->stats.fbbytes; stash->planes = nc->stats.planes; @@ -211,9 +212,12 @@ void summarize_stats(notcurses* nc){ (stats->fgelisions * 100.0) / (stats->fgemissions + stats->fgelisions), (stats->bgemissions + stats->bgelisions) == 0 ? 0 : (stats->bgelisions * 100.0) / (stats->bgemissions + stats->bgelisions)); - fprintf(stderr, "Sprixel emits:elides: %ju:%ju (%.2f%%)\n", + char totalbuf[BPREFIXSTRLEN + 1]; + qprefix(stats->sprixelbytes, 1, totalbuf, 1); + fprintf(stderr, "Sprixel emits:elides: %ju:%ju (%.2f%%) %sB\n", stats->sprixelemissions, stats->sprixelelisions, (stats->sprixelemissions + stats->sprixelelisions) == 0 ? 0 : - (stats->sprixelelisions * 100.0) / (stats->sprixelemissions + stats->sprixelelisions)); + (stats->sprixelelisions * 100.0) / (stats->sprixelemissions + stats->sprixelelisions), + totalbuf); } }