blob: d3fd74a9a9a304c8bcdeb9d298133d3f16f3837e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass90b6fef2016-01-18 19:52:26 -07002/*
3 * Copyright (c) 2014 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glass90b6fef2016-01-18 19:52:26 -07005 */
6
Simon Glass90b6fef2016-01-18 19:52:26 -07007#include <bzlib.h>
8#include <dm.h>
Simon Glass8bd7f602021-11-19 13:23:58 -07009#include <gzip.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -070011#include <malloc.h>
Simon Glass90b6fef2016-01-18 19:52:26 -070012#include <mapmem.h>
13#include <os.h>
14#include <video.h>
15#include <video_console.h>
Simon Glassc3b5adf2021-11-19 13:23:50 -070016#include <asm/test.h>
Sergei Antonov5da2b462023-06-13 00:19:04 +030017#include <asm/sdl.h>
Simon Glass90b6fef2016-01-18 19:52:26 -070018#include <dm/test.h>
19#include <dm/uclass-internal.h>
Simon Glass75c4d412020-07-19 10:15:37 -060020#include <test/test.h>
Simon Glass90b6fef2016-01-18 19:52:26 -070021#include <test/ut.h>
22
23/*
24 * These tests use the standard sandbox frame buffer, the resolution of which
25 * is defined in the device tree. This only supports 16bpp so the tests only
26 * test that code path. It would be possible to adjust this fairly easily,
27 * by adjusting the bpix value in struct sandbox_sdl_plat. However the code
28 * in sandbox_sdl_sync() would also need to change to handle the different
29 * surface depth.
30 */
Simon Glass90b6fef2016-01-18 19:52:26 -070031/* Basic test of the video uclass */
32static int dm_test_video_base(struct unit_test_state *uts)
33{
34 struct video_priv *priv;
35 struct udevice *dev;
36
37 ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
38 ut_asserteq(1366, video_get_xsize(dev));
39 ut_asserteq(768, video_get_ysize(dev));
40 priv = dev_get_uclass_priv(dev);
41 ut_asserteq(priv->fb_size, 1366 * 768 * 2);
42
43 return 0;
44}
Simon Glass1a92f832024-08-22 07:57:48 -060045DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass90b6fef2016-01-18 19:52:26 -070046
47/**
48 * compress_frame_buffer() - Compress the frame buffer and return its size
49 *
50 * We want to write tests which perform operations on the video console and
51 * check that the frame buffer ends up with the correct contents. But it is
52 * painful to store 'known good' images for comparison with the frame
53 * buffer. As an alternative, we can compress the frame buffer and check the
54 * size of the compressed data. This provides a pretty good level of
55 * certainty and the resulting tests need only check a single value.
56 *
Simon Glass2a0f8e32020-07-02 21:12:29 -060057 * @uts: Test state
Simon Glass90b6fef2016-01-18 19:52:26 -070058 * @dev: Video device
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +030059 * @use_copy: Use copy frame buffer if available
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +010060 * Return: compressed size of the frame buffer, or -ve on error
Simon Glass90b6fef2016-01-18 19:52:26 -070061 */
Simon Glass2a0f8e32020-07-02 21:12:29 -060062static int compress_frame_buffer(struct unit_test_state *uts,
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +030063 struct udevice *dev,
64 bool use_copy)
Simon Glass90b6fef2016-01-18 19:52:26 -070065{
66 struct video_priv *priv = dev_get_uclass_priv(dev);
67 uint destlen;
68 void *dest;
69 int ret;
70
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +030071 if (!IS_ENABLED(CONFIG_VIDEO_COPY))
72 use_copy = false;
73
Simon Glass90b6fef2016-01-18 19:52:26 -070074 destlen = priv->fb_size;
75 dest = malloc(priv->fb_size);
76 if (!dest)
77 return -ENOMEM;
78 ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +030079 use_copy ? priv->copy_fb : priv->fb,
80 priv->fb_size,
Simon Glass90b6fef2016-01-18 19:52:26 -070081 3, 0, 0);
82 free(dest);
83 if (ret)
84 return ret;
85
86 return destlen;
87}
88
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +030089/**
90 * check_copy_frame_buffer() - Compare main frame buffer to copy
91 *
92 * If the copy frame buffer is enabled, this compares it to the main
93 * frame buffer. Normally they should have the same contents after a
94 * sync.
95 *
96 * @uts: Test state
97 * @dev: Video device
98 * Return: 0, or -ve on error
99 */
100static int check_copy_frame_buffer(struct unit_test_state *uts,
101 struct udevice *dev)
102{
103 struct video_priv *priv = dev_get_uclass_priv(dev);
104
105 if (!IS_ENABLED(CONFIG_VIDEO_COPY))
106 return 0;
107
Alexander Graff88b6a22022-06-10 00:59:21 +0200108 video_sync(dev, false);
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300109 ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size),
110 "Copy framebuffer does not match fb");
111
112 return 0;
113}
114
Simon Glass90b6fef2016-01-18 19:52:26 -0700115/*
116 * Call this function at any point to halt and show the current display. Be
117 * sure to run the test with the -l flag.
118 */
119static void __maybe_unused see_output(void)
120{
121 video_sync_all();
122 while (1);
123}
124
Simon Glassdaac9c72016-01-14 18:10:50 -0700125/* Select the video console driver to use for a video device */
126static int select_vidconsole(struct unit_test_state *uts, const char *drv_name)
127{
128 struct sandbox_sdl_plat *plat;
129 struct udevice *dev;
130
131 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
132 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700133 plat = dev_get_plat(dev);
Simon Glassdaac9c72016-01-14 18:10:50 -0700134 plat->vidconsole_drv_name = "vidconsole0";
135
136 return 0;
137}
138
Simon Glass87a3cd72021-11-19 13:24:03 -0700139/**
140 * video_get_nologo() - Disable the logo on the video device and return it
141 *
142 * @uts: Test state
143 * @devp: Returns video device
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100144 * Return: 0 if OK, -ve on error
Simon Glass87a3cd72021-11-19 13:24:03 -0700145 */
146static int video_get_nologo(struct unit_test_state *uts, struct udevice **devp)
147{
148 struct video_uc_plat *uc_plat;
149 struct udevice *dev;
150
151 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
152 ut_assertnonnull(dev);
153 uc_plat = dev_get_uclass_plat(dev);
154 uc_plat->hide_logo = true;
155
156 /* now probe it */
157 ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
158 ut_assertnonnull(dev);
159 *devp = dev;
160
161 return 0;
162}
163
Simon Glass90b6fef2016-01-18 19:52:26 -0700164/* Test text output works on the video console */
165static int dm_test_video_text(struct unit_test_state *uts)
166{
167 struct udevice *dev, *con;
168 int i;
169
170#define WHITE 0xffff
171#define SCROLL_LINES 100
172
Simon Glassdaac9c72016-01-14 18:10:50 -0700173 ut_assertok(select_vidconsole(uts, "vidconsole0"));
Simon Glass87a3cd72021-11-19 13:24:03 -0700174 ut_assertok(video_get_nologo(uts, &dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300175 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
176 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300177 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300178 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700179
180 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
181 vidconsole_putc_xy(con, 0, 0, 'a');
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300182 ut_asserteq(79, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300183 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700184
185 vidconsole_putc_xy(con, 0, 0, ' ');
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300186 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300187 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700188
189 for (i = 0; i < 20; i++)
Simon Glass52c10c52016-01-14 18:10:37 -0700190 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300191 ut_asserteq(273, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300192 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700193
194 vidconsole_set_row(con, 0, WHITE);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300195 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300196 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700197
198 for (i = 0; i < 20; i++)
Simon Glass52c10c52016-01-14 18:10:37 -0700199 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300200 ut_asserteq(273, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300201 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700202
203 return 0;
204}
Simon Glass1a92f832024-08-22 07:57:48 -0600205DM_TEST(dm_test_video_text, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass90b6fef2016-01-18 19:52:26 -0700206
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300207static int dm_test_video_text_12x22(struct unit_test_state *uts)
208{
209 struct udevice *dev, *con;
210 int i;
211
212#define WHITE 0xffff
213#define SCROLL_LINES 100
214
215 ut_assertok(select_vidconsole(uts, "vidconsole0"));
216 ut_assertok(video_get_nologo(uts, &dev));
217 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
218 ut_assertok(vidconsole_select_font(con, "12x22", 0));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300219 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300220 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300221
222 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
223 vidconsole_putc_xy(con, 0, 0, 'a');
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300224 ut_asserteq(89, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300225 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300226
227 vidconsole_putc_xy(con, 0, 0, ' ');
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300228 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300229 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300230
231 for (i = 0; i < 20; i++)
232 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300233 ut_asserteq(363, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300234 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300235
236 vidconsole_set_row(con, 0, WHITE);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300237 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300238 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300239
240 for (i = 0; i < 20; i++)
241 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300242 ut_asserteq(363, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300243 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300244
245 return 0;
246}
Simon Glass1a92f832024-08-22 07:57:48 -0600247DM_TEST(dm_test_video_text_12x22, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300248
Simon Glass90b6fef2016-01-18 19:52:26 -0700249/* Test handling of special characters in the console */
250static int dm_test_video_chars(struct unit_test_state *uts)
251{
252 struct udevice *dev, *con;
Simon Glass37b80202016-01-14 18:10:38 -0700253 const char *test_string = "Well\b\b\b\bxhe is\r \n\ta very \amodest \bman\n\t\tand Has much to\b\bto be modest about.";
Simon Glass90b6fef2016-01-18 19:52:26 -0700254
Simon Glassdaac9c72016-01-14 18:10:50 -0700255 ut_assertok(select_vidconsole(uts, "vidconsole0"));
Simon Glass87a3cd72021-11-19 13:24:03 -0700256 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700257 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300258 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Rob Clark985935b2017-09-25 15:45:08 -0400259 vidconsole_put_string(con, test_string);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300260 ut_asserteq(466, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300261 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700262
263 return 0;
264}
Simon Glass1a92f832024-08-22 07:57:48 -0600265DM_TEST(dm_test_video_chars, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass90b6fef2016-01-18 19:52:26 -0700266
Rob Clark09d64b32017-09-25 15:45:09 -0400267#ifdef CONFIG_VIDEO_ANSI
268#define ANSI_ESC "\x1b"
269/* Test handling of ANSI escape sequences */
270static int dm_test_video_ansi(struct unit_test_state *uts)
271{
272 struct udevice *dev, *con;
273
274 ut_assertok(select_vidconsole(uts, "vidconsole0"));
Simon Glass87a3cd72021-11-19 13:24:03 -0700275 ut_assertok(video_get_nologo(uts, &dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400276 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300277 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Rob Clark09d64b32017-09-25 15:45:09 -0400278
279 /* reference clear: */
280 video_clear(con->parent);
Simon Glass0806dcc2018-10-01 11:55:14 -0600281 video_sync(con->parent, false);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300282 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300283 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400284
285 /* test clear escape sequence: [2J */
286 vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300287 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300288 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400289
290 /* test set-cursor: [%d;%df */
291 vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300292 ut_asserteq(143, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300293 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400294
295 /* test colors (30-37 fg color, 40-47 bg color) */
296 vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
297 vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300298 ut_asserteq(272, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300299 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400300
301 return 0;
302}
Simon Glass1a92f832024-08-22 07:57:48 -0600303DM_TEST(dm_test_video_ansi, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Rob Clark09d64b32017-09-25 15:45:09 -0400304#endif
305
Simon Glass90b6fef2016-01-18 19:52:26 -0700306/**
307 * check_vidconsole_output() - Run a text console test
308 *
309 * @uts: Test state
Simon Glass4425bf42020-07-02 21:12:28 -0600310 * @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
311 * 2=upside down, 3=90 degree counterclockwise)
Simon Glass90b6fef2016-01-18 19:52:26 -0700312 * @wrap_size: Expected size of compressed frame buffer for the wrap test
313 * @scroll_size: Same for the scroll test
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100314 * Return: 0 on success
Simon Glass90b6fef2016-01-18 19:52:26 -0700315 */
316static int check_vidconsole_output(struct unit_test_state *uts, int rot,
317 int wrap_size, int scroll_size)
318{
319 struct udevice *dev, *con;
320 struct sandbox_sdl_plat *plat;
321 int i;
322
323 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
324 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700325 plat = dev_get_plat(dev);
Simon Glass90b6fef2016-01-18 19:52:26 -0700326 plat->rot = rot;
327
Simon Glass87a3cd72021-11-19 13:24:03 -0700328 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700329 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300330 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300331 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300332 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700333
334 /* Check display wrap */
335 for (i = 0; i < 120; i++)
336 vidconsole_put_char(con, 'A' + i % 50);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300337 ut_asserteq(wrap_size, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300338 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700339
340 /* Check display scrolling */
341 for (i = 0; i < SCROLL_LINES; i++) {
342 vidconsole_put_char(con, 'A' + i % 50);
343 vidconsole_put_char(con, '\n');
344 }
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300345 ut_asserteq(scroll_size, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300346 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700347
348 /* If we scroll enough, the screen becomes blank again */
349 for (i = 0; i < SCROLL_LINES; i++)
350 vidconsole_put_char(con, '\n');
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300351 ut_asserteq(46, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300352 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700353
354 return 0;
355}
356
357/* Test text output through the console uclass */
358static int dm_test_video_context(struct unit_test_state *uts)
359{
Simon Glassdaac9c72016-01-14 18:10:50 -0700360 ut_assertok(select_vidconsole(uts, "vidconsole0"));
361 ut_assertok(check_vidconsole_output(uts, 0, 788, 453));
362
363 return 0;
Simon Glass90b6fef2016-01-18 19:52:26 -0700364}
Simon Glass1a92f832024-08-22 07:57:48 -0600365DM_TEST(dm_test_video_context, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassa0f1efe2016-01-18 19:52:27 -0700366
367/* Test rotated text output through the console uclass */
368static int dm_test_video_rotation1(struct unit_test_state *uts)
369{
370 ut_assertok(check_vidconsole_output(uts, 1, 1112, 680));
371
372 return 0;
373}
Simon Glass1a92f832024-08-22 07:57:48 -0600374DM_TEST(dm_test_video_rotation1, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassa0f1efe2016-01-18 19:52:27 -0700375
376/* Test rotated text output through the console uclass */
377static int dm_test_video_rotation2(struct unit_test_state *uts)
378{
Simon Glassf50a6b92020-07-02 21:12:17 -0600379 ut_assertok(check_vidconsole_output(uts, 2, 783, 445));
Simon Glassa0f1efe2016-01-18 19:52:27 -0700380
381 return 0;
382}
Simon Glass1a92f832024-08-22 07:57:48 -0600383DM_TEST(dm_test_video_rotation2, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassa0f1efe2016-01-18 19:52:27 -0700384
385/* Test rotated text output through the console uclass */
386static int dm_test_video_rotation3(struct unit_test_state *uts)
387{
388 ut_assertok(check_vidconsole_output(uts, 3, 1134, 681));
389
390 return 0;
391}
Simon Glass1a92f832024-08-22 07:57:48 -0600392DM_TEST(dm_test_video_rotation3, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass7a1cb292016-01-18 19:52:28 -0700393
394/* Read a file into memory and return a pointer to it */
395static int read_file(struct unit_test_state *uts, const char *fname,
396 ulong *addrp)
397{
398 int buf_size = 100000;
399 ulong addr = 0;
400 int size, fd;
401 char *buf;
402
403 buf = map_sysmem(addr, 0);
404 ut_assert(buf != NULL);
405 fd = os_open(fname, OS_O_RDONLY);
406 ut_assert(fd >= 0);
407 size = os_read(fd, buf, buf_size);
Simon Glass9050c5f2016-01-30 15:45:17 -0700408 os_close(fd);
Simon Glass7a1cb292016-01-18 19:52:28 -0700409 ut_assert(size >= 0);
410 ut_assert(size < buf_size);
Simon Glass7a1cb292016-01-18 19:52:28 -0700411 *addrp = addr;
412
413 return 0;
414}
415
416/* Test drawing a bitmap file */
417static int dm_test_video_bmp(struct unit_test_state *uts)
418{
419 struct udevice *dev;
420 ulong addr;
421
Simon Glass87a3cd72021-11-19 13:24:03 -0700422 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700423 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
424
425 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300426 ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300427 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700428
429 return 0;
430}
Simon Glass1a92f832024-08-22 07:57:48 -0600431DM_TEST(dm_test_video_bmp, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass7a1cb292016-01-18 19:52:28 -0700432
Simon Glassc3b5adf2021-11-19 13:23:50 -0700433/* Test drawing a bitmap file on a 8bpp display */
434static int dm_test_video_bmp8(struct unit_test_state *uts)
435{
436 struct udevice *dev;
437 ulong addr;
438
439 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
440 ut_assertnonnull(dev);
441 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
442
443 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
444
445 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300446 ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300447 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glassc3b5adf2021-11-19 13:23:50 -0700448
449 return 0;
450}
Simon Glass1a92f832024-08-22 07:57:48 -0600451DM_TEST(dm_test_video_bmp8, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassc3b5adf2021-11-19 13:23:50 -0700452
Simon Glass8bd7f602021-11-19 13:23:58 -0700453/* Test drawing a bitmap file on a 16bpp display */
454static int dm_test_video_bmp16(struct unit_test_state *uts)
455{
456 ulong src, src_len = ~0UL;
457 uint dst_len = ~0U;
458 struct udevice *dev;
459 ulong dst = 0x10000;
460
461 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
462 ut_assertnonnull(dev);
463 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP16));
464
465 ut_assertok(read_file(uts, "tools/logos/denx-16bpp.bmp.gz", &src));
466 ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
467 &src_len));
468
469 ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300470 ut_asserteq(3700, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300471 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass8bd7f602021-11-19 13:23:58 -0700472
473 return 0;
474}
Simon Glass1a92f832024-08-22 07:57:48 -0600475DM_TEST(dm_test_video_bmp16, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass8bd7f602021-11-19 13:23:58 -0700476
Simon Glass6a92e882021-11-19 13:23:59 -0700477/* Test drawing a 24bpp bitmap file on a 16bpp display */
478static int dm_test_video_bmp24(struct unit_test_state *uts)
479{
480 ulong src, src_len = ~0UL;
481 uint dst_len = ~0U;
482 struct udevice *dev;
483 ulong dst = 0x10000;
484
485 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
486 ut_assertnonnull(dev);
487 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP16));
488
489 ut_assertok(read_file(uts, "tools/logos/denx-24bpp.bmp.gz", &src));
490 ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
491 &src_len));
492
493 ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300494 ut_asserteq(3656, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300495 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass6a92e882021-11-19 13:23:59 -0700496
497 return 0;
498}
Simon Glass1a92f832024-08-22 07:57:48 -0600499DM_TEST(dm_test_video_bmp24, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass6a92e882021-11-19 13:23:59 -0700500
501/* Test drawing a 24bpp bitmap file on a 32bpp display */
502static int dm_test_video_bmp24_32(struct unit_test_state *uts)
503{
504 ulong src, src_len = ~0UL;
505 uint dst_len = ~0U;
506 struct udevice *dev;
507 ulong dst = 0x10000;
508
509 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
510 ut_assertnonnull(dev);
511 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
512
513 ut_assertok(read_file(uts, "tools/logos/denx-24bpp.bmp.gz", &src));
514 ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
515 &src_len));
516
517 ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300518 ut_asserteq(6827, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300519 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass6a92e882021-11-19 13:23:59 -0700520
521 return 0;
522}
Simon Glass1a92f832024-08-22 07:57:48 -0600523DM_TEST(dm_test_video_bmp24_32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass6a92e882021-11-19 13:23:59 -0700524
Simon Glassc3b5adf2021-11-19 13:23:50 -0700525/* Test drawing a bitmap file on a 32bpp display */
526static int dm_test_video_bmp32(struct unit_test_state *uts)
527{
528 struct udevice *dev;
529 ulong addr;
530
531 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
532 ut_assertnonnull(dev);
533 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
534 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
535
536 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300537 ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300538 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glassc3b5adf2021-11-19 13:23:50 -0700539
540 return 0;
541}
Simon Glass1a92f832024-08-22 07:57:48 -0600542DM_TEST(dm_test_video_bmp32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassc3b5adf2021-11-19 13:23:50 -0700543
Simon Glass7a1cb292016-01-18 19:52:28 -0700544/* Test drawing a compressed bitmap file */
545static int dm_test_video_bmp_comp(struct unit_test_state *uts)
546{
547 struct udevice *dev;
548 ulong addr;
549
Simon Glass87a3cd72021-11-19 13:24:03 -0700550 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700551 ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
552
553 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300554 ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300555 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700556
557 return 0;
558}
Simon Glass1a92f832024-08-22 07:57:48 -0600559DM_TEST(dm_test_video_bmp_comp, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass32337982016-01-14 18:10:51 -0700560
Simon Glass490bb992021-11-19 13:23:55 -0700561/* Test drawing a bitmap file on a 32bpp display */
562static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
563{
564 struct udevice *dev;
565 ulong addr;
566
567 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
568 ut_assertnonnull(dev);
569 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
570
571 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
572
573 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300574 ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300575 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass490bb992021-11-19 13:23:55 -0700576
577 return 0;
578}
Simon Glass1a92f832024-08-22 07:57:48 -0600579DM_TEST(dm_test_video_comp_bmp32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass490bb992021-11-19 13:23:55 -0700580
581/* Test drawing a bitmap file on a 8bpp display */
582static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
583{
584 struct udevice *dev;
585 ulong addr;
586
587 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
588 ut_assertnonnull(dev);
589 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
590
591 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
592
593 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300594 ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300595 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass490bb992021-11-19 13:23:55 -0700596
597 return 0;
598}
Simon Glass1a92f832024-08-22 07:57:48 -0600599DM_TEST(dm_test_video_comp_bmp8, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass490bb992021-11-19 13:23:55 -0700600
Simon Glass32337982016-01-14 18:10:51 -0700601/* Test TrueType console */
602static int dm_test_video_truetype(struct unit_test_state *uts)
603{
604 struct udevice *dev, *con;
605 const char *test_string = "Criticism may not be agreeable, but it is necessary. It fulfils the same function as pain in the human body. It calls attention to an unhealthy state of things. Some see private enterprise as a predatory target to be shot, others as a cow to be milked, but few are those who see it as a sturdy horse pulling the wagon. The \aprice OF\b\bof greatness\n\tis responsibility.\n\nBye";
Simon Glass32337982016-01-14 18:10:51 -0700606
Simon Glass87a3cd72021-11-19 13:24:03 -0700607 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass32337982016-01-14 18:10:51 -0700608 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Rob Clark985935b2017-09-25 15:45:08 -0400609 vidconsole_put_string(con, test_string);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300610 ut_asserteq(12174, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300611 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass32337982016-01-14 18:10:51 -0700612
613 return 0;
614}
Simon Glass1a92f832024-08-22 07:57:48 -0600615DM_TEST(dm_test_video_truetype, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass32337982016-01-14 18:10:51 -0700616
617/* Test scrolling TrueType console */
618static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
619{
620 struct sandbox_sdl_plat *plat;
621 struct udevice *dev, *con;
622 const char *test_string = "Criticism may not be agreeable, but it is necessary. It fulfils the same function as pain in the human body. It calls attention to an unhealthy state of things. Some see private enterprise as a predatory target to be shot, others as a cow to be milked, but few are those who see it as a sturdy horse pulling the wagon. The \aprice OF\b\bof greatness\n\tis responsibility.\n\nBye";
Simon Glass32337982016-01-14 18:10:51 -0700623
624 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
625 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700626 plat = dev_get_plat(dev);
Simon Glass32337982016-01-14 18:10:51 -0700627 plat->font_size = 100;
628
Simon Glass87a3cd72021-11-19 13:24:03 -0700629 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass32337982016-01-14 18:10:51 -0700630 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Rob Clark985935b2017-09-25 15:45:08 -0400631 vidconsole_put_string(con, test_string);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300632 ut_asserteq(34287, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300633 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass32337982016-01-14 18:10:51 -0700634
635 return 0;
636}
Simon Glass1a92f832024-08-22 07:57:48 -0600637DM_TEST(dm_test_video_truetype_scroll, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass32337982016-01-14 18:10:51 -0700638
639/* Test TrueType backspace, within and across lines */
640static int dm_test_video_truetype_bs(struct unit_test_state *uts)
641{
642 struct sandbox_sdl_plat *plat;
643 struct udevice *dev, *con;
644 const char *test_string = "...Criticism may or may\b\b\b\b\b\bnot be agreeable, but seldom it is necessary\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bit is necessary. It fulfils the same function as pain in the human body. It calls attention to an unhealthy state of things.";
Simon Glass32337982016-01-14 18:10:51 -0700645
646 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
647 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700648 plat = dev_get_plat(dev);
Simon Glass32337982016-01-14 18:10:51 -0700649 plat->font_size = 100;
650
Simon Glass87a3cd72021-11-19 13:24:03 -0700651 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass32337982016-01-14 18:10:51 -0700652 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Rob Clark985935b2017-09-25 15:45:08 -0400653 vidconsole_put_string(con, test_string);
Alper Nebi Yasaka29b0f92023-08-20 17:46:46 +0300654 ut_asserteq(29471, compress_frame_buffer(uts, dev, false));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300655 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass32337982016-01-14 18:10:51 -0700656
657 return 0;
658}
Simon Glass1a92f832024-08-22 07:57:48 -0600659DM_TEST(dm_test_video_truetype_bs, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Alper Nebi Yasak5e8253d2023-08-18 17:31:27 +0300660
661/* Test partial rendering onto hardware frame buffer */
662static int dm_test_video_copy(struct unit_test_state *uts)
663{
664 struct sandbox_sdl_plat *plat;
665 struct video_uc_plat *uc_plat;
666 struct udevice *dev, *con;
667 struct video_priv *priv;
668 const char *test_string = "\n\tCriticism may not be agreeable, but it is necessary.\t";
669 ulong addr;
670
671 if (!IS_ENABLED(CONFIG_VIDEO_COPY))
672 return -EAGAIN;
673
674 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
675 ut_assertnonnull(dev);
676 uc_plat = dev_get_uclass_plat(dev);
677 uc_plat->hide_logo = true;
678 plat = dev_get_plat(dev);
679 plat->font_size = 32;
680 ut_assert(!device_active(dev));
681 ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
682 ut_assertnonnull(dev);
683 priv = dev_get_uclass_priv(dev);
684
685 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
686 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
687
688 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
689 vidconsole_put_string(con, "\n\n\n\n\n");
690 vidconsole_put_string(con, test_string);
691 vidconsole_put_string(con, test_string);
692
693 ut_asserteq(6678, compress_frame_buffer(uts, dev, false));
694 ut_assertok(check_copy_frame_buffer(uts, dev));
695
696 /*
697 * Secretly clear the hardware frame buffer, but in a different
698 * color (black) to see which parts will be overwritten.
699 */
700 memset(priv->copy_fb, 0, priv->fb_size);
701
702 /*
703 * We should have the full content on the main buffer, but only
Alexander Graff88b6a22022-06-10 00:59:21 +0200704 * 'damage' should have been copied to the copy buffer. This consists
705 * of a while rectangle with the Denx logo and four lines of text. The
706 * rest of the display is black.
707 *
708 * An easy way to try this is by changing video_sync() to call
709 * sandbox_sdl_sync(priv->copy_fb) instead of priv->fb then running the
710 * unit test:
711 *
712 * ./u-boot -Tl
713 * ut dm dm_test_video_copy
Alper Nebi Yasak5e8253d2023-08-18 17:31:27 +0300714 */
715 vidconsole_put_string(con, test_string);
716 vidconsole_put_string(con, test_string);
Alexander Graff88b6a22022-06-10 00:59:21 +0200717 video_sync(dev, true);
Alper Nebi Yasak5e8253d2023-08-18 17:31:27 +0300718 ut_asserteq(7589, compress_frame_buffer(uts, dev, false));
Alexander Graff88b6a22022-06-10 00:59:21 +0200719 ut_asserteq(7704, compress_frame_buffer(uts, dev, true));
Alper Nebi Yasak5e8253d2023-08-18 17:31:27 +0300720
721 return 0;
722}
723DM_TEST(dm_test_video_copy, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Alper Nebi Yasakfc5740a2023-08-18 17:55:08 +0300724
725/* Test video damage tracking */
726static int dm_test_video_damage(struct unit_test_state *uts)
727{
728 struct sandbox_sdl_plat *plat;
729 struct udevice *dev, *con;
730 struct video_priv *priv;
731 const char *test_string_1 = "Criticism may not be agreeable, ";
732 const char *test_string_2 = "but it is necessary.";
733 const char *test_string_3 = "It fulfils the same function as pain in the human body.";
734
735 if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE))
736 return -EAGAIN;
737
738 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
739 ut_assert(!device_active(dev));
740 plat = dev_get_plat(dev);
741 plat->font_size = 32;
742
743 ut_assertok(video_get_nologo(uts, &dev));
744 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
745 priv = dev_get_uclass_priv(dev);
746
747 vidconsole_position_cursor(con, 14, 10);
748 vidconsole_put_string(con, test_string_2);
749 ut_asserteq(449, priv->damage.xstart);
750 ut_asserteq(325, priv->damage.ystart);
751 ut_asserteq(661, priv->damage.xend);
752 ut_asserteq(350, priv->damage.yend);
753
754 vidconsole_position_cursor(con, 7, 5);
755 vidconsole_put_string(con, test_string_1);
756 ut_asserteq(225, priv->damage.xstart);
757 ut_asserteq(164, priv->damage.ystart);
758 ut_asserteq(661, priv->damage.xend);
759 ut_asserteq(350, priv->damage.yend);
760
761 vidconsole_position_cursor(con, 21, 15);
762 vidconsole_put_string(con, test_string_3);
763 ut_asserteq(225, priv->damage.xstart);
764 ut_asserteq(164, priv->damage.ystart);
765 ut_asserteq(1280, priv->damage.xend);
766 ut_asserteq(510, priv->damage.yend);
767
768 video_sync(dev, true);
769 ut_asserteq(priv->xsize, priv->damage.xstart);
770 ut_asserteq(priv->ysize, priv->damage.ystart);
771 ut_asserteq(0, priv->damage.xend);
772 ut_asserteq(0, priv->damage.yend);
773
774 ut_asserteq(7339, compress_frame_buffer(uts, dev, false));
775 ut_assertok(check_copy_frame_buffer(uts, dev));
776
777 return 0;
778}
779DM_TEST(dm_test_video_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassfff57f62025-04-02 06:29:35 +1300780
781/* Test font measurement */
782static int dm_test_font_measure(struct unit_test_state *uts)
783{
784 const char *test_string = "There is always much to be said for not "
785 "attempting more than you can do and for making a certainty of "
786 "what you try. But this principle, like others in life and "
787 "war, has its exceptions.";
Simon Glasseb4efc62025-04-02 06:29:37 +1300788 const struct vidconsole_mline *line;
Simon Glassfff57f62025-04-02 06:29:35 +1300789 struct vidconsole_bbox bbox;
790 struct video_priv *priv;
791 struct udevice *dev, *con;
Simon Glass95bcad42025-04-02 06:29:36 +1300792 struct alist lines;
Simon Glassfff57f62025-04-02 06:29:35 +1300793
794 ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
795 priv = dev_get_uclass_priv(dev);
796 ut_asserteq(1366, priv->xsize);
797 ut_asserteq(768, priv->ysize);
798
799 /* this is using the Nimbus font with size of 18 pixels */
800 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
801 vidconsole_position_cursor(con, 0, 0);
Simon Glasseb4efc62025-04-02 06:29:37 +1300802 alist_init_struct(&lines, struct vidconsole_mline);
Simon Glass95bcad42025-04-02 06:29:36 +1300803 ut_assertok(vidconsole_measure(con, NULL, 0, test_string, &bbox,
804 &lines));
Simon Glassfff57f62025-04-02 06:29:35 +1300805 ut_asserteq(0, bbox.x0);
806 ut_asserteq(0, bbox.y0);
807 ut_asserteq(0x47a, bbox.x1);
808 ut_asserteq(0x12, bbox.y1);
Simon Glasseb4efc62025-04-02 06:29:37 +1300809 ut_asserteq(1, lines.count);
810
811 line = alist_get(&lines, 0, struct vidconsole_mline);
812 ut_assertnonnull(line);
813 ut_asserteq(0, line->bbox.x0);
814 ut_asserteq(0, line->bbox.y0);
815 ut_asserteq(0x47a, line->bbox.x1);
816 ut_asserteq(0x12, line->bbox.y1);
817 ut_asserteq(0, line->start);
818 ut_asserteq(strlen(test_string), line->len);
Simon Glassfff57f62025-04-02 06:29:35 +1300819
820 return 0;
821}
822DM_TEST(dm_test_font_measure, UTF_SCAN_FDT);