1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(sdl): make SDL work with all rendering modes and 1 or 2 buffers

This commit is contained in:
Gabor Kiss-Vamosi 2023-08-10 08:23:01 +02:00
parent 52caac9de3
commit 76d4e56036
3 changed files with 68 additions and 37 deletions

View File

@ -719,8 +719,9 @@
#define LV_USE_SDL 0 #define LV_USE_SDL 0
#if LV_USE_SDL #if LV_USE_SDL
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h> #define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
#define LV_SDL_PARTIAL_MODE 0 /*Recommended only to emulate a setup with a display controller*/ #define LV_SDL_RENDER_MODE LV_DISP_RENDER_MODE_DIRECT /*LV_DISP_RENDER_MODE_DIRECT is recommended for best performance*/
#define LV_SDL_FULLSCREEN 0 #define LV_SDL_BUF_COUNT 1 /*1 or 2*/
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL widows are closed*/ #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL widows are closed*/
#endif #endif

View File

@ -26,7 +26,9 @@ typedef struct {
SDL_Window * window; SDL_Window * window;
SDL_Renderer * renderer; SDL_Renderer * renderer;
SDL_Texture * texture; SDL_Texture * texture;
uint8_t * fb; uint8_t * fb1;
uint8_t * fb2;
uint8_t * fb_act;
uint8_t zoom; uint8_t zoom;
uint8_t ignore_size_chg; uint8_t ignore_size_chg;
} lv_sdl_window_t; } lv_sdl_window_t;
@ -96,14 +98,20 @@ lv_disp_t * lv_sdl_window_create(lv_coord_t hor_res, lv_coord_t ver_res)
window_create(disp); window_create(disp);
lv_disp_set_flush_cb(disp, flush_cb); lv_disp_set_flush_cb(disp, flush_cb);
#if LV_SDL_PARTIAL_MODE if(LV_SDL_RENDER_MODE == LV_DISP_RENDER_MODE_PARTIAL) {
uint8_t * buf = malloc(32 * 1024); uint8_t * buf1 = malloc(32 * 1024);
lv_disp_set_draw_buffers(disp, buf, NULL, uint8_t * buf2 = NULL;
32 * 1024, LV_DISP_RENDER_MODE_PARTIAL); #if LV_SDL_BUF_COUNT == 2
#else buf2 = malloc(32 * 1024);
uint32_t stride = lv_draw_buf_width_to_stride(lv_disp_get_hor_res(disp), lv_disp_get_color_format(disp));
lv_disp_set_draw_buffers(disp, dsc->fb, NULL, stride * lv_disp_get_ver_res(disp), LV_DISP_RENDER_MODE_DIRECT);
#endif #endif
lv_disp_set_draw_buffers(disp, buf1, buf2,
32 * 1024, LV_DISP_RENDER_MODE_PARTIAL);
}
/*LV_DISP_RENDER_MODE_DIRECT or FULL */
else {
uint32_t stride = lv_draw_buf_width_to_stride(lv_disp_get_hor_res(disp), lv_disp_get_color_format(disp));
lv_disp_set_draw_buffers(disp, dsc->fb1, dsc->fb2, stride * lv_disp_get_ver_res(disp), LV_SDL_RENDER_MODE);
}
lv_disp_add_event(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); lv_disp_add_event(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
return disp; return disp;
@ -160,29 +168,30 @@ void lv_sdl_quit()
static void flush_cb(lv_disp_t * disp, const lv_area_t * area, uint8_t * px_map) static void flush_cb(lv_disp_t * disp, const lv_area_t * area, uint8_t * px_map)
{ {
#if LV_SDL_PARTIAL_MODE
int32_t y;
lv_sdl_window_t * dsc = lv_disp_get_driver_data(disp); lv_sdl_window_t * dsc = lv_disp_get_driver_data(disp);
uint8_t * fb_tmp = dsc->fb; if(LV_SDL_RENDER_MODE == LV_DISP_RENDER_MODE_PARTIAL) {
uint32_t px_size = lv_color_format_get_size(lv_disp_get_color_format(disp)); int32_t y;
uint32_t px_map_stride = lv_area_get_width(area) * px_size; uint8_t * fb_tmp = dsc->fb_act;
lv_coord_t fb_stride = lv_disp_get_hor_res(disp) * px_size; uint32_t px_size = lv_color_format_get_size(lv_disp_get_color_format(disp));
fb_tmp += area->y1 * fb_stride; uint32_t px_map_stride = lv_area_get_width(area) * px_size;
fb_tmp += area->x1 * px_size; lv_coord_t fb_stride = lv_disp_get_hor_res(disp) * px_size;
for(y = area->y1; y <= area->y2; y++) { fb_tmp += area->y1 * fb_stride;
lv_memcpy(fb_tmp, px_map, px_map_stride); fb_tmp += area->x1 * px_size;
px_map += px_map_stride; for(y = area->y1; y <= area->y2; y++) {
fb_tmp += fb_stride; lv_memcpy(fb_tmp, px_map, px_map_stride);
px_map += px_map_stride;
fb_tmp += fb_stride;
}
} }
#else
LV_UNUSED(area);
LV_UNUSED(px_map);
#endif
/* TYPICALLY YOU DO NOT NEED THIS /* TYPICALLY YOU DO NOT NEED THIS
* If it was the last part to refresh update the texture of the window.*/ * If it was the last part to refresh update the texture of the window.*/
if(lv_disp_flush_is_last(disp)) { if(lv_disp_flush_is_last(disp)) {
if(LV_SDL_RENDER_MODE != LV_DISP_RENDER_MODE_PARTIAL) {
dsc->fb_act = px_map;
}
window_update(disp); window_update(disp);
} }
@ -270,7 +279,10 @@ static void window_create(lv_disp_t * disp)
dsc->renderer = SDL_CreateRenderer(dsc->window, -1, SDL_RENDERER_SOFTWARE); dsc->renderer = SDL_CreateRenderer(dsc->window, -1, SDL_RENDERER_SOFTWARE);
texture_resize(disp); texture_resize(disp);
uint32_t px_size = lv_color_format_get_size(lv_disp_get_color_format(disp)); uint32_t px_size = lv_color_format_get_size(lv_disp_get_color_format(disp));
lv_memset(dsc->fb, 0xff, hor_res * ver_res * px_size); lv_memset(dsc->fb1, 0xff, hor_res * ver_res * px_size);
#if LV_SDL_DIRECT_MODE_2_BUF
lv_memset(dsc->fb2, 0xff, hor_res * ver_res * px_size);
#endif
/*Some platforms (e.g. Emscripten) seem to require setting the size again */ /*Some platforms (e.g. Emscripten) seem to require setting the size again */
SDL_SetWindowSize(dsc->window, hor_res * dsc->zoom, ver_res * dsc->zoom); SDL_SetWindowSize(dsc->window, hor_res * dsc->zoom, ver_res * dsc->zoom);
texture_resize(disp); texture_resize(disp);
@ -281,7 +293,7 @@ static void window_update(lv_disp_t * disp)
lv_sdl_window_t * dsc = lv_disp_get_driver_data(disp); lv_sdl_window_t * dsc = lv_disp_get_driver_data(disp);
lv_coord_t hor_res = lv_disp_get_hor_res(disp); lv_coord_t hor_res = lv_disp_get_hor_res(disp);
uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_disp_get_color_format(disp)); uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_disp_get_color_format(disp));
SDL_UpdateTexture(dsc->texture, NULL, dsc->fb, stride); SDL_UpdateTexture(dsc->texture, NULL, dsc->fb_act, stride);
SDL_RenderClear(dsc->renderer); SDL_RenderClear(dsc->renderer);
@ -297,12 +309,19 @@ static void texture_resize(lv_disp_t * disp)
uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_disp_get_color_format(disp)); uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_disp_get_color_format(disp));
lv_sdl_window_t * dsc = lv_disp_get_driver_data(disp); lv_sdl_window_t * dsc = lv_disp_get_driver_data(disp);
dsc->fb = realloc(dsc->fb, stride * ver_res); dsc->fb1 = realloc(dsc->fb1, stride * ver_res);
memset(dsc->fb, 0x00, stride * ver_res); memset(dsc->fb1, 0x00, stride * ver_res);
#if LV_SDL_PARTIAL_MODE == 0 if(LV_SDL_RENDER_MODE == LV_DISP_RENDER_MODE_PARTIAL) {
lv_disp_set_draw_buffers(disp, dsc->fb, NULL, stride * ver_res, LV_DISP_RENDER_MODE_DIRECT); dsc->fb_act = dsc->fb1;
}
else {
#if LV_SDL_BUF_COUNT == 2
dsc->fb2 = realloc(dsc->fb2, stride * ver_res);
memset(dsc->fb2, 0x00, stride * ver_res);
#endif #endif
lv_disp_set_draw_buffers(disp, dsc->fb1, dsc->fb2, stride * ver_res, LV_SDL_RENDER_MODE);
}
if(dsc->texture) SDL_DestroyTexture(dsc->texture); if(dsc->texture) SDL_DestroyTexture(dsc->texture);
#if LV_COLOR_DEPTH == 32 #if LV_COLOR_DEPTH == 32

View File

@ -2319,18 +2319,29 @@
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h> #define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif #endif
#endif #endif
#ifndef LV_SDL_PARTIAL_MODE #ifndef LV_SDL_RENDER_MODE
#ifdef CONFIG_LV_SDL_PARTIAL_MODE #ifdef CONFIG_LV_SDL_RENDER_MODE
#define LV_SDL_PARTIAL_MODE CONFIG_LV_SDL_PARTIAL_MODE #define LV_SDL_RENDER_MODE CONFIG_LV_SDL_RENDER_MODE
#else #else
#define LV_SDL_PARTIAL_MODE 0 /*Recommended only to emulate a setup with a display controller*/ #define LV_SDL_RENDER_MODE LV_DISP_RENDER_MODE_DIRECT /*LV_DISP_RENDER_MODE_DIRECT is recommended for best performance*/
#endif
#endif
#ifndef LV_SDL_BUF_COUNT
#ifdef _LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_SDL_BUF_COUNT
#define LV_SDL_BUF_COUNT CONFIG_LV_SDL_BUF_COUNT
#else
#define LV_SDL_BUF_COUNT 0
#endif
#else
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/
#endif #endif
#endif #endif
#ifndef LV_SDL_FULLSCREEN #ifndef LV_SDL_FULLSCREEN
#ifdef CONFIG_LV_SDL_FULLSCREEN #ifdef CONFIG_LV_SDL_FULLSCREEN
#define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN #define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN
#else #else
#define LV_SDL_FULLSCREEN 0 #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
#endif #endif
#endif #endif
#ifndef LV_SDL_DIRECT_EXIT #ifndef LV_SDL_DIRECT_EXIT