[PATCH v2 12/56] video: Add a function to draw a rectangle
Simon Glass
sjg at chromium.org
Fri Mar 28 14:05:59 CET 2025
Provide a way to draw an unfilled box of a certain width. This is useful
for grouping menu items together.
Add a comment showing how to see the copy-framebuffer, for testing.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
(no changes since v1)
drivers/video/video-uclass.c | 36 ++++++++++++++++++++++++++++++++++++
include/video.h | 19 ++++++++++++++++++-
test/dm/video.c | 21 +++++++++++++++++++++
3 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index db40744c196..780b2bc6125 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -26,6 +26,7 @@
#ifdef CONFIG_SANDBOX
#include <asm/sdl.h>
#endif
+#include "vidconsole_internal.h"
/*
* Theory of operation:
@@ -216,6 +217,40 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
return 0;
}
+int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
+ int width, u32 colour)
+{
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+ int pbytes = VNBYTES(priv->bpix);
+ void *start, *line;
+ int pixels = x1 - x0;
+ int row;
+
+ start = priv->fb + y0 * priv->line_length;
+ start += x0 * pbytes;
+ line = start;
+ for (row = y0; row < y1; row++) {
+ void *ptr = line;
+ int i;
+
+ for (i = 0; i < width; i++)
+ fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
+ if (row < y0 + width || row >= y1 - width) {
+ for (i = 0; i < pixels - width * 2; i++)
+ fill_pixel_and_goto_next(&ptr, colour, pbytes,
+ pbytes);
+ } else {
+ ptr += (pixels - width * 2) * pbytes;
+ }
+ for (i = 0; i < width; i++)
+ fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
+ line += priv->line_length;
+ }
+ video_damage(dev, x0, y0, x1 - x0, y1 - y0);
+
+ return 0;
+}
+
int video_reserve_from_bloblist(struct video_handoff *ho)
{
if (!ho->fb || ho->size == 0)
@@ -479,6 +514,7 @@ int video_sync(struct udevice *vid, bool force)
video_flush_dcache(vid, true);
#if defined(CONFIG_VIDEO_SANDBOX_SDL)
+ /* to see the copy framebuffer, use priv->copy_fb */
sandbox_sdl_sync(priv->fb);
#endif
priv->last_sync = get_timer(0);
diff --git a/include/video.h b/include/video.h
index 0ec6b1ca289..9ea6b676463 100644
--- a/include/video.h
+++ b/include/video.h
@@ -249,7 +249,7 @@ int video_fill(struct udevice *dev, u32 colour);
/**
* video_fill_part() - Erase a region
*
- * Erase a rectangle of the display within the given bounds.
+ * Erase a rectangle on the display within the given bounds
*
* @dev: Device to update
* @xstart: X start position in pixels from the left
@@ -262,6 +262,23 @@ int video_fill(struct udevice *dev, u32 colour);
int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
int yend, u32 colour);
+/**
+ * video_draw_box() - Draw a box
+ *
+ * Draw a rectangle on the display within the given bounds
+ *
+ * @dev: Device to update
+ * @x0: X start position in pixels from the left
+ * @y0: Y start position in pixels from the top
+ * @x1: X end position in pixels from the left
+ * @y1: Y end position in pixels from the top
+ * @width: width in pixels
+ * @colour: Value to write
+ * Return: 0 if OK, -ENOSYS if the display depth is not supported
+ */
+int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
+ int width, u32 colour);
+
/**
* video_sync() - Sync a device's frame buffer with its hardware
*
diff --git a/test/dm/video.c b/test/dm/video.c
index dd06b2f58e8..ecf74605b5c 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -902,3 +902,24 @@ static int dm_test_video_silence(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_video_silence, UTF_SCAN_FDT);
+
+/* test drawing a box */
+static int dm_test_video_box(struct unit_test_state *uts)
+{
+ struct video_priv *priv;
+ struct udevice *dev;
+
+ ut_assertok(video_get_nologo(uts, &dev));
+ priv = dev_get_uclass_priv(dev);
+ video_draw_box(dev, 100, 100, 200, 200, 3,
+ video_index_to_colour(priv, VID_LIGHT_BLUE));
+ video_draw_box(dev, 300, 100, 400, 200, 1,
+ video_index_to_colour(priv, VID_MAGENTA));
+ video_draw_box(dev, 500, 100, 600, 200, 20,
+ video_index_to_colour(priv, VID_LIGHT_RED));
+ ut_asserteq(133, video_compress_fb(uts, dev, false));
+ ut_assertok(video_check_copy_fb(uts, dev));
+
+ return 0;
+}
+DM_TEST(dm_test_video_box, UTF_SCAN_FDT);
--
2.43.0
More information about the U-Boot
mailing list