123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- * Copyright (c) 2014 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include <bzlib.h>
- #include <dm.h>
- #include <mapmem.h>
- #include <os.h>
- #include <video.h>
- #include <video_console.h>
- #include <dm/test.h>
- #include <dm/uclass-internal.h>
- #include <test/ut.h>
- /*
- * These tests use the standard sandbox frame buffer, the resolution of which
- * is defined in the device tree. This only supports 16bpp so the tests only
- * test that code path. It would be possible to adjust this fairly easily,
- * by adjusting the bpix value in struct sandbox_sdl_plat. However the code
- * in sandbox_sdl_sync() would also need to change to handle the different
- * surface depth.
- */
- DECLARE_GLOBAL_DATA_PTR;
- /* Basic test of the video uclass */
- static int dm_test_video_base(struct unit_test_state *uts)
- {
- struct video_priv *priv;
- struct udevice *dev;
- ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
- ut_asserteq(1366, video_get_xsize(dev));
- ut_asserteq(768, video_get_ysize(dev));
- priv = dev_get_uclass_priv(dev);
- ut_asserteq(priv->fb_size, 1366 * 768 * 2);
- return 0;
- }
- DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /**
- * compress_frame_buffer() - Compress the frame buffer and return its size
- *
- * We want to write tests which perform operations on the video console and
- * check that the frame buffer ends up with the correct contents. But it is
- * painful to store 'known good' images for comparison with the frame
- * buffer. As an alternative, we can compress the frame buffer and check the
- * size of the compressed data. This provides a pretty good level of
- * certainty and the resulting tests need only check a single value.
- *
- * @dev: Video device
- * @return compressed size of the frame buffer, or -ve on error
- */
- static int compress_frame_buffer(struct udevice *dev)
- {
- struct video_priv *priv = dev_get_uclass_priv(dev);
- uint destlen;
- void *dest;
- int ret;
- destlen = priv->fb_size;
- dest = malloc(priv->fb_size);
- if (!dest)
- return -ENOMEM;
- ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
- priv->fb, priv->fb_size,
- 3, 0, 0);
- free(dest);
- if (ret)
- return ret;
- return destlen;
- }
- /*
- * Call this function at any point to halt and show the current display. Be
- * sure to run the test with the -l flag.
- */
- static void __maybe_unused see_output(void)
- {
- video_sync_all();
- while (1);
- }
- /* Test text output works on the video console */
- static int dm_test_video_text(struct unit_test_state *uts)
- {
- struct udevice *dev, *con;
- int i;
- #define WHITE 0xffff
- #define SCROLL_LINES 100
- ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
- ut_asserteq(46, compress_frame_buffer(dev));
- ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
- vidconsole_putc_xy(con, 0, 0, 'a');
- ut_asserteq(79, compress_frame_buffer(dev));
- vidconsole_putc_xy(con, 0, 0, ' ');
- ut_asserteq(46, compress_frame_buffer(dev));
- for (i = 0; i < 20; i++)
- vidconsole_putc_xy(con, i * 8, 0, ' ' + i);
- ut_asserteq(273, compress_frame_buffer(dev));
- vidconsole_set_row(con, 0, WHITE);
- ut_asserteq(46, compress_frame_buffer(dev));
- for (i = 0; i < 20; i++)
- vidconsole_putc_xy(con, i * 8, 0, ' ' + i);
- ut_asserteq(273, compress_frame_buffer(dev));
- return 0;
- }
- DM_TEST(dm_test_video_text, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /* Test handling of special characters in the console */
- static int dm_test_video_chars(struct unit_test_state *uts)
- {
- struct udevice *dev, *con;
- const char *test_string = "Well\b\b\b\bxhe is\r \n\ta very modest \bman\n\t\tand Has much to\b\bto be modest about.";
- const char *s;
- ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
- ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
- for (s = test_string; *s; s++)
- vidconsole_put_char(con, *s);
- ut_asserteq(466, compress_frame_buffer(dev));
- return 0;
- }
- DM_TEST(dm_test_video_chars, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /**
- * check_vidconsole_output() - Run a text console test
- *
- * @uts: Test state
- * @rot: Console rotation (0, 90, 180, 270)
- * @wrap_size: Expected size of compressed frame buffer for the wrap test
- * @scroll_size: Same for the scroll test
- * @return 0 on success
- */
- static int check_vidconsole_output(struct unit_test_state *uts, int rot,
- int wrap_size, int scroll_size)
- {
- struct udevice *dev, *con;
- struct sandbox_sdl_plat *plat;
- int i;
- ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
- ut_assert(!device_active(dev));
- plat = dev_get_platdata(dev);
- plat->rot = rot;
- ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
- ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
- ut_asserteq(46, compress_frame_buffer(dev));
- /* Check display wrap */
- for (i = 0; i < 120; i++)
- vidconsole_put_char(con, 'A' + i % 50);
- ut_asserteq(wrap_size, compress_frame_buffer(dev));
- /* Check display scrolling */
- for (i = 0; i < SCROLL_LINES; i++) {
- vidconsole_put_char(con, 'A' + i % 50);
- vidconsole_put_char(con, '\n');
- }
- ut_asserteq(scroll_size, compress_frame_buffer(dev));
- /* If we scroll enough, the screen becomes blank again */
- for (i = 0; i < SCROLL_LINES; i++)
- vidconsole_put_char(con, '\n');
- ut_asserteq(46, compress_frame_buffer(dev));
- return 0;
- }
- /* Test text output through the console uclass */
- static int dm_test_video_context(struct unit_test_state *uts)
- {
- return check_vidconsole_output(uts, 0, 788, 453);
- }
- DM_TEST(dm_test_video_context, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /* Test rotated text output through the console uclass */
- static int dm_test_video_rotation1(struct unit_test_state *uts)
- {
- ut_assertok(check_vidconsole_output(uts, 1, 1112, 680));
- return 0;
- }
- DM_TEST(dm_test_video_rotation1, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /* Test rotated text output through the console uclass */
- static int dm_test_video_rotation2(struct unit_test_state *uts)
- {
- ut_assertok(check_vidconsole_output(uts, 2, 785, 446));
- return 0;
- }
- DM_TEST(dm_test_video_rotation2, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /* Test rotated text output through the console uclass */
- static int dm_test_video_rotation3(struct unit_test_state *uts)
- {
- ut_assertok(check_vidconsole_output(uts, 3, 1134, 681));
- return 0;
- }
- DM_TEST(dm_test_video_rotation3, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /* Read a file into memory and return a pointer to it */
- static int read_file(struct unit_test_state *uts, const char *fname,
- ulong *addrp)
- {
- int buf_size = 100000;
- ulong addr = 0;
- int size, fd;
- char *buf;
- buf = map_sysmem(addr, 0);
- ut_assert(buf != NULL);
- fd = os_open(fname, OS_O_RDONLY);
- ut_assert(fd >= 0);
- size = os_read(fd, buf, buf_size);
- ut_assert(size >= 0);
- ut_assert(size < buf_size);
- os_close(fd);
- *addrp = addr;
- return 0;
- }
- /* Test drawing a bitmap file */
- static int dm_test_video_bmp(struct unit_test_state *uts)
- {
- struct udevice *dev;
- ulong addr;
- ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
- ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
- ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(1368, compress_frame_buffer(dev));
- return 0;
- }
- DM_TEST(dm_test_video_bmp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
- /* Test drawing a compressed bitmap file */
- static int dm_test_video_bmp_comp(struct unit_test_state *uts)
- {
- struct udevice *dev;
- ulong addr;
- ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
- ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
- ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
- ut_asserteq(1368, compress_frame_buffer(dev));
- return 0;
- }
- DM_TEST(dm_test_video_bmp_comp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|