From eb056315c389cf5077e445ebaf0c711f3b645bef Mon Sep 17 00:00:00 2001 From: xennex22 <25083624+xennex22@users.noreply.github.com> Date: Tue, 22 Sep 2020 06:53:36 -0700 Subject: [PATCH 01/18] Changed non-debug macro expansion (#1808) --- src/lv_conf_internal.h | 2 +- src/lv_core/lv_disp.c | 1 - src/lv_core/lv_disp.h | 1 - src/lv_core/lv_obj.c | 1 - src/lv_core/lv_obj.h | 4 +-- src/lv_core/lv_style.h | 8 +++--- src/lv_draw/lv_draw_mask.c | 4 --- src/lv_misc/lv_debug.h | 18 ++++++------ src/lv_misc/lv_log.h | 55 ++++++++---------------------------- src/lv_misc/lv_math.h | 2 -- src/lv_widgets/lv_keyboard.c | 4 ++- src/lv_widgets/lv_list.c | 4 ++- src/lv_widgets/lv_page.c | 1 - src/lv_widgets/lv_roller.c | 1 - src/lv_widgets/lv_table.c | 1 - src/lv_widgets/lv_textarea.c | 1 - 16 files changed, 33 insertions(+), 75 deletions(-) diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 0bc7aacbe..ea41b0720 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -1251,7 +1251,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */ /* Support bidirectional texts. * Allows mixing Left-to-Right and Right-to-Left texts. - * The direction will be processed according to the Unicode Bidirectioanl Algorithm: + * The direction will be processed according to the Unicode Bidirectional Algorithm: * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ #ifndef LV_USE_BIDI # ifdef CONFIG_LV_USE_BIDI diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index 80326f81d..9d0158aa8 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -120,7 +120,6 @@ lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp) return disp->sys_layer; } - /** * Assign a screen to a display. * @param disp pointer to a display where to assign the screen diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index 3083c46d2..00a9de8db 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -184,7 +184,6 @@ static inline void lv_scr_load(lv_obj_t * scr) lv_disp_load_scr(scr); } - /********************** * MACROS **********************/ diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index c555b320a..827c7311d 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -360,7 +360,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #if LV_USE_GROUP new_obj->group_p = NULL; - #endif /*Set attributes*/ diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 3b97675ac..bcd923650 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -1527,11 +1527,11 @@ bool lv_debug_check_obj_valid(const lv_obj_t * obj); # if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/ # define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p) # else -# define LV_ASSERT_OBJ(obj_p, obj_type) true +# define LV_ASSERT_OBJ(obj_p, obj_type) # endif # endif #else -# define LV_ASSERT_OBJ(obj, obj_type) true +# define LV_ASSERT_OBJ(obj, obj_type) #endif diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 8d9d15d8e..4e1f74d97 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -618,13 +618,13 @@ bool lv_debug_check_style_list(const lv_style_list_t * list); # define LV_ASSERT_STYLE_LIST(list_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE_LIST(list_p), "Invalid style list", list_p); # endif # else -# define LV_ASSERT_STYLE(style_p) true -# define LV_ASSERT_STYLE_LIST(list_p) true +# define LV_ASSERT_STYLE(style_p) +# define LV_ASSERT_STYLE_LIST(list_p) # endif #else -# define LV_ASSERT_STYLE(p) true -# define LV_ASSERT_STYLE_LIST(p) true +# define LV_ASSERT_STYLE(p) +# define LV_ASSERT_STYLE_LIST(p) #endif #ifdef __cplusplus diff --git a/src/lv_draw/lv_draw_mask.c b/src/lv_draw/lv_draw_mask.c index dcd1d4a9f..f7b8bc1ff 100644 --- a/src/lv_draw/lv_draw_mask.c +++ b/src/lv_draw/lv_draw_mask.c @@ -1,7 +1,3 @@ - - - - /** * @file lv_mask.c * diff --git a/src/lv_misc/lv_debug.h b/src/lv_misc/lv_debug.h index 2fa0fb95a..9160ceee8 100644 --- a/src/lv_misc/lv_debug.h +++ b/src/lv_misc/lv_debug.h @@ -81,7 +81,7 @@ void lv_debug_log_error(const char * msg, uint64_t value); # define LV_ASSERT_NULL(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "NULL pointer", p); # endif #else -# define LV_ASSERT_NULL(p) true +# define LV_ASSERT_NULL(p) #endif #if LV_USE_ASSERT_MEM @@ -89,7 +89,7 @@ void lv_debug_log_error(const char * msg, uint64_t value); # define LV_ASSERT_MEM(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "Out of memory", p); # endif #else -# define LV_ASSERT_MEM(p) true +# define LV_ASSERT_MEM(p) #endif #if LV_USE_ASSERT_MEM_INTEGRITY @@ -97,7 +97,7 @@ void lv_debug_log_error(const char * msg, uint64_t value); # define LV_ASSERT_MEM_INTEGRITY() LV_DEBUG_ASSERT(LV_DEBUG_CHECK_MEM_INTEGRITY(), "Memory integrity error", 0); # endif #else -# define LV_ASSERT_MEM_INTEGRITY() true +# define LV_ASSERT_MEM_INTEGRITY() #endif #if LV_USE_ASSERT_STR @@ -108,7 +108,7 @@ void lv_debug_log_error(const char * msg, uint64_t value); # if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/ # define LV_ASSERT_STR(str) LV_ASSERT_NULL(str) # else -# define LV_ASSERT_STR(str) true +# define LV_ASSERT_STR(str) # endif #endif @@ -117,11 +117,11 @@ void lv_debug_log_error(const char * msg, uint64_t value); #define LV_DEBUG_ASSERT(expr, msg, value) do{}while(0) -#define LV_ASSERT_NULL(p) true -#define LV_ASSERT_MEM(p) true -#define LV_ASSERT_MEM_INTEGRITY() true -#define LV_ASSERT_STR(p) true -#define LV_ASSERT_OBJ(obj, obj_type) true +#define LV_ASSERT_NULL(p) +#define LV_ASSERT_MEM(p) +#define LV_ASSERT_MEM_INTEGRITY() +#define LV_ASSERT_STR(p) +#define LV_ASSERT_OBJ(obj, obj_type) #endif /* LV_USE_DEBUG */ /*clang-format on*/ diff --git a/src/lv_misc/lv_log.h b/src/lv_misc/lv_log.h index 7e07712eb..a85427e78 100644 --- a/src/lv_misc/lv_log.h +++ b/src/lv_misc/lv_log.h @@ -79,75 +79,42 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * #if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE #define LV_LOG_TRACE(...) _lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, __func__, __VA_ARGS__); #else -#define LV_LOG_TRACE(...) \ - { \ - ; \ - } +#define LV_LOG_TRACE(...) #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO #define LV_LOG_INFO(...) _lv_log_add(LV_LOG_LEVEL_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__); #else -#define LV_LOG_INFO(...) \ - { \ - ; \ - } +#define LV_LOG_INFO(...) #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_WARN #define LV_LOG_WARN(...) _lv_log_add(LV_LOG_LEVEL_WARN, __FILE__, __LINE__, __func__, __VA_ARGS__); #else -#define LV_LOG_WARN(...) \ - { \ - ; \ - } +#define LV_LOG_WARN(...) #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_ERROR #define LV_LOG_ERROR(...) _lv_log_add(LV_LOG_LEVEL_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__); #else -#define LV_LOG_ERROR(...) \ - { \ - ; \ - } +#define LV_LOG_ERROR(...) #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_USER #define LV_LOG_USER(...) _lv_log_add(LV_LOG_LEVEL_USER, __FILE__, __LINE__, __func__, __VA_ARGS__); #else -#define LV_LOG_USER(...) \ - { \ - ; \ - } +#define LV_LOG_USER(...) #endif #else /*LV_USE_LOG*/ /*Do nothing if `LV_USE_LOG 0`*/ -#define _lv_log_add(level, file, line, ...) \ - { \ - ; \ - } -#define LV_LOG_TRACE(...) \ - { \ - ; \ - } -#define LV_LOG_INFO(...) \ - { \ - ; \ - } -#define LV_LOG_WARN(...) \ - { \ - ; \ - } -#define LV_LOG_ERROR(...) \ - { \ - ; \ - } -#define LV_LOG_USER(...) \ - { \ - ; \ - } +#define _lv_log_add(level, file, line, ...) +#define LV_LOG_TRACE(...) +#define LV_LOG_INFO(...) +#define LV_LOG_WARN(...) +#define LV_LOG_ERROR(...) +#define LV_LOG_USER(...) #endif /*LV_USE_LOG*/ #ifdef __cplusplus diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index d4d626ef9..3c5600d2b 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -42,8 +42,6 @@ extern "C" { #define LV_BEZIER_VAL_MAX 1024 /**< Max time in Bezier functions (not [0..1] to use integers) */ #define LV_BEZIER_VAL_SHIFT 10 /**< log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/ - - /********************** * TYPEDEFS **********************/ diff --git a/src/lv_widgets/lv_keyboard.c b/src/lv_widgets/lv_keyboard.c index 9138b171e..ae40b4deb 100644 --- a/src/lv_widgets/lv_keyboard.c +++ b/src/lv_widgets/lv_keyboard.c @@ -189,7 +189,9 @@ lv_obj_t * lv_keyboard_create(lv_obj_t * par, const lv_obj_t * copy) void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta) { LV_ASSERT_OBJ(kb, LV_OBJX_NAME); - if(ta) LV_ASSERT_OBJ(ta, "lv_textarea"); + if(ta) { + LV_ASSERT_OBJ(ta, "lv_textarea"); + } lv_keyboard_ext_t * ext = lv_obj_get_ext_attr(kb); diff --git a/src/lv_widgets/lv_list.c b/src/lv_widgets/lv_list.c index e67135ba9..8ccdb0b33 100644 --- a/src/lv_widgets/lv_list.c +++ b/src/lv_widgets/lv_list.c @@ -276,7 +276,9 @@ bool lv_list_remove(const lv_obj_t * list, uint16_t index) void lv_list_focus_btn(lv_obj_t * list, lv_obj_t * btn) { LV_ASSERT_OBJ(list, LV_OBJX_NAME); - if(btn) LV_ASSERT_OBJ(btn, "lv_btn"); + if(btn) { + LV_ASSERT_OBJ(btn, "lv_btn"); + } lv_list_ext_t * ext = lv_obj_get_ext_attr(list); diff --git a/src/lv_widgets/lv_page.c b/src/lv_widgets/lv_page.c index 03c15bcc3..2400dccd3 100644 --- a/src/lv_widgets/lv_page.c +++ b/src/lv_widgets/lv_page.c @@ -132,7 +132,6 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_signal_cb(page, lv_page_signal); lv_obj_set_design_cb(page, lv_page_design); - lv_page_set_scrollbar_mode(page, ext->scrlbar.mode); lv_theme_apply(page, LV_THEME_PAGE); diff --git a/src/lv_widgets/lv_roller.c b/src/lv_widgets/lv_roller.c index b412470b4..0e8b12ceb 100644 --- a/src/lv_widgets/lv_roller.c +++ b/src/lv_widgets/lv_roller.c @@ -1,4 +1,3 @@ - /** * @file lv_roller.c * diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index b71135176..bcaf7565b 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -974,7 +974,6 @@ static lv_style_list_t * lv_table_get_style(lv_obj_t * table, uint8_t part) static void refr_size(lv_obj_t * table) { - lv_coord_t h = 0; lv_coord_t w = 0; diff --git a/src/lv_widgets/lv_textarea.c b/src/lv_widgets/lv_textarea.c index 2b1489462..2233ce281 100644 --- a/src/lv_widgets/lv_textarea.c +++ b/src/lv_widgets/lv_textarea.c @@ -260,7 +260,6 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c) return; } - /*If a new line was added it shouldn't show edge flash effect*/ bool edge_flash_en = lv_textarea_get_edge_flash(ta); lv_textarea_set_edge_flash(ta, false); From 1508320aa8410c0c0b2c647a249dfb8a6ab62810 Mon Sep 17 00:00:00 2001 From: jozba <64474383+jozba@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:57:38 +0200 Subject: [PATCH 02/18] PXP support for NXP RTxxx MCUs (#1702) * PXP: Added basic PXP acceleration PXP accelerated features: - fill (+ opacity) - BLIT (+ opacity) - recoloring (+ opacity) - color keying (+ opacity) Recoloring + color keying simultaneously not supported. Signed-off-by: Jozef Bastek * PXP: Added abstraction for interrupt handling Previous imlpementation used IRQ polling on PXP, which doesn't allow real CPU offload. Therefore added set of callbacks for interrupt handling that should be implemented by user, with possible RTOS integration. Default/example implementation of callbacks for bare metal and FreeRTOS provided (lv_gpu_nxp_pxp_osa.c), enabled by LV_USE_GPU_NXP_PXP_DEFAULT_OSA switch, accesible via pxp_default_cfg structure. Signed-off-by: Jozef Bastek * PXP: Optimized cache flushing Previous implementation flushed areas of (LCD width * object height) size. Cache flush is expensive operation and flushing line by line, smallest possible area, boost performance by shortening time spent on cache flushes. Signed-off-by: Jozef Bastek * PXP: Added documentation for NXP PXP accelerator Signed-off-by: Jozef Bastek * PXP: added missing extern c in header files Signed-off-by: Jozef Bastek * PXP: Fixed ifdefs - Removed LV_USE_GPU, fixed internal config LV_USE_GPU is not intended as a global GPU enable switch. It's used only for gpu_blend_cb and gpu_fill_cb callbacks, which are obsolete. This patch removes LV_USE_GPU dependency for PXP code, so it's enabled only with LV_USE_GPU_NXP_PXP symbol. Added missing symbols to internal conf, so automatic testd can pass build step. Signed-off-by: Jozef Bastek * PXP: Default OSA changed to PXP auto-initialization Auto init feature added so if user run FreeRTOS or bare-metal, no PXP Init code is required. Renamed symbol to be more clear. Signed-off-by: Jozef Bastek * PXP: Documentation moved to docs repo Signed-off-by: Jozef Bastek * PXP: Fixed alpha configuration - Coverity issue: AS blend config used uninitialized structure. No impact on functionality, as blend module is not used (porter-duff blends in this case) - Alpha config fixed - swapped alpha values produced different result from SW render Signed-off-by: Jozef Bastek --- lv_conf_template.h | 11 + src/lv_conf_internal.h | 14 + src/lv_core/lv_obj.c | 12 + src/lv_draw/lv_draw_blend.c | 44 ++- src/lv_draw/lv_draw_img.c | 21 +- src/lv_gpu/lv_gpu_nxp_pxp.c | 474 ++++++++++++++++++++++++++++++++ src/lv_gpu/lv_gpu_nxp_pxp.h | 184 +++++++++++++ src/lv_gpu/lv_gpu_nxp_pxp_osa.c | 166 +++++++++++ src/lv_gpu/lv_gpu_nxp_pxp_osa.h | 47 ++++ 9 files changed, 962 insertions(+), 11 deletions(-) create mode 100644 src/lv_gpu/lv_gpu_nxp_pxp.c create mode 100644 src/lv_gpu/lv_gpu_nxp_pxp.h create mode 100644 src/lv_gpu/lv_gpu_nxp_pxp_osa.c create mode 100644 src/lv_gpu/lv_gpu_nxp_pxp_osa.h diff --git a/lv_conf_template.h b/lv_conf_template.h index 708faecb3..8c9606814 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -195,6 +195,17 @@ typedef void * lv_group_user_data_t; e.g. "stm32f769xx.h" or "stm32f429xx.h" */ #define LV_GPU_DMA2D_CMSIS_INCLUDE +/*1: Use PXP for CPU off-load on NXP RTxxx platforms */ +#define LV_USE_GPU_NXP_PXP 0 + +/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) + * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS + * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. + *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() + * */ +#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 + + /* 1: Enable file system (might be required for images */ #define LV_USE_FILESYSTEM 1 #if LV_USE_FILESYSTEM diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index ea41b0720..ef6fc6cc0 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -476,6 +476,20 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */ # endif #endif +/*1: Use PXP for CPU off-load on NXP RTxxx platforms */ +#ifndef LV_USE_GPU_NXP_PXP +#define LV_USE_GPU_NXP_PXP 0 +#endif + +/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) + * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS + * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. + *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() + * */ +#ifndef LV_USE_GPU_NXP_PXP_AUTO_INIT +#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 +#endif + /* 1: Enable file system (might be required for images */ #ifndef LV_USE_FILESYSTEM # ifdef CONFIG_LV_USE_FILESYSTEM diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index b02333cfc..b59265ab9 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -27,6 +27,11 @@ #include #include +#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT + #include "lv_gpu/lv_gpu_nxp_pxp.h" + #include "lv_gpu/lv_gpu_nxp_pxp_osa.h" +#endif + #if defined(LV_GC_INCLUDE) #include LV_GC_INCLUDE #endif /* LV_ENABLE_GC */ @@ -194,6 +199,13 @@ void lv_init(void) lv_gpu_stm32_dma2d_init(); #endif +#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT + if (lv_gpu_nxp_pxp_init(&pxp_default_cfg) != LV_RES_OK) { + LV_LOG_ERROR("PXP init error. STOP.\n"); + for ( ; ; ) ; + } +#endif + _lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(lv_style_trans_t)); _lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t)); diff --git a/src/lv_draw/lv_draw_blend.c b/src/lv_draw/lv_draw_blend.c index 109246556..618431a3d 100644 --- a/src/lv_draw/lv_draw_blend.c +++ b/src/lv_draw/lv_draw_blend.c @@ -12,13 +12,18 @@ #include "../lv_hal/lv_hal_disp.h" #include "../lv_core/lv_refr.h" +#if LV_USE_GPU_NXP_PXP +#include "../lv_gpu/lv_gpu_nxp_pxp.h" +#elif LV_USE_GPU_STM32_DMA2D #include "../lv_gpu/lv_gpu_stm32_dma2d.h" +#endif /********************* * DEFINES *********************/ #define GPU_SIZE_LIMIT 240 + /********************** * TYPEDEFS **********************/ @@ -335,9 +340,12 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co disp->driver.gpu_fill_cb(&disp->driver, disp_buf, disp_w, draw_area, color); return; } -#endif - -#if LV_USE_GPU_STM32_DMA2D +#elif LV_USE_GPU_NXP_PXP + if(lv_area_get_size(draw_area) >= GPU_NXP_PXP_FILL_SIZE_LIMIT) { + lv_gpu_nxp_pxp_fill(disp_buf, disp_w, draw_area, color, opa); + return; + } +#elif LV_USE_GPU_STM32_DMA2D if(lv_area_get_size(draw_area) >= 240) { lv_gpu_stm32_dma2d_fill(disp_buf_first, disp_w, color, draw_area_w, draw_area_h); return; @@ -351,7 +359,13 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co } /*No mask with opacity*/ else { -#if LV_USE_GPU + +#if LV_USE_GPU_NXP_PXP + if(lv_area_get_size(draw_area) >= GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT) { + lv_gpu_nxp_pxp_fill(disp_buf, disp_w, draw_area, color, opa); + return; + } +#elif LV_USE_GPU if(disp->driver.gpu_blend_cb && lv_area_get_size(draw_area) > GPU_SIZE_LIMIT) { for(x = 0; x < draw_area_w ; x++) blend_buf[x].full = color.full; @@ -726,11 +740,16 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col #endif if(opa > LV_OPA_MAX) { -#if LV_USE_GPU_STM32_DMA2D - if(lv_area_get_size(draw_area) >= 240) { - lv_gpu_stm32_dma2d_copy(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h); - return; - } +#if LV_USE_GPU_NXP_PXP + if (lv_area_get_size(draw_area) >= GPU_NXP_PXP_BLIT_SIZE_LIMIT) { + lv_gpu_nxp_pxp_blit(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h, opa); + return; + } +#elif LV_USE_GPU_STM32_DMA2D + if(lv_area_get_size(draw_area) >= 240) { + lv_gpu_stm32_dma2d_copy(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h); + return; + } #endif /*Software rendering*/ @@ -741,7 +760,12 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col } } else { -#if LV_USE_GPU_STM32_DMA2D +#if LV_USE_GPU_NXP_PXP + if (lv_area_get_size(draw_area) >= GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT) { + lv_gpu_nxp_pxp_blit(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h, opa); + return; + } +#elif LV_USE_GPU_STM32_DMA2D if(lv_area_get_size(draw_area) >= 240) { lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, map_buf_first, opa, map_w, draw_area_w, draw_area_h); return; diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 47615724a..421cab9b8 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -13,8 +13,11 @@ #include "../lv_core/lv_refr.h" #include "../lv_misc/lv_mem.h" #include "../lv_misc/lv_math.h" +#if LV_USE_GPU_STM32_DMA2D #include "../lv_gpu/lv_gpu_stm32_dma2d.h" - +#elif LV_USE_GPU_NXP_PXP +#include "../lv_gpu/lv_gpu_nxp_pxp.h" +#endif /********************* * DEFINES @@ -355,6 +358,22 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const _lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa, draw_dsc->blend_mode); } +#if LV_USE_GPU_NXP_PXP + /* Simple case without masking and transformations */ + else if (other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false && + chroma_key == true && draw_dsc->recolor_opa == LV_OPA_TRANSP) { /* copy with color keying (+ alpha) */ + lv_gpu_nxp_pxp_enable_color_key(); + _lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa, + draw_dsc->blend_mode); + lv_gpu_nxp_pxp_disable_color_key(); + } else if (other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false && + chroma_key == false && draw_dsc->recolor_opa != LV_OPA_TRANSP) { /* copy with recolor (+ alpha) */ + lv_gpu_nxp_pxp_enable_recolor(draw_dsc->recolor, draw_dsc->recolor_opa); + _lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa, + draw_dsc->blend_mode); + lv_gpu_nxp_pxp_disable_recolor(); + } +#endif /*In the other cases every pixel need to be checked one-by-one*/ else { /*The pixel size in byte is different if an alpha byte is added too*/ diff --git a/src/lv_gpu/lv_gpu_nxp_pxp.c b/src/lv_gpu/lv_gpu_nxp_pxp.c new file mode 100644 index 000000000..7efa6341f --- /dev/null +++ b/src/lv_gpu/lv_gpu_nxp_pxp.c @@ -0,0 +1,474 @@ +/** + * @file lv_gpu_nxp_pxp.c + * + */ + +/** + * MIT License + * + * Copyright (c) 2020 NXP + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next paragraph) + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +/********************* + * INCLUDES + *********************/ + +#include "lv_conf.h" + +#if LV_USE_GPU_NXP_PXP + +#include "lvgl.h" +#include "lv_gpu_nxp_pxp.h" +#include "../lv_misc/lv_mem.h" +#include "../lv_misc/lv_log.h" + +#include "fsl_pxp.h" +#include "fsl_cache.h" + +/********************* + * DEFINES + *********************/ + +/* PXP instance ID */ +#define PXP_ID PXP + +#if LV_COLOR_16_SWAP + #error Color swap not implemented. Disable LV_COLOR_16_SWAP feature. +#endif + +#if LV_COLOR_DEPTH==16 + #define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatRGB565 + #define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatRGB565 + #define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB565 +#elif + #error Only 16bit color depth is supported. Set LV_COLOR_DEPTH to 16. +#endif + + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_gpu_nxp_pxp_run(void); +static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src, + lv_coord_t src_width, + lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa, lv_color_t recolor, lv_opa_t recolorOpa); +static void lv_gpu_nxp_invalidate_cache(uint32_t address, uint32_t width, uint32_t height, uint32_t stride, uint32_t pxSize); + +/********************** + * STATIC VARIABLES + **********************/ + +static bool colorKeyEnabled = false; +static uint32_t colorKey = 0x0; + +static bool recolorEnabled = false; +static lv_color_t recolor = {.full = 0x0}; +static lv_opa_t recolorOpa = 0x0; + +static lv_nxp_pxp_cfg_t pxp_cfg; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Reset and initialize PXP device. This function should be called as a part + * of display init sequence. + * + * @return LV_RES_OK: PXP init ok; LV_RES_INV: init error. See error log for more information. + */ +lv_res_t lv_gpu_nxp_pxp_init(lv_nxp_pxp_cfg_t * cfg) +{ + if(!cfg || !cfg->pxp_interrupt_deinit || !cfg->pxp_interrupt_init || !cfg->pxp_run) { + LV_LOG_ERROR("PXP configuration error. Check callback pointers."); + return LV_RES_INV; + } + + PXP_Init(PXP); + PXP_EnableCsc1(PXP, false); /* Disable CSC1, it is enabled by default. */ + PXP_EnableInterrupts(PXP, kPXP_CompleteInterruptEnable); + + pxp_cfg = *cfg; + if(pxp_cfg.pxp_interrupt_init() != LV_RES_OK) { + PXP_Deinit(PXP); + LV_LOG_ERROR("PXP interrupt init error. Check pxp_interrupt_init callback."); + return LV_RES_INV; + } + + colorKey = lv_color_to32(LV_COLOR_TRANSP); + + return LV_RES_OK; +} + +/** + * Disable PXP device. Should be called during display deinit sequence. + */ +void lv_gpu_nxp_pxp_deinit(void) +{ + pxp_cfg.pxp_interrupt_deinit(); + PXP_DisableInterrupts(PXP, kPXP_CompleteInterruptEnable); + PXP_Deinit(PXP_ID); +} + + +/** + * Fill area, with optional opacity. + * + * @param[in/out] dest_buf destination buffer + * @param[in] dest_width width (stride) of destination buffer in pixels + * @param[in] fill_area area to fill + * @param[in] color color + * @param[in] opa transparency of the color + */ +void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_width, const lv_area_t * fill_area, lv_color_t color, + lv_opa_t opa) +{ + PXP_Init(PXP_ID); + PXP_EnableCsc1(PXP_ID, false); /* Disable CSC1, it is enabled by default. */ + PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16); /* Block size 16x16 for higher performance */ + + /* OUT buffer configure */ + pxp_output_buffer_config_t outputConfig = { + .pixelFormat = PXP_OUT_PIXEL_FORMAT, + .interlacedMode = kPXP_OutputProgressive, + .buffer0Addr = (uint32_t)(dest_buf + dest_width * fill_area->y1 + fill_area->x1), + .buffer1Addr = (uint32_t)NULL, + .pitchBytes = dest_width * sizeof(lv_color_t), + .width = fill_area->x2 - fill_area->x1 + 1, + .height = fill_area->y2 - fill_area->y1 + 1, + }; + lv_gpu_nxp_invalidate_cache(outputConfig.buffer0Addr, outputConfig.width, outputConfig.height, outputConfig.pitchBytes, sizeof(lv_color_t)); + PXP_SetOutputBufferConfig(PXP_ID, &outputConfig); + + if(opa > LV_OPA_MAX) { + /* Simple color fill without opacity - AS disabled, PS as color generator */ + PXP_SetAlphaSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); /* Disable AS. */ + PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); /* Disable PS. */ + PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to32(color)); + } + else { + /* Fill with opacity - AS used as source (same as OUT), PS used as color generator, blended together */ + pxp_as_buffer_config_t asBufferConfig; + pxp_porter_duff_config_t pdConfig; + + /* Set AS to OUT */ + asBufferConfig.pixelFormat = PXP_AS_PIXEL_FORMAT; + asBufferConfig.bufferAddr = (uint32_t)outputConfig.buffer0Addr; + asBufferConfig.pitchBytes = outputConfig.pitchBytes; + + PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig); + PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, fill_area->x2 - fill_area->x1 + 1, fill_area->y2 - fill_area->y1 + 1); + + /* Disable PS, use as color generator */ + PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); + PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to32(color)); + + /* Configure Porter-Duff blending - For RGB 565 only! */ + pdConfig.enable = 1; + pdConfig.dstColorMode = kPXP_PorterDuffColorStraight; + pdConfig.srcColorMode = kPXP_PorterDuffColorStraight; + pdConfig.dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha; + pdConfig.srcGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha; + pdConfig.srcFactorMode = kPXP_PorterDuffFactorStraight; + pdConfig.dstFactorMode = kPXP_PorterDuffFactorStraight; + pdConfig.srcGlobalAlpha = opa; + pdConfig.dstGlobalAlpha = 255 - opa; + pdConfig.srcAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */ + pdConfig.dstAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */ + PXP_SetPorterDuffConfig(PXP_ID, &pdConfig); + } + + lv_gpu_nxp_pxp_run(); /* Start PXP task */ +} + +/** + * @brief BLock Image Transfer - copy rectangular image from src buffer to dst buffer with effects. + * + * By default, image is copied directly, with optional opacity configured by \p opa. + * Color keying can be enabled by calling lv_gpu_nxp_pxp_enable_color_key() before calling this function. + * Recoloring can be enabled by calling lv_gpu_nxp_pxp_enable_recolor() before calling this function. + * Note that color keying and recoloring at the same time is not supported and black rectangle is rendered. + * + * @param[in/out] dest destination buffer + * @param[in] dest_width width (stride) of destination buffer in pixels + * @param[in] src source buffer + * @param[in] src_with width (stride) of source buffer in pixels + * @param[in] copy_w width of area to be copied from src to dest + * @param[in] copy_h height of area to be copied from src to dest + * @param[in] opa opacity of the result + */ +void lv_gpu_nxp_pxp_blit(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src, lv_coord_t src_width, + lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa) +{ + + if(recolorEnabled) { /* switch to recolor version of blit */ + lv_gpu_nxp_pxp_blit_recolor(dest, dest_width, src, src_width, copy_width, copy_height, opa, recolor, recolorOpa); + return; + }; + + PXP_Init(PXP); + PXP_EnableCsc1(PXP, false); /* Disable CSC1, it is enabled by default. */ + PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16); /* block size 16x16 for higher performance */ + + pxp_output_buffer_config_t outputBufferConfig; + pxp_as_buffer_config_t asBufferConfig; + pxp_as_blend_config_t asBlendConfig; + + asBlendConfig.alpha = opa; + asBlendConfig.invertAlpha = false; + asBlendConfig.alphaMode = kPXP_AlphaRop; + asBlendConfig.ropMode = kPXP_RopMergeAs; + + if(opa >= LV_OPA_MAX && !colorKeyEnabled) { + /* Simple blit, no effect - Disable PS buffer */ + PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); + } + else { + /* Alpha blending or color keying enabled - PS must be enabled to fetch background pixels + PS and OUT buffers are the same, blend will be done in-place */ + pxp_ps_buffer_config_t psBufferConfig = { + .pixelFormat = PXP_PS_PIXEL_FORMAT, + .swapByte = false, + .bufferAddr = (uint32_t)dest, + .bufferAddrU = 0U, + .bufferAddrV = 0U, + .pitchBytes = dest_width * sizeof(lv_color_t) + }; + asBlendConfig.alphaMode = kPXP_AlphaOverride; + PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig); + PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, copy_width - 1, copy_height - 1); + } + + /* AS buffer - source image */ + asBufferConfig.pixelFormat = PXP_AS_PIXEL_FORMAT; + asBufferConfig.bufferAddr = (uint32_t)src; + asBufferConfig.pitchBytes = src_width * sizeof(lv_color_t); + PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig); + PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, copy_width - 1U, copy_height - 1U); + PXP_SetAlphaSurfaceBlendConfig(PXP_ID, &asBlendConfig); + + lv_gpu_nxp_invalidate_cache(asBufferConfig.bufferAddr, copy_width, copy_height, asBufferConfig.pitchBytes, sizeof(lv_color_t)); + + if(colorKeyEnabled) { + PXP_SetAlphaSurfaceOverlayColorKey(PXP_ID, colorKey, colorKey); + } + PXP_EnableAlphaSurfaceOverlayColorKey(PXP_ID, colorKeyEnabled); + + + /* Output buffer. */ + outputBufferConfig.pixelFormat = (pxp_output_pixel_format_t)PXP_OUT_PIXEL_FORMAT; + outputBufferConfig.interlacedMode = kPXP_OutputProgressive; + outputBufferConfig.buffer0Addr = (uint32_t)dest; + outputBufferConfig.buffer1Addr = (uint32_t)0U; + outputBufferConfig.pitchBytes = dest_width * sizeof(lv_color_t); + outputBufferConfig.width = copy_width; + outputBufferConfig.height = copy_height; + PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig); + + lv_gpu_nxp_invalidate_cache(outputBufferConfig.buffer0Addr, outputBufferConfig.width, outputBufferConfig.height, outputBufferConfig.pitchBytes, sizeof(lv_color_t)); + + lv_gpu_nxp_pxp_run(); /* Start PXP task */ +} + +/** + * @brief Enable color keying for subsequent calls to lv_gpu_nxp_pxp_blit() + * + * Color key is defined by LV_COLOR_TRANSP symbol in lv_conf.h + */ +void lv_gpu_nxp_pxp_enable_color_key(void) +{ + colorKeyEnabled = true; +} + +/** + * @brief Disable color keying for subsequent calls to lv_gpu_nxp_pxp_blit() + * + */ +void lv_gpu_nxp_pxp_disable_color_key(void) +{ + colorKeyEnabled = false; +} + +/** + * @brief Enable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit() + * + * @param[in] color recolor value + * @param[in] opa effect opacity + */ +void lv_gpu_nxp_pxp_enable_recolor(lv_color_t color, lv_opa_t opa) +{ + recolorEnabled = true; + recolor = color; + recolorOpa = opa; + +} + +/** + * @brief Disable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit() + */ +void lv_gpu_nxp_pxp_disable_recolor(void) +{ + recolorEnabled = false; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * @brief Start PXP job and wait for results + * + * Function used internally to start PXP task according current device + * configuration. + */ +static void lv_gpu_nxp_pxp_run(void) +{ + pxp_cfg.pxp_run(); +} + +/** + * @brief BLock Image Transfer - copy rectangular image from src buffer to dst buffer with recoloring. + * + * Note that color keying and recoloring at the same time is not supported and black rectangle is rendered. + * + * @param[in/out] dest destination buffer + * @param[in] dest_width width (stride) of destination buffer in pixels + * @param[in] src source buffer + * @param[in] src_with width (stride) of source buffer in pixels + * @param[in] copy_w width of area to be copied from src to dest + * @param[in] copy_h height of area to be copied from src to dest + * @param[in] opa opacity of the result + * @param[in] recolor recolor value + * @param[in] recolorOpa effect opacity + */ +static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src, + lv_coord_t src_width, + lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa, lv_color_t recolor, lv_opa_t recolorOpa) +{ + pxp_output_buffer_config_t outputBufferConfig; + pxp_as_buffer_config_t asBufferConfig; + + if(colorKeyEnabled) { + /* should never get here, recolor & color keying not supported. Draw black box instead. */ + const lv_area_t fill_area = {.x1 = 0, .y1 = 0, .x2 = copy_width - 1, .y2 = copy_height - 1}; + lv_gpu_nxp_pxp_fill(dest, dest_width, &fill_area, LV_COLOR_BLACK, LV_OPA_MAX); + LV_LOG_WARN("Recoloring and color keying is not supported. Black rectangle rendered."); + return ; + } + else { + /* Recoloring without color keying */ + if(opa > LV_OPA_MAX) { + /* Recolor with full opacity - AS source image, PS color generator, OUT destination */ + PXP_Init(PXP); + PXP_EnableCsc1(PXP, false); /* Disable CSC1, it is enabled by default. */ + PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16); /* block size 16x16 for higher performance */ + + /* AS buffer - source image */ + asBufferConfig.pixelFormat = PXP_AS_PIXEL_FORMAT; + asBufferConfig.bufferAddr = (uint32_t)src; + asBufferConfig.pitchBytes = src_width * sizeof(lv_color_t); + PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig); + PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, copy_width - 1U, copy_height - 1U); + + lv_gpu_nxp_invalidate_cache(asBufferConfig.bufferAddr, copy_width, copy_height, asBufferConfig.pitchBytes, sizeof(lv_color_t)); + + /* Disable PS buffer, use as color generator */ + PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); + PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to32(recolor)); + + /* Output buffer */ + outputBufferConfig.pixelFormat = (pxp_output_pixel_format_t)PXP_OUT_PIXEL_FORMAT; + outputBufferConfig.interlacedMode = kPXP_OutputProgressive; + outputBufferConfig.buffer0Addr = (uint32_t)dest; + outputBufferConfig.buffer1Addr = (uint32_t)0U; + outputBufferConfig.pitchBytes = dest_width * sizeof(lv_color_t); + outputBufferConfig.width = copy_width; + outputBufferConfig.height = copy_height; + PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig); + + lv_gpu_nxp_invalidate_cache(outputBufferConfig.buffer0Addr, outputBufferConfig.width, outputBufferConfig.height, outputBufferConfig.pitchBytes, sizeof(lv_color_t)); + + pxp_porter_duff_config_t pdConfig; + + /* Configure Porter-Duff blending - For RGB 565 only! */ + pdConfig.enable = 1; + pdConfig.dstColorMode = kPXP_PorterDuffColorStraight; + pdConfig.srcColorMode = kPXP_PorterDuffColorStraight; + pdConfig.dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha; + pdConfig.srcGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha; + pdConfig.srcFactorMode = kPXP_PorterDuffFactorStraight; + pdConfig.dstFactorMode = kPXP_PorterDuffFactorStraight; + pdConfig.srcGlobalAlpha = recolorOpa; + pdConfig.dstGlobalAlpha = 255 - recolorOpa; + pdConfig.srcAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */ + pdConfig.dstAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */ + PXP_SetPorterDuffConfig(PXP_ID, &pdConfig); + + lv_gpu_nxp_pxp_run(); /* Start PXP task */ + + } + else { + /* Recolor with transparency */ + + /* Step 1: Recolor with full opacity to temporary buffer */ + lv_color_t * tmpBuf = (lv_color_t *) _lv_mem_buf_get(copy_width * copy_height * sizeof(lv_color_t)); + lv_gpu_nxp_pxp_blit_recolor(tmpBuf, copy_width, src, src_width, copy_width, copy_height, LV_OPA_COVER, recolor, + recolorOpa); + + /* Step 2: BLIT temporary results with required opacity to output */ + lv_gpu_nxp_pxp_disable_recolor(); /* make sure to take BLIT path, not the recolor */ + lv_gpu_nxp_pxp_blit(dest, dest_width, tmpBuf, copy_width, copy_width, copy_height, opa); + lv_gpu_nxp_pxp_enable_recolor(recolor, recolorOpa); /* restore state */ + + /* Step 3: Clean-up memory */ + _lv_mem_buf_release(tmpBuf); + } + } +} + +/** + * @brief Invalidate cache for rectangular area of memory + * + * @param[in] address starting address of area + * @param[in] width width of area in pixels + * @param[in] height height of area in pixels + * @param[in] stride stride in bytes + * @param[in] pxSize pixel size in bytes + */ +static void lv_gpu_nxp_invalidate_cache(uint32_t address, uint32_t width, uint32_t height, uint32_t stride, uint32_t pxSize) { + int y; + + for (y = 0; y < height; y++) { + DCACHE_CleanInvalidateByRange(address, width*pxSize); + address += stride; + } +} +#endif /* LV_USE_GPU && LV_USE_GPU_NXP_PXP */ diff --git a/src/lv_gpu/lv_gpu_nxp_pxp.h b/src/lv_gpu/lv_gpu_nxp_pxp.h new file mode 100644 index 000000000..10207dd30 --- /dev/null +++ b/src/lv_gpu/lv_gpu_nxp_pxp.h @@ -0,0 +1,184 @@ +/** + * @file lv_gpu_nxp_pxp.h + * + */ + +/** + * MIT License + * + * Copyright (c) 2020 NXP + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next paragraph) + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LV_SRC_LV_GPU_LV_GPU_NXP_PXP_H_ +#define LV_SRC_LV_GPU_LV_GPU_NXP_PXP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_misc/lv_area.h" +#include "../lv_misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +/* PXP module instance to use */ +#define PXP_ID PXP + +/* PXP interrupt line ID */ +#define PXP_IRQ_ID PXP_IRQn + +/* Minimum area for image copy with 100% opacity to be handled by PXP */ +#ifndef GPU_NXP_PXP_BLIT_SIZE_LIMIT +#define GPU_NXP_PXP_BLIT_SIZE_LIMIT 1 +#endif + +/* Minimum area for image copy with transparency to be handled by PXP */ +#ifndef GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT +#define GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT 16 +#endif + +/* Minimum area to be filled by PXP with 100% opacity */ +#ifndef GPU_NXP_PXP_FILL_SIZE_LIMIT +#define GPU_NXP_PXP_FILL_SIZE_LIMIT 64 +#endif + +/* Minimum area to be filled by PXP with transparency */ +#ifndef GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT +#define GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT 32 +#endif + +/********************** + * TYPEDEFS + **********************/ +/** + * NXP PXP device configuration - call-backs used for + * interrupt init/wait/deinit. + */ +typedef struct { + /** Callback for PXP interrupt initialization */ + lv_res_t (*pxp_interrupt_init)(void); + + /** Callback for PXP interrupt de-initialization */ + void (*pxp_interrupt_deinit)(void); + + /** Callback that should start PXP and wait for operation complete */ + void (*pxp_run)(void); +} lv_nxp_pxp_cfg_t; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Reset and initialize PXP device. This function should be called as a part + * of display init sequence. + * + * @return LV_RES_OK: PXP init ok; LV_RES_INV: init error. See error log for more information. + */ +lv_res_t lv_gpu_nxp_pxp_init(lv_nxp_pxp_cfg_t *cfg); + +/** + * Disable PXP device. Should be called during display deinit sequence. + */ +void lv_gpu_nxp_pxp_deinit(void); + +/** + * Fill area, with optional opacity. + * + * @param[in/out] dest_buf destination buffer + * @param[in] dest_width width (stride) of destination buffer in pixels + * @param[in] fill_area area to fill + * @param[in] color color + * @param[in] opa transparency of the color + */ +void lv_gpu_nxp_pxp_fill(lv_color_t *dest_buf, lv_coord_t dest_width, const lv_area_t *fill_area, lv_color_t color, lv_opa_t opa); + + + +/** + * @brief BLock Image Transfer - copy rectangular image from src buffer to dst buffer with effects. + * + * By default, image is copied directly, with optional opacity configured by \p opa. + * Color keying can be enabled by calling lv_gpu_nxp_pxp_enable_color_key() before calling this function. + * Recoloring can be enabled by calling lv_gpu_nxp_pxp_enable_recolor() before calling this function. + * Note that color keying and recoloring at the same time is not supported and black rectangle is rendered. + * + * @param[in/out] dest destination buffer + * @param[in] dest_width width (stride) of destination buffer in pixels + * @param[in] src source buffer + * @param[in] src_with width (stride) of source buffer in pixels + * @param[in] copy_w width of area to be copied from src to dest + * @param[in] copy_h height of area to be copied from src to dest + * @param[in] opa opacity of the result + */ +void lv_gpu_nxp_pxp_blit(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src, lv_coord_t src_width, lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa); + + +/** + * @brief Enable color keying for subsequent calls to lv_gpu_nxp_pxp_blit() + * + * Color key is defined by LV_COLOR_TRANSP symbol in lv_conf.h + */ +void lv_gpu_nxp_pxp_enable_color_key(void); + +/** + * @brief Disable color keying for subsequent calls to lv_gpu_nxp_pxp_blit() + * + */ +void lv_gpu_nxp_pxp_disable_color_key(void); + + +/** + * @brief Enable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit() + * + * @param[in] color recolor value + * @param[in] opa effect opacity + */ +void lv_gpu_nxp_pxp_enable_recolor(lv_color_t color, lv_opa_t opa); + +/** + * @brief Disable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit() + */ +void lv_gpu_nxp_pxp_disable_recolor(void); + +/********************** + * STATIC FUNCTIONS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SRC_LV_GPU_LV_GPU_NXP_PXP_H_ */ diff --git a/src/lv_gpu/lv_gpu_nxp_pxp_osa.c b/src/lv_gpu/lv_gpu_nxp_pxp_osa.c new file mode 100644 index 000000000..eb23fbbe3 --- /dev/null +++ b/src/lv_gpu/lv_gpu_nxp_pxp_osa.c @@ -0,0 +1,166 @@ +/** + * @file lv_gpu_nxp_pxp_osa.c + * + */ + +/** + * MIT License + * + * Copyright (c) 2020 NXP + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next paragraph) + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_conf.h" + +#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT + +#include "lv_gpu_nxp_pxp.h" +#include "fsl_pxp.h" + +#if defined(FSL_RTOS_FREE_RTOS) + #include "FreeRTOS.h" + #include "semphr.h" +#endif + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void); +static void _lv_gpu_nxp_pxp_interrupt_deinit(void); +static void _lv_gpu_nxp_pxp_run(void); + +/********************** + * STATIC VARIABLES + **********************/ + +#if defined(FSL_RTOS_FREE_RTOS) + static SemaphoreHandle_t s_pxpIdle; +#else + static volatile bool s_pxpIdle; +#endif + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * PXP device interrupt handler. Used to check PXP task completion status. + */ +void PXP_IRQHandler(void) +{ +#if defined(FSL_RTOS_FREE_RTOS) + BaseType_t taskAwake = pdFALSE; +#endif + + if(kPXP_CompleteFlag & PXP_GetStatusFlags(PXP_ID)) { + PXP_ClearStatusFlags(PXP_ID, kPXP_CompleteFlag); +#if defined(FSL_RTOS_FREE_RTOS) + xSemaphoreGiveFromISR(s_pxpIdle, &taskAwake); + portYIELD_FROM_ISR(taskAwake); +#else + s_pxpIdle = true; +#endif + + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * PXP interrupt initialization. + */ +static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void) +{ +#if defined(FSL_RTOS_FREE_RTOS) + s_pxpIdle = xSemaphoreCreateBinary(); + if(s_pxpIdle == NULL) { + return LV_RES_INV; + } + + NVIC_SetPriority(PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); +#else + s_pxpIdle = true; +#endif + + NVIC_EnableIRQ(PXP_IRQ_ID); + + return LV_RES_OK; +} + +/** + * PXP interrupt de-initialization. + */ +static void _lv_gpu_nxp_pxp_interrupt_deinit(void) +{ + NVIC_DisableIRQ(PXP_IRQ_ID); +#if defined(FSL_RTOS_FREE_RTOS) + vSemaphoreDelete(s_pxpIdle); +#endif +} + +/** + * Function to start PXP job. This function must wait for task complete. + */ +static void _lv_gpu_nxp_pxp_run(void) +{ +#if !defined(FSL_RTOS_FREE_RTOS) + s_pxpIdle = false; +#endif + + PXP_EnableInterrupts(PXP_ID, kPXP_CompleteInterruptEnable); + PXP_Start(PXP_ID); + +#if defined(FSL_RTOS_FREE_RTOS) + if(xSemaphoreTake(s_pxpIdle, portMAX_DELAY) != pdTRUE) { + LV_LOG_ERROR("xSemaphoreTake error. Task halted."); + for(; ;) ; + } +#else + while(s_pxpIdle == false) { + } +#endif +} + +lv_nxp_pxp_cfg_t pxp_default_cfg = { + .pxp_interrupt_init = _lv_gpu_nxp_pxp_interrupt_init, + .pxp_interrupt_deinit = _lv_gpu_nxp_pxp_interrupt_deinit, + .pxp_run = _lv_gpu_nxp_pxp_run +}; + +#endif /* LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT */ diff --git a/src/lv_gpu/lv_gpu_nxp_pxp_osa.h b/src/lv_gpu/lv_gpu_nxp_pxp_osa.h new file mode 100644 index 000000000..9a10df9e2 --- /dev/null +++ b/src/lv_gpu/lv_gpu_nxp_pxp_osa.h @@ -0,0 +1,47 @@ +/** + * @file lv_gpu_nxp_pxp_osa.h + * + */ + +/** + * MIT License + * + * Copyright (c) 2020 NXP + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next paragraph) + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LV_SRC_LV_GPU_LV_GPU_NXP_PXP_OSA_H_ +#define LV_SRC_LV_GPU_LV_GPU_NXP_PXP_OSA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lv_conf.h" + +#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT +extern lv_nxp_pxp_cfg_t pxp_default_cfg; +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SRC_LV_GPU_LV_GPU_NXP_PXP_OSA_H_ */ From 27eb84667f73f67c52e1533042f0bab83685842e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 23 Sep 2020 09:59:09 +0200 Subject: [PATCH 03/18] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 602710fe2..3d32264c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # Changelog -## v7.7.0 (22.09.2020) +## v7.7.0 (06.10.2020) ### New features +- Add PXP GPU support (for NXP MCUs) +- Allow max. 16 cell types for table ### Bugfixes From 686a3b5271a554146da5b7cb36df685d9c33240f Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 23 Sep 2020 10:14:06 +0200 Subject: [PATCH 04/18] Update ROADMAP.md --- docs/ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index eb63f9fe0..dbafdd689 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -22,7 +22,6 @@ Planned to September/October 2020 - Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier - Work in progress - Remove the align parameter from `lv_canvas_draw_text` -- RGB888 support [#1722](https://github.com/lvgl/lvgl/issues/1722) ## v8.1 - Add radio button widget @@ -34,6 +33,7 @@ Planned to September/October 2020 - Consider direct binary font format support ## Ideas +- RGB888 support [#1722](https://github.com/lvgl/lvgl/issues/1722) - CPP binding. See [Forum](https://forum.lvgl.io/t/is-it-possible-to-officially-support-optional-cpp-api/2736) - Optmize font decompression - Switch to RGBA colors in styles From 23f5a11340e9bec30066e81e0d25131322d5db98 Mon Sep 17 00:00:00 2001 From: Ali Rostami <9710249+ali-rostami@users.noreply.github.com> Date: Wed, 23 Sep 2020 11:53:37 +0330 Subject: [PATCH 05/18] Table fmt (#1803) * update lv_obj_refresh_style describtion. * fmt version of lv_table_set_cell_value added. * fix a bug. * add include lv_printf.h * fix a bug for LV_USE_BIDI in lv_table_set_cell_value_fmt * fix a missed part for arabic_persian chars in lv_table_set_cell_value --- src/lv_widgets/lv_table.c | 111 +++++++++++++++++++++++++++++++++++++- src/lv_widgets/lv_table.h | 9 ++++ 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index 0aff233c0..f2f4adeb3 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -14,6 +14,7 @@ #include "../lv_misc/lv_txt.h" #include "../lv_misc/lv_math.h" #include "../lv_draw/lv_draw_label.h" +#include "../lv_misc/lv_printf.h" #include "../lv_themes/lv_theme.h" /********************* @@ -169,11 +170,117 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const format.s.crop = 0; } - ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ +#if LV_USE_ARABIC_PERSIAN_CHARS + /*Get the size of the Arabic text and process it*/ + size_t len_ap = _lv_txt_ap_calc_bytes_cnt(txt); + ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], len_ap + 1); LV_ASSERT_MEM(ext->cell_data[cell]); if(ext->cell_data[cell] == NULL) return; - strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/ + _lv_txt_ap_proc(txt, &ext->cell_data[cell][1]); +#else + ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ + LV_ASSERT_MEM(ext->cell_data[cell]); + if(ext->cell_data[cell] == NULL) return; + + strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/ +#endif + + ext->cell_data[cell][0] = format.format_byte; + refr_size(table); +} + + +/** + * Set the value of a cell. Memory will be allocated to store the text by the table. + * @param table pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param fmt `printf`-like format + */ +void lv_table_set_cell_value_fmt(lv_obj_t * table, uint16_t row, uint16_t col, const char * fmt, ...) +{ + LV_ASSERT_OBJ(table, LV_OBJX_NAME); + LV_ASSERT_STR(fmt); + + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_value: invalid column"); + return; + } + + /*Auto expand*/ + if(row >= ext->row_cnt) { + lv_table_set_row_cnt(table, row + 1); + } + + uint32_t cell = row * ext->col_cnt + col; + lv_table_cell_format_t format; + + /*Save the format byte*/ + if(ext->cell_data[cell]) { + format.format_byte = ext->cell_data[cell][0]; + } + /*Initialize the format byte*/ + else { + lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table); + if(base_dir == LV_BIDI_DIR_LTR) format.s.align = LV_LABEL_ALIGN_LEFT; + else if(base_dir == LV_BIDI_DIR_RTL) format.s.align = LV_LABEL_ALIGN_RIGHT; + else if(base_dir == LV_BIDI_DIR_AUTO) +#if LV_USE_BIDI + format.s.align = _lv_bidi_detect_base_dir(fmt); +#else + format.s.align = LV_LABEL_ALIGN_LEFT; +#endif + format.s.right_merge = 0; + format.s.type = 0; + format.s.crop = 0; + } + + va_list ap, ap2; + va_start(ap, fmt); + va_copy(ap2, ap); + + /*Allocate space for the new text by using trick from C99 standard section 7.19.6.12 */ + uint32_t len = lv_vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + +#if LV_USE_ARABIC_PERSIAN_CHARS + /*Put together the text according to the format string*/ + char * raw_txt = _lv_mem_buf_get(len + 1); + LV_ASSERT_MEM(raw_txt); + if(raw_txt == NULL) { + va_end(ap2); + return; + } + + lv_vsnprintf(raw_txt, len + 1, fmt, ap2); + + /*Get the size of the Arabic text and process it*/ + size_t len_ap = _lv_txt_ap_calc_bytes_cnt(raw_txt); + ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], len_ap + 1); + LV_ASSERT_MEM(ext->cell_data[cell]); + if(ext->cell_data[cell] == NULL) { + va_end(ap2); + return; + } + _lv_txt_ap_proc(raw_txt, &ext->cell_data[cell][1]); + + _lv_mem_buf_release(raw_txt); +#else + ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], len + 2); /*+1: trailing '\0; +1: format byte*/ + LV_ASSERT_MEM(ext->cell_data[cell]); + if(ext->cell_data[cell] == NULL) { + va_end(ap2); + return; + } + + ext->cell_data[cell][len + 1] = 0; /* Ensure NULL termination */ + + lv_vsnprintf(&ext->cell_data[cell][1], len + 1, fmt, ap2); +#endif + + va_end(ap2); ext->cell_data[cell][0] = format.format_byte; refr_size(table); diff --git a/src/lv_widgets/lv_table.h b/src/lv_widgets/lv_table.h index d05f2ce9a..82bdf4b06 100644 --- a/src/lv_widgets/lv_table.h +++ b/src/lv_widgets/lv_table.h @@ -110,6 +110,15 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy); */ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt); +/** + * Set the value of a cell. Memory will be allocated to store the text by the table. + * @param table pointer to a Table object + * @param row id of the row [0 .. row_cnt -1] + * @param col id of the column [0 .. col_cnt -1] + * @param fmt `printf`-like format + */ +void lv_table_set_cell_value_fmt(lv_obj_t * table, uint16_t row, uint16_t col, const char * fmt, ...); + /** * Set the number of rows * @param table table pointer to a Table object From 0b3759201f0843399ab93ee60c5be27a4821c933 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 23 Sep 2020 10:23:45 +0200 Subject: [PATCH 06/18] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d32264c9..3fdc75f86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### New features - Add PXP GPU support (for NXP MCUs) - Allow max. 16 cell types for table +- Add `lv_table_set_text_fmt()` + ### Bugfixes From 2b49a7eb280d0ba3238a692b50350c026a665059 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 23 Sep 2020 11:00:15 +0200 Subject: [PATCH 07/18] add missing style cache invalidation on state change --- src/lv_core/lv_obj.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 827c7311d..b7e416d04 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1781,8 +1781,16 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state) } } if(cmp_res == STYLE_COMPARE_DIFF) lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); + + if(cmp_res == STYLE_COMPARE_VISUAL_DIFF) { + invalidate_style_cache(obj, part, LV_STYLE_PROP_ALL); + } } - if(cmp_res == STYLE_COMPARE_VISUAL_DIFF) lv_obj_invalidate(obj); + + if(cmp_res == STYLE_COMPARE_VISUAL_DIFF) { + lv_obj_invalidate(obj); + } + #endif } From b2d201dba779abe710e0704a86c77932e0b46acb Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 23 Sep 2020 06:41:37 -0400 Subject: [PATCH 08/18] Fix #1795: ensure switch/bar visual state matches logical state (#1805) --- src/lv_widgets/lv_bar.c | 1 + src/lv_widgets/lv_switch.c | 8 ++++---- src/lv_widgets/lv_switch.h | 4 +--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/lv_widgets/lv_bar.c b/src/lv_widgets/lv_bar.c index acd90fdb2..efd53af91 100644 --- a/src/lv_widgets/lv_bar.c +++ b/src/lv_widgets/lv_bar.c @@ -737,6 +737,7 @@ static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_ anim_info->anim_start = anim_info->anim_end; anim_info->anim_end = new_value; } + *value_ptr = new_value; /* Stop the previous animation if it exists */ lv_anim_del(anim_info, NULL); diff --git a/src/lv_widgets/lv_switch.c b/src/lv_widgets/lv_switch.c index 9340f1efa..396ca8eb5 100644 --- a/src/lv_widgets/lv_switch.c +++ b/src/lv_widgets/lv_switch.c @@ -126,8 +126,8 @@ void lv_switch_on(lv_obj_t * sw, lv_anim_enable_t anim) #if LV_USE_ANIMATION == 0 anim = LV_ANIM_OFF; #endif - lv_switch_ext_t * ext = lv_obj_get_ext_attr(sw); - ext->state = 1; + if(lv_bar_get_value(sw) == 1) + return; lv_bar_set_value(sw, 1, anim); lv_obj_add_state(sw, LV_STATE_CHECKED); } @@ -144,8 +144,8 @@ void lv_switch_off(lv_obj_t * sw, lv_anim_enable_t anim) #if LV_USE_ANIMATION == 0 anim = LV_ANIM_OFF; #endif - lv_switch_ext_t * ext = lv_obj_get_ext_attr(sw); - ext->state = 0; + if(lv_bar_get_value(sw) == 0) + return; lv_bar_set_value(sw, 0, anim); lv_obj_clear_state(sw, LV_STATE_CHECKED); } diff --git a/src/lv_widgets/lv_switch.h b/src/lv_widgets/lv_switch.h index 609e44fcc..868951cc7 100644 --- a/src/lv_widgets/lv_switch.h +++ b/src/lv_widgets/lv_switch.h @@ -37,7 +37,6 @@ typedef struct { lv_bar_ext_t bar; /*Ext. of ancestor*/ /*New data for this type */ lv_style_list_t style_knob; /*Style of the knob*/ - uint8_t state : 1; /*The current state*/ } lv_switch_ext_t; /** @@ -112,8 +111,7 @@ static inline void lv_switch_set_anim_time(lv_obj_t * sw, uint16_t anim_time) */ static inline bool lv_switch_get_state(const lv_obj_t * sw) { - lv_switch_ext_t * ext = (lv_switch_ext_t *)lv_obj_get_ext_attr(sw); - return ext->state ? true : false; + return lv_bar_get_value(sw) == 1 ? true : false; } /** From 6b06ac4b726f5e90881607387593e402202fca37 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 23 Sep 2020 13:24:00 -0400 Subject: [PATCH 09/18] Fix grammar error in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af3a4cde5..7972392d1 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ For more examples see the [lv_examples](https://github.com/lvgl/lv_examples) rep ### Button with label ```c -lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button the current screen*/ +lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button to the current screen*/ lv_obj_set_pos(btn, 10, 10); /*Set its position*/ lv_obj_set_size(btn, 100, 50); /*Set its size*/ lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/ From 672537dcc254fdbb438e0bb6da62730078a62505 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 23 Sep 2020 19:26:22 +0200 Subject: [PATCH 10/18] propogate checkbox state change to bullet and label too --- src/lv_widgets/lv_checkbox.c | 49 ++++++++++++++++++++++++++++++++++++ src/lv_widgets/lv_checkbox.h | 15 +++-------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/lv_widgets/lv_checkbox.c b/src/lv_widgets/lv_checkbox.c index 3f8ac3dc7..4226ba10e 100644 --- a/src/lv_widgets/lv_checkbox.c +++ b/src/lv_widgets/lv_checkbox.c @@ -132,6 +132,55 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt) lv_label_set_text_static(ext->label, txt); } +/** + * Set the state of the check box + * @param cb pointer to a check box object + * @param checked true: make the check box checked; false: make it unchecked + */ +void lv_checkbox_set_checked(lv_obj_t * cb, bool checked) +{ + lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb); + lv_btn_set_state(cb, checked ? LV_BTN_STATE_CHECKED_RELEASED : LV_BTN_STATE_RELEASED); + + if(checked) { + lv_obj_add_state(ext->bullet, LV_STATE_CHECKED); + lv_obj_add_state(ext->label, LV_STATE_CHECKED); + } else { + lv_obj_clear_state(ext->bullet, LV_STATE_CHECKED); + lv_obj_clear_state(ext->label, LV_STATE_CHECKED); + } + + lv_obj_clear_state(ext->bullet, LV_STATE_DISABLED); + lv_obj_clear_state(ext->label, LV_STATE_DISABLED); +} + + +/** + * Make the check box inactive (disabled) + * @param cb pointer to a check box object + */ +void lv_checkbox_set_disabled(lv_obj_t * cb) +{ + lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb); + lv_btn_set_state(cb, LV_BTN_STATE_DISABLED); + + lv_obj_add_state(ext->bullet, LV_STATE_DISABLED); + lv_obj_add_state(ext->label, LV_STATE_DISABLED); +} + +/** + * Set the state of a check box + * @param cb pointer to a check box object + * @param state the new state of the check box (from lv_btn_state_t enum) + */ +void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state) +{ + lv_checkbox_ext_t * ext = lv_obj_get_ext_attr(cb); + lv_btn_set_state(cb, state); + lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG)); + lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG)); +} + /*===================== * Getter functions *====================*/ diff --git a/src/lv_widgets/lv_checkbox.h b/src/lv_widgets/lv_checkbox.h index 96bb0f1e2..0ea2ecf37 100644 --- a/src/lv_widgets/lv_checkbox.h +++ b/src/lv_widgets/lv_checkbox.h @@ -92,29 +92,20 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt); * @param cb pointer to a check box object * @param checked true: make the check box checked; false: make it unchecked */ -static inline void lv_checkbox_set_checked(lv_obj_t * cb, bool checked) -{ - lv_btn_set_state(cb, checked ? LV_BTN_STATE_CHECKED_RELEASED : LV_BTN_STATE_RELEASED); -} +void lv_checkbox_set_checked(lv_obj_t * cb, bool checked); /** * Make the check box inactive (disabled) * @param cb pointer to a check box object */ -static inline void lv_checkbox_set_disabled(lv_obj_t * cb) -{ - lv_btn_set_state(cb, LV_BTN_STATE_DISABLED); -} +void lv_checkbox_set_disabled(lv_obj_t * cb); /** * Set the state of a check box * @param cb pointer to a check box object * @param state the new state of the check box (from lv_btn_state_t enum) */ -static inline void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state) -{ - lv_btn_set_state(cb, state); -} +void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state); /*===================== * Getter functions *====================*/ From ffd9b872d9dab7345c16cb5b36206809510296ee Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 27 Sep 2020 14:47:11 +0200 Subject: [PATCH 11/18] fix BIDI support in dropdown list --- CHANGELOG.md | 1 + src/lv_widgets/lv_dropdown.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f39180e05..94e3ecae7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bugfixes - Fix selection of options with non-ASCII letters in dropdown list - Fix font loader to support LV_FONT_FMT_TXT_LARGE +- Fix BIDI support in dropdown list ## v7.5.0 (15.09.2020) diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index 7a2d6090b..2952b6325 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -588,6 +588,8 @@ void lv_dropdown_open(lv_obj_t * ddlist) lv_obj_add_protect(ext->page, LV_PROTECT_POS | LV_PROTECT_CLICK_FOCUS); lv_obj_add_protect(lv_page_get_scrollable(ext->page), LV_PROTECT_CLICK_FOCUS); + lv_obj_set_base_dir(ext->page, lv_obj_get_base_dir(ddlist)); + if(ancestor_page_signal == NULL) ancestor_page_signal = lv_obj_get_signal_cb(ext->page); if(ancestor_page_scrl_signal == NULL) ancestor_page_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrollable( ext->page)); From f0fc45eb5244f5cc8fc16044d52fdd881766fa22 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 28 Sep 2020 10:43:05 +0200 Subject: [PATCH 12/18] checkbox: do not play transition on manual state change --- src/lv_widgets/lv_checkbox.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lv_widgets/lv_checkbox.c b/src/lv_widgets/lv_checkbox.c index 4226ba10e..04fb584b0 100644 --- a/src/lv_widgets/lv_checkbox.c +++ b/src/lv_widgets/lv_checkbox.c @@ -152,6 +152,9 @@ void lv_checkbox_set_checked(lv_obj_t * cb, bool checked) lv_obj_clear_state(ext->bullet, LV_STATE_DISABLED); lv_obj_clear_state(ext->label, LV_STATE_DISABLED); + + lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG); + lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN); } @@ -166,6 +169,9 @@ void lv_checkbox_set_disabled(lv_obj_t * cb) lv_obj_add_state(ext->bullet, LV_STATE_DISABLED); lv_obj_add_state(ext->label, LV_STATE_DISABLED); + + lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG); + lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN); } /** @@ -179,6 +185,9 @@ void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state) lv_btn_set_state(cb, state); lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG)); lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG)); + + lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG); + lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN); } /*===================== From ce11b4c71c28fd686e2219290cba3a9acfb8c424 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 28 Sep 2020 10:51:26 +0200 Subject: [PATCH 13/18] fix build error --- src/lv_widgets/lv_checkbox.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lv_widgets/lv_checkbox.c b/src/lv_widgets/lv_checkbox.c index 04fb584b0..276a76279 100644 --- a/src/lv_widgets/lv_checkbox.c +++ b/src/lv_widgets/lv_checkbox.c @@ -153,8 +153,10 @@ void lv_checkbox_set_checked(lv_obj_t * cb, bool checked) lv_obj_clear_state(ext->bullet, LV_STATE_DISABLED); lv_obj_clear_state(ext->label, LV_STATE_DISABLED); +#if LV_USE_ANIMATION lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG); lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN); +#endif } @@ -170,8 +172,10 @@ void lv_checkbox_set_disabled(lv_obj_t * cb) lv_obj_add_state(ext->bullet, LV_STATE_DISABLED); lv_obj_add_state(ext->label, LV_STATE_DISABLED); +#if LV_USE_ANIMATION lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG); lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN); +#endif } /** @@ -186,8 +190,10 @@ void lv_checkbox_set_state(lv_obj_t * cb, lv_btn_state_t state) lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG)); lv_obj_set_state(ext->bullet, lv_obj_get_state(cb, LV_CHECKBOX_PART_BG)); +#if LV_USE_ANIMATION lv_obj_finish_transitions(cb, LV_CHECKBOX_PART_BG); lv_obj_finish_transitions(ext->bullet, LV_OBJ_PART_MAIN); +#endif } /*===================== From 8ff5e2337832c95302319cbc12a5211a7ac04f84 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 28 Sep 2020 11:07:49 +0200 Subject: [PATCH 14/18] Update ROADMAP.md --- docs/ROADMAP.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index dbafdd689..edad72f1b 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -33,6 +33,7 @@ Planned to September/October 2020 - Consider direct binary font format support ## Ideas +- Text node. See [#1701](https://github.com/lvgl/lvgl/issues/1701#issuecomment-699479408) - RGB888 support [#1722](https://github.com/lvgl/lvgl/issues/1722) - CPP binding. See [Forum](https://forum.lvgl.io/t/is-it-possible-to-officially-support-optional-cpp-api/2736) - Optmize font decompression From 5be1fcadca3c71b1b61af28fbc24ff6748017be5 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 28 Sep 2020 11:48:06 +0200 Subject: [PATCH 15/18] fix copying base dir in lv_obj_craete --- src/lv_core/lv_obj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index b7e416d04..9b6ea5120 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -404,6 +404,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) _lv_memcpy(&new_obj->user_data, ©->user_data, sizeof(lv_obj_user_data_t)); #endif + new_obj->base_dir = copy->base_dir; + /*Copy realign*/ #if LV_USE_OBJ_REALIGN new_obj->realign.align = copy->realign.align; From a24e3f619ffac05e63cfb24b62685a6c0d4fdc9d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 28 Sep 2020 11:48:27 +0200 Subject: [PATCH 16/18] dropdown list fixes with Bidi == RTL --- CHANGELOG.md | 1 + src/lv_widgets/lv_dropdown.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94e3ecae7..19a127c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Fix selection of options with non-ASCII letters in dropdown list - Fix font loader to support LV_FONT_FMT_TXT_LARGE - Fix BIDI support in dropdown list +- Fix copying base dir in lv_obj_craete ## v7.5.0 (15.09.2020) diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index 2952b6325..eec0754d6 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -677,6 +677,10 @@ void lv_dropdown_open(lv_obj_t * ddlist) lv_obj_set_y(ext->page, lv_obj_get_y(ext->page) - (ext->page->coords.y2 - LV_VER_RES)); } } + + if(lv_label_get_align(label) == LV_LABEL_ALIGN_RIGHT) { + lv_obj_set_x(label, lv_obj_get_width_fit(ext->page) - lv_obj_get_width(label)); + } } /** @@ -739,7 +743,11 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c const char * txt; - txt = ext->dir != LV_DROPDOWN_DIR_LEFT ? opt_txt : ext->symbol; + bool rev = false; + if(ext->dir == LV_DROPDOWN_DIR_LEFT) rev = true; + if(lv_obj_get_base_dir(ddlist) == LV_BIDI_DIR_RTL) rev = true; + + txt = rev ? ext->symbol : opt_txt; if(txt) { _lv_txt_get_size(&txt_size, txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, label_dsc.flag); @@ -759,7 +767,7 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c lv_draw_label(&txt_area, clip_area, &label_dsc, txt, NULL); } - txt = ext->dir != LV_DROPDOWN_DIR_LEFT ? ext->symbol : opt_txt; + txt =rev ? opt_txt : ext->symbol; if(txt) { _lv_txt_get_size(&txt_size, txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, label_dsc.flag); From 5a0006cd3c48f8cfa16abf6bb28d659f2408a14a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 29 Sep 2020 09:33:57 +0200 Subject: [PATCH 17/18] Update ROADMAP.md --- docs/ROADMAP.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index edad72f1b..cbae70459 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -31,6 +31,7 @@ Planned to September/October 2020 - Unit testing (gtest?). See [#1658](https://github.com/lvgl/lvgl/issues/1658) - Benchmarking (gem5?). See [#1660](https://github.com/lvgl/lvgl/issues/1660) - Consider direct binary font format support +- Remove the copy paramter from create functions ## Ideas - Text node. See [#1701](https://github.com/lvgl/lvgl/issues/1701#issuecomment-699479408) From 8c824b265e3340be98577af804b2087133a4b9a3 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 30 Sep 2020 06:54:59 +0200 Subject: [PATCH 18/18] style cahce: add margin --- src/lv_core/lv_obj.c | 26 +++++++++++++++++++++----- src/lv_core/lv_style.h | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 9b6ea5120..159abd96a 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2585,9 +2585,6 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_BG_GRAD_DIR: - if(list->bg_grad_dir_none) def = true; - break; case LV_STYLE_CLIP_CORNER: if(list->clip_corner_off) def = true; break; @@ -2625,6 +2622,12 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_PAD_RIGHT: if(list->pad_all_zero) def = true; break; + case LV_STYLE_MARGIN_TOP: + case LV_STYLE_MARGIN_BOTTOM: + case LV_STYLE_MARGIN_LEFT: + case LV_STYLE_MARGIN_RIGHT: + if(list->margin_all_zero) def = true; + break; case LV_STYLE_BG_BLEND_MODE: case LV_STYLE_BORDER_BLEND_MODE: case LV_STYLE_IMAGE_BLEND_MODE: @@ -2636,6 +2639,9 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_VALUE_BLEND_MODE: if(list->blend_mode_all_normal) def = true; break; + case LV_STYLE_TEXT_DECOR: + if(list->text_decor_none) def = true; + break; } if(def) { @@ -4551,7 +4557,6 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) switch(prop) { case LV_STYLE_PROP_ALL: - case LV_STYLE_BG_GRAD_DIR: case LV_STYLE_CLIP_CORNER: case LV_STYLE_TEXT_LETTER_SPACE: case LV_STYLE_TEXT_LINE_SPACE: @@ -4575,6 +4580,10 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) case LV_STYLE_PAD_BOTTOM: case LV_STYLE_PAD_LEFT: case LV_STYLE_PAD_RIGHT: + case LV_STYLE_MARGIN_TOP: + case LV_STYLE_MARGIN_BOTTOM: + case LV_STYLE_MARGIN_LEFT: + case LV_STYLE_MARGIN_RIGHT: case LV_STYLE_BG_BLEND_MODE: case LV_STYLE_BORDER_BLEND_MODE: case LV_STYLE_IMAGE_BLEND_MODE: @@ -4625,7 +4634,6 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->bg_opa_transp = bg_opa == LV_OPA_TRANSP ? 1 : 0; list->bg_opa_cover = bg_opa == LV_OPA_COVER ? 1 : 0; - list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0; list->border_side_full = lv_obj_get_style_border_side(obj, part) == LV_BORDER_SIDE_FULL ? 1 : 0; list->border_post_off = lv_obj_get_style_border_post(obj, part) == 0 ? 1 : 0; @@ -4654,6 +4662,14 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->pad_all_zero = 0; } + list->margin_all_zero = 1; + if(lv_obj_get_style_margin_top(obj, part) != 0 || + lv_obj_get_style_margin_bottom(obj, part) != 0 || + lv_obj_get_style_margin_left(obj, part) != 0 || + lv_obj_get_style_margin_right(obj, part) != 0) { + list->margin_all_zero = 0; + } + list->blend_mode_all_normal = 1; #if LV_USE_BLEND_MODES if(lv_obj_get_style_bg_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 4e1f74d97..36876fbe4 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -234,10 +234,10 @@ typedef struct { uint32_t clip_corner_off : 1; uint32_t transform_all_zero : 1; uint32_t pad_all_zero : 1; + uint32_t margin_all_zero : 1; uint32_t blend_mode_all_normal : 1; uint32_t bg_opa_transp : 1; uint32_t bg_opa_cover : 1; - uint32_t bg_grad_dir_none : 1; uint32_t border_width_zero : 1; uint32_t border_side_full : 1;