persist elision/emission stats, expose them in API

This commit is contained in:
nick black 2019-12-03 14:08:26 -05:00
parent d09029f7f4
commit 5554b3fccb
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
2 changed files with 34 additions and 25 deletions

View File

@ -190,6 +190,22 @@ API unsigned notcurses_supported_styles(const struct notcurses* nc);
// color support.
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',
// '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

View File

@ -27,13 +27,6 @@
#define ESC "\x1b"
#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 {
int ttyfd; // file descriptor 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;
}
void notcurses_stats(const notcurses* nc, ncstats* stats){
memcpy(stats, &nc->stats, sizeof(*stats));
}
static inline int
fbcellidx(const ncplane* n, int row, int col){
return row * n->lenx + col;
@ -630,6 +627,7 @@ notcurses* notcurses_init(const notcurses_options* opts){
if(ret == NULL){
return ret;
}
memset(&ret->stats, 0, sizeof(ret->stats));
ret->ttyfp = opts->outfp;
ret->renderfp = opts->renderfp;
ret->ttyinfp = stdin; // FIXME
@ -673,7 +671,6 @@ notcurses* notcurses_init(const notcurses_options* opts){
if((ret->stdscr = create_initial_ncplane(ret)) == NULL){
goto err;
}
memset(&ret->stats, 0, sizeof(ret->stats));
if(ret->smkx && term_emit(ret->smkx, ret->ttyfp, true)){
free_plane(ret->top);
goto err;
@ -1090,15 +1087,15 @@ int notcurses_render(notcurses* nc){
// no need to write a clearscreen, since we update everything that's been
// changed. just move the physical cursor to the upper left corner.
term_emit(tiparm(nc->cup, 0, 0), out, false);
unsigned lastr, lastg, lastb;
unsigned lastbr, lastbg, lastbb;
// FIXME as of at least gcc 9.2.1, we get a false -Wmaybe-uninitialized below
// 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
// cells and the current cell uses no defaults, or if both the current and
// the last used both defaults.
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){
// 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
@ -1118,10 +1115,10 @@ int notcurses_render(notcurses* nc){
// we can elide the default set iff the previous used both defaults
if(cell_fg_default_p(c) || cell_bg_default_p(c)){
if(!defaultelidable){
++defaultemissions;
++nc->stats.defaultemissions;
term_emit(nc->op, out, false);
}else{
++defaultelisions;
++nc->stats.defaultelisions;
}
// if either is not default, this will get turned off
defaultelidable = true;
@ -1132,13 +1129,11 @@ int notcurses_render(notcurses* nc){
// we can elide the foreground set iff the previous used fg and matched
if(!cell_fg_default_p(c)){
cell_get_fg(c, &r, &g, &b);
if(fgelidable){
if(lastr == r && lastg == g && lastb == b){
++fgelisions;
}
if(fgelidable && lastr == r && lastg == g && lastb == b){
++nc->stats.fgelisions;
}else{
term_fg_rgb8(nc, out, r, g, b);
++fgemissions;
++nc->stats.fgemissions;
fgelidable = true;
}
lastr = r; lastg = g; lastb = b;
@ -1146,13 +1141,11 @@ int notcurses_render(notcurses* nc){
}
if(!cell_bg_default_p(c)){
cell_get_bg(c, &br, &bg, &bb);
if(bgelidable){
if(lastbr == br && lastbg == bg && lastbb == bb){
++bgelisions;
}
if(bgelidable && lastbr == br && lastbg == bg && lastbb == bb){
++nc->stats.bgelisions;
}else{
term_bg_rgb8(nc, out, br, bg, bb);
++bgemissions;
++nc->stats.bgemissions;
bgelidable = true;
}
lastbr = br; lastbg = bg; lastbb = bb;