console/font: draw bg only if needed
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 15 Jul 2012 10:55:50 +0000 (12:55 +0200)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 15 Jul 2012 10:55:50 +0000 (12:55 +0200)
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>
src/console.c
src/console.h
src/font.h
src/font_pango.c

index 97a76a3..e6ededc 100644 (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);
                        }
                }
        }
index 2424bf6..ccdf167 100644 (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);
index 0fa9142..cce6ff8 100644 (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 */
index b820f6f..cc1804a 100644 (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);