Linux framebuffer in direct mode (#1959)

In direct mode, we need to call through to `pixel_draw()` rather than just printing it ourselves, given that Linux framebuffer drawing doesn't involve printing (but instead writing to the memory map). Do so.
pull/1988/head
nick black 3 years ago committed by GitHub
parent 4f1de02710
commit 45986668a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -515,7 +515,7 @@ ncdirect_dump_plane(ncdirect* n, const ncplane* np, int xoff){
if(ncdirect_flush(n)){
return -1;
}
if(blocking_write(fileno(n->ttyfp), np->sprite->glyph, np->sprite->glyphlen) < 0){
if(sprite_draw(&n->tcache, NULL, np->sprite, n->ttyfp, 0, xoff)){
return -1;
}
if(sprite_commit(&n->tcache, n->ttyfp, np->sprite, true)){

@ -682,28 +682,28 @@ sprite_scrub(const notcurses* n, const ncpile* p, 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,
sprite_draw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out,
int y, int x){
//sprixel_debug(s, stderr);
logdebug("Sprixel %u state %d\n", s->id, s->invalidated);
return n->tcache.pixel_draw(p, s, out, y, x);
return ti->pixel_draw(ti, p, s, out, y, x);
}
// precondition: s->invalidated is SPRIXEL_MOVED or SPRIXEL_INVALIDATED
// returns -1 on error, or the number of bytes written.
static inline int
sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out,
sprite_redraw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out,
int y, int x){
//sprixel_debug(s, stderr);
logdebug("Sprixel %u state %d\n", s->id, s->invalidated);
if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){
if(s->invalidated == SPRIXEL_MOVED && ti->pixel_move){
// if we are kitty prior to 0.20.0, C=1 isn't available to us, and we must
// not emit it. we use sixel_maxy_pristine as a side channel to encode
// this version information.
bool noscroll = !n->tcache.sixel_maxy_pristine;
return n->tcache.pixel_move(s, out, noscroll);
bool noscroll = !ti->sixel_maxy_pristine;
return ti->pixel_move(s, out, noscroll);
}else{
return n->tcache.pixel_draw(p, s, out, y, x);
return ti->pixel_draw(ti, p, s, out, y, x);
}
}

@ -26,9 +26,12 @@ int iterm_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec){
}
// spit out the control sequence and data.
int iterm_draw(const ncpile *p, sprixel* s, FILE* out, int y, int x){
if(goto_location(p->nc, out, y, x)){
return -1;
int iterm_draw(const tinfo* ti, const ncpile *p, sprixel* s, FILE* out, int y, int x){
(void)ti;
if(p){
if(goto_location(p->nc, out, y, x)){
return -1;
}
}
if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){
return -1;

@ -952,7 +952,9 @@ int kitty_scrub(const ncpile* p, sprixel* s){
}
// returns the number of bytes written
int kitty_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){
int kitty_draw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out,
int y, int x){
(void)ti;
(void)p;
(void)y;
(void)x;

@ -124,16 +124,16 @@ int fbcon_scrub(const struct ncpile* p, sprixel* s){
return 0;
}
int fbcon_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x){
int fbcon_draw(const tinfo* ti, const struct ncpile *p, sprixel* s, FILE* out, int y, int x){
(void)p;
(void)out; // we don't write to the stream
const tinfo* ti = &p->nc->tcache;
int wrote = 0;
for(int l = 0 ; l < s->pixy ; ++l){
for(unsigned l = 0 ; l < (unsigned)s->pixy && l < ti->pixy ; ++l){
// FIXME pixel size isn't necessarily 4B, line isn't necessarily psize*pixx
size_t offset = ((l + y * ti->cellpixy) * ti->pixx + x * ti->cellpixx) * 4;
uint8_t* tl = ti->linux_fbuffer + offset;
const char* src = s->glyph + (l * s->pixx * 4);
for(int c = 0 ; c < s->pixx ; ++c){
for(unsigned c = 0 ; c < (unsigned)s->pixx && c < ti->pixx ; ++c){
uint32_t pixel;
memcpy(&pixel, src, 4);
if(!rgba_trans_p(pixel, 0)){

@ -862,7 +862,7 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){
if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l)){
return -1;
}
int r = sprite_redraw(nc, p, s, out, y + nc->margin_t, x + nc->margin_l);
int r = sprite_redraw(&nc->tcache, p, s, out, y + nc->margin_t, x + nc->margin_l);
if(r < 0){
return -1;
}
@ -923,7 +923,7 @@ rasterize_sprixels(notcurses* nc, ncpile* p, FILE* out){
//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);
int y,x;
ncplane_yx(s->n, &y, &x);
int r = sprite_draw(nc, p, s, out, y + nc->margin_t, x + nc->margin_l);
int r = sprite_draw(&nc->tcache, p, s, out, y + nc->margin_t, x + nc->margin_l);
if(r < 0){
return -1;
}

@ -828,7 +828,9 @@ int sixel_scrub(const ncpile* p, sprixel* s){
}
// returns the number of bytes written
int sixel_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){
int sixel_draw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out,
int y, int x){
(void)ti;
// 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.
if(s->wipes_outstanding){
@ -837,15 +839,17 @@ int sixel_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){
}
s->wipes_outstanding = false;
}
if(goto_location(p->nc, out, y, x)){
return -1;
}
if(s->invalidated == SPRIXEL_MOVED){
for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){
for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){
struct crender *r = &p->crender[yy * p->dimx + xx];
if(!r->sprixel || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE_SIXEL){
r->s.damaged = 1;
if(p){
if(goto_location(p->nc, out, y, x)){
return -1;
}
if(s->invalidated == SPRIXEL_MOVED){
for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){
for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){
struct crender *r = &p->crender[yy * p->dimx + xx];
if(!r->sprixel || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE_SIXEL){
r->s.damaged = 1;
}
}
}
}

@ -172,9 +172,12 @@ int kitty_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int iterm_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int fbcon_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int kitty_rebuild_animation(sprixel* s, int ycell, int xcell, uint8_t* auxvec);
int sixel_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x);
int kitty_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x);
int iterm_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x);
int sixel_draw(const tinfo* ti, const struct ncpile *p, sprixel* s,
FILE* out, int y, int x);
int kitty_draw(const tinfo* ti, const struct ncpile *p, sprixel* s,
FILE* out, int y, int x);
int iterm_draw(const tinfo* ti, const struct ncpile *p, sprixel* s,
FILE* out, int y, int x);
int kitty_move(sprixel* s, FILE* out, unsigned noscroll);
int sixel_scrub(const struct ncpile* p, sprixel* s);
int kitty_scrub(const struct ncpile* p, sprixel* s);
@ -198,7 +201,8 @@ int kitty_blit_animated(struct ncplane* n, int linesize, const void* data,
int leny, int lenx, const struct blitterargs* bargs);
int fbcon_blit(struct ncplane* nc, int linesize, const void* data,
int leny, int lenx, const struct blitterargs* bargs);
int fbcon_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x);
int fbcon_draw(const tinfo* ti, const struct ncpile *p, sprixel* s,
FILE* out, int y, int x);
#ifdef __cplusplus
}

@ -152,8 +152,8 @@ typedef struct tinfo {
int (*pixel_rebuild)(struct sprixel* s, int y, int x, uint8_t* auxvec);
int (*pixel_remove)(int id, FILE* out); // kitty only, issue actual delete command
int (*pixel_init)(const struct tinfo*, int fd); // called when support is detected
int (*pixel_draw)(const struct ncpile* p, struct sprixel* s, FILE* out,
int y, int x);
int (*pixel_draw)(const struct tinfo*, const struct ncpile* p,
struct sprixel* s, FILE* out, int y, int x);
// execute move (erase old graphic, place at new location) if non-NULL
int (*pixel_move)(struct sprixel* s, FILE* out, unsigned noscroll);
int (*pixel_scrub)(const struct ncpile* p, struct sprixel* s);

Loading…
Cancel
Save