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 <jwerner@chromium.org>
Original-Reviewed-on: https://review.coreboot.org/15524
Original-Tested-by: build bot (Jenkins)
Original-Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/358591
Reviewed-by: Martin Roth <martinroth@chromium.org>
This commit is contained in:
Julius Werner 2016-06-30 22:34:57 -07:00 committed by chrome-bot
commit 9e8d262eb5

View file

@ -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;
}