glyph-based background spec elision #131

When we emit a glyph that has no background pixels (i.e.
the U+2588 FULL BLOCK glyph), there's no need to emit a
background color change.

Eagle demo currently has hand-coded elision. Results from
80x70 runs using the `-c` parameter:

No optimization: 12.63MiB
Hand-optimized: 12.48MiB
New scheme, no hand-coded optimization: 12.45MiB

w00t!
pull/238/head
nick black 5 years ago committed by Nick Black
parent 113a8f8f62
commit 5b322add56

@ -3,6 +3,7 @@
#include <time.h>
#include <uchar.h>
#include <ctype.h>
#include <wchar.h>
#include <stdio.h>
#include <stdint.h>
@ -1317,18 +1318,37 @@ cell_set_bg_alpha(cell* c, int alpha){
return channels_set_bg_alpha(&c->channels, alpha);
}
// does the cell contain an East Asian Wide codepoint?
// Does the cell contain an East Asian Wide codepoint?
static inline bool
cell_double_wide_p(const cell* c){
return (c->channels & CELL_WIDEASIAN_MASK);
}
// is the cell simple (a lone ASCII character, encoded as such)?
// Is the cell simple (a lone ASCII character, encoded as such)?
static inline bool
cell_simple_p(const cell* c){
return c->gcluster < 0x80;
}
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
// is invalidated by any further operation on the plane 'n', so...watch out!
API const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
// True if the cell does not generate foreground pixels (i.e., the cell is
// entirely whitespace or special characters).
// FIXME do this at cell prep time and set a bit in the channels
static inline bool
cell_noforeground_p(const cell* c){
return cell_simple_p(c) || isspace(c->gcluster);
}
// True if the cell does not generate background pixels. Only the FULL BLOCK
// glyph has this property, AFAIK.
static inline bool
cell_nobackground_p(const struct ncplane* n, const cell* c){
return !cell_simple_p(c) && !strcmp(cell_extended_gcluster(n, c), "\xe2\x96\x88");
}
static inline int
cell_load_simple(struct ncplane* n, cell* c, char ch){
cell_release(n, c);
@ -1347,10 +1367,6 @@ cell_egc_idx(const cell* c){
return c->gcluster - 0x80;
}
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
// is invalidated by any further operation on the plane 'n', so...watch out!
API const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
// load up six cells with the EGCs necessary to draw a box. returns 0 on
// success, -1 on error. on error, any cells this function might
// have loaded before the error are cell_release()d. There must be at least

@ -121,8 +121,6 @@ draw_eagle(struct ncplane* n, const char* sprite){
size_t s;
int sbytes;
uint64_t channels = 0;
// optimization so we can elide more color changes, see README's "#perf"
channels_set_bg_rgb(&channels, 0x00, 0x00, 0x00);
ncplane_cursor_move_yx(n, 0, 0);
for(s = 0 ; sprite[s] ; ++s){
switch(sprite[s]){

@ -534,8 +534,16 @@ notcurses_render_internal(notcurses* nc){
// escapes ourselves, if either is set to default, we first send op, and
// then a turnon for whichever aren't default.
// we can elide the default set iff the previous used both defaults
if(cell_fg_default_p(&c) || cell_bg_default_p(&c)){
// if our cell has a default foreground *or* background, we can elide the
// default set iff one of:
// * we are a partial glyph, and the previous was default on both, or
// * we are a no-foreground glyph, and the previous was default background, or
// * we are a no-background glyph, and the previous was default foreground
// FIXME move these into the cell bits
bool noforeground = cell_noforeground_p(&c);
bool nobackground = cell_nobackground_p(p, &c);
if((!noforeground && cell_fg_default_p(&c)) || (!nobackground && cell_bg_default_p(&c))){
if(!nc->rstate.defaultelidable){
++nc->stats.defaultemissions;
term_emit("op", nc->op, out, false);
@ -548,8 +556,11 @@ notcurses_render_internal(notcurses* nc){
nc->rstate.bgelidable = false;
}
// we can elide the foreground set iff the previous used fg and matched
if(!cell_fg_default_p(&c)){
// if our cell has a non-default foreground, we can elide the non-default
// foreground set iff either:
// * the previous was non-default, and matches what we have now, or
// * we are a no-foreground glyph (iswspace() is true)
if(/*!noforeground &&*/ !cell_fg_default_p(&c)){
cell_get_fg_rgb(&c, &r, &g, &b);
if(nc->rstate.fgelidable && nc->rstate.lastr == r && nc->rstate.lastg == g && nc->rstate.lastb == b){
++nc->stats.fgelisions;
@ -561,7 +572,7 @@ notcurses_render_internal(notcurses* nc){
nc->rstate.lastr = r; nc->rstate.lastg = g; nc->rstate.lastb = b;
nc->rstate.defaultelidable = false;
}
if(!cell_bg_default_p(&c)){
if(!nobackground && !cell_bg_default_p(&c)){
cell_get_bg_rgb(&c, &br, &bg, &bb);
if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){
++nc->stats.bgelisions;

Loading…
Cancel
Save