persist elision/emission stats, expose them in API

pull/108/head
nick black 5 years ago
parent d09029f7f4
commit 5554b3fccb
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -190,6 +190,22 @@ API unsigned notcurses_supported_styles(const struct notcurses* nc);
// color support. // color support.
API int notcurses_palette_size(const struct notcurses* nc); API int notcurses_palette_size(const struct notcurses* nc);
typedef struct ncstats {
uint64_t renders; // number of notcurses_render() runs
uint64_t renders_ns; // nanoseconds spent in notcurses_render()
int64_t render_max_ns; // max ns spent in notcurses_render()
int64_t render_min_ns; // min ns spent in successful notcurses_render()
uint64_t fgelisions; // RGB fg elision count
uint64_t fgemissions; // RGB fg emissions
uint64_t bgelisions; // RGB bg elision count
uint64_t bgemissions; // RGB bg emissions
uint64_t defaultelisions; // default color was emitted
uint64_t defaultemissions; // default color was elided
} ncstats;
// Acquire a snapshot of the notcurses object's stats.
API void notcurses_stats(const struct notcurses* nc, ncstats* stats);
// Resize the specified ncplane. The four parameters 'keepy', 'keepx', // Resize the specified ncplane. The four parameters 'keepy', 'keepx',
// 'keepleny', and 'keeplenx' define a subset of the ncplane to keep, // 'keepleny', and 'keeplenx' define a subset of the ncplane to keep,
// unchanged. This may be a section of size 0, though none of these four // unchanged. This may be a section of size 0, though none of these four

@ -27,13 +27,6 @@
#define ESC "\x1b" #define ESC "\x1b"
#define NANOSECS_IN_SEC 1000000000 #define NANOSECS_IN_SEC 1000000000
typedef struct ncstats {
uint64_t renders; // number of notcurses_render() runs
uint64_t renders_ns; // number of nanoseconds spent in notcurses_render()
int64_t render_max_ns; // max ns spent in notcurses_render()
int64_t render_min_ns; // min ns spent in successful notcurses_render()
} ncstats;
typedef struct notcurses { typedef struct notcurses {
int ttyfd; // file descriptor for controlling tty, from opts->ttyfp int ttyfd; // file descriptor for controlling tty, from opts->ttyfp
FILE* ttyfp; // FILE* for controlling tty, from opts->ttyfp FILE* ttyfp; // FILE* for controlling tty, from opts->ttyfp
@ -182,6 +175,10 @@ const char* notcurses_version(void){
return NOTCURSES_VERSION; return NOTCURSES_VERSION;
} }
void notcurses_stats(const notcurses* nc, ncstats* stats){
memcpy(stats, &nc->stats, sizeof(*stats));
}
static inline int static inline int
fbcellidx(const ncplane* n, int row, int col){ fbcellidx(const ncplane* n, int row, int col){
return row * n->lenx + col; return row * n->lenx + col;
@ -630,6 +627,7 @@ notcurses* notcurses_init(const notcurses_options* opts){
if(ret == NULL){ if(ret == NULL){
return ret; return ret;
} }
memset(&ret->stats, 0, sizeof(ret->stats));
ret->ttyfp = opts->outfp; ret->ttyfp = opts->outfp;
ret->renderfp = opts->renderfp; ret->renderfp = opts->renderfp;
ret->ttyinfp = stdin; // FIXME ret->ttyinfp = stdin; // FIXME
@ -673,7 +671,6 @@ notcurses* notcurses_init(const notcurses_options* opts){
if((ret->stdscr = create_initial_ncplane(ret)) == NULL){ if((ret->stdscr = create_initial_ncplane(ret)) == NULL){
goto err; goto err;
} }
memset(&ret->stats, 0, sizeof(ret->stats));
if(ret->smkx && term_emit(ret->smkx, ret->ttyfp, true)){ if(ret->smkx && term_emit(ret->smkx, ret->ttyfp, true)){
free_plane(ret->top); free_plane(ret->top);
goto err; goto err;
@ -1090,15 +1087,15 @@ int notcurses_render(notcurses* nc){
// no need to write a clearscreen, since we update everything that's been // no need to write a clearscreen, since we update everything that's been
// changed. just move the physical cursor to the upper left corner. // changed. just move the physical cursor to the upper left corner.
term_emit(tiparm(nc->cup, 0, 0), out, false); term_emit(tiparm(nc->cup, 0, 0), out, false);
unsigned lastr, lastg, lastb; // FIXME as of at least gcc 9.2.1, we get a false -Wmaybe-uninitialized below
unsigned lastbr, lastbg, lastbb; // when using these without explicit initializations. for the life of me, i
// can't see any such path, and valgrind is cool with it, so what ya gonna do?
unsigned lastr = 0, lastg = 0, lastb = 0;
unsigned lastbr = 0, lastbg = 0, lastbb = 0;
// we can elide a color escape iff the color has not changed between the two // we can elide a color escape iff the color has not changed between the two
// cells and the current cell uses no defaults, or if both the current and // cells and the current cell uses no defaults, or if both the current and
// the last used both defaults. // the last used both defaults.
bool fgelidable = false, bgelidable = false, defaultelidable = false; bool fgelidable = false, bgelidable = false, defaultelidable = false;
uint64_t fgelisions = 0, fgemissions = 0;
uint64_t bgelisions = 0, bgemissions = 0;
uint64_t defaultelisions = 0, defaultemissions = 0;
for(y = 0 ; y < nc->stdscr->leny ; ++y){ for(y = 0 ; y < nc->stdscr->leny ; ++y){
// FIXME previous line could have ended halfway through multicol. what happens? // FIXME previous line could have ended halfway through multicol. what happens?
// FIXME also must explicitly move to next line if we're to deal with // FIXME also must explicitly move to next line if we're to deal with
@ -1118,10 +1115,10 @@ int notcurses_render(notcurses* nc){
// we can elide the default set iff the previous used both defaults // we can elide the default set iff the previous used both defaults
if(cell_fg_default_p(c) || cell_bg_default_p(c)){ if(cell_fg_default_p(c) || cell_bg_default_p(c)){
if(!defaultelidable){ if(!defaultelidable){
++defaultemissions; ++nc->stats.defaultemissions;
term_emit(nc->op, out, false); term_emit(nc->op, out, false);
}else{ }else{
++defaultelisions; ++nc->stats.defaultelisions;
} }
// if either is not default, this will get turned off // if either is not default, this will get turned off
defaultelidable = true; defaultelidable = true;
@ -1132,13 +1129,11 @@ int notcurses_render(notcurses* nc){
// we can elide the foreground set iff the previous used fg and matched // we can elide the foreground set iff the previous used fg and matched
if(!cell_fg_default_p(c)){ if(!cell_fg_default_p(c)){
cell_get_fg(c, &r, &g, &b); cell_get_fg(c, &r, &g, &b);
if(fgelidable){ if(fgelidable && lastr == r && lastg == g && lastb == b){
if(lastr == r && lastg == g && lastb == b){ ++nc->stats.fgelisions;
++fgelisions;
}
}else{ }else{
term_fg_rgb8(nc, out, r, g, b); term_fg_rgb8(nc, out, r, g, b);
++fgemissions; ++nc->stats.fgemissions;
fgelidable = true; fgelidable = true;
} }
lastr = r; lastg = g; lastb = b; lastr = r; lastg = g; lastb = b;
@ -1146,13 +1141,11 @@ int notcurses_render(notcurses* nc){
} }
if(!cell_bg_default_p(c)){ if(!cell_bg_default_p(c)){
cell_get_bg(c, &br, &bg, &bb); cell_get_bg(c, &br, &bg, &bb);
if(bgelidable){ if(bgelidable && lastbr == br && lastbg == bg && lastbb == bb){
if(lastbr == br && lastbg == bg && lastbb == bb){ ++nc->stats.bgelisions;
++bgelisions;
}
}else{ }else{
term_bg_rgb8(nc, out, br, bg, bb); term_bg_rgb8(nc, out, br, bg, bb);
++bgemissions; ++nc->stats.bgemissions;
bgelidable = true; bgelidable = true;
} }
lastbr = br; lastbg = bg; lastbb = bb; lastbr = br; lastbg = bg; lastbb = bb;

Loading…
Cancel
Save