1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(sdl): add I1 color format render support (#7036)

Co-authored-by: liamHowatt <liamjmh0@gmail.com>
Co-authored-by: Neo Xu <neo.xu1990@gmail.com>
This commit is contained in:
Attila Kiss 2024-12-03 11:37:55 +01:00 committed by GitHub
parent b2404835e0
commit 20b00ef65d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 76 additions and 8 deletions

View File

@ -126,6 +126,26 @@ static void rotate270_l8(const uint8_t * src, uint8_t * dst, int32_t src_width,
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
void lv_draw_sw_i1_to_argb8888(const void * buf_i1, void * buf_argb8888, uint32_t width, uint32_t height,
uint32_t buf_i1_stride, uint32_t buf_argb8888_stride, uint32_t index0_color, uint32_t index1_color)
{
/*Extract the bits of I1 px_map and convert them to ARGB8888*/
const uint8_t * src = buf_i1;
uint32_t * dst = buf_argb8888;
uint32_t i1_row_byte_count = width / 8;
for(uint32_t row = 0; row < height; row++) {
uint32_t * dst_p = dst;
for(uint32_t i = 0; i < i1_row_byte_count; i++) {
/*From MSB to LSB (pixel 0 to pixel 7 in a byte)*/
for(int32_t bit = 7; bit >= 0; bit--) {
*dst_p++ = ((src[i] >> bit) & 1) ? index1_color : index0_color;
}
}
src += buf_i1_stride;
dst += buf_argb8888_stride / 4;
}
}
void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px) void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px)
{ {
if(LV_DRAW_SW_RGB565_SWAP(buf, buf_size_px) == LV_RESULT_OK) return; if(LV_DRAW_SW_RGB565_SWAP(buf, buf_size_px) == LV_RESULT_OK) return;

View File

@ -29,6 +29,21 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
/**
* Converts an I1 buffer to ARGB8888 format.
* @param buf_i1 pointer to buffer with I1 formatted render
* @param buf_argb8888 pointer to buffer for ARGB8888 render
* @param width width in pixels of the area.
* must be a multiple of 8.
* @param height height in pixels of the area
* @param buf_i1_stride stride of i1 buffer in bytes
* @param buf_argb8888_stride stride of argb8888 buffer in bytes
* @param index0_color color of the 0 bits of i1 buf
* @param index1_color color of the 1 bits of i1 buf
*/
void lv_draw_sw_i1_to_argb8888(const void * buf_i1, void * buf_argb8888, uint32_t width, uint32_t height,
uint32_t buf_i1_stride, uint32_t buf_argb8888_stride, uint32_t index0_color, uint32_t index1_color);
/** /**
* Swap the upper and lower byte of an RGB565 buffer. * Swap the upper and lower byte of an RGB565 buffer.
* Might be required if a 8bit parallel port or an SPI port send the bytes in the wrong order. * Might be required if a 8bit parallel port or an SPI port send the bytes in the wrong order.

View File

@ -109,12 +109,13 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res)
#if LV_USE_DRAW_SDL == 0 #if LV_USE_DRAW_SDL == 0
if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) {
dsc->buf1 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024); uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(lv_display_get_color_format(disp)) * 4;
uint32_t buffer_size_bytes = 32 * 1024 + palette_size;
dsc->buf1 = sdl_draw_buf_realloc_aligned(NULL, buffer_size_bytes);
#if LV_SDL_BUF_COUNT == 2 #if LV_SDL_BUF_COUNT == 2
dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024); dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, buffer_size_bytes);
#endif #endif
lv_display_set_buffers(disp, dsc->buf1, dsc->buf2, lv_display_set_buffers(disp, dsc->buf1, dsc->buf2, buffer_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL);
32 * 1024, LV_DISPLAY_RENDER_MODE_PARTIAL);
} }
/*LV_DISPLAY_RENDER_MODE_DIRECT or FULL */ /*LV_DISPLAY_RENDER_MODE_DIRECT or FULL */
else { else {
@ -210,8 +211,29 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_m
#if LV_USE_DRAW_SDL == 0 #if LV_USE_DRAW_SDL == 0
lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp);
lv_color_format_t cf = lv_display_get_color_format(disp); lv_color_format_t cf = lv_display_get_color_format(disp);
uint32_t * argb_px_map = NULL;
if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) {
/*Update values in a special OLED I1 --> ARGB8888 case
We render everything in I1, but display it in ARGB8888*/
if(cf == LV_COLOR_FORMAT_I1) {
/*I1 uses 1 bit wide pixels, ARGB8888 uses 4 byte wide pixels*/
cf = LV_COLOR_FORMAT_ARGB8888;
uint32_t width = lv_area_get_width(area);
uint32_t height = lv_area_get_height(area);
uint32_t argb_px_map_size = width * height * 4;
argb_px_map = malloc(argb_px_map_size);
if(argb_px_map == NULL) {
LV_LOG_ERROR("malloc failed");
lv_display_flush_ready(disp);
return;
}
/* skip the palette */
px_map += LV_COLOR_INDEXED_PALETTE_SIZE(LV_COLOR_FORMAT_I1) * 4;
lv_draw_sw_i1_to_argb8888(px_map, argb_px_map, width, height, width / 8, width * 4, 0xFF000000u, 0xFFFFFFFFu);
px_map = (uint8_t *)argb_px_map;
}
lv_area_t rotated_area = *area; lv_area_t rotated_area = *area;
lv_display_rotate_area(disp, &rotated_area); lv_display_rotate_area(disp, &rotated_area);
@ -247,6 +269,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_m
window_update(disp); window_update(disp);
} }
free(argb_px_map);
#else #else
LV_UNUSED(area); LV_UNUSED(area);
LV_UNUSED(px_map); LV_UNUSED(px_map);
@ -352,7 +375,11 @@ static void window_update(lv_display_t * disp)
lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp);
#if LV_USE_DRAW_SDL == 0 #if LV_USE_DRAW_SDL == 0
int32_t hor_res = disp->hor_res; int32_t hor_res = disp->hor_res;
uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_display_get_color_format(disp)); lv_color_format_t cf = lv_display_get_color_format(disp);
if(cf == LV_COLOR_FORMAT_I1) {
cf = LV_COLOR_FORMAT_ARGB8888;
}
uint32_t stride = lv_draw_buf_width_to_stride(hor_res, cf);
SDL_UpdateTexture(dsc->texture, NULL, dsc->fb_act, stride); SDL_UpdateTexture(dsc->texture, NULL, dsc->fb_act, stride);
SDL_RenderClear(dsc->renderer); SDL_RenderClear(dsc->renderer);
@ -366,7 +393,14 @@ static void window_update(lv_display_t * disp)
#if LV_USE_DRAW_SDL == 0 #if LV_USE_DRAW_SDL == 0
static void texture_resize(lv_display_t * disp) static void texture_resize(lv_display_t * disp)
{ {
uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res, lv_display_get_color_format(disp)); lv_color_format_t cf = lv_display_get_color_format(disp);
/*In some cases SDL stride might be different than LVGL render stride, like in I1 format.
SDL still uses ARGB8888 as the color format, but LVGL renders in I1, thus causing a mismatch
This ensures correct stride for SDL buffers in this case.*/
if(cf == LV_COLOR_FORMAT_I1) {
cf = LV_COLOR_FORMAT_ARGB8888;
}
uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res, cf);
lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp);
dsc->fb1 = sdl_draw_buf_realloc_aligned(dsc->fb1, stride * disp->ver_res); dsc->fb1 = sdl_draw_buf_realloc_aligned(dsc->fb1, stride * disp->ver_res);
@ -384,7 +418,7 @@ static void texture_resize(lv_display_t * disp)
} }
if(dsc->texture) SDL_DestroyTexture(dsc->texture); if(dsc->texture) SDL_DestroyTexture(dsc->texture);
#if LV_COLOR_DEPTH == 32 #if LV_COLOR_DEPTH == 32 || LV_COLOR_DEPTH == 1
SDL_PixelFormatEnum px_format = SDL_PixelFormatEnum px_format =
SDL_PIXELFORMAT_RGB888; /*same as SDL_PIXELFORMAT_RGB888, but it's not supported in older versions*/ SDL_PIXELFORMAT_RGB888; /*same as SDL_PIXELFORMAT_RGB888, but it's not supported in older versions*/
#elif LV_COLOR_DEPTH == 24 #elif LV_COLOR_DEPTH == 24
@ -394,7 +428,6 @@ static void texture_resize(lv_display_t * disp)
#else #else
#error("Unsupported color format") #error("Unsupported color format")
#endif #endif
// px_format = SDL_PIXELFORMAT_BGR24;
dsc->texture = SDL_CreateTexture(dsc->renderer, px_format, dsc->texture = SDL_CreateTexture(dsc->renderer, px_format,
SDL_TEXTUREACCESS_STATIC, disp->hor_res, disp->ver_res); SDL_TEXTUREACCESS_STATIC, disp->hor_res, disp->ver_res);