drivers: display: sdl: Add support for L8 pixel format

Adds support for the 8bit grayscale pixel format to the SDL
display driver.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
This commit is contained in:
Fabian Blatz 2025-03-10 15:49:44 +01:00 committed by Benjamin Cabé
commit 1ba9e4d707
2 changed files with 56 additions and 6 deletions

View file

@ -37,6 +37,9 @@ choice SDL_DISPLAY_DEFAULT_PIXEL_FORMAT
config SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565
bool "BGR 565"
config SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_L_8
bool "Grayscale 8bit"
endchoice
config SDL_DISPLAY_ZOOM_PCT

View file

@ -69,6 +69,8 @@ static int sdl_display_init(const struct device *dev)
PIXEL_FORMAT_RGB_565
#elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565)
PIXEL_FORMAT_BGR_565
#elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_L_8)
PIXEL_FORMAT_L_8
#else /* SDL_DISPLAY_DEFAULT_PIXEL_FORMAT */
PIXEL_FORMAT_ARGB_8888
#endif /* SDL_DISPLAY_DEFAULT_PIXEL_FORMAT */
@ -223,6 +225,26 @@ static void sdl_display_write_mono(uint8_t *disp_buf,
}
}
static void sdl_display_write_l8(uint8_t *disp_buf, const struct display_buffer_descriptor *desc,
const void *buf)
{
uint32_t w_idx;
uint32_t h_idx;
uint32_t pixel;
const uint8_t *byte_ptr;
__ASSERT((desc->pitch * desc->height) <= desc->buf_size, "Input buffer too small");
for (h_idx = 0U; h_idx < desc->height; ++h_idx) {
for (w_idx = 0U; w_idx < desc->width; ++w_idx) {
byte_ptr = (const uint8_t *)buf + ((h_idx * desc->pitch) + w_idx);
pixel = *byte_ptr;
*((uint32_t *)disp_buf) = pixel | (pixel << 8) | (pixel << 16) | 0xFF000000;
disp_buf += 4;
}
}
}
static int sdl_display_write(const struct device *dev, const uint16_t x,
const uint16_t y,
const struct display_buffer_descriptor *desc,
@ -262,6 +284,8 @@ static int sdl_display_write(const struct device *dev, const uint16_t x,
sdl_display_write_rgb565(disp_data->buf, desc, buf);
} else if (disp_data->current_pixel_format == PIXEL_FORMAT_BGR_565) {
sdl_display_write_bgr565(disp_data->buf, desc, buf);
} else if (disp_data->current_pixel_format == PIXEL_FORMAT_L_8) {
sdl_display_write_l8(disp_data->buf, desc, buf);
}
sdl_display_write_bottom(desc->height, desc->width, x, y, disp_data->renderer,
@ -388,10 +412,29 @@ static void sdl_display_read_mono(const uint8_t *read_buf,
}
}
static int sdl_display_read(const struct device *dev, const uint16_t x,
const uint16_t y,
const struct display_buffer_descriptor *desc,
void *buf)
static void sdl_display_read_l8(const uint8_t *read_buf,
const struct display_buffer_descriptor *desc, void *buf)
{
uint32_t w_idx;
uint32_t h_idx;
uint8_t *buf8;
const uint32_t *pix_ptr;
__ASSERT((desc->pitch * desc->height) <= desc->buf_size, "Read buffer is too small");
for (h_idx = 0U; h_idx < desc->height; ++h_idx) {
buf8 = ((uint8_t *)buf) + desc->pitch * h_idx;
for (w_idx = 0U; w_idx < desc->width; ++w_idx) {
pix_ptr = (const uint32_t *)read_buf + ((h_idx * desc->pitch) + w_idx);
*buf8 = *pix_ptr & 0xFF;
buf8 += 1;
}
}
}
static int sdl_display_read(const struct device *dev, const uint16_t x, const uint16_t y,
const struct display_buffer_descriptor *desc, void *buf)
{
struct sdl_display_data *disp_data = dev->data;
int err;
@ -423,6 +466,8 @@ static int sdl_display_read(const struct device *dev, const uint16_t x,
sdl_display_read_rgb565(disp_data->read_buf, desc, buf);
} else if (disp_data->current_pixel_format == PIXEL_FORMAT_BGR_565) {
sdl_display_read_bgr565(disp_data->read_buf, desc, buf);
} else if (disp_data->current_pixel_format == PIXEL_FORMAT_L_8) {
sdl_display_read_l8(disp_data->read_buf, desc, buf);
}
return 0;
@ -507,7 +552,8 @@ static void sdl_display_get_capabilities(
PIXEL_FORMAT_MONO01 |
PIXEL_FORMAT_MONO10 |
PIXEL_FORMAT_RGB_565 |
PIXEL_FORMAT_BGR_565;
PIXEL_FORMAT_BGR_565 |
PIXEL_FORMAT_L_8;
capabilities->current_pixel_format = disp_data->current_pixel_format;
capabilities->screen_info = SCREEN_INFO_MONO_VTILED |
(IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_MSB_FIRST) ? SCREEN_INFO_MONO_MSB_FIRST : 0);
@ -525,6 +571,7 @@ static int sdl_display_set_pixel_format(const struct device *dev,
case PIXEL_FORMAT_MONO10:
case PIXEL_FORMAT_RGB_565:
case PIXEL_FORMAT_BGR_565:
case PIXEL_FORMAT_L_8:
disp_data->current_pixel_format = pixel_format;
return 0;
default: