libpayload: cbgfx: Support buffered I/O

For payloads with UI based on CBGFX, they usually start by calling
clear_canvas or clear_screen and then draw the UI elements. However,
that makes the screen flicker.

A typical solution is to identify and minimize the area to redraw.
However for payloads with complicated UI and do not care about latency,
an alternative is to enable buffered I/O.

The new enable_graphics_buffer() will redirect all graphics I/O
into an invisible working buffer. To flush (redraw) the buffer to the
real screen, call flush_graphics_buffer(). To stop buffering, call
disable_graphics_buffer().

BUG=None
TEST=Add the enable, flush and disable calls to payload 'depthcharge',
     built a firmware and boots into Chrome OS recover UI. No more
     flickering. The average rendering time on x86 platform is 1.2ms.

Change-Id: Id60a2824fd9e164feae16b92b68b003beabea8d3
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/44654
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Hung-Te Lin
2020-08-17 16:22:21 +08:00
committed by Julius Werner
parent 6d7996439f
commit d04b388381
2 changed files with 61 additions and 1 deletions

View File

@ -56,6 +56,8 @@
#define CBGFX_ERROR_FRAMEBUFFER_ADDR 0x15
/* portrait screen not supported */
#define CBGFX_ERROR_PORTRAIT_SCREEN 0x16
/* cannot use buffered I/O */
#define CBGFX_ERROR_GRAPHICS_BUFFER 0x17
struct fraction {
int32_t n;
@ -272,3 +274,24 @@ void clear_blend(void);
* 0 = min alpha argument, 0% opacity
*/
#define ALPHA(percentage) MIN(255, (256 * percentage / 100))
/**
* Enable buffered I/O. All CBGFX operations will be redirected to a working
* buffer, and only updated (redrawn) when flush_graphics_buffer() is called.
*
* @return CBGFX_* error codes
*/
int enable_graphics_buffer(void);
/**
* Redraw buffered graphics data to real screen if graphics buffer is already
* enabled.
*
* @return CBGFX_* error codes
*/
int flush_graphics_buffer(void);
/**
* Stop using buffered I/O and release allocated memory.
*/
void disable_graphics_buffer(void);