@@ -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" },
{ }
@@ -7,6 +7,7 @@
#define __DM_TEST_H
#include <linux/types.h>
+#include <video_defs.h>
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
@@ -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);