[bitmaps] be less aggressive about third phase

When we scribble underneath a TRANSPARENT or ANNIHILATED
sprixcell, or even an OPAQUE or MIXED one in Kitty, we
needn't invalidate the sprixel. Perform these checks for
less aggressive invalidation, eliminating the flicker we
were seeing in xray using Kitty. Closes #1522.
pull/1549/head
nick black 4 years ago committed by Nick Black
parent 333b4414d9
commit 5a702512c5

@ -917,8 +917,6 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int y, int x);
int sixel_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell);
int sprite_destroy(const struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s);
void sprixel_free(sprixel* s);
void sprixel_invalidate(sprixel* s, int y, int x);
void sprixel_movefrom(sprixel* s, int y, int x);
void sprixel_hide(sprixel* s);
int sprite_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out);
int kitty_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out);
@ -937,6 +935,22 @@ int sprite_init(const notcurses* nc);
int kitty_shutdown(int fd);
int sixel_shutdown(int fd);
sprixel* sprixel_by_id(const notcurses* nc, uint32_t id);
// these three all use absolute coordinates
void sprixel_invalidate(sprixel* s, int y, int x);
void sprixel_movefrom(sprixel* s, int y, int x);
// is the sprixel backend kitty?
static inline bool sprixel_kitty_p(const tinfo* t){
return t->pixel_shutdown == kitty_shutdown;
}
// get the TAM entry for these (absolute) coordinates
static inline sprixcell_e sprixel_state(sprixel* s, int y, int x){
int localy = y - s->n->absy;
int localx = x - s->n->absx;
return s->n->tacache[localy * s->dimx + localx];
}
static inline void
pool_release(egcpool* pool, nccell* c){

@ -865,7 +865,7 @@ clean_sprixels(notcurses* nc, const ncpile* p, FILE* out){
ncplane_yx(s->n, &y, &x);
y += s->y;
x += s->x;
//fprintf(stderr, "DRAWING BITMAP %d AT %d/%d for %p\n", s->id, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n);
//fprintf(stderr, "DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n);
if(goto_location(nc, out, y + nc->stdplane->absy, x + nc->stdplane->absx) == 0){
if(sprite_draw(nc, p, s, out)){
return -1;
@ -891,7 +891,7 @@ rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){
ncplane_yx(s->n, &y, &x);
y += s->y;
x += s->x;
//fprintf(stderr, "DRAWING BITMAP %d AT %d/%d for %p\n", s->id, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n);
//fprintf(stderr, "DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n);
if(goto_location(nc, out, y + nc->stdplane->absy, x + nc->stdplane->absx) == 0){
if(sprite_draw(nc, p, s, out)){
return -1;
@ -1009,7 +1009,15 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
nc->rstate.bgpalelidable = false;
}
//fprintf(stderr, "RAST %08x [%s] to %d/%d cols: %u %016lx\n", srccell->gcluster, pool_extended_gcluster(&nc->pool, srccell), y, x, srccell->width, srccell->channels);
if(rvec[damageidx].sprixel){
// this is used to invalidate the sprixel in the first text round,
// which is only necessary for sixel, not kitty.
if(rvec[damageidx].sprixel
&& sprixel_state(rvec[damageidx].sprixel, y, x) != SPRIXCELL_TRANSPARENT
&& sprixel_state(rvec[damageidx].sprixel, y, x) != SPRIXCELL_ANNIHILATED
&& !rvec[damageidx].s.p_beats_sprixel
&& !sprixel_kitty_p(&nc->tcache)){
//fprintf(stderr, "INVALIDATING at %d/%d (%u)\n", y, x, rvec[damageidx].s.p_beats_sprixel);
sprixel_invalidate(rvec[damageidx].sprixel, y, x);
}
if(term_putc(out, &nc->pool, srccell)){

@ -60,7 +60,7 @@ void sprixel_hide(sprixel* s){
}
}
// y and x are absolute coordinates
// y and x are absolute coordinates.
void sprixel_invalidate(sprixel* s, int y, int x){
//fprintf(stderr, "INVALIDATING AT %d/%d\n", y, x);
if(s->invalidated != SPRIXEL_HIDE && s->n){

@ -1,7 +1,7 @@
#include "main.h"
#include <vector>
TEST_CASE("Pixel") {
TEST_CASE("Bitmaps") {
auto nc_ = testing_notcurses();
REQUIRE(nullptr != nc_);
ncplane* ncp_ = notcurses_stdplane(nc_);
@ -169,7 +169,7 @@ TEST_CASE("Pixel") {
struct ncvisual_options vopts = {
.n = nullptr,
.scaling = NCSCALE_NONE,
.y = 0, .x = 0,
.y = 2, .x = 2,
.begy = 0, .begx = 0,
.leny = y, .lenx = x,
.blitter = NCBLIT_PIXEL,
@ -193,6 +193,11 @@ TEST_CASE("Pixel") {
CHECK((i % 2) == tam[(i / dimx) + (i % dimx)]);
ncpixel_set_a(&v[py * x + px], 0);
}
for(int yy = vopts.y ; yy < vopts.y + dimy ; ++yy){
for(int xx = vopts.x ; xx < vopts.x + dimx ; ++xx){
CHECK(((yy * dimx + xx) % 2) == sprixel_state(s, yy, xx));
}
}
ncplane_destroy(n);
}
Loading…
Cancel
Save