Skip to content

Commit

Permalink
[render] gratuitous hpa only on plane changes #2199
Browse files Browse the repository at this point in the history
  • Loading branch information
dankamongmen committed Oct 28, 2021
1 parent d5a3ec2 commit 9501644
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 35 deletions.
7 changes: 2 additions & 5 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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`
Expand Down
9 changes: 7 additions & 2 deletions src/lib/in.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 11 additions & 4 deletions src/lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1148,22 +1150,26 @@ 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
// TERM i know supporting cup sans hpa is vt100, and vt100 can suck it.
// 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;
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/kitty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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){
Expand Down
4 changes: 2 additions & 2 deletions src/lib/notcurses.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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){
Expand Down
22 changes: 7 additions & 15 deletions src/lib/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)){
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/sixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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){
Expand Down
10 changes: 5 additions & 5 deletions src/lib/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 :
Expand Down

0 comments on commit 9501644

Please sign in to comment.