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:
parent
b2404835e0
commit
20b00ef65d
@ -126,6 +126,26 @@ static void rotate270_l8(const uint8_t * src, uint8_t * dst, int32_t src_width,
|
||||
* 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)
|
||||
{
|
||||
if(LV_DRAW_SW_RGB565_SWAP(buf, buf_size_px) == LV_RESULT_OK) return;
|
||||
|
@ -29,6 +29,21 @@ extern "C" {
|
||||
* 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.
|
||||
* Might be required if a 8bit parallel port or an SPI port send the bytes in the wrong order.
|
||||
|
@ -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(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
|
||||
dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024);
|
||||
dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, buffer_size_bytes);
|
||||
#endif
|
||||
lv_display_set_buffers(disp, dsc->buf1, dsc->buf2,
|
||||
32 * 1024, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
lv_display_set_buffers(disp, dsc->buf1, dsc->buf2, buffer_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
}
|
||||
/*LV_DISPLAY_RENDER_MODE_DIRECT or FULL */
|
||||
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
|
||||
lv_sdl_window_t * dsc = lv_display_get_driver_data(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) {
|
||||
/*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_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);
|
||||
}
|
||||
free(argb_px_map);
|
||||
#else
|
||||
LV_UNUSED(area);
|
||||
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);
|
||||
#if LV_USE_DRAW_SDL == 0
|
||||
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_RenderClear(dsc->renderer);
|
||||
@ -366,7 +393,14 @@ static void window_update(lv_display_t * disp)
|
||||
#if LV_USE_DRAW_SDL == 0
|
||||
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);
|
||||
|
||||
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 LV_COLOR_DEPTH == 32
|
||||
#if LV_COLOR_DEPTH == 32 || LV_COLOR_DEPTH == 1
|
||||
SDL_PixelFormatEnum px_format =
|
||||
SDL_PIXELFORMAT_RGB888; /*same as SDL_PIXELFORMAT_RGB888, but it's not supported in older versions*/
|
||||
#elif LV_COLOR_DEPTH == 24
|
||||
@ -394,7 +428,6 @@ static void texture_resize(lv_display_t * disp)
|
||||
#else
|
||||
#error("Unsupported color format")
|
||||
#endif
|
||||
// px_format = SDL_PIXELFORMAT_BGR24;
|
||||
|
||||
dsc->texture = SDL_CreateTexture(dsc->renderer, px_format,
|
||||
SDL_TEXTUREACCESS_STATIC, disp->hor_res, disp->ver_res);
|
||||
|
Loading…
x
Reference in New Issue
Block a user