From c0789c416bf1e014161f22bfc1f94b2bdecb6ce7 Mon Sep 17 00:00:00 2001 From: Gabriel Valcazar Date: Mon, 6 Nov 2023 14:25:00 +0100 Subject: [PATCH] lvgl-demo-fb: generalize for any backend and add improvements Rename the recipe to lvgl-demo to reflect the generalization and select the most appropriate backend for each platform. Aside from making sure each backend builds and runs fine, add some usability improvements: * Specify the mouse as the default evdev device instead of the touchscreen * Use common resolution variables to be able to configure the app's dimensions easily https://onedigi.atlassian.net/browse/DEL-8740 Signed-off-by: Gabriel Valcazar --- .../recipes-graphics/lvgl/lv-drivers.inc | 12 +- .../lvgl/lvgl-demo-fb_8.3.0.bb | 46 ---- ...ake-demo-compatible-with-any-backend.patch | 204 ++++++++++++++++++ .../0002-Miscellaneous-improvements.patch | 87 ++++++++ .../recipes-graphics/lvgl/lvgl-demo_8.3.0.bb | 57 +++++ 5 files changed, 353 insertions(+), 53 deletions(-) delete mode 100644 meta-digi-dey/recipes-graphics/lvgl/lvgl-demo-fb_8.3.0.bb create mode 100644 meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0001-Make-demo-compatible-with-any-backend.patch create mode 100644 meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0002-Miscellaneous-improvements.patch create mode 100644 meta-digi-dey/recipes-graphics/lvgl/lvgl-demo_8.3.0.bb diff --git a/meta-digi-dey/recipes-graphics/lvgl/lv-drivers.inc b/meta-digi-dey/recipes-graphics/lvgl/lv-drivers.inc index 6cfb7fa07..c10856d0a 100644 --- a/meta-digi-dey/recipes-graphics/lvgl/lv-drivers.inc +++ b/meta-digi-dey/recipes-graphics/lvgl/lv-drivers.inc @@ -7,15 +7,15 @@ LVGL_CONFIG_USE_DRM = "${@bb.utils.contains('PACKAGECONFIG', 'drm', '1', '0', d) LVGL_CONFIG_DRM_CARD ?= "/dev/dri/card0" LVGL_CONFIG_USE_EVDEV = "${@bb.utils.contains_any('PACKAGECONFIG', 'drm fbdev', '1', '0', d)}" -LVGL_CONFIG_EVDEV_INPUT ?= "/dev/input/touchscreen" +LVGL_CONFIG_EVDEV_INPUT ?= "/dev/input/mouse0" LVGL_CONFIG_USE_FBDEV = "${@bb.utils.contains('PACKAGECONFIG', 'fbdev', '1', '0', d)}" LVGL_CONFIG_USE_SDL = "${@bb.utils.contains('PACKAGECONFIG', 'sdl', '1', '0', d)}" LVGL_CONFIG_USE_WAYLAND = "${@bb.utils.contains('PACKAGECONFIG', 'wayland', '1', '0', d)}" -LVGL_CONFIG_WAYLAND_HOR_RES ?= "480" -LVGL_CONFIG_WAYLAND_VER_RES ?= "320" +LVGL_CONFIG_HOR_RES ?= "800" +LVGL_CONFIG_VER_RES ?= "480" ALLOW_EMPTY:${PN} = "1" @@ -37,12 +37,10 @@ do_configure:append() { -e "s|\(^# define USE_FBDEV \).*|# define USE_FBDEV ${LVGL_CONFIG_USE_FBDEV}|g" \ \ -e "s|\(^# define USE_SDL \).*|# define USE_SDL ${LVGL_CONFIG_USE_SDL}|g" \ - -e "s|\(^# define USE_SDL_GPU \).*|# define USE_SDL_GPU 1|g" \ - -e "s|\(^# define SDL_DOUBLE_BUFFERED \).*|# define SDL_DOUBLE_BUFFERED 1|g" \ \ -e "s|\(^# define USE_WAYLAND \).*|# define USE_WAYLAND ${LVGL_CONFIG_USE_WAYLAND}|g" \ - -e "s|\(^ *# *define *WAYLAND_HOR_RES *\).*|\1${LVGL_CONFIG_WAYLAND_HOR_RES}|g" \ - -e "s|\(^ *# *define *WAYLAND_VER_RES *\).*|\1${LVGL_CONFIG_WAYLAND_VER_RES}|g" \ + -e "s|\(^#define *LV_DRV_DISP_HOR_RES *\).*|\1${LVGL_CONFIG_HOR_RES}|g" \ + -e "s|\(^#define *LV_DRV_DISP_VER_RES *\).*|\1${LVGL_CONFIG_VER_RES}|g" \ \ -i "${S}/lv_drv_conf.h" } diff --git a/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo-fb_8.3.0.bb b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo-fb_8.3.0.bb deleted file mode 100644 index 32f833a02..000000000 --- a/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo-fb_8.3.0.bb +++ /dev/null @@ -1,46 +0,0 @@ -SUMMARY = "LVGL Demo Application for Framebuffer" -HOMEPAGE = "https://github.com/lvgl/lv_port_linux_frame_buffer" -LICENSE = "MIT" -LIC_FILES_CHKSUM = "file://LICENSE;md5=802d3d83ae80ef5f343050bf96cce3a4 \ - file://lv_drivers/LICENSE;md5=d6fc0df890c5270ef045981b516bb8f2 \ - file://lvgl/LICENCE.txt;md5=bf1198c89ae87f043108cea62460b03a" - -SRC_URI = "gitsm://github.com/lvgl/lv_port_linux_frame_buffer.git;branch=master;protocol=https" -SRCREV = "adf2c4490e17a1b9ec1902cc412a24b3b8235c8e" - -EXTRA_OEMAKE = "DESTDIR=${D}" - -PACKAGECONFIG ??= "drm" -require lv-drivers.inc - -inherit cmake - -S = "${WORKDIR}/git" - -TARGET_CFLAGS += "-I${STAGING_INCDIR}/libdrm" - -do_configure:prepend() { - if [ "${LVGL_CONFIG_USE_DRM}" -eq 1 ] ; then - # Add libdrm build dependency - sed -i '/^target_link_libraries/ s@lvgl::drivers@& drm@' "${S}/CMakeLists.txt" - # Switch from fbdev to drm usage - sed -i 's@fbdev@drm@g' "${S}/main.c" - # Pull resolution from DRM instead of hardcoding it - sed -i '/disp_drv.hor_res/ d' "${S}/main.c" - sed -i '/disp_drv.ver_res/ s@disp_drv.ver_res.*@drm_get_sizes(\&disp_drv.hor_res, \&disp_drv.ver_res, NULL);@' "${S}/main.c" - fi - - if [ "${LVGL_CONFIG_USE_SDL}" -eq 1 ] ; then - # Add libsdl build dependency - sed -i '/^target_link_libraries/ s@lvgl::drivers@& SDL2@' "${S}/CMakeLists.txt" - # Switch from fbdev to sdl usage - sed -i 's@fbdev_flush@sdl_display_flush@g' "${S}/main.c" - sed -i 's@lv_drivers/display/fbdev.h@lv_drivers/sdl/sdl.h@g' "${S}/main.c" - sed -i 's@fbdev@sdl@g' "${S}/main.c" - fi -} - -do_install:append() { - install -d ${D}${bindir} - install -m 0755 ${B}/lvgl_fb ${D}${bindir}/ -} diff --git a/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0001-Make-demo-compatible-with-any-backend.patch b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0001-Make-demo-compatible-with-any-backend.patch new file mode 100644 index 000000000..985c79bc0 --- /dev/null +++ b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0001-Make-demo-compatible-with-any-backend.patch @@ -0,0 +1,204 @@ +From: Gabriel Valcazar +Date: Mon, 6 Nov 2023 13:45:27 +0100 +Subject: [PATCH] Make demo compatible with any backend + +Apply changes so the demo builds and runs with any of the 4 major backends +(wayland, sdl, drm and fbdev) + +Signed-off-by: Gabriel Valcazar +--- + main.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 128 insertions(+), 14 deletions(-) + +diff --git a/main.c b/main.c +index 33cd734..bb0248a 100644 +--- a/main.c ++++ b/main.c +@@ -1,12 +1,23 @@ + #include "lvgl/lvgl.h" + #include "lvgl/demos/lv_demos.h" + #include "lv_drivers/display/fbdev.h" ++#include "lv_drivers/display/drm.h" + #include "lv_drivers/indev/evdev.h" ++#include "lv_drivers/sdl/sdl.h" ++#include "lv_drivers/wayland/wayland.h" ++ ++#if USE_SDL ++#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ ++#include ++#endif ++ + #include + #include + #include + #include + ++static void backend_init(void); ++ + #define DISP_BUF_SIZE (128 * 1024) + + int main(void) +@@ -14,8 +25,78 @@ int main(void) + /*LittlevGL init*/ + lv_init(); + +- /*Linux frame buffer device init*/ +- fbdev_init(); ++ backend_init(); ++ ++ /*Create a Demo*/ ++ lv_demo_widgets(); ++ ++ /*Handle LitlevGL tasks (tickless mode)*/ ++ while(1) { ++ lv_timer_handler(); ++ usleep(5000); ++ } ++ ++ return 0; ++} ++ ++static void backend_init(void) ++{ ++#if USE_WAYLAND ++ lv_wayland_init(); ++ ++ /* Create a display */ ++ lv_disp_t * disp = lv_wayland_create_window(800, 480, "lvgl wayland demo", NULL /*close_cb*/); ++#elif USE_SDL ++ sdl_init(); ++ ++ /*A small buffer for LittlevGL to draw the screen's content*/ ++ static lv_color_t buf[SDL_HOR_RES * 100]; ++ ++ /*Initialize a descriptor for the buffer*/ ++ static lv_disp_draw_buf_t disp_buf; ++ lv_disp_draw_buf_init(&disp_buf, buf, NULL, SDL_HOR_RES * 100); ++ ++ /*Initialize and register a display driver*/ ++ static lv_disp_drv_t disp_drv; ++ lv_disp_drv_init(&disp_drv); ++ disp_drv.draw_buf = &disp_buf; ++ disp_drv.flush_cb = sdl_display_flush; ++ disp_drv.hor_res = SDL_HOR_RES; ++ disp_drv.ver_res = SDL_VER_RES; ++ lv_disp_drv_register(&disp_drv); ++ ++ lv_group_t * g = lv_group_create(); ++ lv_group_set_default(g); ++ ++ static lv_indev_drv_t indev_drv_1; ++ lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/ ++ indev_drv_1.type = LV_INDEV_TYPE_POINTER; ++ ++ /*This function will be called periodically (by the library) to get the mouse position and state*/ ++ indev_drv_1.read_cb = sdl_mouse_read; ++ lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1); ++ ++ /*Set a cursor for the mouse*/ ++ LV_IMG_DECLARE(mouse_cursor_icon) ++ lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */ ++ lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ ++ lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/ ++ ++ static lv_indev_drv_t indev_drv_2; ++ lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/ ++ indev_drv_2.type = LV_INDEV_TYPE_KEYPAD; ++ indev_drv_2.read_cb = sdl_keyboard_read; ++ lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_2); ++ lv_indev_set_group(kb_indev, g); ++ ++ static lv_indev_drv_t indev_drv_3; ++ lv_indev_drv_init(&indev_drv_3); /*Basic initialization*/ ++ indev_drv_3.type = LV_INDEV_TYPE_ENCODER; ++ indev_drv_3.read_cb = sdl_mousewheel_read; ++ lv_indev_t * enc_indev = lv_indev_drv_register(&indev_drv_3); ++ lv_indev_set_group(enc_indev, g); ++#elif USE_DRM ++ drm_init(); + + /*A small buffer for LittlevGL to draw the screen's content*/ + static lv_color_t buf[DISP_BUF_SIZE]; +@@ -28,12 +109,20 @@ int main(void) + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.draw_buf = &disp_buf; +- disp_drv.flush_cb = fbdev_flush; +- disp_drv.hor_res = 800; +- disp_drv.ver_res = 480; ++ disp_drv.flush_cb = drm_flush; ++ lv_coord_t drm_width, drm_height; ++ /* get size from DRM/KMS backend */ ++ uint32_t drm_dpi; ++ drm_get_sizes(&drm_width, &drm_height, &drm_dpi); ++ disp_drv.hor_res = drm_width; ++ disp_drv.ver_res = drm_height; + lv_disp_drv_register(&disp_drv); + + evdev_init(); ++ ++ lv_group_t * g = lv_group_create(); ++ lv_group_set_default(g); ++ + static lv_indev_drv_t indev_drv_1; + lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/ + indev_drv_1.type = LV_INDEV_TYPE_POINTER; +@@ -42,24 +131,49 @@ int main(void) + indev_drv_1.read_cb = evdev_read; + lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1); + +- + /*Set a cursor for the mouse*/ + LV_IMG_DECLARE(mouse_cursor_icon) + lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */ + lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ + lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/ ++#elif USE_FBDEV ++ fbdev_init(); + ++ /*A small buffer for LittlevGL to draw the screen's content*/ ++ static lv_color_t buf[DISP_BUF_SIZE]; + +- /*Create a Demo*/ +- lv_demo_widgets(); ++ /*Initialize a descriptor for the buffer*/ ++ static lv_disp_draw_buf_t disp_buf; ++ lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE); + +- /*Handle LitlevGL tasks (tickless mode)*/ +- while(1) { +- lv_timer_handler(); +- usleep(5000); +- } ++ /*Initialize and register a display driver*/ ++ static lv_disp_drv_t disp_drv; ++ lv_disp_drv_init(&disp_drv); ++ disp_drv.draw_buf = &disp_buf; ++ disp_drv.flush_cb = fbdev_flush; ++ disp_drv.hor_res = 800; ++ disp_drv.ver_res = 480; ++ lv_disp_drv_register(&disp_drv); + +- return 0; ++ evdev_init(); ++ ++ lv_group_t * g = lv_group_create(); ++ lv_group_set_default(g); ++ ++ static lv_indev_drv_t indev_drv_1; ++ lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/ ++ indev_drv_1.type = LV_INDEV_TYPE_POINTER; ++ ++ /*This function will be called periodically (by the library) to get the mouse position and state*/ ++ indev_drv_1.read_cb = evdev_read; ++ lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1); ++ ++ /*Set a cursor for the mouse*/ ++ LV_IMG_DECLARE(mouse_cursor_icon) ++ lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */ ++ lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ ++ lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/ ++#endif + } + + /*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/ diff --git a/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0002-Miscellaneous-improvements.patch b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0002-Miscellaneous-improvements.patch new file mode 100644 index 000000000..5f11761cf --- /dev/null +++ b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo/0002-Miscellaneous-improvements.patch @@ -0,0 +1,87 @@ +From: Gabriel Valcazar +Date: Wed, 8 Nov 2023 13:25:25 +0100 +Subject: [PATCH] Miscellaneous improvements: + + * Change LV_COLOR_DEPTH from 32 to 16 to fix output on fbdev backend + * Increase DISP_BUF_SIZE to 8 MiB to improve performance on fbdev and drm + backends + * Create common macros for app dimensions + +Signed-off-by: Gabriel Valcazar +--- + lv_conf.h | 2 +- + lv_drv_conf.h | 6 ++++-- + main.c | 9 +++++---- + 3 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/lv_conf.h b/lv_conf.h +index 3137b1a..3f36997 100644 +--- a/lv_conf.h ++++ b/lv_conf.h +@@ -30,7 +30,7 @@ extern uint32_t custom_tick_get(void); + *====================*/ + + /*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/ +-#define LV_COLOR_DEPTH 32 ++#define LV_COLOR_DEPTH 16 + + /*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/ + #define LV_COLOR_16_SWAP 0 +diff --git a/lv_drv_conf.h b/lv_drv_conf.h +index d40e703..554eba9 100644 +--- a/lv_drv_conf.h ++++ b/lv_drv_conf.h +@@ -32,6 +32,8 @@ + #define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ + #define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ + #define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ ++#define LV_DRV_DISP_HOR_RES 800 ++#define LV_DRV_DISP_VER_RES 480 + + /*--------- + * SPI +@@ -95,8 +97,8 @@ + #endif + + #if USE_SDL || USE_SDL_GPU +-# define SDL_HOR_RES 480 +-# define SDL_VER_RES 320 ++# define SDL_HOR_RES LV_DRV_DISP_HOR_RES ++# define SDL_VER_RES LV_DRV_DISP_VER_RES + + /* Scale window by this factor (useful when simulating small screens) */ + # define SDL_ZOOM 1 +diff --git a/main.c b/main.c +index bb0248a..f3fb69e 100644 +--- a/main.c ++++ b/main.c +@@ -18,7 +18,8 @@ + + static void backend_init(void); + +-#define DISP_BUF_SIZE (128 * 1024) ++/* Originally 128 KiB, increase to 8 MiB to improve performance */ ++#define DISP_BUF_SIZE (8 * 1024 * 1024) + + int main(void) + { +@@ -45,7 +46,7 @@ static void backend_init(void) + lv_wayland_init(); + + /* Create a display */ +- lv_disp_t * disp = lv_wayland_create_window(800, 480, "lvgl wayland demo", NULL /*close_cb*/); ++ lv_disp_t * disp = lv_wayland_create_window(LV_DRV_DISP_HOR_RES, LV_DRV_DISP_VER_RES, "lvgl wayland demo", NULL /*close_cb*/); + #elif USE_SDL + sdl_init(); + +@@ -151,8 +152,8 @@ static void backend_init(void) + lv_disp_drv_init(&disp_drv); + disp_drv.draw_buf = &disp_buf; + disp_drv.flush_cb = fbdev_flush; +- disp_drv.hor_res = 800; +- disp_drv.ver_res = 480; ++ disp_drv.hor_res = LV_DRV_DISP_HOR_RES; ++ disp_drv.ver_res = LV_DRV_DISP_VER_RES; + lv_disp_drv_register(&disp_drv); + + evdev_init(); diff --git a/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo_8.3.0.bb b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo_8.3.0.bb new file mode 100644 index 000000000..73224d4dd --- /dev/null +++ b/meta-digi-dey/recipes-graphics/lvgl/lvgl-demo_8.3.0.bb @@ -0,0 +1,57 @@ +SUMMARY = "LVGL Demo Application" +HOMEPAGE = "https://github.com/lvgl/lv_port_linux_frame_buffer" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=802d3d83ae80ef5f343050bf96cce3a4 \ + file://lv_drivers/LICENSE;md5=d6fc0df890c5270ef045981b516bb8f2 \ + file://lvgl/LICENCE.txt;md5=bf1198c89ae87f043108cea62460b03a" + +SRC_URI = " \ + gitsm://github.com/lvgl/lv_port_linux_frame_buffer.git;branch=master;protocol=https \ + file://0001-Make-demo-compatible-with-any-backend.patch \ + file://0002-Miscellaneous-improvements.patch \ +" +SRCREV = "adf2c4490e17a1b9ec1902cc412a24b3b8235c8e" + +EXTRA_OEMAKE = "DESTDIR=${D}" + +# By default, use wayland backend if possible. +# If unavailable, fall back to a secondary backend +MINIMAL_BACKEND ?= "fbdev" +MINIMAL_BACKEND:imxdrm = "drm" +MINIMAL_BACKEND:ccmp15 = "sdl" +PACKAGECONFIG = "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland', '${MINIMAL_BACKEND}', d)}" + +require lv-drivers.inc + +inherit cmake + +S = "${WORKDIR}/git" + +TARGET_CFLAGS += "-I${STAGING_INCDIR}/libdrm" + +# Change DRM card used for i.MX8-based platforms +LVGL_CONFIG_DRM_CARD:mx8-generic-bsp = "/dev/dri/card1" + +do_configure:prepend() { + if [ "${LVGL_CONFIG_USE_DRM}" -eq 1 ] ; then + # Add libdrm build dependency + sed -i '/^target_link_libraries/ s@lvgl::drivers@& drm@' "${S}/CMakeLists.txt" + fi + + if [ "${LVGL_CONFIG_USE_SDL}" -eq 1 ] ; then + # Add libsdl build dependency + sed -i '/^target_link_libraries/ s@lvgl::drivers@& SDL2@' "${S}/CMakeLists.txt" + fi + + if [ "${LVGL_CONFIG_USE_WAYLAND}" -eq 1 ] ; then + # Add wayland build dependencies + sed -i '/^target_link_libraries/ s@lvgl::drivers@& wayland-client wayland-cursor xkbcommon@' "${S}/CMakeLists.txt" + fi +} + +do_install:append() { + install -d ${D}${bindir} + install -m 0755 ${B}/lvgl_fb ${D}${bindir}/lvgl_demo +} + +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul|ccimx8m|ccimx8x|ccimx93|ccmp15)"