mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
[render] gratuitous hpa only on plane changes #2199
This commit is contained in:
parent
935e96a3bc
commit
a85a9097f9
7
NEWS.md
7
NEWS.md
@ -196,7 +196,7 @@ rearrangements of Notcurses.
|
||||
* Added `ncplane_moverel()`.
|
||||
* Documented `ncplane_move_yx()` in `notcurses_plane.3`, and removed the
|
||||
false comment that "passing -1 as a coordinate will hold that axis
|
||||
constant" from `USGAE.md` and `notcurses.h`. This has never been true.
|
||||
constant" from `USAGE.md` and `notcurses.h`. This has never been true.
|
||||
* Added `ncdirect_putegc()` to perform Unicode segmentation. It returns
|
||||
the number of columns consumed, and makes available the number of bytes
|
||||
used by the EGC.
|
||||
@ -588,10 +588,7 @@ rearrangements of Notcurses.
|
||||
* Add new function `ncpile_render()`, which renders the pile containing the
|
||||
specified plane to the specified buffer. Add new function
|
||||
`ncpile_rasterize()` to rasterize the specified buffer to output.
|
||||
* Added `NCSTYLE_STRUCK` for strikethrough. Note that this is not supported
|
||||
by terminfo, and we instead just hardcode the control sequence. Use at your
|
||||
own risk! If your terminal doesn't support this control sequence, behavior
|
||||
is undefined.
|
||||
* Added `NCSTYLE_STRUCK` for strikethrough.
|
||||
|
||||
* 2.0.7 (2020-11-21)
|
||||
* The `horiz` union of `ncplane_options` has been discarded; the `int x`
|
||||
|
@ -1035,6 +1035,8 @@ da2_cb(inputctx* ictx){
|
||||
if(pv == 0){
|
||||
return 2;
|
||||
}
|
||||
// modern XTerm replies to XTVERSION, but older versions require extracting
|
||||
// the version from secondary DA
|
||||
if(ictx->initdata->qterm == TERMINAL_XTERM){
|
||||
if(ictx->initdata->version == NULL){
|
||||
char ver[8];
|
||||
@ -1217,11 +1219,14 @@ tcap_cb(inputctx* ictx){
|
||||
// 'TN' (Terminal Name)
|
||||
if(strncasecmp(str, "544e=", 5) == 0){
|
||||
const char* tn = str + 5;
|
||||
// FIXME clean this crap up
|
||||
if(strcasecmp(tn, "6D6C7465726D") == 0){
|
||||
ictx->initdata->qterm = TERMINAL_MLTERM;
|
||||
}else if(strcasecmp(tn, "787465726d") == 0){
|
||||
ictx->initdata->qterm = TERMINAL_XTERM; // "xterm"
|
||||
}else if(strcasecmp(tn, "787465726d2d6b69747479") == 0){
|
||||
ictx->initdata->qterm = TERMINAL_KITTY;
|
||||
}else if(strcasecmp(tn, "787465726D2D323536636F6C6F72") == 0){
|
||||
ictx->initdata->qterm = TERMINAL_KITTY; // "xterm-kitty"
|
||||
}else if(strcasecmp(tn, "787465726d2d323536636f6c6f72") == 0){
|
||||
ictx->initdata->qterm = TERMINAL_XTERM; // "xterm-256color"
|
||||
}else{
|
||||
logdebug("unknown terminal name %s\n", tn);
|
||||
|
@ -128,6 +128,8 @@ typedef struct rasterstate {
|
||||
// modified by: output, cursor moves, clearing the screen (during refresh).
|
||||
int y, x;
|
||||
|
||||
const ncplane* lastsrcp; // last source plane (we emit hpa on plane changes)
|
||||
|
||||
unsigned lastr; // foreground rgb, overloaded for palindexed fg
|
||||
unsigned lastg;
|
||||
unsigned lastb;
|
||||
@ -1148,13 +1150,14 @@ mouse_disable(tinfo* ti, fbuf* f){
|
||||
// sync the drawing position to the specified location with as little overhead
|
||||
// as possible (with nothing, if already at the right location). we prefer
|
||||
// absolute horizontal moves (hpa) to relative ones, in the rare event that
|
||||
// our understanding of our horizontal location is faulty.
|
||||
// our understanding of our horizontal location is faulty. if we're moving from
|
||||
// one plane to another, we emit an hpa no matter what.
|
||||
// FIXME fall back to synthesized moves in the absence of capabilities (i.e.
|
||||
// textronix lacks cup; fake it with horiz+vert moves)
|
||||
// if hardcursorpos is non-zero, we always perform a cup. this is done when we
|
||||
// don't know where the cursor currently is =].
|
||||
static inline int
|
||||
goto_location(notcurses* nc, fbuf* f, int y, int x){
|
||||
goto_location(notcurses* nc, fbuf* f, int y, int x, const ncplane* srcp){
|
||||
//fprintf(stderr, "going to %d/%d from %d/%d hard: %u\n", y, x, nc->rstate.y, nc->rstate.x, nc->rstate.hardcursorpos);
|
||||
int ret = 0;
|
||||
// if we don't have hpa, force a cup even if we're only 1 char away. the only
|
||||
@ -1162,8 +1165,11 @@ goto_location(notcurses* nc, fbuf* f, int y, int x){
|
||||
// you can't use cuf for backwards moves anyway; again, vt100 can suck it.
|
||||
const char* hpa = get_escape(&nc->tcache, ESCAPE_HPA);
|
||||
if(nc->rstate.y == y && hpa && !nc->rstate.hardcursorpos){ // only need move x
|
||||
if(nc->rstate.x == x){ // needn't move shit
|
||||
return 0;
|
||||
if(nc->rstate.x == x){
|
||||
if(nc->rstate.lastsrcp == srcp){
|
||||
return 0; // needn't move shit
|
||||
}
|
||||
++nc->stats.s.hpa_gratuitous;
|
||||
}
|
||||
if(fbuf_emit(f, tiparm(hpa, x))){
|
||||
return -1;
|
||||
@ -1182,6 +1188,7 @@ goto_location(notcurses* nc, fbuf* f, int y, int x){
|
||||
nc->rstate.x = x;
|
||||
nc->rstate.y = y;
|
||||
nc->rstate.hardcursorpos = 0;
|
||||
nc->rstate.lastsrcp = srcp;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1183,7 @@ int kitty_move(sprixel* s, fbuf* f, unsigned noscroll, int yoff, int xoff){
|
||||
const int targx = s->n->absx;
|
||||
logdebug("moving %u to %d %d\n", s->id, targy, targx);
|
||||
int ret = 0;
|
||||
if(goto_location(ncplane_notcurses(s->n), f, targy + yoff, targx + xoff)){
|
||||
if(goto_location(ncplane_notcurses(s->n), f, targy + yoff, targx + xoff, s->n)){
|
||||
ret = -1;
|
||||
}else if(fbuf_printf(f, "\e_Ga=p,i=%d,p=1,q=2%s\e\\", s->id,
|
||||
noscroll ? ",C=1" : "") < 0){
|
||||
|
@ -1093,7 +1093,7 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
||||
// the u7 led the queries so that we would get a cursor position
|
||||
// unaffected by any query spill (unconsumed control sequences). move
|
||||
// us back to that location, in case there was any such spillage.
|
||||
if(goto_location(ret, &ret->rstate.f, *cursory, *cursorx)){
|
||||
if(goto_location(ret, &ret->rstate.f, *cursory, *cursorx, NULL)){
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -1227,7 +1227,7 @@ int notcurses_stop(notcurses* nc){
|
||||
fbuf_putc(&nc->rstate.f, '\n');
|
||||
--targy;
|
||||
}
|
||||
goto_location(nc, &nc->rstate.f, targy, 0);
|
||||
goto_location(nc, &nc->rstate.f, targy, 0, NULL);
|
||||
fbuf_finalize(&nc->rstate.f, stdout);
|
||||
}
|
||||
if(nc->stdplane){
|
||||
|
@ -976,7 +976,7 @@ rasterize_scrolls(const ncpile* p, fbuf* f){
|
||||
if(p->nc->tcache.pixel_scroll){
|
||||
p->nc->tcache.pixel_scroll(p, &p->nc->tcache, scrolls);
|
||||
}
|
||||
if(goto_location(p->nc, f, p->dimy, 0)){
|
||||
if(goto_location(p->nc, f, p->dimy, 0, NULL)){
|
||||
return -1;
|
||||
}
|
||||
// terminals advertising 'bce' will scroll in the current background color;
|
||||
@ -1018,7 +1018,7 @@ rasterize_sprixels(notcurses* nc, ncpile* p, fbuf* f){
|
||||
if(nc->tcache.pixel_commit){
|
||||
int y, x;
|
||||
ncplane_abs_yx(s->n, &y, &x);
|
||||
if(goto_location(nc, f, y + nc->margin_t, x + nc->margin_l)){
|
||||
if(goto_location(nc, f, y + nc->margin_t, x + nc->margin_l, NULL)){
|
||||
return -1;
|
||||
}
|
||||
if(sprite_commit(&nc->tcache, f, s, false)){
|
||||
@ -1107,7 +1107,7 @@ rasterize_core(notcurses* nc, const ncpile* p, fbuf* f, unsigned phase){
|
||||
// was not above a sprixel (and the cell is damaged). in the second
|
||||
// phase, we draw everything that remains damaged.
|
||||
++nc->stats.s.cellemissions;
|
||||
if(goto_location(nc, f, y, x)){
|
||||
if(goto_location(nc, f, y, x, rvec[damageidx].p)){
|
||||
return -1;
|
||||
}
|
||||
// set the style. this can change the color back to the default; if it
|
||||
@ -1322,7 +1322,7 @@ notcurses_rasterize(notcurses* nc, ncpile* p, fbuf* f){
|
||||
if(cursory >= 0){
|
||||
notcurses_cursor_enable(nc, cursory, cursorx);
|
||||
}else if(nc->rstate.logendy >= 0){
|
||||
goto_location(nc, f, nc->rstate.logendy, nc->rstate.logendx);
|
||||
goto_location(nc, f, nc->rstate.logendy, nc->rstate.logendx, NULL);
|
||||
if(fbuf_flush(f, nc->ttyfp)){
|
||||
ret = -1;
|
||||
}
|
||||
@ -1341,18 +1341,10 @@ int clear_and_home(notcurses* nc, tinfo* ti, fbuf* f){
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
const ncplane* stdn = notcurses_stdplane_const(nc);
|
||||
// clearscr didn't fly. try scrolling everything off. first, go to the
|
||||
// bottom of the screen, then write N newlines.
|
||||
if(goto_location(nc, f, ncplane_dim_y(stdn) - 1, 0)){
|
||||
if(emit_scrolls(ti, ncplane_dim_y(notcurses_stdplane_const(nc)), f)){
|
||||
return -1;
|
||||
}
|
||||
for(int y = 0 ; y < ncplane_dim_y(stdn) ; ++y){
|
||||
if(fbuf_putc(f, '\n') < 0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(goto_location(nc, f, 0, 0)){
|
||||
if(goto_location(nc, f, 0, 0, NULL)){
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1682,7 +1674,7 @@ int notcurses_cursor_enable(notcurses* nc, int y, int x){
|
||||
return -1;
|
||||
}
|
||||
// updates nc->rstate.cursor{y,x}
|
||||
if(goto_location(nc, &f, y + nc->margin_t, x + nc->margin_l)){
|
||||
if(goto_location(nc, &f, y + nc->margin_t, x + nc->margin_l, nc->rstate.lastsrcp)){
|
||||
fbuf_free(&f);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1010,7 +1010,7 @@ int sixel_draw(const tinfo* ti, const ncpile* p, sprixel* s, fbuf* f,
|
||||
if(p){
|
||||
const int targy = s->n->absy + yoff;
|
||||
const int targx = s->n->absx + xoff;
|
||||
if(goto_location(p->nc, f, targy, targx)){
|
||||
if(goto_location(p->nc, f, targy, targx, NULL)){
|
||||
return -1;
|
||||
}
|
||||
if(s->invalidated == SPRIXEL_MOVED){
|
||||
|
@ -204,10 +204,11 @@ void summarize_stats(notcurses* nc){
|
||||
1, minbuf, 1),
|
||||
bprefix(stats->renders ? stats->render_bytes / stats->renders : 0, 1, avgbuf, 1);
|
||||
bprefix(stats->render_max_bytes, 1, maxbuf, 1),
|
||||
fprintf(stderr, "%s%sB (%sB min, %sB avg, %sB max) %"PRIu64" input%s" NL,
|
||||
fprintf(stderr, "%s%sB (%sB min, %sB avg, %sB max) %"PRIu64" input%s Ghpa: %"PRIu64 NL,
|
||||
clreol, totalbuf, minbuf, avgbuf, maxbuf,
|
||||
stats->input_events,
|
||||
stats->input_events == 1 ? "" : "s");
|
||||
stats->input_events == 1 ? "" : "s",
|
||||
stats->hpa_gratuitous);
|
||||
}
|
||||
fprintf(stderr, "%s%"PRIu64" failed render%s, %"PRIu64" failed raster%s, %"
|
||||
PRIu64" refresh%s, %"PRIu64" input error%s" NL,
|
||||
@ -216,14 +217,13 @@ void summarize_stats(notcurses* nc){
|
||||
stats->refreshes, stats->refreshes == 1 ? "" : "es",
|
||||
stats->input_errors, stats->input_errors == 1 ? "" : "s");
|
||||
fprintf(stderr, "%sRGB emits:elides: def %"PRIu64":%"PRIu64" fg %"PRIu64":%"
|
||||
PRIu64" bg %"PRIu64":%"PRIu64" Ghpa: %"PRIu64 NL,
|
||||
PRIu64" bg %"PRIu64":%"PRIu64 NL,
|
||||
clreol, stats->defaultemissions,
|
||||
stats->defaultelisions,
|
||||
stats->fgemissions,
|
||||
stats->fgelisions,
|
||||
stats->bgemissions,
|
||||
stats->bgelisions,
|
||||
stats->hpa_gratuitous);
|
||||
stats->bgelisions);
|
||||
fprintf(stderr, "%sCell emits:elides: %"PRIu64":%"PRIu64" (%.2f%%) %.2f%% %.2f%% %.2f%%" NL,
|
||||
clreol, stats->cellemissions, stats->cellelisions,
|
||||
(stats->cellemissions + stats->cellelisions) == 0 ? 0 :
|
||||
|
Loading…
x
Reference in New Issue
Block a user