console/font: draw bg only if needed

If the background color is identical to the background-color of the glyph
to be drawn, then we can skip drawing the background. This increases
performance a _lot_.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-07-15 12:55:50 +02:00
parent a6bca387da
commit 2cd8cdbea4
4 changed files with 54 additions and 16 deletions

View File

@ -62,6 +62,9 @@ struct kmscon_console {
/* default attributes for new cells */ /* default attributes for new cells */
struct font_char_attr def_attr; struct font_char_attr def_attr;
uint8_t bg_r;
uint8_t bg_g;
uint8_t bg_b;
/* current buffer */ /* current buffer */
unsigned int size_x; unsigned int size_x;
@ -628,6 +631,18 @@ void kmscon_console_clear_sb(struct kmscon_console *con)
con->sb_pos = NULL; con->sb_pos = NULL;
} }
/* set background color */
void kmscon_console_set_bg(struct kmscon_console *con, uint8_t r, uint8_t g,
uint8_t b)
{
if (!con)
return;
con->bg_r = r;
con->bg_g = g;
con->bg_b = b;
}
void kmscon_console_reset(struct kmscon_console *con) void kmscon_console_reset(struct kmscon_console *con)
{ {
unsigned int i; unsigned int i;
@ -721,7 +736,7 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
struct line *iter, *line = NULL; struct line *iter, *line = NULL;
struct cell *cell; struct cell *cell;
float m[16]; float m[16];
bool cursor_done = false; bool cursor_done = false, draw_bg;
struct font_char_attr attr; struct font_char_attr attr;
if (!con || !fscr) if (!con || !fscr)
@ -764,8 +779,23 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
* foreground */ * foreground */
if (con->flags & KMSCON_CONSOLE_INVERSE) if (con->flags & KMSCON_CONSOLE_INVERSE)
attr.inverse = !attr.inverse; attr.inverse = !attr.inverse;
/* draw bg only if it differs from real bg */
if (attr.inverse &&
attr.fr == con->bg_r &&
attr.fg == con->bg_g &&
attr.fb == con->bg_b)
draw_bg = false;
else if (!attr.inverse &&
attr.br == con->bg_r &&
attr.bg == con->bg_g &&
attr.bb == con->bg_b)
draw_bg = false;
else
draw_bg = true;
font_screen_draw_char(fscr, cell->ch, &attr, font_screen_draw_char(fscr, cell->ch, &attr,
j, i, 1, 1); j, i, 1, 1, draw_bg);
} }
if (k == cur_y + 1 && !cursor_done) { if (k == cur_y + 1 && !cursor_done) {
@ -774,7 +804,7 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
if (!(con->flags & KMSCON_CONSOLE_INVERSE)) if (!(con->flags & KMSCON_CONSOLE_INVERSE))
attr.inverse = !attr.inverse; attr.inverse = !attr.inverse;
font_screen_draw_char(fscr, 0, &attr, font_screen_draw_char(fscr, 0, &attr,
cur_x, i, 1, 1); cur_x, i, 1, 1, true);
} }
} }
} }

View File

@ -64,6 +64,8 @@ int kmscon_console_set_margins(struct kmscon_console *con,
void kmscon_console_set_max_sb(struct kmscon_console *con, unsigned int max); void kmscon_console_set_max_sb(struct kmscon_console *con, unsigned int max);
void kmscon_console_clear_sb(struct kmscon_console *con); void kmscon_console_clear_sb(struct kmscon_console *con);
void kmscon_console_set_bg(struct kmscon_console *con, uint8_t r, uint8_t g,
uint8_t b);
void kmscon_console_reset(struct kmscon_console *con); void kmscon_console_reset(struct kmscon_console *con);
void kmscon_console_set_flags(struct kmscon_console *con, unsigned int flags); void kmscon_console_set_flags(struct kmscon_console *con, unsigned int flags);
void kmscon_console_reset_flags(struct kmscon_console *con, unsigned int flags); void kmscon_console_reset_flags(struct kmscon_console *con, unsigned int flags);

View File

@ -159,7 +159,8 @@ int font_screen_draw_start(struct font_screen *screen);
int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch, int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch,
const struct font_char_attr *attr, const struct font_char_attr *attr,
unsigned int cellx, unsigned int celly, unsigned int cellx, unsigned int celly,
unsigned int width, unsigned int height); unsigned int width, unsigned int height,
bool draw_bg);
int font_screen_draw_perform(struct font_screen *screen, float *m); int font_screen_draw_perform(struct font_screen *screen, float *m);
#endif /* FONT_FONT_H */ #endif /* FONT_FONT_H */

View File

@ -710,7 +710,8 @@ int font_screen_draw_start(struct font_screen *screen)
int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch, int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch,
const struct font_char_attr *attr, const struct font_char_attr *attr,
unsigned int cellx, unsigned int celly, unsigned int cellx, unsigned int celly,
unsigned int width, unsigned int height) unsigned int width, unsigned int height,
bool draw_bg)
{ {
struct font_glyph *glyph; struct font_glyph *glyph;
int ret; int ret;
@ -728,18 +729,22 @@ int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch,
return ret; return ret;
} }
if (attr->inverse) if (draw_bg) {
cairo_set_source_rgb(screen->cr, attr->fr, attr->fg, attr->fb); if (attr->inverse)
else cairo_set_source_rgb(screen->cr, attr->fr, attr->fg,
cairo_set_source_rgb(screen->cr, attr->br, attr->bg, attr->bb); attr->fb);
else
cairo_set_source_rgb(screen->cr, attr->br, attr->bg,
attr->bb);
cairo_move_to(screen->cr, cellx * screen->advance_x, cairo_move_to(screen->cr, cellx * screen->advance_x,
celly * screen->advance_y); celly * screen->advance_y);
cairo_rel_line_to(screen->cr, screen->advance_x, 0); cairo_rel_line_to(screen->cr, screen->advance_x, 0);
cairo_rel_line_to(screen->cr, 0, screen->advance_y); cairo_rel_line_to(screen->cr, 0, screen->advance_y);
cairo_rel_line_to(screen->cr, -screen->advance_x, 0); cairo_rel_line_to(screen->cr, -screen->advance_x, 0);
cairo_close_path(screen->cr); cairo_close_path(screen->cr);
cairo_fill(screen->cr); cairo_fill(screen->cr);
}
if (attr->inverse) if (attr->inverse)
cairo_set_source_rgb(screen->cr, attr->br, attr->bg, attr->bb); cairo_set_source_rgb(screen->cr, attr->br, attr->bg, attr->bb);