diff mbox series

[5/6] video: sandbox_sdl: Implement more pixel formats

Message ID 20240516-rework-video-format-v1-5-f69822b742a3@flygoat.com
State New
Delegated to: Anatolij Gustschin
Headers show
Series video: pixel format handling fixes and improvements | expand

Commit Message

Jiaxun Yang May 16, 2024, 10:16 p.m. UTC
Support most of possible pixel formats so we can test them
in sandbox.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/sandbox/cpu/sdl.c         | 58 +++++++++++++++++++++++++++++++++++++-----
 arch/sandbox/include/asm/sdl.h | 17 ++++++++-----
 drivers/video/sandbox_sdl.c    | 16 +++++++-----
 include/dm/test.h              |  2 ++
 test/dm/video.c                | 14 +++++-----
 5 files changed, 81 insertions(+), 26 deletions(-)
diff mbox series

Patch

diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index ed84646bdab7..436c0448de1f 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -5,8 +5,10 @@ 
 
 #include <errno.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <stdbool.h>
 #include <sysreset.h>
+#include <video_format.h>
 #include <linux/input.h>
 #include <SDL2/SDL.h>
 #include <asm/state.h>
@@ -69,6 +71,47 @@  static struct sdl_info {
 	int src_depth;
 } sdl;
 
+static inline SDL_PixelFormatEnum sandbox_video_format(int l2bbp, int format)
+{
+	switch (l2bbp) {
+	case VIDEO_BPP8:
+		switch (format) {
+		case VIDEO_DEFAULT:
+		case VIDEO_RGB332:
+			return SDL_PIXELFORMAT_RGB332;
+		}
+	case VIDEO_BPP16:
+		switch (format) {
+		case VIDEO_DEFAULT:
+		case VIDEO_RGB565:
+			return SDL_PIXELFORMAT_RGB565;
+		default:
+			break;
+		}
+		break;
+	case VIDEO_BPP32:
+		switch (format) {
+		case VIDEO_DEFAULT:
+		case VIDEO_XRGB8888:
+			return SDL_PIXELFORMAT_RGB888;
+		case VIDEO_BGRX8888:
+			return SDL_PIXELFORMAT_BGRX8888;
+		case VIDEO_XBGR8888:
+			return SDL_PIXELFORMAT_BGR888;
+		case VIDEO_RGBA8888:
+			return SDL_PIXELFORMAT_RGBA8888;
+		case VIDEO_XRGB2101010:
+			return SDL_PIXELFORMAT_ARGB2101010;
+		default:
+			break;
+		}
+	default:
+		break;
+	}
+
+	return SDL_PIXELFORMAT_UNKNOWN;
+}
+
 static void sandbox_sdl_poll_events(void)
 {
 	/*
@@ -122,9 +165,10 @@  int sandbox_sdl_remove_display(void)
 }
 
 int sandbox_sdl_init_display(int width, int height, int log2_bpp,
-			     bool double_size)
+			     int format, bool double_size)
 {
 	struct sandbox_state *state = state_get_current();
+	SDL_PixelFormatEnum sdl_format;
 	int err;
 
 	if (!width || !state->show_lcd)
@@ -135,6 +179,12 @@  int sandbox_sdl_init_display(int width, int height, int log2_bpp,
 	if (sdl.renderer)
 		sandbox_sdl_remove_display();
 
+	sdl_format = sandbox_video_format(log2_bpp, format);
+	if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) {
+		printf("Unsupported video format\n");
+		return -EINVAL;
+	}
+
 	if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
 		printf("Unable to initialise SDL LCD: %s\n", SDL_GetError());
 		return -EPERM;
@@ -153,8 +203,6 @@  int sandbox_sdl_init_display(int width, int height, int log2_bpp,
 		printf("Unable to init hinting: %s", SDL_GetError());
 
 	sdl.src_depth = 1 << log2_bpp;
-	if (log2_bpp != 4 && log2_bpp != 5)
-		log2_bpp = 5;
 	sdl.depth = 1 << log2_bpp;
 	sdl.pitch = sdl.width * sdl.depth / 8;
 	sdl.screen = SDL_CreateWindow("U-Boot", SDL_WINDOWPOS_UNDEFINED,
@@ -174,9 +222,7 @@  int sandbox_sdl_init_display(int width, int height, int log2_bpp,
 		return -EIO;
 	}
 
-	sdl.texture = SDL_CreateTexture(sdl.renderer, log2_bpp == 4 ?
-					SDL_PIXELFORMAT_RGB565 :
-					SDL_PIXELFORMAT_RGB888,
+	sdl.texture = SDL_CreateTexture(sdl.renderer, sdl_format,
 					SDL_TEXTUREACCESS_STREAMING,
 					width, height);
 	if (!sdl.texture) {
diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h
index ee4991f7c24a..7b4f26f994da 100644
--- a/arch/sandbox/include/asm/sdl.h
+++ b/arch/sandbox/include/asm/sdl.h
@@ -24,7 +24,7 @@ 
  *		and -EPERM if the video failed to come up.
  */
 int sandbox_sdl_init_display(int width, int height, int log2_bpp,
-			     bool double_size);
+			     int format, bool double_size);
 
 /**
  * sandbox_sdl_remove_display() - Remove the SDL screen
@@ -89,12 +89,13 @@  int sandbox_sdl_sound_stop(void);
 int sandbox_sdl_sound_init(int rate, int channels);
 
 /**
- * sandbox_sdl_set_bpp() - Set the depth of the sandbox display
+ * sandbox_sdl_set_pixel() - Set depth and format of the sandbox display
  *
  * The device must not be active when this function is called. It activiates it
  * before returning.
  *
- * This updates the depth value and adjusts a few other settings accordingly.
+ * This updates the depth value and pixel format for the sandbox display, then
+ * it adjusts a few other settings accordingly.
  * It must be called before the display is probed.
  *
  * @dev: Device to adjust
@@ -102,11 +103,12 @@  int sandbox_sdl_sound_init(int rate, int channels);
  * Return: 0 if the device was already active, other error if it fails to probe
  * after the change
  */
-int sandbox_sdl_set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp);
+int sandbox_sdl_set_pixel(struct udevice *dev, enum video_log2_bpp l2bpp,
+			  enum video_format format);
 
 #else
 static inline int sandbox_sdl_init_display(int width, int height, int log2_bpp,
-					   bool double_size)
+					   int format, bool double_size)
 {
 	return -ENODEV;
 }
@@ -151,8 +153,9 @@  static inline int sandbox_sdl_sound_init(int rate, int channels)
 	return -ENODEV;
 }
 
-static inline int sandbox_sdl_set_bpp(struct udevice *dev,
-				      enum video_log2_bpp l2bpp)
+static inline int sandbox_sdl_set_pixel(struct udevice *dev,
+					enum video_log2_bpp l2bpp,
+					enum video_format format)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 69dfa9302735..ddd72a14de83 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -31,7 +31,7 @@  static int sandbox_sdl_probe(struct udevice *dev)
 	int ret;
 
 	ret = sandbox_sdl_init_display(plat->xres, plat->yres, plat->bpix,
-				       state->double_lcd);
+				       plat->format, state->double_lcd);
 	if (ret) {
 		puts("LCD init failed\n");
 		return ret;
@@ -39,6 +39,7 @@  static int sandbox_sdl_probe(struct udevice *dev)
 	uc_priv->xsize = plat->xres;
 	uc_priv->ysize = plat->yres;
 	uc_priv->bpix = plat->bpix;
+	uc_priv->format = plat->format;
 	uc_priv->rot = plat->rot;
 	uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name;
 	uc_priv->font_size = plat->font_size;
@@ -48,12 +49,14 @@  static int sandbox_sdl_probe(struct udevice *dev)
 	return 0;
 }
 
-static void set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp)
+static void set_pixel(struct udevice *dev, enum video_log2_bpp l2bpp,
+		      enum video_format format)
 {
 	struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
 	struct sandbox_sdl_plat *plat = dev_get_plat(dev);
 
 	plat->bpix = l2bpp;
+	plat->format = format;
 
 	uc_plat->size = plat->xres * plat->yres * VNBYTES(plat->bpix);
 
@@ -61,7 +64,7 @@  static void set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp)
 	 * Set up to the maximum size we'll ever need. This is a strange case.
 	 * The video memory is allocated by video_post_bind() called from
 	 * board_init_r(). If a test changes the reoslution so it needs more
-	 * memory later (with sandbox_sdl_set_bpp()), it is too late to make
+	 * memory later (with sandbox_sdl_set_pixel()), it is too late to make
 	 * the frame buffer larger.
 	 *
 	 * So use a maximum size here.
@@ -79,7 +82,8 @@  static void set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp)
 		uc_plat->size *= 2;
 }
 
-int sandbox_sdl_set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp)
+int sandbox_sdl_set_pixel(struct udevice *dev, enum video_log2_bpp l2bpp,
+			  enum video_format format)
 {
 	struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
 	int ret;
@@ -89,7 +93,7 @@  int sandbox_sdl_set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp)
 	sandbox_sdl_remove_display();
 
 	uc_plat->hide_logo = true;
-	set_bpp(dev, l2bpp);
+	set_pixel(dev, l2bpp, format);
 
 	ret = device_probe(dev);
 	if (ret)
@@ -122,7 +126,7 @@  static int sandbox_sdl_bind(struct udevice *dev)
 	l2bpp = dev_read_u32_default(dev, "log2-depth", VIDEO_BPP16);
 	plat->rot = dev_read_u32_default(dev, "rotate", 0);
 
-	set_bpp(dev, l2bpp);
+	set_pixel(dev, l2bpp, VIDEO_DEFAULT);
 
 	return ret;
 }
diff --git a/include/dm/test.h b/include/dm/test.h
index 02737411a164..87568d741d49 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -153,6 +153,7 @@  extern struct unit_test_state global_dm_test_state;
  * @xres: Width of display in pixels
  * @yres: Height of display in pixels
  * @bpix: Log2 of bits per pixel (enum video_log2_bpp)
+ * @format: Pixel format (enum video_format)
  * @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
  *	2=upside down, 3=90 degree counterclockwise)
  * @vidconsole_drv_name: Name of video console driver (set by tests)
@@ -162,6 +163,7 @@  struct sandbox_sdl_plat {
 	int xres;
 	int yres;
 	int bpix;
+	int format;
 	int rot;
 	const char *vidconsole_drv_name;
 	int font_size;
diff --git a/test/dm/video.c b/test/dm/video.c
index 0da96aec5efd..47a8df511e8b 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -395,7 +395,7 @@  static int dm_test_video_bmp8(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP8, VIDEO_DEFAULT));
 
 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
 
@@ -416,7 +416,7 @@  static int dm_test_video_bmp16(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP16));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP16, VIDEO_DEFAULT));
 
 	ut_assertok(read_file(uts, "tools/logos/denx-16bpp.bmp.gz", &src));
 	ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
@@ -439,7 +439,7 @@  static int dm_test_video_bmp24(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP16));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP16, VIDEO_DEFAULT));
 
 	ut_assertok(read_file(uts, "tools/logos/denx-24bpp.bmp.gz", &src));
 	ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
@@ -462,7 +462,7 @@  static int dm_test_video_bmp24_32(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP32, VIDEO_DEFAULT));
 
 	ut_assertok(read_file(uts, "tools/logos/denx-24bpp.bmp.gz", &src));
 	ut_assertok(gunzip(map_sysmem(dst, 0), dst_len, map_sysmem(src, 0),
@@ -483,7 +483,7 @@  static int dm_test_video_bmp32(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP32, VIDEO_DEFAULT));
 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
 
 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
@@ -517,7 +517,7 @@  static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP32, VIDEO_DEFAULT));
 
 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
 
@@ -536,7 +536,7 @@  static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
 
 	ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
 	ut_assertnonnull(dev);
-	ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
+	ut_assertok(sandbox_sdl_set_pixel(dev, VIDEO_BPP8, VIDEO_DEFAULT));
 
 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));