From patchwork Fri Oct 3 16:55:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 503 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510632; bh=fXg3y1MGcmhHWZjUm1WUnWeVAxFX+bJNPpAL2VuLVJs=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=GYQntcf+kQibLPfpA98kpd4/Ml+eTmorPUa221VJNSqFmKyXCzE6kQySRsF5aShh2 uW10jz9xUIdWt6RR+UMEaUrGfG9VDZgejC7OEIV/gcGMxdY0zQUL2wRwAAi6OUY3Xi GvxvBBNeZHtBwNXpcYR7VHOc4nrq+aq6P/SLu7oxs1JfsVkwOiZnLWS6r7XdOKkNfo 9xr8OxHGcfo4wEN6WAjU9lSO51iWbRYPPC36HozAlFlBBjO+daFjHNf/GEZ9PVjpx8 h7OrUGCy6SG+nk9Ptqpsv0umT1BNe7jSrmiOAvBb8hcoM9EiE4GvPROw3UodWBT93u yDUKjdK8xoncQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 2750067EBD for ; Fri, 3 Oct 2025 10:57:12 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id l2exEG4RCmGA for ; Fri, 3 Oct 2025 10:57:12 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510632; bh=fXg3y1MGcmhHWZjUm1WUnWeVAxFX+bJNPpAL2VuLVJs=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=GYQntcf+kQibLPfpA98kpd4/Ml+eTmorPUa221VJNSqFmKyXCzE6kQySRsF5aShh2 uW10jz9xUIdWt6RR+UMEaUrGfG9VDZgejC7OEIV/gcGMxdY0zQUL2wRwAAi6OUY3Xi GvxvBBNeZHtBwNXpcYR7VHOc4nrq+aq6P/SLu7oxs1JfsVkwOiZnLWS6r7XdOKkNfo 9xr8OxHGcfo4wEN6WAjU9lSO51iWbRYPPC36HozAlFlBBjO+daFjHNf/GEZ9PVjpx8 h7OrUGCy6SG+nk9Ptqpsv0umT1BNe7jSrmiOAvBb8hcoM9EiE4GvPROw3UodWBT93u yDUKjdK8xoncQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 1666267E82 for ; Fri, 3 Oct 2025 10:57:12 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510629; bh=DPviaa0aHH6JF6aVeUWATW7VwrAlOccX1yPUtx0Ostw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YWQrilnBkD8QxkskuK3YNJCAnpEaQ+BQKfheCgUXY9AnQAxBl+2o971P2Oq7vEIT9 u+xXkhCwmRlPEOzSg7h/oQvKTuu665+cAny50DJQyfZzGRSkrz618MJKby3aN3S/Tz 0zWQ24sBZ+AxoId6kJtrTJi8TH6x0RzNN5GT3P/xNUPyP7Sp3laGWlAJMTWvVEL93m WEIwV8XwwhGXwnbyqwvaTUqklkSKs5LwSEDOPl4+3/VYVPepjWeepUPqqmxsIbJNLL g9IMw1Z51FDVLVyeze9ONIHzzcIIHQeMyKr/dKquUloWJIIZYWgceck5/qxl3p7gx2 qFLvzLTgrMTZA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9829167E82; Fri, 3 Oct 2025 10:57:09 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id KrDrtOZ9vVsQ; Fri, 3 Oct 2025 10:57:09 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759510624; bh=IqiXKxYKv1xu2qWReTvBwQ8H8YekE2ax8xaqVUzz7FI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wx/S0btNMojKUvaXSKSWlq58DB3MizScqcnjkqHawsRJxrgdFwq1unD7OlvctysUl AlSijUcFLU6CL3DNEZLCAJ73t+MEOzsSaEtwoS/6Gz536TXe8cTU8NHOYJUyhioyNp FyPKp717QfrCceXvpkINWY5hFV1jXwf8YOVmWUJLCbXvHn0f7tv4QpzD4kmwt+2xxC I7BLRiMeHCcal8unyi8k2+kvmmHUVxrahxFltecdlKMTXFk06ejXUJ81YlRXDEGF0b X0jMmcBwrXTvSUK6oz59gqTbdn/yW1GODN8xbnq7PS4dzC4ZA4nRF0+jevEkzZCuGb d3uJ4wrFjSppQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 64E7767E12; Fri, 3 Oct 2025 10:57:04 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Fri, 3 Oct 2025 10:55:15 -0600 Message-ID: <20251003165525.440173-23-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003165525.440173-1-sjg@u-boot.org> References: <20251003165525.440173-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: L3KPHQ7GLRGAPRNHQDJFSEDXB6GXGLQC X-Message-ID-Hash: L3KPHQ7GLRGAPRNHQDJFSEDXB6GXGLQC X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 22/22] video: sandbox: Add test for sync() damage rectangle List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add a test that verifies the sandbox SDL driver receives the correct damage rectangle in its sync() method. The test: - Clears the display and verifies full-screen damage is passed to sync() - Writes text at a specific position and verifies smaller damage region - Draws a box and verifies the damage matches the box dimensions The damage rectangle is recorded in sandbox_sdl_plat.last_sync_damage and can be retrieved using sandbox_sdl_get_sync_damage() for testing purposes. Co-developed-by: Claude Signed-off-by: Simon Glass --- drivers/video/sandbox_sdl.c | 23 +++++++-- include/dm/test.h | 15 ++++++ test/dm/video.c | 96 +++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c index 67b4b6c7911..fc5843a2822 100644 --- a/drivers/video/sandbox_sdl.c +++ b/drivers/video/sandbox_sdl.c @@ -129,22 +129,39 @@ static int sandbox_sdl_bind(struct udevice *dev) static int sandbox_sdl_video_sync(struct udevice *vid, uint flags) { - struct video_priv *priv = dev_get_uclass_priv(vid); + struct sandbox_sdl_plat *plat = dev_get_plat(vid); + struct video_priv *uc_priv = dev_get_uclass_priv(vid); const struct video_bbox *damage = NULL; if (!(flags & VIDSYNC_FLUSH)) return 0; if (IS_ENABLED(CONFIG_VIDEO_DAMAGE)) - damage = &priv->damage; + damage = &uc_priv->damage; - return sandbox_sdl_sync(priv->fb, damage); + /* Record the damage box for testing */ + if (damage) + plat->last_sync_damage = *damage; + else + memset(&plat->last_sync_damage, '\0', + sizeof(plat->last_sync_damage)); + + return sandbox_sdl_sync(uc_priv->fb, damage); } static const struct video_ops sandbox_sdl_ops = { .sync = sandbox_sdl_video_sync, }; +int sandbox_sdl_get_sync_damage(struct udevice *dev, struct video_bbox *damage) +{ + struct sandbox_sdl_plat *plat = dev_get_plat(dev); + + *damage = plat->last_sync_damage; + + return 0; +} + static const struct udevice_id sandbox_sdl_ids[] = { { .compatible = "sandbox,lcd-sdl" }, { } diff --git a/include/dm/test.h b/include/dm/test.h index 4aabb4603b9..10fd63e759f 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -7,6 +7,7 @@ #define __DM_TEST_H #include +#include struct udevice; @@ -157,6 +158,7 @@ extern struct unit_test_state global_dm_test_state; * 2=upside down, 3=90 degree counterclockwise) * @vidconsole_drv_name: Name of video console driver (set by tests) * @font_size: Console font size to select (set by tests) + * @last_sync_damage: Last damage rectangle passed to sync() method (for testing) */ struct sandbox_sdl_plat { int xres; @@ -165,6 +167,7 @@ struct sandbox_sdl_plat { int rot; const char *vidconsole_drv_name; int font_size; + struct video_bbox last_sync_damage; }; /** @@ -232,4 +235,16 @@ void dm_leak_check_start(struct unit_test_state *uts); * @dms: Overall test state */int dm_leak_check_end(struct unit_test_state *uts); +/** + * sandbox_sdl_get_sync_damage() - Get the last damage rect passed to sync() + * + * This is used for testing to verify that the correct damage rectangle was + * passed to the driver's sync() method. + * + * @dev: Video device + * @damage: Returns the last damage rectangle + * Return: 0 if OK, -ve on error + */ +int sandbox_sdl_get_sync_damage(struct udevice *dev, struct video_bbox *damage); + #endif diff --git a/test/dm/video.c b/test/dm/video.c index 080297d8350..5a5d8053856 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -1372,3 +1372,99 @@ static int dm_test_video_manual_sync(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_video_manual_sync, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test that sync() receives the correct damage rectangle */ +static int dm_test_video_sync_damage(struct unit_test_state *uts) +{ + struct video_bbox damage; + struct udevice *dev, *con; + struct video_priv *priv; + + if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE)) + return -EAGAIN; + + ut_assertok(select_vidconsole(uts, "vidconsole0")); + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "8x16", 0)); + priv = dev_get_uclass_priv(dev); + + /* Use manual sync to prevent interference with the test */ + video_set_manual_sync(true); + + /* Clear the display - this creates a full-screen damage and syncs */ + video_clear(dev); + ut_assertok(video_manual_sync(dev, VIDSYNC_FLUSH | VIDSYNC_COPY)); + ut_asserteq(46, video_compress_fb(uts, dev, false)); + + /* Get the damage rectangle that was passed to sync() */ + ut_assertok(sandbox_sdl_get_sync_damage(dev, &damage)); + + /* Should be the full screen */ + ut_assert(video_bbox_valid(&damage)); + ut_asserteq(0, damage.x0); + ut_asserteq(0, damage.y0); + ut_asserteq(priv->xsize, damage.x1); + ut_asserteq(priv->ysize, damage.y1); + + /* Sync again with no changes - should have empty damage */ + ut_assertok(video_manual_sync(dev, VIDSYNC_FLUSH | VIDSYNC_COPY)); + ut_assertok(sandbox_sdl_get_sync_damage(dev, &damage)); + ut_assert(!video_bbox_valid(&damage)); + + /* Check that priv->damage is still reset to empty */ + ut_assert(!video_bbox_valid(&priv->damage)); + + /* Write a small piece of text at a specific position */ + vidconsole_putc_xy(con, VID_TO_POS(400), 67, 'T'); + + /* Check priv->damage before sync - should have text damage */ + ut_assert(video_bbox_valid(&priv->damage)); + ut_asserteq(400, priv->damage.x0); + ut_asserteq(67, priv->damage.y0); + ut_asserteq(400 + 8, priv->damage.x1); /* 8x16 font */ + ut_asserteq(67 + 16, priv->damage.y1); + + ut_assertok(video_manual_sync(dev, VIDSYNC_FLUSH | VIDSYNC_COPY)); + + /* Get the damage rectangle that was passed to sync() */ + ut_assertok(sandbox_sdl_get_sync_damage(dev, &damage)); + + /* The damage should cover just the character */ + ut_assert(video_bbox_valid(&damage)); + ut_asserteq(400, damage.x0); + ut_asserteq(67, damage.y0); + ut_asserteq(400 + 8, damage.x1); + ut_asserteq(67 + 16, damage.y1); + + /* Check priv->damage after sync - should be reset to empty */ + ut_assert(!video_bbox_valid(&priv->damage)); + + /* Draw a filled box at a different position */ + ut_assertok(video_draw_box(dev, 200, 300, 250, 340, 1, 0xffffff, true)); + + /* Check priv->damage before sync - should have box damage */ + ut_assert(video_bbox_valid(&priv->damage)); + ut_asserteq(200, priv->damage.x0); + ut_asserteq(300, priv->damage.y0); + ut_asserteq(250, priv->damage.x1); + ut_asserteq(340, priv->damage.y1); + + ut_assertok(video_manual_sync(dev, VIDSYNC_FLUSH | VIDSYNC_COPY)); + + /* Get the damage rectangle for the box */ + ut_assertok(sandbox_sdl_get_sync_damage(dev, &damage)); + + /* The damage should cover the box area */ + ut_assert(video_bbox_valid(&damage)); + ut_asserteq(200, damage.x0); + ut_asserteq(300, damage.y0); + ut_asserteq(250, damage.x1); + ut_asserteq(340, damage.y1); + + /* Check priv->damage after sync - should be reset to inverted/empty */ + ut_assert(!video_bbox_valid(&priv->damage)); + + return 0; +} +DM_TEST(dm_test_video_sync_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT);