[coreboot-gerrit] New patch to review for coreboot: cbgfx: Use memset() for faster screen clearing if possible

Julius Werner (jwerner@chromium.org) gerrit at coreboot.org
Fri Jul 1 07:45:05 CEST 2016


Julius Werner (jwerner at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15524

-gerrit

commit e678453bda748d23cd973c6d41b62a02e310d853
Author: Julius Werner <jwerner at chromium.org>
Date:   Thu Jun 30 22:34:57 2016 -0700

    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 whole framebuffer lines 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).
    
    Change-Id: I22f032afbb86b96fa5a0cbbdce8526a905c67b58
    Signed-off-by: Julius Werner <jwerner at chromium.org>
---
 payloads/libpayload/drivers/video/graphics.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c
index 01e3565..89e5729 100644
--- a/payloads/libpayload/drivers/video/graphics.c
+++ b/payloads/libpayload/drivers/video/graphics.c
@@ -223,16 +223,26 @@ 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 color is grey, we can fastpath through memset.
+	 * We assume that for 32bpp the high 8 bits get ignored anyway. */
+	if ((((color >> 8) & 0xff) == (color & 0xff)) && (bpp == 16 ||
+	    (((color >> 16) & 0xff) == (color & 0xff)))) {
+		uint8_t *row, *end = fbaddr + fbinfo->y_resolution * bpl;
+		for (row = fbaddr; row < end; row += bpl)
+			memset(row, color & 0xff, fbinfo->x_resolution * bpp/8);
+	} 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;
 }



More information about the coreboot-gerrit mailing list