diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c index d4eaa09997..49563267a9 100644 --- a/payloads/libpayload/drivers/video/graphics.c +++ b/payloads/libpayload/drivers/video/graphics.c @@ -106,7 +106,8 @@ static int within_box(const struct vector *v, const struct rect *bound) return -1; } -static inline uint32_t calculate_color(const struct rgb_color *rgb) +static inline uint32_t calculate_color(const struct rgb_color *rgb, + uint8_t invert) { uint32_t color = 0; color |= (rgb->red >> (8 - fbinfo->red_mask_size)) @@ -115,6 +116,8 @@ static inline uint32_t calculate_color(const struct rgb_color *rgb) << fbinfo->green_mask_pos; color |= (rgb->blue >> (8 - fbinfo->blue_mask_size)) << fbinfo->blue_mask_pos; + if (invert) + color ^= 0xffffffff; return color; } @@ -180,7 +183,7 @@ int draw_box(const struct rect *box, const struct rgb_color *rgb) struct vector top_left; struct vector size; struct vector p, t; - const uint32_t color = calculate_color(rgb); + const uint32_t color = calculate_color(rgb, 0); const struct scale top_left_s = { .x = { .n = box->offset.x, .d = CANVAS_SCALE, }, .y = { .n = box->offset.y, .d = CANVAS_SCALE, } @@ -230,7 +233,7 @@ int clear_screen(const struct rgb_color *rgb) return CBGFX_ERROR_INIT; struct vector p; - uint32_t color = calculate_color(rgb); + uint32_t color = calculate_color(rgb, 0); const int bpp = fbinfo->bits_per_pixel; const int bpl = fbinfo->bytes_per_line; @@ -269,7 +272,8 @@ static int draw_bitmap_v3(const struct vector *top_left, const struct vector *dim_org, const struct bitmap_header_v3 *header, const struct bitmap_palette_element_v3 *pal, - const uint8_t *pixel_array) + const uint8_t *pixel_array, + uint8_t invert) { const int bpp = header->bits_per_pixel; int32_t dir; @@ -361,7 +365,7 @@ static int draw_bitmap_v3(const struct vector *top_left, pal[c01].blue, pal[c11].blue, &tx, &ty), }; - set_pixel(&p, calculate_color(&rgb)); + set_pixel(&p, calculate_color(&rgb, invert)); } } @@ -552,8 +556,8 @@ static int check_boundary(const struct vector *top_left, } int draw_bitmap(const void *bitmap, size_t size, - const struct scale *pos_rel, uint8_t pivot, - const struct scale *dim_rel) + const struct scale *pos_rel, const struct scale *dim_rel, + uint32_t flags) { struct bitmap_header_v3 header; const struct bitmap_palette_element_v3 *palette; @@ -561,6 +565,8 @@ int draw_bitmap(const void *bitmap, size_t size, struct vector top_left, dim, dim_org; struct scale scale; int rv; + const uint8_t pivot = flags & PIVOT_MASK; + const uint8_t invert = (flags & INVERT_COLORS) >> INVERT_SHIFT; if (cbgfx_init()) return CBGFX_ERROR_INIT; @@ -594,7 +600,7 @@ int draw_bitmap(const void *bitmap, size_t size, } return draw_bitmap_v3(&top_left, &scale, &dim, &dim_org, - &header, palette, pixel_array); + &header, palette, pixel_array, invert); } int draw_bitmap_direct(const void *bitmap, size_t size, @@ -629,7 +635,7 @@ int draw_bitmap_direct(const void *bitmap, size_t size, } return draw_bitmap_v3(top_left, &scale, &dim, &dim, - &header, palette, pixel_array); + &header, palette, pixel_array, 0); } int get_bitmap_dimension(const void *bitmap, size_t sz, struct scale *dim_rel) diff --git a/payloads/libpayload/include/cbgfx.h b/payloads/libpayload/include/cbgfx.h index dca1be0acd..cffc7fd7a6 100644 --- a/payloads/libpayload/include/cbgfx.h +++ b/payloads/libpayload/include/cbgfx.h @@ -130,11 +130,14 @@ int clear_screen(const struct rgb_color *rgb); * @param[in] bitmap Pointer to the bitmap data, starting from file header * @param[in] size Size of the bitmap data * @param[in] pos_rel Coordinate of the pivot relative to the canvas - * @param[in] pivot Pivot position. Use PIVOT_H_* and PIVOT_V_* flags. * @param[in] dim_rel Width and height of the image relative to the canvas * width and height. They must not exceed 1 (=100%). If one * is zero, it's derived from the other to keep the aspect * ratio. + * @param[in] flags lower 8 bits is Pivot position. Use PIVOT_H_* and + * PIVOT_V_* flags. + * Bit 9 is bit to indicate if we invert the rendering. + * 0 = render image as is, 1 = invert image. * * @return CBGFX_* error codes * @@ -143,8 +146,8 @@ int clear_screen(const struct rgb_color *rgb); * positioned so that pos_rel matches the center of the image. */ int draw_bitmap(const void *bitmap, size_t size, - const struct scale *pos_rel, uint8_t pivot, - const struct scale *dim_rel); + const struct scale *pos_rel, const struct scale *dim_rel, + uint32_t flags); /* Pivot flags. See the draw_bitmap description. */ #define PIVOT_H_LEFT (1 << 0) @@ -153,6 +156,11 @@ int draw_bitmap(const void *bitmap, size_t size, #define PIVOT_V_TOP (1 << 3) #define PIVOT_V_CENTER (1 << 4) #define PIVOT_V_BOTTOM (1 << 5) +#define PIVOT_MASK 0x000000ff + +/* invert flag */ +#define INVERT_SHIFT 8 +#define INVERT_COLORS (1 << INVERT_SHIFT) /** * Draw a bitmap image at screen coordinate with no scaling