[Concept,11/27] sandbox: Add 'sb grid' command to enable grid overlay

Message ID 20260119204130.3972647-12-sjg@u-boot.org
State New
Headers
Series Expo debugging and textedit improvements (part E) |

Commit Message

Simon Glass Jan. 19, 2026, 8:41 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add a new 'sb grid <0|1>' command to enable or disable a grid overlay
on the sandbox video display. This is useful for debugging UI layout
and alignment.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 arch/sandbox/include/asm/state.h |  1 +
 cmd/sb.c                         | 15 +++++++++++++++
 doc/usage/cmd/sb.rst             |  8 ++++++++
 drivers/video/sandbox_sdl.c      |  6 +++++-
 test/cmd/sb.c                    | 23 +++++++++++++++++++++++
 5 files changed, 52 insertions(+), 1 deletion(-)
  

Patch

diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 1b6eef4a9c3..31766a6e7ea 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -179,6 +179,7 @@  struct sandbox_state {
 	bool no_term_present;		/* Assume no terminal present */
 	bool quiet_vidconsole;		/* Don't use vidconsole for stdout */
 	bool disable_mcheck;		/* Disable mcheck heap protection */
+	bool show_grid;			/* Show grid overlay on video */
 	int video_test;			/* ms to wait before next assert */
 	const char *video_frames_dir;	/* Directory to write video frames */
 	int video_frame_count;		/* Number of frames written */
diff --git a/cmd/sb.c b/cmd/sb.c
index 7de43e7edc3..55a4b5b447f 100644
--- a/cmd/sb.c
+++ b/cmd/sb.c
@@ -97,6 +97,19 @@  static int do_sb_devon(struct cmd_tbl *cmdtp, int flag, int argc,
 	return CMD_RET_SUCCESS;
 }
 
+static int do_sb_grid(struct cmd_tbl *cmdtp, int flag, int argc,
+		      char *const argv[])
+{
+	struct sandbox_state *state = state_get_current();
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	state->show_grid = hextoul(argv[1], NULL);
+
+	return 0;
+}
+
 static int do_sb_devoff(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
@@ -147,6 +160,7 @@  static int do_sb_devoff(struct cmd_tbl *cmdtp, int flag, int argc,
 U_BOOT_LONGHELP(sb,
 	"devoff <node>  - Disable device from device tree node\n"
 	"sb devon <node>   - Enable device from device tree node\n"
+	"sb grid <0|1>     - Enable/disable grid overlay on video\n"
 	"sb handoff        - Show handoff data received from SPL\n"
 	"sb map            - Show mapped memory\n"
 	"sb state          - Show sandbox state");
@@ -154,6 +168,7 @@  U_BOOT_LONGHELP(sb,
 U_BOOT_CMD_WITH_SUBCMDS(sb, "Sandbox status commands", sb_help_text,
 	U_BOOT_SUBCMD_MKENT(devoff, 2, 1, do_sb_devoff),
 	U_BOOT_SUBCMD_MKENT(devon, 2, 1, do_sb_devon),
+	U_BOOT_SUBCMD_MKENT(grid, 2, 1, do_sb_grid),
 	U_BOOT_SUBCMD_MKENT(handoff, 1, 1, do_sb_handoff),
 	U_BOOT_SUBCMD_MKENT(map, 1, 1, do_sb_map),
 	U_BOOT_SUBCMD_MKENT(state, 1, 1, do_sb_state));
diff --git a/doc/usage/cmd/sb.rst b/doc/usage/cmd/sb.rst
index b908631dc08..ee72ecd0db9 100644
--- a/doc/usage/cmd/sb.rst
+++ b/doc/usage/cmd/sb.rst
@@ -13,6 +13,7 @@  Synopsis
 
     sb devoff <node>
     sb devon <node>
+    sb grid <0|1>
     sb handoff
     sb map
     sb state
@@ -40,6 +41,13 @@  devices that are not automatically bound at startup, i.e. those marked as
 status = "disabled" in the device tree. The parameter is the name of a root
 devicetree node.
 
+sb grid
+~~~~~~~
+
+This enables or disables a grid overlay on the video display. When enabled,
+a 10-pixel grid is drawn over the display, which is useful for debugging UI
+layout and alignment. Use ``sb grid 1`` to enable and ``sb grid 0`` to disable.
+
 sb handoff
 ~~~~~~~~~~
 
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 2e2ebe14f84..4785185dd70 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -131,6 +131,8 @@  static int sandbox_sdl_video_sync(struct udevice *vid, uint flags)
 {
 	struct sandbox_sdl_plat *plat = dev_get_plat(vid);
 	struct video_priv *uc_priv = dev_get_uclass_priv(vid);
+	struct sandbox_state *state = state_get_current();
+	struct sandbox_sdl_sync_opts opts;
 	const struct vid_bbox *damage = NULL;
 
 	if (!(flags & VIDSYNC_FLUSH))
@@ -146,7 +148,9 @@  static int sandbox_sdl_video_sync(struct udevice *vid, uint flags)
 		memset(&plat->last_sync_damage, '\0',
 		       sizeof(plat->last_sync_damage));
 
-	return sandbox_sdl_sync(uc_priv->fb, damage, NULL);
+	opts.draw_grid = state->show_grid;
+
+	return sandbox_sdl_sync(uc_priv->fb, damage, &opts);
 }
 
 static const struct video_ops sandbox_sdl_ops = {
diff --git a/test/cmd/sb.c b/test/cmd/sb.c
index cb871dffd57..4ce8a8c4215 100644
--- a/test/cmd/sb.c
+++ b/test/cmd/sb.c
@@ -6,6 +6,7 @@ 
  */
 
 #include <dm.h>
+#include <asm/state.h>
 #include <dm/test.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -121,3 +122,25 @@  static int dm_test_sb_devoff_not_bound(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_sb_devoff_not_bound, UTF_SCAN_FDT | UTF_CONSOLE);
+
+/* Test 'sb grid' command */
+static int dm_test_sb_grid(struct unit_test_state *uts)
+{
+	struct sandbox_state *state = state_get_current();
+
+	/* Ensure grid is initially off */
+	state->show_grid = false;
+
+	/* Enable grid */
+	ut_assertok(run_command("sb grid 1", 0));
+	ut_assert_console_end();
+	ut_asserteq(true, state->show_grid);
+
+	/* Disable grid */
+	ut_assertok(run_command("sb grid 0", 0));
+	ut_assert_console_end();
+	ut_asserteq(false, state->show_grid);
+
+	return 0;
+}
+DM_TEST(dm_test_sb_grid, UTF_CONSOLE);