From 9e8d262eb5a2c671aaa6d709b2040560df8e4de3 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 30 Jun 2016 22:34:57 -0700 Subject: [PATCH] UPSTREAM: cbgfx: Use memset() for faster screen clearing if possible cbgfx currently makes a separate function call (recomputing some values) for every single pixel it draws. While we mostly don't care that much about display speed, this can become an issue if you're trying to paint the whole screen white on a lowly-clocked Cortex-A53. As a simple solution for these extreme cases, we can build a fast path into clear_screen() that just memset()s the whole framebuffer if the color and pixel format allow it. BUG=chrome-os-partner:54416 TEST=Screen drawing speed on Kevin visibly improves (from 2.5s to 3ms). BUG=None BRANCH=None TEST=None Change-Id: I22f032afbb86b96fa5a0cbbdce8526a905c67b58 Original-Signed-off-by: Julius Werner Original-Reviewed-on: https://review.coreboot.org/15524 Original-Tested-by: build bot (Jenkins) Original-Reviewed-by: Daisuke Nojiri Original-Reviewed-by: Aaron Durbin Signed-off-by: Aaron Durbin Reviewed-on: https://chromium-review.googlesource.com/358591 Reviewed-by: Martin Roth --- payloads/libpayload/drivers/video/graphics.c | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c index 01e3565996..943f8edcae 100644 --- a/payloads/libpayload/drivers/video/graphics.c +++ b/payloads/libpayload/drivers/video/graphics.c @@ -223,16 +223,24 @@ int clear_canvas(const struct rgb_color *rgb) int clear_screen(const struct rgb_color *rgb) { - uint32_t color; - struct vector p; - if (cbgfx_init()) return CBGFX_ERROR_INIT; - color = calculate_color(rgb); - for (p.y = 0; p.y < screen.size.height; p.y++) - for (p.x = 0; p.x < screen.size.width; p.x++) - set_pixel(&p, color); + struct vector p; + uint32_t color = calculate_color(rgb); + const int bpp = fbinfo->bits_per_pixel; + const int bpl = fbinfo->bytes_per_line; + + /* If all significant bytes in color are equal, fastpath through memset. + * We assume that for 32bpp the high byte gets ignored anyway. */ + if ((((color >> 8) & 0xff) == (color & 0xff)) && (bpp == 16 || + (((color >> 16) & 0xff) == (color & 0xff)))) { + memset(fbaddr, color & 0xff, screen.size.height * bpl); + } else { + for (p.y = 0; p.y < screen.size.height; p.y++) + for (p.x = 0; p.x < screen.size.width; p.x++) + set_pixel(&p, color); + } return CBGFX_SUCCESS; }