From fce35569b87835c7a9161b6d2fb10595d5619a78 Mon Sep 17 00:00:00 2001 From: Ioannis Karachalios Date: Wed, 20 Dec 2023 15:32:39 +0200 Subject: [PATCH] modules: lvgl: Add support for frame rounder callback Add support for LVGL rounder callback function. Sometimes, either the underlying display controller and/or the LCD host controller might impose restrictions on frame resolution. For instance, the E1394AA65A display model should impose that either axis of a frame be multiple of 2 pixels or the Renesas LCD controller of the DA1469x SoC, should impose that the stride value, number of bytes between consecutive frame lines, be multiple of 4 bytes. Signed-off-by: Ioannis Karachalios --- modules/lvgl/Kconfig | 20 ++++++++++++++++++++ modules/lvgl/include/lvgl_display.h | 4 ++++ modules/lvgl/lvgl_display.c | 26 +++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/modules/lvgl/Kconfig b/modules/lvgl/Kconfig index 4bd00b1bc5..dba26b76d8 100644 --- a/modules/lvgl/Kconfig +++ b/modules/lvgl/Kconfig @@ -52,6 +52,10 @@ config LV_Z_LOG_LEVEL default 3 if LV_LOG_LEVEL_USER default 4 if LV_LOG_LEVEL_TRACE +config LV_Z_USE_ROUNDER_CB + bool + default y if LV_Z_AREA_X_ALIGNMENT_WIDTH != 1 || LV_Z_AREA_Y_ALIGNMENT_WIDTH != 1 + config APP_LINK_WITH_LVGL bool "Link 'app' with LVGL" default y @@ -107,6 +111,22 @@ config LV_Z_FLUSH_THREAD_PRIO endif # LV_Z_FLUSH_THREAD +config LV_Z_AREA_X_ALIGNMENT_WIDTH + int "Frame X alignment size" + default 1 + help + Number of pixels, X axis should be rounded to. Should be used to override + the current frame dimensions to meet display and/or LCD host + controller requirements. The value must be power of 2. + +config LV_Z_AREA_Y_ALIGNMENT_WIDTH + int "Frame Y alignment size" + default 1 + help + Number of pixels, Y axis should be rounded to. Should be used to override + the current frame dimensions to meet display and/or LCD host + controller requirements. The value must be power of 2. + rsource "Kconfig.memory" rsource "Kconfig.input" rsource "Kconfig.shell" diff --git a/modules/lvgl/include/lvgl_display.h b/modules/lvgl/include/lvgl_display.h index b031958c73..9a0c14c683 100644 --- a/modules/lvgl/include/lvgl_display.h +++ b/modules/lvgl/include/lvgl_display.h @@ -49,6 +49,10 @@ int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv); void lvgl_flush_display(struct lvgl_display_flush *request); +#ifdef CONFIG_LV_Z_USE_ROUNDER_CB +void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area); +#endif + #ifdef __cplusplus } #endif diff --git a/modules/lvgl/lvgl_display.c b/modules/lvgl/lvgl_display.c index 8ac4fc97a6..604cd0078d 100644 --- a/modules/lvgl/lvgl_display.c +++ b/modules/lvgl/lvgl_display.c @@ -45,6 +45,26 @@ void lvgl_wait_cb(lv_disp_drv_t *disp_drv) #endif /* CONFIG_LV_Z_FLUSH_THREAD */ +#ifdef CONFIG_LV_Z_USE_ROUNDER_CB +void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) +{ +#if CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH != 1 + __ASSERT(POPCOUNT(CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH) == 1, "Invalid X alignment width"); + + area->x1 &= ~(CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH - 1); + area->x2 |= (CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH - 1); +#endif +#if CONFIG_LV_Z_AREA_Y_ALIGNMENT_WIDTH != 1 + __ASSERT(POPCOUNT(CONFIG_LV_Z_AREA_Y_ALIGNMENT_WIDTH) == 1, "Invalid Y alignment width"); + + area->y1 &= ~(CONFIG_LV_Z_AREA_Y_ALIGNMENT_WIDTH - 1); + area->y2 |= (CONFIG_LV_Z_AREA_Y_ALIGNMENT_WIDTH - 1); +#endif +} +#else +#define lvgl_rounder_cb NULL +#endif + int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv) { int err = 0; @@ -57,7 +77,7 @@ int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv) switch (data->cap.current_pixel_format) { case PIXEL_FORMAT_ARGB_8888: disp_drv->flush_cb = lvgl_flush_cb_32bit; - disp_drv->rounder_cb = NULL; + disp_drv->rounder_cb = lvgl_rounder_cb; #ifdef CONFIG_LV_COLOR_DEPTH_32 disp_drv->set_px_cb = NULL; #else @@ -66,13 +86,13 @@ int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv) break; case PIXEL_FORMAT_RGB_888: disp_drv->flush_cb = lvgl_flush_cb_24bit; - disp_drv->rounder_cb = NULL; + disp_drv->rounder_cb = lvgl_rounder_cb; disp_drv->set_px_cb = lvgl_set_px_cb_24bit; break; case PIXEL_FORMAT_RGB_565: case PIXEL_FORMAT_BGR_565: disp_drv->flush_cb = lvgl_flush_cb_16bit; - disp_drv->rounder_cb = NULL; + disp_drv->rounder_cb = lvgl_rounder_cb; #ifdef CONFIG_LV_COLOR_DEPTH_16 disp_drv->set_px_cb = NULL; #else