render: drop cell_locked_p() #914

pull/931/head
nick black 4 years ago
parent 01249a0546
commit c9c18ef740

@ -150,22 +150,6 @@ cellcmp_and_dupfar(egcpool* dampool, cell* damcell,
return 1;
}
// Is this cell locked in? I.e. does it have all three of:
// * a selected EGC
// * CELL_ALPHA_OPAQUE foreground channel
// * CELL_ALPHA_OPAQUE background channel
static inline bool
cell_locked_p(const cell* p){
if(p->gcluster || cell_double_wide_p(p)){
if(cell_fg_alpha(p) == CELL_ALPHA_OPAQUE){
if(cell_bg_alpha(p) == CELL_ALPHA_OPAQUE){
return 1;
}
}
}
return 0;
}
// Extracellular state for a cell during the render process. This array is
// passed along to rasterization, which uses only the 'damaged' bools.
struct crender {
@ -237,13 +221,9 @@ lock_in_highcontrast(cell* targc, struct crender* crender){
}
}
// Paints a single ncplane 'p' into the provided scratch framebuffer 'fb', and
// ultimately 'lastframe' (we can't always write directly into 'lastframe',
// because we need build state to solve certain cells, and need compare their
// solved result to the last frame). Whenever a cell is locked in, it is
// compared against the last frame. If it is different, the 'rvec' bitmap is
// updated with a 1. 'pool' is typically nc->pool, but should be whatever's
// backing fb.
// Paints a single ncplane 'p' into the provided scratch framebuffer 'fb' (we
// can't always write directly into lastframe, because we need build state to
// solve certain cells, and need compare their solved result to the last frame).
//
// dstleny: leny of target rendering area described by fb/lastframe
// dstlenx: lenx of target rendering area described by fb
@ -253,9 +233,8 @@ lock_in_highcontrast(cell* targc, struct crender* crender){
// only those cells where 'p' intersects with the target rendering area are
// rendered.
static int
paint(const ncplane* p, cell* lastframe, struct crender* rvec,
cell* fb, egcpool* pool, int dstleny, int dstlenx,
int dstabsy, int dstabsx){
paint(const ncplane* p, struct crender* rvec, cell* fb,
int dstleny, int dstlenx, int dstabsy, int dstabsx){
int y, x, dimy, dimx, offy, offx;
ncplane_dim_yx(p, &dimy, &dimx);
offy = p->absy - dstabsy;
@ -285,9 +264,6 @@ paint(const ncplane* p, cell* lastframe, struct crender* rvec,
break;
}
cell* targc = &fb[fbcellidx(absy, dstlenx, absx)];
if(cell_locked_p(targc)){
continue;
}
struct crender* crender = &rvec[fbcellidx(absy, dstlenx, absx)];
const cell* vis = &p->fb[nfbcellidx(p, y, x)];
// if we never loaded any content into the cell (or obliterated it by
@ -330,66 +306,41 @@ paint(const ncplane* p, cell* lastframe, struct crender* rvec,
// If it's transparent, it has no effect. Otherwise, update the
// background channel and balpha.
// Evaluate the background first, in case we have HIGHCONTRAST fg text.
vis = &p->fb[nfbcellidx(p, y, x)];
if(cell_bg_default_p(vis)){
vis = &p->basecell;
}
if(cell_bg_palindex_p(vis)){
if(cell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_bg_palindex(targc, cell_bg_palindex(vis));
}
}else if(cell_bg_alpha(targc) > CELL_ALPHA_OPAQUE){
cell_blend_bchannel(targc, cell_bchannel(vis), &crender->bgblends);
}
vis = &p->fb[nfbcellidx(p, y, x)];
if(cell_fg_default_p(vis)){
vis = &p->basecell;
}
if(cell_fg_palindex_p(vis)){
if(cell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_fg_palindex(targc, cell_fg_palindex(vis));
if(cell_bg_alpha(targc) > CELL_ALPHA_OPAQUE){
vis = &p->fb[nfbcellidx(p, y, x)];
if(cell_bg_default_p(vis)){
vis = &p->basecell;
}
}else if(cell_fg_alpha(targc) > CELL_ALPHA_OPAQUE){
if(cell_fg_alpha(vis) == CELL_ALPHA_HIGHCONTRAST){
crender->highcontrast = true;
crender->hcfgblends = crender->fgblends;
crender->hcfg = cell_fchannel(targc);
}
cell_blend_fchannel(targc, cell_fchannel(vis), &crender->fgblends);
// crender->highcontrast can only be true if we just set it, since we're
// about to set targc opaque based on crender->highcontrast (and this
// entire stanza is conditional on targc not being CELL_ALPHA_OPAQUE).
if(crender->highcontrast){
cell_set_fg_alpha(targc, CELL_ALPHA_OPAQUE);
if(cell_bg_palindex_p(vis)){
if(cell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_bg_palindex(targc, cell_bg_palindex(vis));
}
}else{
cell_blend_bchannel(targc, cell_bchannel(vis), &crender->bgblends);
}
}
// have we locked this coordinate in as a result of this plane (cells
// which were already locked in were skipped at the top of the loop)?
if(cell_locked_p(targc)){
lock_in_highcontrast(targc, crender);
cell* prevcell = &lastframe[fbcellidx(absy, dstlenx, absx)];
/*if(cell_simple_p(targc)){
fprintf(stderr, "WROTE %u [%c] to %d/%d (%d/%d)\n", targc->gcluster, targc->gcluster, y, x, absy, absx);
}else{
fprintf(stderr, "WROTE %u [%s] to %d/%d (%d/%d)\n", targc->gcluster, extended_gcluster(crender->p, targc), y, x, absy, absx);
}*/
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc)){
crender->damaged = true;
if(cell_wide_left_p(targc)){
const ncplane* tmpp = crender->p;
++crender;
crender->p = tmpp;
++x;
++prevcell;
++targc;
targc->gcluster = 0;
targc->channels = targc[-1].channels;
targc->stylemask = targc[-1].stylemask;
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc)){
crender->damaged = true;
}
if(cell_fg_alpha(targc) > CELL_ALPHA_OPAQUE){
vis = &p->fb[nfbcellidx(p, y, x)];
if(cell_fg_default_p(vis)){
vis = &p->basecell;
}
if(cell_fg_palindex_p(vis)){
if(cell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_fg_palindex(targc, cell_fg_palindex(vis));
}
}else{
if(cell_fg_alpha(vis) == CELL_ALPHA_HIGHCONTRAST){
crender->highcontrast = true;
crender->hcfgblends = crender->fgblends;
crender->hcfg = cell_fchannel(targc);
}
cell_blend_fchannel(targc, cell_fchannel(vis), &crender->fgblends);
// crender->highcontrast can only be true if we just set it, since we're
// about to set targc opaque based on crender->highcontrast (and this
// entire stanza is conditional on targc not being CELL_ALPHA_OPAQUE).
if(crender->highcontrast){
cell_set_fg_alpha(targc, CELL_ALPHA_OPAQUE);
}
}
}
@ -416,12 +367,24 @@ postpaint(cell* fb, cell* lastframe, int dimy, int dimx,
for(int y = 0 ; y < dimy ; ++y){
for(int x = 0 ; x < dimx ; ++x){
cell* targc = &fb[fbcellidx(y, dimx, x)];
if(!cell_locked_p(targc)){
struct crender* crender = &rvec[fbcellidx(y, dimx, x)];
lock_in_highcontrast(targc, crender);
cell* prevcell = &lastframe[fbcellidx(y, dimx, x)];
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc)){
crender->damaged = true;
struct crender* crender = &rvec[fbcellidx(y, dimx, x)];
lock_in_highcontrast(targc, crender);
cell* prevcell = &lastframe[fbcellidx(y, dimx, x)];
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc)){
crender->damaged = true;
if(cell_wide_left_p(targc)){
const ncplane* tmpp = crender->p;
++crender;
crender->p = tmpp;
++x;
++prevcell;
++targc;
targc->gcluster = 0;
targc->channels = targc[-1].channels;
targc->stylemask = targc[-1].stylemask;
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc)){
crender->damaged = true;
}
}
}
}
@ -444,15 +407,13 @@ int ncplane_mergedown(ncplane* restrict src, ncplane* restrict dst){
memset(rvec, 0, crenderlen);
init_fb(tmpfb, dimy, dimx);
init_fb(rendfb, dimy, dimx);
if(paint(src, rendfb, rvec, tmpfb, &dst->pool, dst->leny, dst->lenx,
dst->absy, dst->absx)){
if(paint(src, rvec, tmpfb, dst->leny, dst->lenx, dst->absy, dst->absx)){
free(rvec);
free(rendfb);
free(tmpfb);
return -1;
}
if(paint(dst, rendfb, rvec, tmpfb, &dst->pool, dst->leny, dst->lenx,
dst->absy, dst->absx)){
if(paint(dst, rvec, tmpfb, dst->leny, dst->lenx, dst->absy, dst->absx)){
free(rvec);
free(rendfb);
free(tmpfb);
@ -1022,8 +983,7 @@ notcurses_render_internal(notcurses* nc, struct crender* rvec){
init_fb(fb, dimy, dimx);
ncplane* p = nc->top;
while(p){
if(paint(p, nc->lastframe, rvec, fb, &nc->pool,
nc->stdplane->leny, nc->stdplane->lenx,
if(paint(p, rvec, fb, nc->stdplane->leny, nc->stdplane->lenx,
nc->stdplane->absy, nc->stdplane->absx)){
free(fb);
return -1;

Loading…
Cancel
Save