libpayload: cbgfx: Clear screen by sequential access

Currently clear_screen() calls set_pixel() to set all pixels. However,
the actual order of pixels being set depends on the framebuffer
orientation. With NORMAL orientation, the framebuffer is accessed
sequentially; with LEFT_UP/RIGHT_UP orientation, it is accessed back and
forth, leading to performance drop (>1 second on bugzzy).

Therefore, ensure sequential access to the framebuffer, regardless of
the orientation.

BUG=b:194967458
TEST=emerge-cherry libpayload
BRANCH=dedede

Change-Id: Iecaff5b6abc24ba4b3859cbc44c0d61b2a90b2d9
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57104
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Yu-Ping Wu 2021-08-23 16:27:18 +08:00 committed by Felix Held
parent b69d1dea47
commit 52889c9c9f
1 changed files with 13 additions and 8 deletions

View File

@ -274,12 +274,19 @@ static inline uint32_t calculate_color(const struct rgb_color *rgb,
* Plot a pixel in a framebuffer. This is called from tight loops. Keep it slim * Plot a pixel in a framebuffer. This is called from tight loops. Keep it slim
* and do the validation at callers' site. * and do the validation at callers' site.
*/ */
static inline void set_pixel(struct vector *coord, uint32_t color) static inline void set_pixel_raw(struct vector *rcoord, uint32_t color)
{ {
const int bpp = fbinfo->bits_per_pixel; const int bpp = fbinfo->bits_per_pixel;
const int bpl = fbinfo->bytes_per_line; const int bpl = fbinfo->bytes_per_line;
struct vector rcoord;
int i; int i;
uint8_t * const pixel = FB + rcoord->y * bpl + rcoord->x * bpp / 8;
for (i = 0; i < bpp / 8; i++)
pixel[i] = (color >> (i * 8));
}
static inline void set_pixel(struct vector *coord, uint32_t color)
{
struct vector rcoord;
switch (fbinfo->orientation) { switch (fbinfo->orientation) {
case CB_FB_ORIENTATION_NORMAL: case CB_FB_ORIENTATION_NORMAL:
@ -301,9 +308,7 @@ static inline void set_pixel(struct vector *coord, uint32_t color)
break; break;
} }
uint8_t * const pixel = FB + rcoord.y * bpl + rcoord.x * bpp / 8; set_pixel_raw(&rcoord, color);
for (i = 0; i < bpp / 8; i++)
pixel[i] = (color >> (i * 8));
} }
/* /*
@ -631,9 +636,9 @@ int clear_screen(const struct rgb_color *rgb)
(((color >> 16) & 0xff) == (color & 0xff)))) { (((color >> 16) & 0xff) == (color & 0xff)))) {
memset(FB, color & 0xff, fbinfo->y_resolution * bpl); memset(FB, color & 0xff, fbinfo->y_resolution * bpl);
} else { } else {
for (p.y = 0; p.y < screen.size.height; p.y++) for (p.y = 0; p.y < fbinfo->y_resolution; p.y++)
for (p.x = 0; p.x < screen.size.width; p.x++) for (p.x = 0; p.x < fbinfo->x_resolution; p.x++)
set_pixel(&p, color); set_pixel_raw(&p, color);
} }
return CBGFX_SUCCESS; return CBGFX_SUCCESS;