From 7e78690597941bd0f78400f3ebf0d845548c02ca Mon Sep 17 00:00:00 2001 From: Nick Black Date: Sun, 4 Apr 2021 05:19:36 -0400 Subject: [PATCH] [bitmaps] new unit test LoadVideoPixelScaleDifferentPlanes (#1502) --- src/lib/notcurses.c | 4 +--- src/lib/render.c | 19 ++++++++++++++----- src/lib/sixel.c | 5 ++++- src/player/play.cpp | 10 +++++----- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 9ee9a48c4..36ef00fbe 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1984,9 +1984,7 @@ void ncplane_yx(const ncplane* n, int* y, int* x){ void ncplane_erase(ncplane* n){ if(n->sprite){ - // FIXME ideally we'd clear out the sprixel here, necessary for multiframe - // media with transparency, but it leads to intense flicker in sixel...=[ - return; + sprixel_hide(n->sprite); } // we must preserve the background, but a pure cell_duplicate() would be // wiped out by the egcpool_dump(). do a duplication (to get the stylemask diff --git a/src/lib/render.c b/src/lib/render.c index 1ad740201..b0bdce42e 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -243,6 +243,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx, break; } struct crender* crender = &rvec[fbcellidx(absy, dstlenx, absx)]; +//fprintf(stderr, "p: %p damaged: %u %d/%d\n", p, crender->s.damaged, y, x); nccell* targc = &crender->c; if(cell_wide_right_p(targc)){ continue; @@ -253,19 +254,21 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx, // glyph, but we *do* need to null out any cellregions that we've // scribbled upon. if(cell_sprixel_p(vis)){ +//fprintf(stderr, "presprixel: %p preid: %d id: %d state: %d\n", rvec->sprixel, rvec->sprixel ? rvec->sprixel->id : 0, cell_sprixel_id(vis), sprixel_by_id(ncplane_notcurses_const(p), cell_sprixel_id(vis))->invalidated); // if we already have a glyph solved, and we run into a bitmap // cell, we need to null that cell out of the bitmap. if(crender->p || crender->s.bgblends){ // if sprite_wipe_cell() fails, we presumably do not have the // ability to wipe, and must reprint the character if(sprite_wipe_cell(ncplane_notcurses_const(p), p->sprite, y, x)){ +//fprintf(stderr, "damaging due to wipe %d/%d\n", y, x); crender->s.p_beats_sprixel = 1; crender->s.damaged = 1; } }else if(!crender->p){ // if we are a bitmap, and above a cell that has changed (and // will thus be printed), we'll need redraw the sprixel. - if(crender->sprixel == NULL){ + if(crender->sprixel == NULL /*|| rvec->sprixel->invalidated == SPRIXEL_HIDE*/){ crender->sprixel = sprixel_by_id(ncplane_notcurses_const(p), cell_sprixel_id(vis)); } } @@ -356,7 +359,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx, // side of a wide glyph (nor the null codepoint). if( (targc->gcluster = vis->gcluster) ){ // index copy only if(crender->sprixel && crender->sprixel->invalidated == SPRIXEL_HIDE){ - crender->s.damaged = true; + crender->s.damaged = 1; } crender->s.blittedquads = cell_blittedquadrants(vis); // we can't plop down a wide glyph if the next cell is beyond the @@ -439,6 +442,7 @@ postpaint_cell(nccell* lastframe, int dimx, struct crender* crender, lock_in_highcontrast(targc, crender); nccell* prevcell = &lastframe[fbcellidx(y, dimx, *x)]; if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc) > 0){ +//fprintf(stderr, "damaging due to cmp\n"); crender->s.damaged = 1; assert(!cell_wide_right_p(targc)); const int width = targc->width; @@ -453,6 +457,7 @@ postpaint_cell(nccell* lastframe, int dimx, struct crender* crender, targc->channels = crender[-i].c.channels; targc->stylemask = crender[-i].c.stylemask; if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc) > 0){ +//fprintf(stderr, "damaging due to cmp2\n"); crender->s.damaged = 1; } } @@ -986,6 +991,9 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){ ++x; } }else if(phase != 0 || !rvec[damageidx].s.p_beats_sprixel){ + // in the first text phase, we draw only those glyphs where the glyph + // was not above a sprixel (and the cell is damaged). in the second + // phase, we draw everything that remains damaged. ++nc->stats.cellemissions; if(goto_location(nc, out, y, x)){ return -1; @@ -1065,6 +1073,7 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){ return -1; } rvec[damageidx].s.damaged = 0; + rvec[damageidx].s.p_beats_sprixel = 0; ++nc->rstate.x; if(srccell->width >= 2){ x += srccell->width - 1; @@ -1085,11 +1094,11 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){ // don't write a clearscreen. we only update things that have been changed. // we explicitly move the cursor at the beginning of each output line, so no // need to home it expliticly. - update_palette(nc, out); //fprintf(stderr, "pile %p ymax: %d xmax: %d\n", p, p->dimy + nc->stdplane->absy, p->dimx + nc->stdplane->absx); if(clean_sprixels(nc, p, out) < 0){ return -1; } + update_palette(nc, out); //fprintf(stderr, "RASTERIZE CORE\n"); if(rasterize_core(nc, p, out, 0)){ return -1; @@ -1187,7 +1196,7 @@ int notcurses_refresh(notcurses* nc, int* restrict dimy, int* restrict dimx){ } init_rvec(p.crender, count); for(int i = 0 ; i < count ; ++i){ - p.crender[i].s.damaged = true; + p.crender[i].s.damaged = 1; } int ret = notcurses_rasterize(nc, &p, nc->rstate.mstreamfp); free(p.crender); @@ -1221,7 +1230,7 @@ int notcurses_render_to_file(notcurses* nc, FILE* fp){ } init_rvec(p.crender, count); for(int i = 0 ; i < count ; ++i){ - p.crender[i].s.damaged = true; + p.crender[i].s.damaged = 1; } int ret = raster_and_write(nc, &p, out); free(p.crender); diff --git a/src/lib/sixel.c b/src/lib/sixel.c index 3772ac2c0..9cac02901 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -482,7 +482,10 @@ int sixel_delete(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ (void)out; for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy ; ++yy){ for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx ; ++xx){ - p->crender[yy * p->dimx + xx].s.damaged = 1; + struct crender *r = &p->crender[yy * p->dimx + xx]; + if(!r->sprixel){ + r->s.damaged = 1; + } } } return 0; diff --git a/src/player/play.cpp b/src/player/play.cpp index 45c71aad7..7b8e1a785 100644 --- a/src/player/play.cpp +++ b/src/player/play.cpp @@ -150,7 +150,7 @@ auto perframe(struct ncvisual* ncv, struct ncvisual_options* vopts, } if(keyp == NCKey::Resize){ return 0; - }else if(keyp == 'L' && ni.ctrl){ + }else if(keyp == 'L' && ni.ctrl && !ni.alt){ nc.refresh(nullptr, nullptr); continue; }else if(keyp >= '0' && keyp <= '6' && !ni.alt && !ni.ctrl){ @@ -161,16 +161,16 @@ auto perframe(struct ncvisual* ncv, struct ncvisual_options* vopts, } continue; }else if(keyp == NCKey::Up){ - // FIXME + // FIXME move backwards significantly continue; }else if(keyp == NCKey::Down){ - // FIXME + // FIXME move forwards significantly continue; }else if(keyp == NCKey::Right){ - // FIXME + // FIXME move forwards continue; }else if(keyp == NCKey::Left){ - // FIXME + // FIXME move backwards continue; } return 1;