blob: 01fa9e1b2415fea1add7cfcb0b91c2629ed0f6f5 [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
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +010059 * Return: compressed size of the frame buffer, or -ve on error
Simon Glass90b6fef2016-01-18 19:52:26 -070060 */
Simon Glass2a0f8e32020-07-02 21:12:29 -060061static int compress_frame_buffer(struct unit_test_state *uts,
62 struct udevice *dev)
Simon Glass90b6fef2016-01-18 19:52:26 -070063{
64 struct video_priv *priv = dev_get_uclass_priv(dev);
65 uint destlen;
66 void *dest;
67 int ret;
68
69 destlen = priv->fb_size;
70 dest = malloc(priv->fb_size);
71 if (!dest)
72 return -ENOMEM;
73 ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
74 priv->fb, priv->fb_size,
75 3, 0, 0);
76 free(dest);
77 if (ret)
78 return ret;
79
80 return destlen;
81}
82
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +030083/**
84 * check_copy_frame_buffer() - Compare main frame buffer to copy
85 *
86 * If the copy frame buffer is enabled, this compares it to the main
87 * frame buffer. Normally they should have the same contents after a
88 * sync.
89 *
90 * @uts: Test state
91 * @dev: Video device
92 * Return: 0, or -ve on error
93 */
94static int check_copy_frame_buffer(struct unit_test_state *uts,
95 struct udevice *dev)
96{
97 struct video_priv *priv = dev_get_uclass_priv(dev);
98
99 if (!IS_ENABLED(CONFIG_VIDEO_COPY))
100 return 0;
101
102 ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size),
103 "Copy framebuffer does not match fb");
104
105 return 0;
106}
107
Simon Glass90b6fef2016-01-18 19:52:26 -0700108/*
109 * Call this function at any point to halt and show the current display. Be
110 * sure to run the test with the -l flag.
111 */
112static void __maybe_unused see_output(void)
113{
114 video_sync_all();
115 while (1);
116}
117
Simon Glassdaac9c72016-01-14 18:10:50 -0700118/* Select the video console driver to use for a video device */
119static int select_vidconsole(struct unit_test_state *uts, const char *drv_name)
120{
121 struct sandbox_sdl_plat *plat;
122 struct udevice *dev;
123
124 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
125 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700126 plat = dev_get_plat(dev);
Simon Glassdaac9c72016-01-14 18:10:50 -0700127 plat->vidconsole_drv_name = "vidconsole0";
128
129 return 0;
130}
131
Simon Glass87a3cd72021-11-19 13:24:03 -0700132/**
133 * video_get_nologo() - Disable the logo on the video device and return it
134 *
135 * @uts: Test state
136 * @devp: Returns video device
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100137 * Return: 0 if OK, -ve on error
Simon Glass87a3cd72021-11-19 13:24:03 -0700138 */
139static int video_get_nologo(struct unit_test_state *uts, struct udevice **devp)
140{
141 struct video_uc_plat *uc_plat;
142 struct udevice *dev;
143
144 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
145 ut_assertnonnull(dev);
146 uc_plat = dev_get_uclass_plat(dev);
147 uc_plat->hide_logo = true;
148
149 /* now probe it */
150 ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
151 ut_assertnonnull(dev);
152 *devp = dev;
153
154 return 0;
155}
156
Simon Glass90b6fef2016-01-18 19:52:26 -0700157/* Test text output works on the video console */
158static int dm_test_video_text(struct unit_test_state *uts)
159{
160 struct udevice *dev, *con;
161 int i;
162
163#define WHITE 0xffff
164#define SCROLL_LINES 100
165
Simon Glassdaac9c72016-01-14 18:10:50 -0700166 ut_assertok(select_vidconsole(uts, "vidconsole0"));
Simon Glass87a3cd72021-11-19 13:24:03 -0700167 ut_assertok(video_get_nologo(uts, &dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300168 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
169 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Simon Glass2a0f8e32020-07-02 21:12:29 -0600170 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300171 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700172
173 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
174 vidconsole_putc_xy(con, 0, 0, 'a');
Simon Glass2a0f8e32020-07-02 21:12:29 -0600175 ut_asserteq(79, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300176 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700177
178 vidconsole_putc_xy(con, 0, 0, ' ');
Simon Glass2a0f8e32020-07-02 21:12:29 -0600179 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300180 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700181
182 for (i = 0; i < 20; i++)
Simon Glass52c10c52016-01-14 18:10:37 -0700183 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
Simon Glass2a0f8e32020-07-02 21:12:29 -0600184 ut_asserteq(273, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300185 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700186
187 vidconsole_set_row(con, 0, WHITE);
Simon Glass2a0f8e32020-07-02 21:12:29 -0600188 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300189 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700190
191 for (i = 0; i < 20; i++)
Simon Glass52c10c52016-01-14 18:10:37 -0700192 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
Simon Glass2a0f8e32020-07-02 21:12:29 -0600193 ut_asserteq(273, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300194 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700195
196 return 0;
197}
Simon Glass1a92f832024-08-22 07:57:48 -0600198DM_TEST(dm_test_video_text, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass90b6fef2016-01-18 19:52:26 -0700199
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300200static int dm_test_video_text_12x22(struct unit_test_state *uts)
201{
202 struct udevice *dev, *con;
203 int i;
204
205#define WHITE 0xffff
206#define SCROLL_LINES 100
207
208 ut_assertok(select_vidconsole(uts, "vidconsole0"));
209 ut_assertok(video_get_nologo(uts, &dev));
210 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
211 ut_assertok(vidconsole_select_font(con, "12x22", 0));
212 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300213 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300214
215 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
216 vidconsole_putc_xy(con, 0, 0, 'a');
217 ut_asserteq(89, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300218 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300219
220 vidconsole_putc_xy(con, 0, 0, ' ');
221 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300222 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300223
224 for (i = 0; i < 20; i++)
225 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
226 ut_asserteq(363, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300227 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300228
229 vidconsole_set_row(con, 0, WHITE);
230 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300231 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300232
233 for (i = 0; i < 20; i++)
234 vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
235 ut_asserteq(363, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300236 ut_assertok(check_copy_frame_buffer(uts, dev));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300237
238 return 0;
239}
Simon Glass1a92f832024-08-22 07:57:48 -0600240DM_TEST(dm_test_video_text_12x22, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300241
Simon Glass90b6fef2016-01-18 19:52:26 -0700242/* Test handling of special characters in the console */
243static int dm_test_video_chars(struct unit_test_state *uts)
244{
245 struct udevice *dev, *con;
Simon Glass37b80202016-01-14 18:10:38 -0700246 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 -0700247
Simon Glassdaac9c72016-01-14 18:10:50 -0700248 ut_assertok(select_vidconsole(uts, "vidconsole0"));
Simon Glass87a3cd72021-11-19 13:24:03 -0700249 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700250 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300251 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Rob Clark985935b2017-09-25 15:45:08 -0400252 vidconsole_put_string(con, test_string);
Simon Glass2a0f8e32020-07-02 21:12:29 -0600253 ut_asserteq(466, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300254 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700255
256 return 0;
257}
Simon Glass1a92f832024-08-22 07:57:48 -0600258DM_TEST(dm_test_video_chars, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass90b6fef2016-01-18 19:52:26 -0700259
Rob Clark09d64b32017-09-25 15:45:09 -0400260#ifdef CONFIG_VIDEO_ANSI
261#define ANSI_ESC "\x1b"
262/* Test handling of ANSI escape sequences */
263static int dm_test_video_ansi(struct unit_test_state *uts)
264{
265 struct udevice *dev, *con;
266
267 ut_assertok(select_vidconsole(uts, "vidconsole0"));
Simon Glass87a3cd72021-11-19 13:24:03 -0700268 ut_assertok(video_get_nologo(uts, &dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400269 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300270 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Rob Clark09d64b32017-09-25 15:45:09 -0400271
272 /* reference clear: */
273 video_clear(con->parent);
Simon Glass0806dcc2018-10-01 11:55:14 -0600274 video_sync(con->parent, false);
Simon Glass2a0f8e32020-07-02 21:12:29 -0600275 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300276 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400277
278 /* test clear escape sequence: [2J */
279 vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
Simon Glass2a0f8e32020-07-02 21:12:29 -0600280 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300281 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400282
283 /* test set-cursor: [%d;%df */
284 vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
Simon Glass2a0f8e32020-07-02 21:12:29 -0600285 ut_asserteq(143, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300286 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400287
288 /* test colors (30-37 fg color, 40-47 bg color) */
289 vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
290 vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
Simon Glass2a0f8e32020-07-02 21:12:29 -0600291 ut_asserteq(272, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300292 ut_assertok(check_copy_frame_buffer(uts, dev));
Rob Clark09d64b32017-09-25 15:45:09 -0400293
294 return 0;
295}
Simon Glass1a92f832024-08-22 07:57:48 -0600296DM_TEST(dm_test_video_ansi, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Rob Clark09d64b32017-09-25 15:45:09 -0400297#endif
298
Simon Glass90b6fef2016-01-18 19:52:26 -0700299/**
300 * check_vidconsole_output() - Run a text console test
301 *
302 * @uts: Test state
Simon Glass4425bf42020-07-02 21:12:28 -0600303 * @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
304 * 2=upside down, 3=90 degree counterclockwise)
Simon Glass90b6fef2016-01-18 19:52:26 -0700305 * @wrap_size: Expected size of compressed frame buffer for the wrap test
306 * @scroll_size: Same for the scroll test
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100307 * Return: 0 on success
Simon Glass90b6fef2016-01-18 19:52:26 -0700308 */
309static int check_vidconsole_output(struct unit_test_state *uts, int rot,
310 int wrap_size, int scroll_size)
311{
312 struct udevice *dev, *con;
313 struct sandbox_sdl_plat *plat;
314 int i;
315
316 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
317 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700318 plat = dev_get_plat(dev);
Simon Glass90b6fef2016-01-18 19:52:26 -0700319 plat->rot = rot;
320
Simon Glass87a3cd72021-11-19 13:24:03 -0700321 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700322 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Dzmitry Sankouskifc785c52023-03-07 13:21:20 +0300323 ut_assertok(vidconsole_select_font(con, "8x16", 0));
Simon Glass2a0f8e32020-07-02 21:12:29 -0600324 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300325 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700326
327 /* Check display wrap */
328 for (i = 0; i < 120; i++)
329 vidconsole_put_char(con, 'A' + i % 50);
Simon Glass2a0f8e32020-07-02 21:12:29 -0600330 ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300331 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700332
333 /* Check display scrolling */
334 for (i = 0; i < SCROLL_LINES; i++) {
335 vidconsole_put_char(con, 'A' + i % 50);
336 vidconsole_put_char(con, '\n');
337 }
Simon Glass2a0f8e32020-07-02 21:12:29 -0600338 ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300339 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700340
341 /* If we scroll enough, the screen becomes blank again */
342 for (i = 0; i < SCROLL_LINES; i++)
343 vidconsole_put_char(con, '\n');
Simon Glass2a0f8e32020-07-02 21:12:29 -0600344 ut_asserteq(46, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300345 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass90b6fef2016-01-18 19:52:26 -0700346
347 return 0;
348}
349
350/* Test text output through the console uclass */
351static int dm_test_video_context(struct unit_test_state *uts)
352{
Simon Glassdaac9c72016-01-14 18:10:50 -0700353 ut_assertok(select_vidconsole(uts, "vidconsole0"));
354 ut_assertok(check_vidconsole_output(uts, 0, 788, 453));
355
356 return 0;
Simon Glass90b6fef2016-01-18 19:52:26 -0700357}
Simon Glass1a92f832024-08-22 07:57:48 -0600358DM_TEST(dm_test_video_context, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassa0f1efe2016-01-18 19:52:27 -0700359
360/* Test rotated text output through the console uclass */
361static int dm_test_video_rotation1(struct unit_test_state *uts)
362{
363 ut_assertok(check_vidconsole_output(uts, 1, 1112, 680));
364
365 return 0;
366}
Simon Glass1a92f832024-08-22 07:57:48 -0600367DM_TEST(dm_test_video_rotation1, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassa0f1efe2016-01-18 19:52:27 -0700368
369/* Test rotated text output through the console uclass */
370static int dm_test_video_rotation2(struct unit_test_state *uts)
371{
Simon Glassf50a6b92020-07-02 21:12:17 -0600372 ut_assertok(check_vidconsole_output(uts, 2, 783, 445));
Simon Glassa0f1efe2016-01-18 19:52:27 -0700373
374 return 0;
375}
Simon Glass1a92f832024-08-22 07:57:48 -0600376DM_TEST(dm_test_video_rotation2, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassa0f1efe2016-01-18 19:52:27 -0700377
378/* Test rotated text output through the console uclass */
379static int dm_test_video_rotation3(struct unit_test_state *uts)
380{
381 ut_assertok(check_vidconsole_output(uts, 3, 1134, 681));
382
383 return 0;
384}
Simon Glass1a92f832024-08-22 07:57:48 -0600385DM_TEST(dm_test_video_rotation3, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass7a1cb292016-01-18 19:52:28 -0700386
387/* Read a file into memory and return a pointer to it */
388static int read_file(struct unit_test_state *uts, const char *fname,
389 ulong *addrp)
390{
391 int buf_size = 100000;
392 ulong addr = 0;
393 int size, fd;
394 char *buf;
395
396 buf = map_sysmem(addr, 0);
397 ut_assert(buf != NULL);
398 fd = os_open(fname, OS_O_RDONLY);
399 ut_assert(fd >= 0);
400 size = os_read(fd, buf, buf_size);
Simon Glass9050c5f2016-01-30 15:45:17 -0700401 os_close(fd);
Simon Glass7a1cb292016-01-18 19:52:28 -0700402 ut_assert(size >= 0);
403 ut_assert(size < buf_size);
Simon Glass7a1cb292016-01-18 19:52:28 -0700404 *addrp = addr;
405
406 return 0;
407}
408
409/* Test drawing a bitmap file */
410static int dm_test_video_bmp(struct unit_test_state *uts)
411{
412 struct udevice *dev;
413 ulong addr;
414
Simon Glass87a3cd72021-11-19 13:24:03 -0700415 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700416 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
417
418 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Simon Glass2a0f8e32020-07-02 21:12:29 -0600419 ut_asserteq(1368, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300420 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700421
422 return 0;
423}
Simon Glass1a92f832024-08-22 07:57:48 -0600424DM_TEST(dm_test_video_bmp, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass7a1cb292016-01-18 19:52:28 -0700425
Simon Glassc3b5adf2021-11-19 13:23:50 -0700426/* Test drawing a bitmap file on a 8bpp display */
427static int dm_test_video_bmp8(struct unit_test_state *uts)
428{
429 struct udevice *dev;
430 ulong addr;
431
432 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
433 ut_assertnonnull(dev);
434 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
435
436 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
437
438 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
439 ut_asserteq(1247, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300440 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glassc3b5adf2021-11-19 13:23:50 -0700441
442 return 0;
443}
Simon Glass1a92f832024-08-22 07:57:48 -0600444DM_TEST(dm_test_video_bmp8, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassc3b5adf2021-11-19 13:23:50 -0700445
Simon Glass8bd7f602021-11-19 13:23:58 -0700446/* Test drawing a bitmap file on a 16bpp display */
447static int dm_test_video_bmp16(struct unit_test_state *uts)
448{
449 ulong src, src_len = ~0UL;
450 uint dst_len = ~0U;
451 struct udevice *dev;
452 ulong dst = 0x10000;
453
454 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
455 ut_assertnonnull(dev);
456 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP16));
457
458 ut_assertok(read_file(uts, "tools/logos/denx-16bpp.bmp.gz", &src));
459 ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
460 &src_len));
461
462 ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
463 ut_asserteq(3700, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300464 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass8bd7f602021-11-19 13:23:58 -0700465
466 return 0;
467}
Simon Glass1a92f832024-08-22 07:57:48 -0600468DM_TEST(dm_test_video_bmp16, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass8bd7f602021-11-19 13:23:58 -0700469
Simon Glass6a92e882021-11-19 13:23:59 -0700470/* Test drawing a 24bpp bitmap file on a 16bpp display */
471static int dm_test_video_bmp24(struct unit_test_state *uts)
472{
473 ulong src, src_len = ~0UL;
474 uint dst_len = ~0U;
475 struct udevice *dev;
476 ulong dst = 0x10000;
477
478 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
479 ut_assertnonnull(dev);
480 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP16));
481
482 ut_assertok(read_file(uts, "tools/logos/denx-24bpp.bmp.gz", &src));
483 ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
484 &src_len));
485
486 ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
487 ut_asserteq(3656, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300488 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass6a92e882021-11-19 13:23:59 -0700489
490 return 0;
491}
Simon Glass1a92f832024-08-22 07:57:48 -0600492DM_TEST(dm_test_video_bmp24, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass6a92e882021-11-19 13:23:59 -0700493
494/* Test drawing a 24bpp bitmap file on a 32bpp display */
495static int dm_test_video_bmp24_32(struct unit_test_state *uts)
496{
497 ulong src, src_len = ~0UL;
498 uint dst_len = ~0U;
499 struct udevice *dev;
500 ulong dst = 0x10000;
501
502 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
503 ut_assertnonnull(dev);
504 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
505
506 ut_assertok(read_file(uts, "tools/logos/denx-24bpp.bmp.gz", &src));
507 ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
508 &src_len));
509
510 ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
511 ut_asserteq(6827, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300512 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass6a92e882021-11-19 13:23:59 -0700513
514 return 0;
515}
Simon Glass1a92f832024-08-22 07:57:48 -0600516DM_TEST(dm_test_video_bmp24_32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass6a92e882021-11-19 13:23:59 -0700517
Simon Glassc3b5adf2021-11-19 13:23:50 -0700518/* Test drawing a bitmap file on a 32bpp display */
519static int dm_test_video_bmp32(struct unit_test_state *uts)
520{
521 struct udevice *dev;
522 ulong addr;
523
524 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
525 ut_assertnonnull(dev);
526 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
527 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
528
529 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
530 ut_asserteq(2024, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300531 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glassc3b5adf2021-11-19 13:23:50 -0700532
533 return 0;
534}
Simon Glass1a92f832024-08-22 07:57:48 -0600535DM_TEST(dm_test_video_bmp32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassc3b5adf2021-11-19 13:23:50 -0700536
Simon Glass7a1cb292016-01-18 19:52:28 -0700537/* Test drawing a compressed bitmap file */
538static int dm_test_video_bmp_comp(struct unit_test_state *uts)
539{
540 struct udevice *dev;
541 ulong addr;
542
Simon Glass87a3cd72021-11-19 13:24:03 -0700543 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700544 ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
545
546 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
Simon Glass2a0f8e32020-07-02 21:12:29 -0600547 ut_asserteq(1368, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300548 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass7a1cb292016-01-18 19:52:28 -0700549
550 return 0;
551}
Simon Glass1a92f832024-08-22 07:57:48 -0600552DM_TEST(dm_test_video_bmp_comp, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass32337982016-01-14 18:10:51 -0700553
Simon Glass490bb992021-11-19 13:23:55 -0700554/* Test drawing a bitmap file on a 32bpp display */
555static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
556{
557 struct udevice *dev;
558 ulong addr;
559
560 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
561 ut_assertnonnull(dev);
562 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
563
564 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
565
566 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
567 ut_asserteq(2024, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300568 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass490bb992021-11-19 13:23:55 -0700569
570 return 0;
571}
Simon Glass1a92f832024-08-22 07:57:48 -0600572DM_TEST(dm_test_video_comp_bmp32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass490bb992021-11-19 13:23:55 -0700573
574/* Test drawing a bitmap file on a 8bpp display */
575static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
576{
577 struct udevice *dev;
578 ulong addr;
579
580 ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
581 ut_assertnonnull(dev);
582 ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
583
584 ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
585
586 ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
587 ut_asserteq(1247, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300588 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass490bb992021-11-19 13:23:55 -0700589
590 return 0;
591}
Simon Glass1a92f832024-08-22 07:57:48 -0600592DM_TEST(dm_test_video_comp_bmp8, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass490bb992021-11-19 13:23:55 -0700593
Simon Glass32337982016-01-14 18:10:51 -0700594/* Test TrueType console */
595static int dm_test_video_truetype(struct unit_test_state *uts)
596{
597 struct udevice *dev, *con;
598 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 -0700599
Simon Glass87a3cd72021-11-19 13:24:03 -0700600 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass32337982016-01-14 18:10:51 -0700601 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Rob Clark985935b2017-09-25 15:45:08 -0400602 vidconsole_put_string(con, test_string);
Simon Glass5f0ca612023-06-01 10:23:04 -0600603 ut_asserteq(12174, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300604 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass32337982016-01-14 18:10:51 -0700605
606 return 0;
607}
Simon Glass1a92f832024-08-22 07:57:48 -0600608DM_TEST(dm_test_video_truetype, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass32337982016-01-14 18:10:51 -0700609
610/* Test scrolling TrueType console */
611static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
612{
613 struct sandbox_sdl_plat *plat;
614 struct udevice *dev, *con;
615 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 -0700616
617 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
618 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700619 plat = dev_get_plat(dev);
Simon Glass32337982016-01-14 18:10:51 -0700620 plat->font_size = 100;
621
Simon Glass87a3cd72021-11-19 13:24:03 -0700622 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass32337982016-01-14 18:10:51 -0700623 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Rob Clark985935b2017-09-25 15:45:08 -0400624 vidconsole_put_string(con, test_string);
Simon Glass5f0ca612023-06-01 10:23:04 -0600625 ut_asserteq(34287, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300626 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass32337982016-01-14 18:10:51 -0700627
628 return 0;
629}
Simon Glass1a92f832024-08-22 07:57:48 -0600630DM_TEST(dm_test_video_truetype_scroll, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass32337982016-01-14 18:10:51 -0700631
632/* Test TrueType backspace, within and across lines */
633static int dm_test_video_truetype_bs(struct unit_test_state *uts)
634{
635 struct sandbox_sdl_plat *plat;
636 struct udevice *dev, *con;
637 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 -0700638
639 ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
640 ut_assert(!device_active(dev));
Simon Glassfa20e932020-12-03 16:55:20 -0700641 plat = dev_get_plat(dev);
Simon Glass32337982016-01-14 18:10:51 -0700642 plat->font_size = 100;
643
Simon Glass87a3cd72021-11-19 13:24:03 -0700644 ut_assertok(video_get_nologo(uts, &dev));
Simon Glass32337982016-01-14 18:10:51 -0700645 ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
Rob Clark985935b2017-09-25 15:45:08 -0400646 vidconsole_put_string(con, test_string);
Simon Glass5f0ca612023-06-01 10:23:04 -0600647 ut_asserteq(29471, compress_frame_buffer(uts, dev));
Alper Nebi Yasake85a8d02023-08-18 13:31:36 +0300648 ut_assertok(check_copy_frame_buffer(uts, dev));
Simon Glass32337982016-01-14 18:10:51 -0700649
650 return 0;
651}
Simon Glass1a92f832024-08-22 07:57:48 -0600652DM_TEST(dm_test_video_truetype_bs, UTF_SCAN_PDATA | UTF_SCAN_FDT);