summaryrefslogtreecommitdiff
path: root/payloads/libpayload/drivers/video/graphics.c
diff options
context:
space:
mode:
authorYu-Ping Wu <yupingso@chromium.org>2021-10-04 15:02:38 +0800
committerHung-Te Lin <hungte@chromium.org>2021-10-07 14:11:56 +0000
commite5824ff2a90199b32941fe136d080f3f753c3b7f (patch)
tree8c4cf4ce93ce1a390d9e99b4e449131dff429f7d /payloads/libpayload/drivers/video/graphics.c
parent1724b57729795f4eed9fb401572f634aa286ab0c (diff)
libpayload: cbgfx: Clear screen by memcpy
Instead of setting each pixel in the framebuffer, use memcpy() to clear screen faster. As this method should be fast enough, remove the fast path using memset(). The speed of clear_screen() on brya (x_resolution = 1920, bytes_per_line = 7680): - Using memset(): 15ms - Setting each pixel: 25ms - Using memcpy(): 14ms Also remove set_pixel_raw() since it's now used in only one place. BUG=none TEST=emerge-brya libpayload TEST=Saw developer screen on brya BRANCH=none Change-Id: I5f08fb50faab48d3db6b61ae022af3226914f72b Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/58128 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Diffstat (limited to 'payloads/libpayload/drivers/video/graphics.c')
-rw-r--r--payloads/libpayload/drivers/video/graphics.c38
1 files changed, 18 insertions, 20 deletions
diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c
index 53de3024f9..7f08d40ea2 100644
--- a/payloads/libpayload/drivers/video/graphics.c
+++ b/payloads/libpayload/drivers/video/graphics.c
@@ -274,19 +274,12 @@ 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
* and do the validation at callers' site.
*/
-static inline void set_pixel_raw(struct vector *rcoord, uint32_t color)
+static inline void set_pixel(struct vector *coord, uint32_t color)
{
const int bpp = fbinfo->bits_per_pixel;
const int bpl = fbinfo->bytes_per_line;
- 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;
+ int i;
switch (fbinfo->orientation) {
case CB_FB_ORIENTATION_NORMAL:
@@ -308,7 +301,9 @@ static inline void set_pixel(struct vector *coord, uint32_t color)
break;
}
- set_pixel_raw(&rcoord, color);
+ uint8_t * const pixel = FB + rcoord.y * bpl + rcoord.x * bpp / 8;
+ for (i = 0; i < bpp / 8; i++)
+ pixel[i] = (color >> (i * 8));
}
/*
@@ -625,22 +620,25 @@ int clear_screen(const struct rgb_color *rgb)
if (cbgfx_init())
return CBGFX_ERROR_INIT;
- struct vector p;
+ int x, y, i;
uint32_t color = calculate_color(rgb, 0);
const int bpp = fbinfo->bits_per_pixel;
const int bpl = fbinfo->bytes_per_line;
+ uint8_t *line = malloc(bpl);
- /* 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(FB, color & 0xff, fbinfo->y_resolution * bpl);
- } else {
- for (p.y = 0; p.y < fbinfo->y_resolution; p.y++)
- for (p.x = 0; p.x < fbinfo->x_resolution; p.x++)
- set_pixel_raw(&p, color);
+ if (!line) {
+ LOG("Failed to allocate line buffer (%u bytes)\n", bpl);
+ return CBGFX_ERROR_UNKNOWN;
}
+ /* Set line buffer pixels, then memcpy to framebuffer */
+ for (x = 0; x < fbinfo->x_resolution; x++)
+ for (i = 0; i < bpp / 8; i++)
+ line[x * bpp / 8 + i] = (color >> (i * 8));
+ for (y = 0; y < fbinfo->y_resolution; y++)
+ memcpy(FB + y * bpl, line, bpl);
+
+ free(line);
return CBGFX_SUCCESS;
}