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 */
struct font_char_attr def_attr;
uint8_t bg_r;
uint8_t bg_g;
uint8_t bg_b;
/* current buffer */
unsigned int size_x;
@ -628,6 +631,18 @@ void kmscon_console_clear_sb(struct kmscon_console *con)
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)
{
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 cell *cell;
float m[16];
bool cursor_done = false;
bool cursor_done = false, draw_bg;
struct font_char_attr attr;
if (!con || !fscr)
@ -764,8 +779,23 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
* foreground */
if (con->flags & KMSCON_CONSOLE_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,
j, i, 1, 1);
j, i, 1, 1, draw_bg);
}
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))
attr.inverse = !attr.inverse;
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_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_set_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,
const struct font_char_attr *attr,
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);
#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,
const struct font_char_attr *attr,
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;
int ret;
@ -728,18 +729,22 @@ int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch,
return ret;
}
if (attr->inverse)
cairo_set_source_rgb(screen->cr, attr->fr, attr->fg, attr->fb);
else
cairo_set_source_rgb(screen->cr, attr->br, attr->bg, attr->bb);
if (draw_bg) {
if (attr->inverse)
cairo_set_source_rgb(screen->cr, attr->fr, attr->fg,
attr->fb);
else
cairo_set_source_rgb(screen->cr, attr->br, attr->bg,
attr->bb);
cairo_move_to(screen->cr, cellx * screen->advance_x,
celly * screen->advance_y);
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, -screen->advance_x, 0);
cairo_close_path(screen->cr);
cairo_fill(screen->cr);
cairo_move_to(screen->cr, cellx * screen->advance_x,
celly * screen->advance_y);
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, -screen->advance_x, 0);
cairo_close_path(screen->cr);
cairo_fill(screen->cr);
}
if (attr->inverse)
cairo_set_source_rgb(screen->cr, attr->br, attr->bg, attr->bb);