video: Provide a buffer to hold pixels behind the cursor

Drawing the cursor is a destructive operation, so we must save the
previous contents of the affected part of the framebuffer, so it can be
restored afterwards.

Add this to the cursor info and set it up when probing the console
device.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-09-18 10:35:52 -06:00
parent f7b1a67327
commit aebedeac44
4 changed files with 58 additions and 1 deletions

View File

@@ -9,6 +9,8 @@
#include <video.h>
#include <video_console.h>
#include <dm.h>
#include <malloc.h>
#include <spl.h>
#include <video_font.h>
#include "vidconsole_internal.h"
@@ -198,9 +200,46 @@ int cursor_show(struct vidconsole_cursor *curs, struct video_priv *vid_priv,
return 0;
}
int console_alloc_cursor(struct udevice *dev)
{
struct vidconsole_priv *vc_priv;
struct vidconsole_cursor *curs;
struct video_priv *vid_priv;
struct udevice *vid;
int save_count;
if (!CONFIG_IS_ENABLED(CURSOR) || xpl_phase() < PHASE_BOARD_R)
return 0;
vc_priv = dev_get_uclass_priv(dev);
vid = dev_get_parent(dev);
vid_priv = dev_get_uclass_priv(vid);
curs = &vc_priv->curs;
/* Allocate cursor save buffer for maximum possible cursor height */
save_count = vid_priv->ysize * VIDCONSOLE_CURSOR_WIDTH;
curs->save_data = malloc(save_count * sizeof(u32));
if (!curs->save_data)
return -ENOMEM;
return 0;
}
int console_probe(struct udevice *dev)
{
return console_set_font(dev, fonts);
int ret;
ret = console_set_font(dev, fonts);
if (ret)
return ret;
if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) {
ret = console_alloc_cursor(dev);
if (ret)
return ret;
}
return 0;
}
const char *console_simple_get_font_size(struct udevice *dev, uint *sizep)

View File

@@ -1111,6 +1111,10 @@ static int console_truetype_probe(struct udevice *dev)
debug("%s: ready\n", __func__);
ret = console_alloc_cursor(dev);
if (ret)
return ret;
return 0;
}

View File

@@ -123,6 +123,16 @@ int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_pri
int cursor_show(struct vidconsole_cursor *curs, struct video_priv *vid_priv,
bool direction);
/**
* console_alloc_cursor() - Allocate cursor save buffer
*
* Allocates memory for saving pixels under the cursor
*
* @dev: vidconsole device
* Return: 0 if success, -ENOMEM if allocation fails
*/
int console_alloc_cursor(struct udevice *dev);
/**
* console probe function.
*

View File

@@ -32,6 +32,8 @@ enum {
* @enabled: cursor is active (e.g. during readline)
* @visible: cursor is currently visible
* @indent: indent subsequent lines to the same position as the first line
* @saved: true if save_data contains valid data
* @save_data: saved pixels under cursor
* @x: cursor left X position in pixels
* @y: cursor top Y position in pixels
* @height: height of cursor in pixels
@@ -41,6 +43,8 @@ struct vidconsole_cursor {
bool enabled;
bool visible;
bool indent;
bool saved;
u32 *save_data;
/* filled in by get_cursor_info(): */
uint x;