diff --git a/Makefile b/Makefile index 72c5a65..198dfe7 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ EXCLUDE_COLD_LIBRARIES:= # Set this to 1 to add additional rules to compile your project as a PROS library template IS_LIBRARY:=1 LIBNAME:=liblvgl -VERSION:=8.3.2 +VERSION:=8.3.6 # EXCLUDE_SRC_FROM_LIB= $(SRCDIR)/unpublishedfile.c # this line excludes opcontrol.c and similar files EXCLUDE_SRC_FROM_LIB+=$(foreach file, $(SRCDIR)/main,$(foreach cext,$(CEXTS),$(file).$(cext)) $(foreach cxxext,$(CXXEXTS),$(file).$(cxxext))) diff --git a/include/liblvgl/core/lv_core.mk b/include/liblvgl/core/lv_core.mk new file mode 100644 index 0000000..677a9f6 --- /dev/null +++ b/include/liblvgl/core/lv_core.mk @@ -0,0 +1,20 @@ +CSRCS += lv_disp.c +CSRCS += lv_group.c +CSRCS += lv_indev.c +CSRCS += lv_indev_scroll.c +CSRCS += lv_obj.c +CSRCS += lv_obj_class.c +CSRCS += lv_obj_draw.c +CSRCS += lv_obj_pos.c +CSRCS += lv_obj_scroll.c +CSRCS += lv_obj_style.c +CSRCS += lv_obj_style_gen.c +CSRCS += lv_obj_tree.c +CSRCS += lv_event.c +CSRCS += lv_refr.c +CSRCS += lv_theme.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core" diff --git a/include/liblvgl/core/lv_disp.h b/include/liblvgl/core/lv_disp.h index cd6efcc..7854cb7 100644 --- a/include/liblvgl/core/lv_disp.h +++ b/include/liblvgl/core/lv_disp.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/hal/lv_hal.h" +#include "../hal/lv_hal.h" #include "lv_obj.h" #include "lv_theme.h" diff --git a/include/liblvgl/core/lv_group.h b/include/liblvgl/core/lv_group.h index 85df325..0910597 100644 --- a/include/liblvgl/core/lv_group.h +++ b/include/liblvgl/core/lv_group.h @@ -14,12 +14,12 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include -#include "liblvgl/misc/lv_ll.h" -#include "liblvgl/misc/lv_types.h" +#include "../misc/lv_ll.h" +#include "../misc/lv_types.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_indev.h b/include/liblvgl/core/lv_indev.h index 4692ef3..a98df86 100644 --- a/include/liblvgl/core/lv_indev.h +++ b/include/liblvgl/core/lv_indev.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "lv_obj.h" -#include "liblvgl/hal/lv_hal_indev.h" +#include "../hal/lv_hal_indev.h" #include "lv_group.h" /********************* diff --git a/include/liblvgl/core/lv_obj_draw.h b/include/liblvgl/core/lv_obj_draw.h index a107e55..3f9d0f3 100644 --- a/include/liblvgl/core/lv_obj_draw.h +++ b/include/liblvgl/core/lv_obj_draw.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/draw/lv_draw.h" +#include "../draw/lv_draw.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_obj_pos.h b/include/liblvgl/core/lv_obj_pos.h index fdc6476..d20ee96 100644 --- a/include/liblvgl/core/lv_obj_pos.h +++ b/include/liblvgl/core/lv_obj_pos.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_area.h" +#include "../misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_obj_scroll.h b/include/liblvgl/core/lv_obj_scroll.h index 3717dec..e1da245 100644 --- a/include/liblvgl/core/lv_obj_scroll.h +++ b/include/liblvgl/core/lv_obj_scroll.h @@ -13,9 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_anim.h" -#include "liblvgl/misc/lv_types.h" +#include "../misc/lv_area.h" +#include "../misc/lv_anim.h" +#include "../misc/lv_types.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_obj_style.h b/include/liblvgl/core/lv_obj_style.h index 18e530a..5d122ca 100644 --- a/include/liblvgl/core/lv_obj_style.h +++ b/include/liblvgl/core/lv_obj_style.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include #include -#include "liblvgl/misc/lv_bidi.h" +#include "../misc/lv_bidi.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_theme.h b/include/liblvgl/core/lv_theme.h index 80da522..ef46336 100644 --- a/include/liblvgl/core/lv_theme.h +++ b/include/liblvgl/core/lv_theme.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/arm2d/lv_draw_arm2d.mk b/include/liblvgl/draw/arm2d/lv_draw_arm2d.mk new file mode 100644 index 0000000..17219b0 --- /dev/null +++ b/include/liblvgl/draw/arm2d/lv_draw_arm2d.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_arm2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d" diff --git a/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h b/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h index cc66990..50fa5a8 100644 --- a/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h +++ b/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h @@ -13,9 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/draw/sw/lv_draw_sw.h" +#include "../../misc/lv_color.h" +#include "../../hal/lv_hal_disp.h" +#include "../sw/lv_draw_sw.h" #if LV_USE_GPU_ARM2D diff --git a/include/liblvgl/draw/lv_draw.h b/include/liblvgl/draw/lv_draw.h index c8aed72..ffe1d4e 100644 --- a/include/liblvgl/draw/lv_draw.h +++ b/include/liblvgl/draw/lv_draw.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" -#include "liblvgl/misc/lv_style.h" -#include "liblvgl/misc/lv_txt.h" +#include "../misc/lv_style.h" +#include "../misc/lv_txt.h" #include "lv_img_decoder.h" #include "lv_img_cache.h" @@ -72,6 +72,7 @@ typedef struct _lv_draw_ctx_t { */ const lv_area_t * clip_area; + void (*init_buf)(struct _lv_draw_ctx_t * draw_ctx); void (*draw_rect)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); diff --git a/include/liblvgl/draw/lv_draw.mk b/include/liblvgl/draw/lv_draw.mk new file mode 100644 index 0000000..f48f48f --- /dev/null +++ b/include/liblvgl/draw/lv_draw.mk @@ -0,0 +1,25 @@ +CSRCS += lv_draw_arc.c +CSRCS += lv_draw.c +CSRCS += lv_draw_img.c +CSRCS += lv_draw_label.c +CSRCS += lv_draw_line.c +CSRCS += lv_draw_mask.c +CSRCS += lv_draw_rect.c +CSRCS += lv_draw_transform.c +CSRCS += lv_draw_layer.c +CSRCS += lv_draw_triangle.c +CSRCS += lv_img_buf.c +CSRCS += lv_img_cache.c +CSRCS += lv_img_decoder.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw" + +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d/lv_draw_arm2d.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/lv_draw_nxp.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl/lv_draw_sdl.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw/lv_draw_sw.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk diff --git a/include/liblvgl/draw/lv_draw_arc.h b/include/liblvgl/draw/lv_draw_arc.h index 8633af5..8783f13 100644 --- a/include/liblvgl/draw/lv_draw_arc.h +++ b/include/liblvgl/draw/lv_draw_arc.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_style.h" +#include "../lv_conf_internal.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_img.h b/include/liblvgl/draw/lv_draw_img.h index dcb7113..a88a33c 100644 --- a/include/liblvgl/draw/lv_draw_img.h +++ b/include/liblvgl/draw/lv_draw_img.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include "lv_img_decoder.h" #include "lv_img_buf.h" -#include "liblvgl/misc/lv_style.h" +#include "../misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_label.h b/include/liblvgl/draw/lv_draw_label.h index 736aa72..de72edd 100644 --- a/include/liblvgl/draw/lv_draw_label.h +++ b/include/liblvgl/draw/lv_draw_label.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_bidi.h" -#include "liblvgl/misc/lv_txt.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_style.h" +#include "../misc/lv_bidi.h" +#include "../misc/lv_txt.h" +#include "../misc/lv_color.h" +#include "../misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_layer.h b/include/liblvgl/draw/lv_draw_layer.h index 1280d33..cd64149 100644 --- a/include/liblvgl/draw/lv_draw_layer.h +++ b/include/liblvgl/draw/lv_draw_layer.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_line.h b/include/liblvgl/draw/lv_draw_line.h index 79ca0dc..d82ea51 100644 --- a/include/liblvgl/draw/lv_draw_line.h +++ b/include/liblvgl/draw/lv_draw_line.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_style.h" +#include "../lv_conf_internal.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_mask.h b/include/liblvgl/draw/lv_draw_mask.h index f3c49e5..b7e4e1c 100644 --- a/include/liblvgl/draw/lv_draw_mask.h +++ b/include/liblvgl/draw/lv_draw_mask.h @@ -15,9 +15,9 @@ extern "C" { * INCLUDES *********************/ #include -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_math.h" +#include "../misc/lv_area.h" +#include "../misc/lv_color.h" +#include "../misc/lv_math.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_rect.h b/include/liblvgl/draw/lv_draw_rect.h index e259446..1583e3e 100644 --- a/include/liblvgl/draw/lv_draw_rect.h +++ b/include/liblvgl/draw/lv_draw_rect.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_style.h" +#include "../lv_conf_internal.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_style.h" #include "sw/lv_draw_sw_gradient.h" /********************* diff --git a/include/liblvgl/draw/lv_draw_transform.h b/include/liblvgl/draw/lv_draw_transform.h index 6e6236c..1926c2f 100644 --- a/include/liblvgl/draw/lv_draw_transform.h +++ b/include/liblvgl/draw/lv_draw_transform.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/misc/lv_area.h" +#include "../lv_conf_internal.h" +#include "../misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_img_buf.h b/include/liblvgl/draw/lv_img_buf.h index 8998839..1be7bb6 100644 --- a/include/liblvgl/draw/lv_img_buf.h +++ b/include/liblvgl/draw/lv_img_buf.h @@ -14,8 +14,8 @@ extern "C" { * INCLUDES *********************/ #include -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_area.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_img_decoder.h b/include/liblvgl/draw/lv_img_decoder.h index c0c5860..9dc84dd 100644 --- a/include/liblvgl/draw/lv_img_decoder.h +++ b/include/liblvgl/draw/lv_img_decoder.h @@ -13,13 +13,13 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include "lv_img_buf.h" -#include "liblvgl/misc/lv_fs.h" -#include "liblvgl/misc/lv_types.h" -#include "liblvgl/misc/lv_area.h" +#include "../misc/lv_fs.h" +#include "../misc/lv_types.h" +#include "../misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/nxp/lv_draw_nxp.mk b/include/liblvgl/draw/nxp/lv_draw_nxp.mk new file mode 100644 index 0000000..18a751e --- /dev/null +++ b/include/liblvgl/draw/nxp/lv_draw_nxp.mk @@ -0,0 +1,7 @@ +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp" + +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp/lv_draw_nxp_pxp.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite/lv_draw_nxp_vglite.mk diff --git a/include/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk b/include/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk new file mode 100644 index 0000000..5c684bc --- /dev/null +++ b/include/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk @@ -0,0 +1,9 @@ +CSRCS += lv_draw_pxp.c +CSRCS += lv_draw_pxp_blend.c +CSRCS += lv_gpu_nxp_pxp_osa.c +CSRCS += lv_gpu_nxp_pxp.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp" diff --git a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h new file mode 100644 index 0000000..1ace3bc --- /dev/null +++ b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h @@ -0,0 +1,72 @@ +/** + * @file lv_draw_pxp.h + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_DRAW_PXP_H +#define LV_DRAW_PXP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GPU_NXP_PXP +#include "../../sw/lv_draw_sw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef lv_draw_sw_ctx_t lv_draw_pxp_ctx_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_pxp_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +void lv_draw_pxp_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_GPU_NXP_PXP*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_PXP_H*/ diff --git a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h index acce871..9fe9192 100644 --- a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h +++ b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2022 NXP + * Copyright 2020-2023 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 @@ -38,7 +38,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_GPU_NXP_PXP #include "lv_gpu_nxp_pxp.h" @@ -48,31 +48,6 @@ extern "C" { * DEFINES *********************/ -#ifndef LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT -/** Minimum area (in pixels) for image copy with 100% opacity to be handled by PXP*/ -#define LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT -/** Minimum area (in pixels) for image copy with transparency to be handled by PXP*/ -#define LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT -/** Minimum invalidated area (in pixels) to be synchronized by PXP during buffer sync */ -#define LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_PXP_FILL_SIZE_LIMIT -/** Minimum area (in pixels) to be filled by PXP with 100% opacity*/ -#define LV_GPU_NXP_PXP_FILL_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT -/** Minimum area (in pixels) to be filled by PXP with transparency*/ -#define LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT 5000 -#endif - /********************** * TYPEDEFS **********************/ @@ -84,51 +59,49 @@ extern "C" { /** * Fill area, with optional opacity. * - * @param[in/out] dest_buf destination buffer - * @param[in] dest_stride 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 - * @retval LV_RES_OK Fill completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] color Color + * @param[in] opa Opacity */ -lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area, - lv_color_t color, lv_opa_t opa); +void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + lv_color_t color, lv_opa_t opa); /** * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects. * By default, image is copied directly, with optional opacity. This function can also * rotate the display output buffer to a specified angle (90x step). * - * @param[in/out] dest_buf destination buffer - * @param[in] dest_area destination area - * @param[in] dest_stride width (stride) of destination buffer in pixels - * @param[in] src_buf source buffer - * @param[in] src_area source area with absolute coordinates to draw on destination buffer - * @param[in] opa opacity of the result - * @param[in] angle display rotation angle (90x) - * @retval LV_RES_OK Fill completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Source area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] opa Opacity + * @param[in] angle Display rotation angle (90x) */ -lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, lv_opa_t opa, lv_disp_rot_t angle); +void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + lv_opa_t opa, lv_disp_rot_t angle); /** * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation. * * - * @param[in/out] dest_buf destination buffer - * @param[in] dest_area destination area - * @param[in] dest_stride width (stride) of destination buffer in pixels - * @param[in] src_buf source buffer - * @param[in] src_area source area with absolute coordinates to draw on destination buffer - * @param[in] dsc image descriptor - * @param[in] cf color format - * @retval LV_RES_OK Fill completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] dsc Image descriptor + * @param[in] cf Color format */ -lv_res_t lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); +void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h index aeb9d6c..10a6721 100644 --- a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h +++ b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2022 NXP + * Copyright 2020-2023 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 @@ -38,7 +38,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_GPU_NXP_PXP #include "fsl_cache.h" @@ -81,8 +81,11 @@ typedef struct { /** Callback for PXP interrupt de-initialization*/ void (*pxp_interrupt_deinit)(void); - /** Callback that should start PXP and wait for operation complete*/ + /** Callback for PXP start*/ void (*pxp_run)(void); + + /** Callback for waiting of PXP completion*/ + void (*pxp_wait)(void); } lv_nxp_pxp_cfg_t; /********************** @@ -104,10 +107,20 @@ lv_res_t lv_gpu_nxp_pxp_init(void); void lv_gpu_nxp_pxp_deinit(void); /** - * Start PXP job and wait for completion. + * Reset PXP device. + */ +void lv_gpu_nxp_pxp_reset(void); + +/** + * Clear cache and start PXP. */ void lv_gpu_nxp_pxp_run(void); +/** + * Wait for PXP completion. + */ +void lv_gpu_nxp_pxp_wait(void); + /********************** * MACROS **********************/ diff --git a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h index d907447..5c87824 100644 --- a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h +++ b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h @@ -38,7 +38,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT #include "lv_gpu_nxp_pxp.h" diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk b/include/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk new file mode 100644 index 0000000..c9473cc --- /dev/null +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk @@ -0,0 +1,12 @@ +CSRCS += lv_draw_vglite.c +CSRCS += lv_draw_vglite_arc.c +CSRCS += lv_draw_vglite_blend.c +CSRCS += lv_draw_vglite_line.c +CSRCS += lv_draw_vglite_rect.c +CSRCS += lv_vglite_buf.c +CSRCS += lv_vglite_utils.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite" diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h new file mode 100644 index 0000000..c44cb8f --- /dev/null +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h @@ -0,0 +1,72 @@ +/** + * @file lv_draw_vglite.h + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_DRAW_VGLITE_H +#define LV_DRAW_VGLITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "../../sw/lv_draw_sw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef lv_draw_sw_ctx_t lv_draw_vglite_ctx_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_vglite_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +void lv_draw_vglite_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_GPU_NXP_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VGLITE_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h index e2da419..0fbff3d 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2021, 2022 NXP + * Copyright 2021-2023 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 @@ -37,10 +37,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_GPU_NXP_VG_LITE -#include "lv_gpu_nxp_vglite.h" +#include "lv_vglite_utils.h" /********************* * DEFINES @@ -54,17 +54,21 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -/*** +/** * Draw arc shape with effects - * @param draw_ctx drawing context - * @param dsc the arc description structure (width, rounded ending, opacity) - * @param center the coordinates of the arc center - * @param radius the radius of external arc - * @param start_angle the starting angle in degrees - * @param end_angle the ending angle in degrees + * + * @param[in] center Arc center with relative coordinates + * @param[in] radius Radius of external arc + * @param[in] start_angle Starting angle in degrees + * @param[in] end_angle Ending angle in degrees + * @param[in] clip_area Clipping area with relative coordinates to dest buff + * @param[in] dsc Arc description structure (width, rounded ending, opacity) + * + * @retval LV_RES_OK Draw completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, - int32_t radius, int32_t start_angle, int32_t end_angle); +lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, int32_t start_angle, int32_t end_angle, + const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h index 1726dcd..025d2b5 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2022 NXP + * Copyright 2020-2023 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 @@ -38,67 +38,19 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_GPU_NXP_VG_LITE -#include "lv_gpu_nxp_vglite.h" +#include "lv_vglite_utils.h" /********************* * DEFINES *********************/ -#ifndef LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT -/** Minimum area (in pixels) to be filled by VG-Lite with 100% opacity*/ -#define LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT -/** Minimum area (in pixels) to be filled by VG-Lite with transparency*/ -#define LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT -/** Minimum area (in pixels) for image copy with 100% opacity to be handled by VG-Lite*/ -#define LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT -/** Minimum invalidated area (in pixels) to be synchronized by VG-Lite during buffer sync */ -#define LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT 5000 -#endif - -#ifndef LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT -/** Minimum area (in pixels) for image copy with transparency to be handled by VG-Lite*/ -#define LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT 5000 -#endif - /********************** * TYPEDEFS **********************/ -/** - * BLock Image Transfer descriptor structure - */ -typedef struct { - - const lv_color_t * src; /**< Source buffer pointer (must be aligned on 32 bytes)*/ - lv_area_t src_area; /**< Area to be copied from source*/ - lv_coord_t src_width; /**< Source buffer width*/ - lv_coord_t src_height; /**< Source buffer height*/ - int32_t src_stride; /**< Source buffer stride in bytes (must be aligned on 16 px)*/ - - const lv_color_t * dst; /**< Destination buffer pointer (must be aligned on 32 bytes)*/ - lv_area_t dst_area; /**< Target area in destination buffer (must be the same as src_area)*/ - lv_coord_t dst_width; /**< Destination buffer width*/ - lv_coord_t dst_height; /**< Destination buffer height*/ - int32_t dst_stride; /**< Destination buffer stride in bytes (must be aligned on 16 px)*/ - - lv_opa_t opa; /**< Opacity - alpha mix (0 = source not copied, 255 = 100% opaque)*/ - uint32_t angle; /**< Rotation angle (1/10 of degree)*/ - uint32_t zoom; /**< 256 = no zoom (1:1 scale ratio)*/ - lv_point_t pivot; /**< The coordinates of rotation pivot in source image buffer*/ -} lv_gpu_nxp_vglite_blit_info_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -106,35 +58,52 @@ typedef struct { /** * Fill area, with optional opacity. * - * @param[in/out] dest_buf Destination buffer pointer (must be aligned on 32 bytes) - * @param[in] dest_width Destination buffer width in pixels (must be aligned on 16 px) - * @param[in] dest_height Destination buffer height in pixels - * @param[in] fill_area Area to be filled - * @param[in] color Fill color + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] color Color * @param[in] opa Opacity (255 = full, 128 = 50% background/50% color, 0 = no fill) + * * @retval LV_RES_OK Fill completed * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height, - const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa); +lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, lv_opa_t opa); /** - * BLock Image Transfer. + * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects. + * By default, image is copied directly, with optional opacity. + * + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Source area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] opa Opacity * - * @param[in] blit Description of the transfer * @retval LV_RES_OK Transfer complete * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit); +lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, + lv_opa_t opa); /** - * BLock Image Transfer with transformation. + * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation. + * By default, image is copied directly, with optional opacity. + * + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Source area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] dsc Image descriptor * - * @param[in] blit Description of the transfer * @retval LV_RES_OK Transfer complete * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit); +lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.h new file mode 100644 index 0000000..cbd4b95 --- /dev/null +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.h @@ -0,0 +1,83 @@ +/** + * @file lv_draw_vglite_line.h + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_DRAW_VGLITE_LINE_H +#define LV_DRAW_VGLITE_LINE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "lv_vglite_utils.h" +#include "../../lv_draw_line.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Draw line shape with effects + * + * @param[in] point1 Starting point with relative coordinates + * @param[in] point2 Ending point with relative coordinates + * @param[in] clip_area Clipping area with relative coordinates to dest buff + * @param[in] dsc Line description structure (width, rounded ending, opacity, ...) + * + * @retval LV_RES_OK Draw completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + */ +lv_res_t lv_gpu_nxp_vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2, + const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VGLITE_RECT_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h index 8a64170..7958227 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2021, 2022 NXP + * Copyright 2021-2023 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 @@ -37,10 +37,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_GPU_NXP_VG_LITE -#include "lv_gpu_nxp_vglite.h" +#include "lv_vglite_utils.h" #include "../../lv_draw_rect.h" /********************* @@ -56,13 +56,33 @@ extern "C" { **********************/ /** - * Draw rectangle shape with effects (rounded corners, gradient) + * Draw rectangle background with effects (rounded corners, gradient) + * + * @param[in] coords Coordinates of the rectangle background (relative to dest buff) + * @param[in] clip_area Clipping area with relative coordinates to dest buff + * @param[in] dsc Description of the rectangle background + * + * @retval LV_RES_OK Draw completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + * + */ +lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * clip_area, + const lv_draw_rect_dsc_t * dsc); + +/** + * Draw rectangle border/outline shape with effects (rounded corners, opacity) + * + * @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff) + * @param[in] clip_area Clipping area with relative coordinates to dest buff + * @param[in] dsc Description of the rectangle border/outline + * @param[in] border True for border, False for outline + * + * @retval LV_RES_OK Draw completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) * - * @param draw_ctx drawing context - * @param dsc description of the rectangle - * @param coords the area where rectangle is clipped */ -lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); +lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const lv_area_t * clip_area, + const lv_draw_rect_dsc_t * dsc, bool border); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h b/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h new file mode 100644 index 0000000..9219dca --- /dev/null +++ b/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h @@ -0,0 +1,113 @@ +/** + * @file lv_vglite_buf.h + * + */ + +/** + * MIT License + * + * Copyright 2023 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_VGLITE_BUF_H +#define LV_VGLITE_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "vg_lite.h" +#include "../../sw/lv_draw_sw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +/** + * Init vglite destination buffer. It will be done once per frame. + * + * @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode) + * @param[in] area Destination buffer area (for width and height) + * @param[in] stride Stride of destination buffer + */ +void lv_gpu_nxp_vglite_init_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride); + +/** + * Get vglite destination buffer pointer. + * + * @retval The vglite destination buffer + */ +vg_lite_buffer_t * lv_vglite_get_dest_buf(void); + +/** + * Get vglite source buffer pointer. + * + * @retval The vglite source buffer + */ +vg_lite_buffer_t * lv_vglite_get_src_buf(void); + +/** + * Set vglite destination buffer address only. + * + * @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode) + */ +void lv_vglite_set_dest_buf_ptr(const lv_color_t * buf); + +/** + * Set vglite source buffer address only. + * + * @param[in] buf Source buffer address + */ +void lv_vglite_set_src_buf_ptr(const lv_color_t * buf); + +/** + * Set vglite source buffer. It will be done only if buffer addreess is different. + * + * @param[in] buf Source buffer address + * @param[in] area Source buffer area (for width and height) + * @param[in] stride Stride of source buffer + */ +void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VGLITE_BUF_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h b/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h new file mode 100644 index 0000000..9ff4de0 --- /dev/null +++ b/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h @@ -0,0 +1,166 @@ +/** + * @file lv_vglite_utils.h + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_VGLITE_UTILS_H +#define LV_VGLITE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "vg_lite.h" +#include "../../sw/lv_draw_sw.h" +#include "../../../misc/lv_log.h" + +/********************* + * DEFINES + *********************/ + +#ifndef LV_GPU_NXP_VG_LITE_LOG_ERRORS +/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/ +#define LV_GPU_NXP_VG_LITE_LOG_ERRORS 1 +#endif + +#ifndef LV_GPU_NXP_VG_LITE_LOG_TRACES +/** Enable logging of VG-Lite traces (\see LV_LOG_ERROR)*/ +#define LV_GPU_NXP_VG_LITE_LOG_TRACES 0 +#endif + + +/* The optimal Bezier control point offset for radial unit + * see: https://spencermortensen.com/articles/bezier-circle/ + **/ +#define BEZIER_OPTIM_CIRCLE 0.551915024494f + +/* Draw lines for control points of Bezier curves */ +#define BEZIER_DBG_CONTROL_POINTS 0 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Premultiplies and swizzles given LVGL 32bit color to obtain vglite color. + * + * @param[in/out] vg_col32 The obtained vglite color + * @param[in] lv_col32 The initial LVGL 32bit color + * @param[in] opa The opacity to premultiply with + * @param[in] vg_col_format The format of the resulting vglite color + * + * @retval LV_RES_OK Operation completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + */ +lv_res_t lv_vglite_premult_and_swizzle(vg_lite_color_t * vg_col32, lv_color32_t lv_col32, lv_opa_t opa, + vg_lite_buffer_format_t vg_col_format); + +/** + * Get vglite blend mode. + * + * @param[in] lv_blend_mode The LVGL blend mode + * + * @retval The vglite blend mode + */ +vg_lite_blend_t lv_vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode); + +/** + * Clear cache and flush command to VG-Lite. + * + * @retval LV_RES_OK Run completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + */ +lv_res_t lv_vglite_run(void); + +/********************** + * MACROS + **********************/ + +#define VG_LITE_COND_STOP(cond, txt) \ + do { \ + if (cond) { \ + LV_LOG_ERROR("%s. STOP!", txt); \ + for ( ; ; ); \ + } \ + } while(0) + +#if LV_GPU_NXP_VG_LITE_LOG_ERRORS +#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ + do { \ + if(err != VG_LITE_SUCCESS) { \ + LV_LOG_ERROR(fmt" (err = %d)", \ + err, ##__VA_ARGS__); \ + return LV_RES_INV; \ + } \ + } while (0) +#else +#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ + do { \ + if(err != VG_LITE_SUCCESS) { \ + return LV_RES_INV; \ + } \ + }while(0) +#endif /*LV_GPU_NXP_VG_LITE_LOG_ERRORS*/ + +#if LV_GPU_NXP_VG_LITE_LOG_TRACES +#define VG_LITE_LOG_TRACE(fmt, ...) \ + do { \ + LV_LOG(fmt, ##__VA_ARGS__); \ + } while (0) + +#define VG_LITE_RETURN_INV(fmt, ...) \ + do { \ + LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ + return LV_RES_INV; \ + } while (0) +#else +#define VG_LITE_LOG_TRACE(fmt, ...) \ + do { \ + } while (0) +#define VG_LITE_RETURN_INV(fmt, ...) \ + do { \ + return LV_RES_INV; \ + }while(0) +#endif /*LV_GPU_NXP_VG_LITE_LOG_TRACES*/ + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VGLITE_UTILS_H*/ diff --git a/include/liblvgl/draw/sdl/README.md b/include/liblvgl/draw/sdl/README.md new file mode 100644 index 0000000..4415ffa --- /dev/null +++ b/include/liblvgl/draw/sdl/README.md @@ -0,0 +1,28 @@ +# SDL_Renderer Based Drawing Functions + +In LVGL, drawing was performed by CPU. To improve drawing performance on platforms with GPU, +we should perform drawing operations on GPU if possible. + +This implementation has moved most bitmap blending and drawing procedures to utilize SDL_Renderer, +which takes advantages of hardware acceleration APIs like DirectX or OpenGL. + +This implementation can be also considered as a reference implementation, for contributors wants to +develop accelerated drawing functions with other APIs such as OpenGL/OpenGL ES. + +## Caveats +`lv_draw_arc`, `lv_draw_line` is not enabled, due to incomplete implementation. So lines and arcs will +have significant impact to drawing performances. + +Performance of this implementation still has room to improve. Or we should use more powerful APIs +such as OpenGL. + +## Notices for files + +### `lv_draw_sdl_stack_blur.c` + +Contains modified code from [android-stackblur](https://github.com/kikoso/android-stackblur) project. +Apache License 2.0 + +### `lv_draw_sdl_lru.c`/`lv_draw_sdl_lru.h` + +Contains modified code from [C-LRU-Cache](https://github.com/willcannings/C-LRU-Cache) project. No license defined. \ No newline at end of file diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl.h b/include/liblvgl/draw/sdl/lv_draw_sdl.h index 7708d5b..9b44a7b 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl.mk b/include/liblvgl/draw/sdl/lv_draw_sdl.mk new file mode 100644 index 0000000..c5c28b6 --- /dev/null +++ b/include/liblvgl/draw/sdl/lv_draw_sdl.mk @@ -0,0 +1,19 @@ +CSRCS += lv_draw_sdl.c +CSRCS += lv_draw_sdl_arc.c +CSRCS += lv_draw_sdl_bg.c +CSRCS += lv_draw_sdl_composite.c +CSRCS += lv_draw_sdl_img.c +CSRCS += lv_draw_sdl_label.c +CSRCS += lv_draw_sdl_line.c +CSRCS += lv_draw_sdl_mask.c +CSRCS += lv_draw_sdl_polygon.c +CSRCS += lv_draw_sdl_rect.c +CSRCS += lv_draw_sdl_stack_blur.c +CSRCS += lv_draw_sdl_texture_cache.c +CSRCS += lv_draw_sdl_utils.c +CSRCS += lv_draw_sdl_layer.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl" diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h b/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h index 3a598d7..72a2dae 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h @@ -14,13 +14,13 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #include LV_GPU_SDL_INCLUDE_PATH #include "lv_draw_sdl.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_color.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_img.h b/include/liblvgl/draw/sdl/lv_draw_sdl_img.h index d6e3758..0e27027 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_img.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_img.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h b/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h index aa4dd2b..a562d73 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h @@ -14,13 +14,13 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #include LV_GPU_SDL_INCLUDE_PATH #include "lv_draw_sdl.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_color.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h b/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h index 736fe89..24a8762 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h b/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h index fc96894..3472af3 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL @@ -59,6 +59,11 @@ typedef struct lv_draw_sdl_rect_header_t { SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius); +SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w, + lv_coord_t h, lv_coord_t radius); + +SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad); + void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture * frag, lv_coord_t frag_size, const lv_area_t * coords, const lv_area_t * clip, bool full); diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h b/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h index 3d854e3..413b1c9 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h @@ -13,7 +13,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h b/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h index 0b54246..1bbf17c 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL @@ -50,6 +50,7 @@ typedef enum { LV_GPU_CACHE_KEY_MAGIC_RECT_BG = 0x31, LV_GPU_CACHE_KEY_MAGIC_RECT_SHADOW = 0x32, LV_GPU_CACHE_KEY_MAGIC_RECT_BORDER = 0x33, + LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD = 0x34, LV_GPU_CACHE_KEY_MAGIC_FONT_GLYPH = 0x41, LV_GPU_CACHE_KEY_MAGIC_MASK = 0x51, } lv_sdl_cache_key_magic_t; diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h b/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h index 943bda3..9afae68 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h @@ -13,7 +13,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL #include "lv_draw_sdl.h" diff --git a/include/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk b/include/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk new file mode 100644 index 0000000..8ed00b0 --- /dev/null +++ b/include/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_stm32_dma2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d" diff --git a/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h b/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h index f2bcdbe..5ecce6d 100644 --- a/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h +++ b/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h @@ -10,52 +10,83 @@ extern "C" { #endif +#include "../../misc/lv_color.h" +#include "../../hal/lv_hal_disp.h" +#include "../sw/lv_draw_sw.h" + +#if LV_USE_GPU_STM32_DMA2D + /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/draw/sw/lv_draw_sw.h" - -#if LV_USE_GPU_STM32_DMA2D +#include LV_GPU_DMA2D_CMSIS_INCLUDE /********************* * DEFINES *********************/ - -#define LV_DMA2D_ARGB8888 0 -#define LV_DMA2D_RGB888 1 -#define LV_DMA2D_RGB565 2 -#define LV_DMA2D_ARGB1555 3 -#define LV_DMA2D_ARGB4444 4 +#if defined(LV_STM32_DMA2D_TEST) +// removes "static" modifier for some internal methods in order to test them +#define LV_STM32_DMA2D_STATIC +#else +#define LV_STM32_DMA2D_STATIC static +#endif /********************** * TYPEDEFS **********************/ +enum dma2d_color_format { + ARGB8888 = 0x0, + RGB888 = 0x01, + RGB565 = 0x02, + ARGB1555 = 0x03, + ARGB4444 = 0x04, + A8 = 0x09, + UNSUPPORTED = 0xff, +}; +typedef enum dma2d_color_format dma2d_color_format_t; typedef lv_draw_sw_ctx_t lv_draw_stm32_dma2d_ctx_t; - struct _lv_disp_drv_t; /********************** * GLOBAL PROTOTYPES **********************/ - -/** - * Turn on the peripheral and set output color mode, this only needs to be done once - */ void lv_draw_stm32_dma2d_init(void); - void lv_draw_stm32_dma2d_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - void lv_draw_stm32_dma2d_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); +static void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); +static void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx, + void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area, + void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area); +static lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc, + const lv_area_t * src_area, const void * src); +static void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx); +static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc, + const lv_area_t * coords, const uint8_t * src_buf, lv_img_cf_t color_format); +static dma2d_color_format_t lv_color_format_to_dma2d_color_format(lv_img_cf_t color_format); +static lv_point_t lv_area_get_offset(const lv_area_t * area1, const lv_area_t * area2); -void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); - -void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx, - void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area, - void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area); - -void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx); +/********************** + * STATIC PROTOTYPES + **********************/ +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_fill(const lv_color_t * dst_buf, lv_coord_t dst_stride, + const lv_area_t * draw_area, lv_color_t color, lv_opa_t opa); +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_map(const lv_color_t * dest_buf, lv_coord_t dest_stride, + const lv_area_t * draw_area, const void * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset, lv_opa_t opa, + dma2d_color_format_t src_color_format, bool ignore_src_alpha); +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_paint(const lv_color_t * dst_buf, lv_coord_t dst_stride, + const lv_area_t * draw_area, const lv_opa_t * mask_buf, lv_coord_t mask_stride, const lv_point_t * mask_offset, + lv_color_t color, lv_opa_t opa); +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_copy_buffer(const lv_color_t * dest_buf, lv_coord_t dest_stride, + const lv_area_t * draw_area, const lv_color_t * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset); +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_await_dma_transfer_finish(lv_disp_drv_t * disp_drv); +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_start_dma_transfer(void); +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_invalidate_cache(uint32_t address, lv_coord_t offset, + lv_coord_t width, lv_coord_t height, uint8_t pixel_size); +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_clean_cache(uint32_t address, lv_coord_t offset, lv_coord_t width, + lv_coord_t height, uint8_t pixel_size); +LV_STM32_DMA2D_STATIC bool _lv_gpu_stm32_dwt_init(void); +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dwt_reset(void); +LV_STM32_DMA2D_STATIC uint32_t _lv_gpu_stm32_dwt_get_us(void); /********************** * MACROS diff --git a/include/liblvgl/draw/sw/lv_draw_sw.h b/include/liblvgl/draw/sw/lv_draw_sw.h index 4496612..1618649 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw.h +++ b/include/liblvgl/draw/sw/lv_draw_sw.h @@ -14,10 +14,10 @@ extern "C" { * INCLUDES *********************/ #include "lv_draw_sw_blend.h" -#include "liblvgl/draw/lv_draw.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/hal/lv_hal_disp.h" +#include "../lv_draw.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" +#include "../../hal/lv_hal_disp.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sw/lv_draw_sw.mk b/include/liblvgl/draw/sw/lv_draw_sw.mk new file mode 100644 index 0000000..4625cbc --- /dev/null +++ b/include/liblvgl/draw/sw/lv_draw_sw.mk @@ -0,0 +1,17 @@ +CSRCS += lv_draw_sw.c +CSRCS += lv_draw_sw_arc.c +CSRCS += lv_draw_sw_blend.c +CSRCS += lv_draw_sw_dither.c +CSRCS += lv_draw_sw_gradient.c +CSRCS += lv_draw_sw_img.c +CSRCS += lv_draw_sw_letter.c +CSRCS += lv_draw_sw_line.c +CSRCS += lv_draw_sw_polygon.c +CSRCS += lv_draw_sw_rect.c +CSRCS += lv_draw_sw_transform.c +CSRCS += lv_draw_sw_layer.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw" diff --git a/include/liblvgl/draw/sw/lv_draw_sw_blend.h b/include/liblvgl/draw/sw/lv_draw_sw_blend.h index 6fa859c..9a00e53 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw_blend.h +++ b/include/liblvgl/draw/sw/lv_draw_sw_blend.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_style.h" -#include "liblvgl/draw/lv_draw_mask.h" +#include "../../misc/lv_color.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_style.h" +#include "../lv_draw_mask.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sw/lv_draw_sw_dither.h b/include/liblvgl/draw/sw/lv_draw_sw_dither.h index 9785e18..6362c5a 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw_dither.h +++ b/include/liblvgl/draw/sw/lv_draw_sw_dither.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj_pos.h" +#include "../../core/lv_obj_pos.h" /********************* diff --git a/include/liblvgl/draw/sw/lv_draw_sw_gradient.h b/include/liblvgl/draw/sw/lv_draw_sw_gradient.h index 0860d50..f5f3215 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw_gradient.h +++ b/include/liblvgl/draw/sw/lv_draw_sw_gradient.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_style.h" +#include "../../misc/lv_color.h" +#include "../../misc/lv_style.h" #include "lv_draw_sw_dither.h" /********************* diff --git a/include/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk b/include/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk new file mode 100644 index 0000000..bc19e38 --- /dev/null +++ b/include/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_swm341_dma2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d" diff --git a/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h b/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h index baec7fe..20b8922 100644 --- a/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h +++ b/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h @@ -13,9 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/draw/sw/lv_draw_sw.h" +#include "../../misc/lv_color.h" +#include "../../hal/lv_hal_disp.h" +#include "../sw/lv_draw_sw.h" #if LV_USE_GPU_SWM341_DMA2D diff --git a/include/liblvgl/extra/README.md b/include/liblvgl/extra/README.md new file mode 100644 index 0000000..80bb49d --- /dev/null +++ b/include/liblvgl/extra/README.md @@ -0,0 +1,31 @@ +# Extra components + +This directory contains extra (optional) components to lvgl. +It's a good place for contributions as there are less strict expectations about the completeness and flexibility of the components here. + +In other words, if you have created a complex widget from other widgets, or modified an existing widget with special events, styles or animations, or have a new feature that could work as a plugin to lvgl feel free to the share it here. + +## How to contribute +- Create a [Pull request](https://docs.lvgl.io/8.0/CONTRIBUTING.html#pull-request) with your new content +- Please and follow the [Coding style](https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md) of LVGL +- Add setter/getter functions in pair +- Update [lv_conf_template.h](https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h) +- Add description in the [docs](https://github.com/lvgl/lvgl/tree/master/docs) +- Add [examples](https://github.com/lvgl/lvgl/tree/master/examples) +- Update the [changelog](https://github.com/lvgl/lvgl/tree/master/docs/CHANGELOG.md) +- Add yourself to the [Contributors](#contributors) section below. + +## Ideas +Here some ideas as inspiration feel free to contribute with ideas too. +- New [Calendar headers](https://github.com/lvgl/lvgl/tree/master/src/extra/widgets/calendar) +- Color picker with RGB and or HSV bars +- Ruler, horizontal or vertical with major and minor ticks and labels +- New [List items types](https://github.com/lvgl/lvgl/tree/master/src/extra/widgets/list) +- [Preloaders](https://www.google.com/search?q=preloader&sxsrf=ALeKk01ddA4YB0WEgLLN1bZNSm8YER7pkg:1623080551559&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiwoN6d7oXxAhVuw4sKHVedBB4Q_AUoAXoECAEQAw&biw=952&bih=940) +- Drop-down list with a container to which content can be added +- 9 patch button: Similar to [lv_imgbtn](https://docs.lvgl.io/8.0/widgets/extra/imgbtn.html) but 9 images for 4 corner, 4 sides and the center + +## Contributors +- lv_animimg: @ZhaoQiang-b45475 +- lv_span: @guoweilkd +- lv_menu: @HX2003 \ No newline at end of file diff --git a/include/liblvgl/extra/layouts/flex/lv_flex.h b/include/liblvgl/extra/layouts/flex/lv_flex.h index d961961..58c3221 100644 --- a/include/liblvgl/extra/layouts/flex/lv_flex.h +++ b/include/liblvgl/extra/layouts/flex/lv_flex.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_FLEX /********************* diff --git a/include/liblvgl/extra/layouts/grid/lv_grid.h b/include/liblvgl/extra/layouts/grid/lv_grid.h index 8e57fd9..5c4f767 100644 --- a/include/liblvgl/extra/layouts/grid/lv_grid.h +++ b/include/liblvgl/extra/layouts/grid/lv_grid.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_GRID /********************* diff --git a/include/liblvgl/extra/libs/bmp/lv_bmp.h b/include/liblvgl/extra/libs/bmp/lv_bmp.h index 3d9e948..db1e540 100644 --- a/include/liblvgl/extra/libs/bmp/lv_bmp.h +++ b/include/liblvgl/extra/libs/bmp/lv_bmp.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_BMP /********************* diff --git a/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h b/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h index f3a365c..8c7fc26 100644 --- a/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h +++ b/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_FFMPEG != 0 /********************* diff --git a/include/liblvgl/extra/libs/freetype/arial.ttf b/include/liblvgl/extra/libs/freetype/arial.ttf new file mode 100644 index 0000000..886789b Binary files /dev/null and b/include/liblvgl/extra/libs/freetype/arial.ttf differ diff --git a/include/liblvgl/extra/libs/freetype/lv_freetype.h b/include/liblvgl/extra/libs/freetype/lv_freetype.h index e576c2e..247a7fb 100644 --- a/include/liblvgl/extra/libs/freetype/lv_freetype.h +++ b/include/liblvgl/extra/libs/freetype/lv_freetype.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_FREETYPE /********************* diff --git a/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h b/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h index 2b0adfd..285d598 100644 --- a/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h +++ b/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" /********************* * DEFINES diff --git a/include/liblvgl/extra/libs/gif/gifdec.h b/include/liblvgl/extra/libs/gif/gifdec.h index eaa4cad..b68fab5 100644 --- a/include/liblvgl/extra/libs/gif/gifdec.h +++ b/include/liblvgl/extra/libs/gif/gifdec.h @@ -2,7 +2,7 @@ #define GIFDEC_H #include -#include "liblvgl/misc/lv_fs.h" +#include "../../../misc/lv_fs.h" #if LV_USE_GIF @@ -29,7 +29,7 @@ typedef struct gd_GIF { int32_t anim_start; uint16_t width, height; uint16_t depth; - uint16_t loop_count; + int32_t loop_count; gd_GCE gce; gd_Palette *palette; gd_Palette lct, gct; diff --git a/include/liblvgl/extra/libs/gif/lv_gif.h b/include/liblvgl/extra/libs/gif/lv_gif.h index b40b690..d8c93db 100644 --- a/include/liblvgl/extra/libs/gif/lv_gif.h +++ b/include/liblvgl/extra/libs/gif/lv_gif.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_GIF #include "gifdec.h" diff --git a/include/liblvgl/extra/libs/png/lodepng.h b/include/liblvgl/extra/libs/png/lodepng.h index 4068d4b..dbfed72 100644 --- a/include/liblvgl/extra/libs/png/lodepng.h +++ b/include/liblvgl/extra/libs/png/lodepng.h @@ -28,7 +28,7 @@ freely, subject to the following restrictions: #include /*for size_t*/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_PNG extern const char* LODEPNG_VERSION_STRING; diff --git a/include/liblvgl/extra/libs/png/lv_png.h b/include/liblvgl/extra/libs/png/lv_png.h index ef63454..4380472 100644 --- a/include/liblvgl/extra/libs/png/lv_png.h +++ b/include/liblvgl/extra/libs/png/lv_png.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_PNG /********************* diff --git a/include/liblvgl/extra/libs/qrcode/lv_qrcode.h b/include/liblvgl/extra/libs/qrcode/lv_qrcode.h index c8db4e5..b0752ac 100644 --- a/include/liblvgl/extra/libs/qrcode/lv_qrcode.h +++ b/include/liblvgl/extra/libs/qrcode/lv_qrcode.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_QRCODE /********************* diff --git a/include/liblvgl/extra/libs/rlottie/lv_rlottie.h b/include/liblvgl/extra/libs/rlottie/lv_rlottie.h index a8aca7b..d66dc22 100644 --- a/include/liblvgl/extra/libs/rlottie/lv_rlottie.h +++ b/include/liblvgl/extra/libs/rlottie/lv_rlottie.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_RLOTTIE /********************* diff --git a/include/liblvgl/extra/libs/sjpg/tjpgd.h b/include/liblvgl/extra/libs/sjpg/tjpgd.h index 866e6b3..b255ccf 100644 --- a/include/liblvgl/extra/libs/sjpg/tjpgd.h +++ b/include/liblvgl/extra/libs/sjpg/tjpgd.h @@ -8,7 +8,7 @@ extern "C" { #endif -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_SJPG #include "tjpgdcnf.h" diff --git a/include/liblvgl/extra/lv_extra.mk b/include/liblvgl/extra/lv_extra.mk new file mode 100644 index 0000000..1afcc7b --- /dev/null +++ b/include/liblvgl/extra/lv_extra.mk @@ -0,0 +1 @@ +CSRCS += $(shell find -L $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra -name \*.c) diff --git a/include/liblvgl/extra/others/fragment/README.md b/include/liblvgl/extra/others/fragment/README.md new file mode 100644 index 0000000..e69de29 diff --git a/include/liblvgl/extra/others/fragment/lv_fragment.h b/include/liblvgl/extra/others/fragment/lv_fragment.h index 9b7312f..da30b39 100644 --- a/include/liblvgl/extra/others/fragment/lv_fragment.h +++ b/include/liblvgl/extra/others/fragment/lv_fragment.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../../lv_conf_internal.h" #if LV_USE_FRAGMENT -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/extra/others/gridnav/lv_gridnav.h b/include/liblvgl/extra/others/gridnav/lv_gridnav.h index 8939120..f480ded 100644 --- a/include/liblvgl/extra/others/gridnav/lv_gridnav.h +++ b/include/liblvgl/extra/others/gridnav/lv_gridnav.h @@ -53,7 +53,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_GRIDNAV diff --git a/include/liblvgl/extra/others/ime/lv_ime_pinyin.h b/include/liblvgl/extra/others/ime/lv_ime_pinyin.h index 2d70d29..3ff7bb9 100644 --- a/include/liblvgl/extra/others/ime/lv_ime_pinyin.h +++ b/include/liblvgl/extra/others/ime/lv_ime_pinyin.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_IME_PINYIN != 0 diff --git a/include/liblvgl/extra/others/imgfont/lv_imgfont.h b/include/liblvgl/extra/others/imgfont/lv_imgfont.h index 4fb6f78..5069b62 100644 --- a/include/liblvgl/extra/others/imgfont/lv_imgfont.h +++ b/include/liblvgl/extra/others/imgfont/lv_imgfont.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_IMGFONT diff --git a/include/liblvgl/extra/others/monkey/lv_monkey.h b/include/liblvgl/extra/others/monkey/lv_monkey.h index 589daf1..bf5e13c 100644 --- a/include/liblvgl/extra/others/monkey/lv_monkey.h +++ b/include/liblvgl/extra/others/monkey/lv_monkey.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_MONKEY != 0 diff --git a/include/liblvgl/extra/others/msg/lv_msg.h b/include/liblvgl/extra/others/msg/lv_msg.h index 64dc0d4..0ac2f77 100644 --- a/include/liblvgl/extra/others/msg/lv_msg.h +++ b/include/liblvgl/extra/others/msg/lv_msg.h @@ -13,12 +13,14 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_MSG /********************* * DEFINES *********************/ +#define LV_MSG_ID_ANY UINT32_MAX +LV_EXPORT_CONST_INT(LV_MSG_ID_ANY); /********************** * TYPEDEFS @@ -70,6 +72,14 @@ void * lv_msg_subsribe_obj(uint32_t msg_id, lv_obj_t * obj, void * user_data); */ void lv_msg_unsubscribe(void * s); +/** + * Unsubscribe an object from a message ID + * @param msg_id the message ID to unsubcribe from or `LV_MSG_ID_ANY` for any message ID + * @param obj the object to unsubscribe or NULL for any object + * @return number of unsubscriptions + */ +uint32_t lv_msg_unsubscribe_obj(uint32_t msg_id, lv_obj_t * obj); + /** * Send a message with a given ID and payload * @param msg_id ID of the message to send @@ -105,6 +115,17 @@ void * lv_msg_get_user_data(lv_msg_t * m); */ lv_msg_t * lv_event_get_msg(lv_event_t * e); +/*Fix typo*/ +static inline void * lv_msg_subscribe(uint32_t msg_id, lv_msg_subscribe_cb_t cb, void * user_data) +{ + return lv_msg_subsribe(msg_id, cb, user_data); +} + +static inline void * lv_msg_subscribe_obj(uint32_t msg_id, lv_obj_t * obj, void * user_data) +{ + return lv_msg_subsribe_obj(msg_id, obj, user_data); +} + /********************** * GLOBAL VARIABLES **********************/ diff --git a/include/liblvgl/extra/others/snapshot/lv_snapshot.h b/include/liblvgl/extra/others/snapshot/lv_snapshot.h index 33d9741..6451926 100644 --- a/include/liblvgl/extra/others/snapshot/lv_snapshot.h +++ b/include/liblvgl/extra/others/snapshot/lv_snapshot.h @@ -16,8 +16,8 @@ extern "C" { #include #include -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/core/lv_obj.h" +#include "../../../lv_conf_internal.h" +#include "../../../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/extra/themes/basic/lv_theme_basic.h b/include/liblvgl/extra/themes/basic/lv_theme_basic.h index 06d6828..93a8fa8 100644 --- a/include/liblvgl/extra/themes/basic/lv_theme_basic.h +++ b/include/liblvgl/extra/themes/basic/lv_theme_basic.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_THEME_BASIC diff --git a/include/liblvgl/extra/themes/default/lv_theme_default.h b/include/liblvgl/extra/themes/default/lv_theme_default.h index 7fab5be..5b1fd91 100644 --- a/include/liblvgl/extra/themes/default/lv_theme_default.h +++ b/include/liblvgl/extra/themes/default/lv_theme_default.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_THEME_DEFAULT diff --git a/include/liblvgl/extra/themes/mono/lv_theme_mono.h b/include/liblvgl/extra/themes/mono/lv_theme_mono.h index 3d907ff..10b8f18 100644 --- a/include/liblvgl/extra/themes/mono/lv_theme_mono.h +++ b/include/liblvgl/extra/themes/mono/lv_theme_mono.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/core/lv_obj.h" +#include "../../../core/lv_obj.h" #if LV_USE_THEME_MONO diff --git a/include/liblvgl/extra/widgets/animimg/lv_animimg.h b/include/liblvgl/extra/widgets/animimg/lv_animimg.h index 9ffe621..5b17f0a 100644 --- a/include/liblvgl/extra/widgets/animimg/lv_animimg.h +++ b/include/liblvgl/extra/widgets/animimg/lv_animimg.h @@ -37,7 +37,7 @@ typedef struct { lv_img_t img; lv_anim_t anim; /*picture sequence */ - lv_img_dsc_t ** dsc; + const void ** dsc; int8_t pic_count; } lv_animimg_t; @@ -69,7 +69,7 @@ lv_obj_t * lv_animimg_create(lv_obj_t * parent); * @param dsc pointer to a series images * @param num images' number */ -void lv_animimg_set_src(lv_obj_t * img, lv_img_dsc_t * dsc[], uint8_t num); +void lv_animimg_set_src(lv_obj_t * img, const void * dsc[], uint8_t num); /** * Startup the image animation. diff --git a/include/liblvgl/extra/widgets/list/lv_list.h b/include/liblvgl/extra/widgets/list/lv_list.h index e9bb626..6142aac 100644 --- a/include/liblvgl/extra/widgets/list/lv_list.h +++ b/include/liblvgl/extra/widgets/list/lv_list.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "liblvgl/core/lv_obj.h" -#include "liblvgl/extra/layouts/flex/lv_flex.h" +#include "../../layouts/flex/lv_flex.h" #if LV_USE_LIST diff --git a/include/liblvgl/font/korean.ttf b/include/liblvgl/font/korean.ttf new file mode 100644 index 0000000..e0ec117 Binary files /dev/null and b/include/liblvgl/font/korean.ttf differ diff --git a/include/liblvgl/font/lv_font.h b/include/liblvgl/font/lv_font.h index 3c0a689..d32902d 100644 --- a/include/liblvgl/font/lv_font.h +++ b/include/liblvgl/font/lv_font.h @@ -271,6 +271,11 @@ LV_FONT_DECLARE(pros_font_dejavu_mono_40); LV_FONT_DECLARE(pros_font_dejavu_mono_40_latin_sup); #endif +/*Declare the custom (user defined) fonts*/ +#ifdef LV_FONT_CUSTOM_DECLARE +LV_FONT_CUSTOM_DECLARE +#endif + /** * Just a wrapper around LV_FONT_DEFAULT because it might be more convenient to use a function in some cases * @return pointer to LV_FONT_DEFAULT diff --git a/include/liblvgl/font/lv_font.mk b/include/liblvgl/font/lv_font.mk new file mode 100644 index 0000000..2201b73 --- /dev/null +++ b/include/liblvgl/font/lv_font.mk @@ -0,0 +1,36 @@ +CSRCS += lv_font.c +CSRCS += lv_font_fmt_txt.c +CSRCS += lv_font_loader.c + +CSRCS += lv_font_dejavu_16_persian_hebrew.c +CSRCS += lv_font_montserrat_8.c +CSRCS += lv_font_montserrat_10.c +CSRCS += lv_font_montserrat_12.c +CSRCS += lv_font_montserrat_12_subpx.c +CSRCS += lv_font_montserrat_14.c +CSRCS += lv_font_montserrat_16.c +CSRCS += lv_font_montserrat_18.c +CSRCS += lv_font_montserrat_20.c +CSRCS += lv_font_montserrat_22.c +CSRCS += lv_font_montserrat_24.c +CSRCS += lv_font_montserrat_26.c +CSRCS += lv_font_montserrat_28.c +CSRCS += lv_font_montserrat_28_compressed.c +CSRCS += lv_font_montserrat_30.c +CSRCS += lv_font_montserrat_32.c +CSRCS += lv_font_montserrat_34.c +CSRCS += lv_font_montserrat_36.c +CSRCS += lv_font_montserrat_38.c +CSRCS += lv_font_montserrat_40.c +CSRCS += lv_font_montserrat_42.c +CSRCS += lv_font_montserrat_44.c +CSRCS += lv_font_montserrat_46.c +CSRCS += lv_font_montserrat_48.c +CSRCS += lv_font_simsun_16_cjk.c +CSRCS += lv_font_unscii_8.c +CSRCS += lv_font_unscii_16.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font" diff --git a/include/liblvgl/font/lv_symbol_def.h b/include/liblvgl/font/lv_symbol_def.h index 1055392..696daf1 100644 --- a/include/liblvgl/font/lv_symbol_def.h +++ b/include/liblvgl/font/lv_symbol_def.h @@ -5,7 +5,7 @@ extern "C" { #endif -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" /*------------------------------- * Symbols from "normal" font diff --git a/include/liblvgl/hal/lv_hal.mk b/include/liblvgl/hal/lv_hal.mk new file mode 100644 index 0000000..c35ec2d --- /dev/null +++ b/include/liblvgl/hal/lv_hal.mk @@ -0,0 +1,8 @@ +CSRCS += lv_hal_disp.c +CSRCS += lv_hal_indev.c +CSRCS += lv_hal_tick.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal" diff --git a/include/liblvgl/hal/lv_hal_disp.h b/include/liblvgl/hal/lv_hal_disp.h index 5b36916..d3425fe 100644 --- a/include/liblvgl/hal/lv_hal_disp.h +++ b/include/liblvgl/hal/lv_hal_disp.h @@ -18,11 +18,11 @@ extern "C" { #include #include #include "lv_hal.h" -#include "liblvgl/draw/lv_draw.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_ll.h" -#include "liblvgl/misc/lv_timer.h" +#include "../draw/lv_draw.h" +#include "../misc/lv_color.h" +#include "../misc/lv_area.h" +#include "../misc/lv_ll.h" +#include "../misc/lv_timer.h" /********************* * DEFINES diff --git a/include/liblvgl/hal/lv_hal_indev.h b/include/liblvgl/hal/lv_hal_indev.h index 630d471..5bbcf53 100644 --- a/include/liblvgl/hal/lv_hal_indev.h +++ b/include/liblvgl/hal/lv_hal_indev.h @@ -15,12 +15,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_timer.h" +#include "../misc/lv_area.h" +#include "../misc/lv_timer.h" /********************* * DEFINES @@ -141,6 +141,7 @@ typedef struct _lv_indev_proc_t { struct { /*Pointer and button data*/ lv_point_t act_point; /**< Current point of input device.*/ + lv_point_t indev_point; lv_point_t last_point; /**< Last point of input device.*/ lv_point_t last_raw_point; /**< Last point read from read_cb. */ lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/ diff --git a/include/liblvgl/hal/lv_hal_tick.h b/include/liblvgl/hal/lv_hal_tick.h index 407fa42..949f56b 100644 --- a/include/liblvgl/hal/lv_hal_tick.h +++ b/include/liblvgl/hal/lv_hal_tick.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include diff --git a/include/liblvgl/lv_conf.old.h b/include/liblvgl/lv_conf.old.h deleted file mode 100644 index 16deedd..0000000 --- a/include/liblvgl/lv_conf.old.h +++ /dev/null @@ -1,341 +0,0 @@ -/** - * @file lv_conf.h - * - */ - -#ifndef LV_CONF_H -#define LV_CONF_H - -/*---------------- - * Dynamic memory - *----------------*/ - -/* Memory size which will be used by the library - * to store the graphical objects and other data */ -#define LV_MEM_CUSTOM \ - 0 /*1: use custom malloc/free, 0: use the built-in \ - lv_mem_alloc/lv_mem_free*/ -#if LV_MEM_CUSTOM == 0 -#define LV_MEM_SIZE \ - (32U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ -#define LV_MEM_ATTR /*Complier prefix for big array declaration*/ -#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ -#else /*LV_MEM_CUSTOM*/ -#define LV_MEM_CUSTOM_INCLUDE \ - /*Header for the dynamic memory function*/ -#define LV_MEM_CUSTOM_ALLOC kmalloc /*Wrapper to malloc*/ -#define LV_MEM_CUSTOM_FREE kfree /*Wrapper to free*/ -#endif /*LV_MEM_CUSTOM*/ -#define LV_ENABLE_GC 0 - -/*=================== - Graphical settings - *===================*/ - -/* Horizontal and vertical resolution of the library.*/ -#define LV_HOR_RES (480) -#define LV_VER_RES (240) -#define LV_DPI 126 - -/* Size of VDB (Virtual Display Buffer: the internal graphics buffer). - * Required for buffered drawing, opacity and anti-aliasing - * VDB makes the double buffering, you don't need to deal with it! - * Typical size: ~1/10 screen */ -#define LV_VDB_SIZE \ - (LV_VER_RES * \ - LV_HOR_RES) /*Size of VDB in pixel count (1/10 screen size is good for \ - first)*/ -#define LV_VDB_ADR \ - 0 /*Place VDB to a specific address (e.g. in external RAM) (0: allocate \ - automatically into RAM)*/ - -/* Use two Virtual Display buffers (VDB) parallelize rendering and flushing - * (optional) - * The flushing should use DMA to write the frame buffer in the background*/ -#define LV_VDB_DOUBLE 0 /*1: Enable the use of 2 VDBs*/ -#define LV_VDB2_ADR \ - 0 /*Place VDB2 to a specific address (e.g. in external RAM) (0: allocate \ - automatically into RAM)*/ - -/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ -#define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ - -/*Screen refresh settings*/ -#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/ -#define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */ - -/*================= - Misc. setting - *=================*/ - -/*Input device settings*/ -#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ -#define LV_INDEV_POINT_MARKER \ - 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/ -#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ -#define LV_INDEV_DRAG_THROW \ - 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */ -#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/ -#define LV_INDEV_LONG_PRESS_REP_TIME \ - 100 /*Repeated trigger period in long press [ms] */ - -/*Color settings*/ -#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/24*/ -#define LV_COLOR_TRANSP \ - LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma \ - keying)*/ - -/*Text settings*/ -#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */ -#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ -#define LV_TXT_LINE_BREAK_LONG_LEN 12 -#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 -#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 1 - -/*Graphics feature usage*/ -#define USE_LV_ANIMATION 1 /*1: Enable all animations*/ -#define USE_LV_SHADOW 1 /*1: Enable shadows*/ -#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ -#define USE_LV_GPU 0 /*1: Enable GPU interface*/ -#define USE_LV_REAL_DRAW \ - 1 /*1: Enable function which draw directly to the frame buffer instead of \ - VDB (required if LV_VDB_SIZE = 0)*/ -#define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/ -#define USE_LV_MULTI_LANG 1 - -/*Compiler attributes*/ -#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to tick increment \ - function */ -#define LV_ATTRIBUTE_TASK_HANDLER -#define LV_ATTRIBUTE_MEM_ALIGN -#define LV_COMPILER_VLA_SUPPORTED 1 -#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 1 - -#define USE_LV_LOG 0 -/*================ - * THEME USAGE - *================*/ -#define LV_THEME_LIVE_UPDATE 1 -#define USE_LV_THEME_TEMPL 0 /*Just for test*/ -#define USE_LV_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/ -#define USE_LV_THEME_ALIEN 1 /*Dark futuristic theme*/ -#define USE_LV_THEME_NIGHT 1 /*Dark elegant theme*/ -#define USE_LV_THEME_MONO 1 /*Mono color theme for monochrome displays*/ -#define USE_LV_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ -#define USE_LV_THEME_ZEN 1 /*Peaceful, mainly light theme */ - -/*================== - * FONT USAGE - *===================*/ - -/* More info about fonts: https://littlevgl.com/basics#fonts - * To enable a built-in font use 1,2,4 or 8 values - * which will determine the bit-per-pixel */ -#define LV_FONT_DEFAULT \ - &lv_font_dejavu_20 /*Always set a default font from the built-in fonts*/ - -#define USE_LV_FONT_DEJAVU_10 4 -#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 4 -#define USE_LV_FONT_DEJAVU_10_CYRILLIC 4 -#define USE_LV_FONT_SYMBOL_10 4 - -#define USE_LV_FONT_DEJAVU_20 4 -#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 4 -#define USE_LV_FONT_DEJAVU_20_CYRILLIC 4 -#define USE_LV_FONT_SYMBOL_20 4 - -#define USE_LV_FONT_DEJAVU_30 0 -#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 0 -#define USE_LV_FONT_DEJAVU_30_CYRILLIC 0 -#define USE_LV_FONT_SYMBOL_30 0 - -#define USE_LV_FONT_DEJAVU_40 0 -#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 0 -#define USE_LV_FONT_DEJAVU_40_CYRILLIC 0 -#define USE_LV_FONT_SYMBOL_40 0 - -/* PROS adds the mono variant of DejaVu sans */ -#define USE_PROS_FONT_DEJAVU_MONO_10 4 -#define USE_PROS_FONT_DEJAVU_MONO_10_LATIN_SUP 4 - -#define USE_PROS_FONT_DEJAVU_MONO_20 4 -#define USE_PROS_FONT_DEJAVU_MONO_LATIN_SUP_20 4 - -#define USE_PROS_FONT_DEJAVU_MONO_30 0 -#define USE_PROS_FONT_DEJAVU_MONO_30_LATIN_SUP 0 - -#define USE_PROS_FONT_DEJAVU_MONO_40 0 -#define USE_PROS_FONT_DEJAVU_MONO_40_LATIN_SUP 0 - -/*=================== - * LV_OBJ SETTINGS - *==================*/ -#define LV_OBJ_FREE_NUM_TYPE \ - uint32_t /*Type of free number attribute (comment out disable free number)*/ -#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/ - -/*================== - * LV OBJ X USAGE - *================*/ -/* - * Documentation of the object types: https://littlevgl.com/object-types - */ - -/***************** - * Simple object - *****************/ - -/*Label (dependencies: -*/ -#define USE_LV_LABEL 1 -#if USE_LV_LABEL != 0 -#define LV_LABEL_SCROLL_SPEED \ - 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' \ - mode*/ -#endif - -/*Image (dependencies: lv_label*/ -#define USE_LV_IMG 1 -#if USE_LV_IMG != 0 -# define LV_IMG_CF_INDEXED 1 -# define LV_IMG_CF_ALPHA 1 -#endif - -/*Line (dependencies: -*/ -#define USE_LV_LINE 1 -#define USE_LV_ARC 1 - -/******************* - * Container objects - *******************/ - -/*Container (dependencies: -*/ -#define USE_LV_CONT 1 - -/*Page (dependencies: lv_cont)*/ -#define USE_LV_PAGE 1 - -/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ -#define USE_LV_WIN 1 - -/*Tab (dependencies: lv_page, lv_btnm)*/ -#define USE_LV_TABVIEW 1 -#if USE_LV_TABVIEW != 0 -#define LV_TABVIEW_ANIM_TIME \ - 300 /*Time of slide animation [ms] (0: no animation)*/ -#endif -#define USE_LV_TILEVIEW 1 -#if USE_LV_TILEVIEW -# define LV_TILEVIEW_ANIM_TIME 300 -#endif - - -/************************* - * Data visualizer objects - *************************/ - -/*Bar (dependencies: -)*/ -#define USE_LV_BAR 1 - -/*Line meter (dependencies: *;)*/ -#define USE_LV_LMETER 1 - -/*Gauge (dependencies:bar, lmeter)*/ -#define USE_LV_GAUGE 1 - -/*Chart (dependencies: -)*/ -#define USE_LV_CHART 1 - -#define USE_LV_TABLE 1 -#if USE_LV_TABLE -# define LV_TABLE_COL_MAX 12 -#endif - -/*LED (dependencies: -)*/ -#define USE_LV_LED 1 - -/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ -#define USE_LV_MBOX 1 - -/*Text area (dependencies: lv_label, lv_page)*/ -#define USE_LV_TA 1 -#if USE_LV_TA != 0 -#define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/ -#define LV_TA_PWD_SHOW_TIME 1500 /*ms*/ -#endif - -#define USE_LV_SPINBOX 1 -#define USE_LV_CALENDAR 1 - -#define USE_PRELOAD 1 -#if USE_LV_PRELOAD != 0 -# define LV_PRELOAD_DEF_ARC_LENGTH 60 -# define LV_PRELOAD_DEF_SPIN_TIME 1000 -# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC -#endif - -#define USE_LV_CANVAS 1 -/************************* - * User input objects - *************************/ - -/*Button (dependencies: lv_cont*/ -#define USE_LV_BTN 1 -#if USE_LV_BTN != 0 -# define LV_BTN_INK_EFFECT 1 -#endif - -#define USE_LV_IMGBTN 1 -#if USE_LV_IMGBTN -# define LV_IMGBTN_TILED 0 -#endif - -/*Button matrix (dependencies: -)*/ -#define USE_LV_BTNM 1 - -/*Keyboard (dependencies: lv_btnm)*/ -#define USE_LV_KB 1 - -/*Check box (dependencies: lv_btn, lv_label)*/ -#define USE_LV_CB 1 - -/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons - * ))*/ -#define USE_LV_LIST 1 -#if USE_LV_LIST != 0 -#define LV_LIST_FOCUS_TIME \ - 100 /*Default animation time of focusing to a list element [ms] (0: no \ - animation) */ -#endif - -/*Drop down list (dependencies: lv_page, lv_label)*/ -#define USE_LV_DDLIST 1 -#if USE_LV_DDLIST != 0 -#define LV_DDLIST_ANIM_TIME \ - 200 /*Open and close default animation time [ms] (0: no animation)*/ -#endif - -/*Roller (dependencies: lv_ddlist)*/ -#define USE_LV_ROLLER 1 -#if USE_LV_ROLLER != 0 -#define LV_ROLLER_ANIM_TIME \ - 200 /*Focus animation time [ms] (0: no \ - animation)*/ -#endif - -/*Slider (dependencies: lv_bar)*/ -#define USE_LV_SLIDER 1 - -/*Switch (dependencies: lv_slider)*/ -#define USE_LV_SW 1 - -#if LV_INDEV_DRAG_THROW <= 0 -#warning "LV_INDEV_DRAG_THROW must be greater than 0" -#undef LV_INDEV_DRAG_THROW -#define LV_INDEV_DRAG_THROW 1 -#endif - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -# define _CRT_SECURE_NO_WARNINGS -#endif -#include "liblvgl/lv_conf_checker.h" -#endif /*LV_CONF_H*/ diff --git a/include/liblvgl/lv_conf_checker.h b/include/liblvgl/lv_conf_checker.h deleted file mode 100644 index 3a8ead5..0000000 --- a/include/liblvgl/lv_conf_checker.h +++ /dev/null @@ -1,664 +0,0 @@ -/** - * GENERATED FILE, DO NOT EDIT IT! - * @file lv_conf_checker.h - * Make sure all the defines of lv_conf.h have a default value -**/ - -#ifndef LV_CONF_CHECKER_H -#define LV_CONF_CHECKER_H -/*=================== - Dynamic memory - *===================*/ - -/* Memory size which will be used by the library - * to store the graphical objects and other data */ -#ifndef LV_MEM_CUSTOM -#define LV_MEM_CUSTOM 0 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/ -#endif -#if LV_MEM_CUSTOM == 0 -#ifndef LV_MEM_SIZE -# define LV_MEM_SIZE (64U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ -#endif -#ifndef LV_MEM_ATTR -# define LV_MEM_ATTR /*Complier prefix for big array declaration*/ -#endif -#ifndef LV_MEM_ADR -# define LV_MEM_ADR 0 /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/ -#endif -#ifndef LV_MEM_AUTO_DEFRAG -# define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ -#endif -#else /*LV_MEM_CUSTOM*/ -#ifndef LV_MEM_CUSTOM_INCLUDE -# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ -#endif -#ifndef LV_MEM_CUSTOM_ALLOC -# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ -#endif -#ifndef LV_MEM_CUSTOM_FREE -# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ -#endif -#endif /*LV_MEM_CUSTOM*/ - -/* Garbage Collector settings - * Used if lvgl is binded to higher language and the memory is managed by that language */ -#ifndef LV_ENABLE_GC -#define LV_ENABLE_GC 0 -#endif -#if LV_ENABLE_GC != 0 -#ifndef LV_MEM_CUSTOM_REALLOC -# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ -#endif -#ifndef LV_MEM_CUSTOM_GET_SIZE -# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ -#endif -#ifndef LV_GC_INCLUDE -# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ -#endif -#endif /* LV_ENABLE_GC */ - -/*=================== - Graphical settings - *===================*/ - -/* Horizontal and vertical resolution of the library.*/ -#ifndef LV_HOR_RES -#define LV_HOR_RES (480) -#endif -#ifndef LV_VER_RES -#define LV_VER_RES (320) -#endif - -/* Dot Per Inch: used to initialize default sizes. E.g. a button with width = LV_DPI / 2 -> half inch wide - * (Not so important, you can adjust it to modify default sizes and spaces)*/ -#ifndef LV_DPI -#define LV_DPI 100 -#endif - -/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ -#ifndef LV_ANTIALIAS -#define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ -#endif - -/*Screen refresh period in milliseconds*/ -#ifndef LV_REFR_PERIOD -#define LV_REFR_PERIOD 30 -#endif - -/*----------------- - * VDB settings - *----------------*/ - -/* VDB (Virtual Display Buffer) is an internal graphics buffer. - * The GUI will be drawn into this buffer first and then - * the buffer will be passed to your `disp_drv.disp_flush` function to - * copy it to your frame buffer. - * VDB is required for: buffered drawing, opacity, anti-aliasing and shadows - * Learn more: https://docs.littlevgl.com/#Drawing*/ - -/* Size of the VDB in pixels. Typical size: ~1/10 screen. Must be >= LV_HOR_RES - * Setting it to 0 will disable VDB and `disp_drv.disp_fill` and `disp_drv.disp_map` functions - * will be called to draw to the frame buffer directly*/ -#ifndef LV_VDB_SIZE -#define LV_VDB_SIZE ((LV_VER_RES * LV_HOR_RES) / 10) -#endif - - /* Bit-per-pixel of VDB. Useful for monochrome or non-standard color format displays. - * Special formats are handled with `disp_drv.vdb_wr`)*/ -#ifndef LV_VDB_PX_BPP -#define LV_VDB_PX_BPP LV_COLOR_SIZE /*LV_COLOR_SIZE comes from LV_COLOR_DEPTH below to set 8, 16 or 32 bit pixel size automatically */ -#endif - - /* Place VDB to a specific address (e.g. in external RAM) - * 0: allocate automatically into RAM - * LV_VDB_ADR_INV: to replace it later with `lv_vdb_set_adr()`*/ -#ifndef LV_VDB_ADR -#define LV_VDB_ADR 0 -#endif - -/* Use two Virtual Display buffers (VDB) to parallelize rendering and flushing - * The flushing should use DMA to write the frame buffer in the background */ -#ifndef LV_VDB_DOUBLE -#define LV_VDB_DOUBLE 0 -#endif - -/* Place VDB2 to a specific address (e.g. in external RAM) - * 0: allocate automatically into RAM - * LV_VDB_ADR_INV: to replace it later with `lv_vdb_set_adr()`*/ -#ifndef LV_VDB2_ADR -#define LV_VDB2_ADR 0 -#endif - -/* Using true double buffering in `disp_drv.disp_flush` you will always get the image of the whole screen. - * Your only task is to set the rendered image (`color_p` parameter) as frame buffer address or send it to your display. - * The best if you do in the blank period of you display to avoid tearing effect. - * Requires: - * - LV_VDB_SIZE = LV_HOR_RES * LV_VER_RES - * - LV_VDB_DOUBLE = 1 - */ -#ifndef LV_VDB_TRUE_DOUBLE_BUFFERED -#define LV_VDB_TRUE_DOUBLE_BUFFERED 0 -#endif - -/*================= - Misc. setting - *=================*/ - -/*Input device settings*/ -#ifndef LV_INDEV_READ_PERIOD -#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ -#endif -#ifndef LV_INDEV_POINT_MARKER -#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/ -#endif -#ifndef LV_INDEV_DRAG_LIMIT -#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ -#endif -#ifndef LV_INDEV_DRAG_THROW -#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%] (must be > 0). Greater value means faster slow-down */ -#endif -#ifndef LV_INDEV_LONG_PRESS_TIME -#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/ -#endif -#ifndef LV_INDEV_LONG_PRESS_REP_TIME -#define LV_INDEV_LONG_PRESS_REP_TIME 100 /*Repeated trigger period in long press [ms] */ -#endif - -/*Color settings*/ -#ifndef LV_COLOR_DEPTH -#define LV_COLOR_DEPTH 16 /*Color depth: 1/8/16/32*/ -#endif -#ifndef LV_COLOR_16_SWAP -#define LV_COLOR_16_SWAP 0 /*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/ -#endif -#ifndef LV_COLOR_SCREEN_TRANSP -#define LV_COLOR_SCREEN_TRANSP 0 /*1: Enable screen transparency. Useful for OSD or other overlapping GUIs. Requires ARGB8888 colors*/ -#endif -#ifndef LV_COLOR_TRANSP -#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/ -#endif - -/*Text settings*/ -#ifndef LV_TXT_UTF8 -#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */ -#endif -#ifndef LV_TXT_BREAK_CHARS -#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ -#endif -#ifndef LV_TXT_LINE_BREAK_LONG_LEN -#define LV_TXT_LINE_BREAK_LONG_LEN 12 /* If a character is at least this long, will break wherever "prettiest" */ -#endif -#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN -#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 /* Minimum number of characters of a word to put on a line before a break */ -#endif -#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN -#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 1 /* Minimum number of characters of a word to put on a line after a break */ -#endif - -/*Feature usage*/ -#ifndef USE_LV_ANIMATION -#define USE_LV_ANIMATION 1 /*1: Enable all animations*/ -#endif -#ifndef USE_LV_SHADOW -#define USE_LV_SHADOW 1 /*1: Enable shadows*/ -#endif -#ifndef USE_LV_GROUP -#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ -#endif -#ifndef USE_LV_GPU -#define USE_LV_GPU 1 /*1: Enable GPU interface*/ -#endif -#ifndef USE_LV_REAL_DRAW -#define USE_LV_REAL_DRAW 1 /*1: Enable function which draw directly to the frame buffer instead of VDB (required if LV_VDB_SIZE = 0)*/ -#endif -#ifndef USE_LV_FILESYSTEM -#define USE_LV_FILESYSTEM 1 /*1: Enable file system (might be required for images*/ -#endif -#ifndef USE_LV_MULTI_LANG -#define USE_LV_MULTI_LANG 0 /* Number of languages for labels to store (0: to disable this feature)*/ -#endif - -/*Compiler settings*/ -#ifndef LV_ATTRIBUTE_TICK_INC -#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to `lv_tick_inc` function */ -#endif -#ifndef LV_ATTRIBUTE_TASK_HANDLER -#define LV_ATTRIBUTE_TASK_HANDLER /* Define a custom attribute to `lv_task_handler` function */ -#endif -#ifndef LV_ATTRIBUTE_MEM_ALIGN -#define LV_ATTRIBUTE_MEM_ALIGN /* With size optimization (-Os) the compiler might not align data to 4 or 8 byte boundary. This alignment will be explicitly applied where needed.*/ -#endif -#ifndef LV_COMPILER_VLA_SUPPORTED -#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/ -#endif -#ifndef LV_COMPILER_NON_CONST_INIT_SUPPORTED -#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 1 /* 1: Initialization with non constant values are supported */ -#endif - -/*HAL settings*/ -#ifndef LV_TICK_CUSTOM -#define LV_TICK_CUSTOM 0 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */ -#endif -#if LV_TICK_CUSTOM == 1 -#ifndef LV_TICK_CUSTOM_INCLUDE -#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/ -#endif -#ifndef LV_TICK_CUSTOM_SYS_TIME_EXPR -#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/ -#endif -#endif /*LV_TICK_CUSTOM*/ - - -/*Log settings*/ -#ifndef USE_LV_LOG -#define USE_LV_LOG 1 /*Enable/disable the log module*/ -#endif -#if USE_LV_LOG -/* How important log should be added: - * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information - * LV_LOG_LEVEL_INFO Log important events - * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't caused problem - * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail - */ -#ifndef LV_LOG_LEVEL -# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN -#endif -/* 1: Print the log with 'printf'; 0: user need to register a callback*/ - -#ifndef LV_LOG_PRINTF -# define LV_LOG_PRINTF 0 -#endif -#endif /*USE_LV_LOG*/ - -/*================ - * THEME USAGE - *================*/ -#ifndef LV_THEME_LIVE_UPDATE -#define LV_THEME_LIVE_UPDATE 1 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/ -#endif - -#ifndef USE_LV_THEME_TEMPL -#define USE_LV_THEME_TEMPL 0 /*Just for test*/ -#endif -#ifndef USE_LV_THEME_DEFAULT -#define USE_LV_THEME_DEFAULT 1 /*Built mainly from the built-in styles. Consumes very few RAM*/ -#endif -#ifndef USE_LV_THEME_ALIEN -#define USE_LV_THEME_ALIEN 1 /*Dark futuristic theme*/ -#endif -#ifndef USE_LV_THEME_NIGHT -#define USE_LV_THEME_NIGHT 1 /*Dark elegant theme*/ -#endif -#ifndef USE_LV_THEME_MONO -#define USE_LV_THEME_MONO 1 /*Mono color theme for monochrome displays*/ -#endif -#ifndef USE_LV_THEME_MATERIAL -#define USE_LV_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ -#endif -#ifndef USE_LV_THEME_ZEN -#define USE_LV_THEME_ZEN 1 /*Peaceful, mainly light theme */ -#endif -#ifndef USE_LV_THEME_NEMO -#define USE_LV_THEME_NEMO 1 /*Water-like theme based on the movie "Finding Nemo"*/ -#endif - -/*================== - * FONT USAGE - *===================*/ - -/* More info about fonts: https://docs.littlevgl.com/#Fonts - * To enable a built-in font use 1,2,4 or 8 values - * which will determine the bit-per-pixel. Higher value means smoother fonts */ -#ifndef USE_LV_FONT_DEJAVU_10 -#define USE_LV_FONT_DEJAVU_10 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_10_LATIN_SUP -#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_10_CYRILLIC -#define USE_LV_FONT_DEJAVU_10_CYRILLIC 4 -#endif -#ifndef USE_LV_FONT_SYMBOL_10 -#define USE_LV_FONT_SYMBOL_10 4 -#endif - -#ifndef USE_LV_FONT_DEJAVU_20 -#define USE_LV_FONT_DEJAVU_20 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_20_LATIN_SUP -#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_20_CYRILLIC -#define USE_LV_FONT_DEJAVU_20_CYRILLIC 4 -#endif -#ifndef USE_LV_FONT_SYMBOL_20 -#define USE_LV_FONT_SYMBOL_20 4 -#endif - -#ifndef USE_LV_FONT_DEJAVU_30 -#define USE_LV_FONT_DEJAVU_30 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_30_LATIN_SUP -#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_30_CYRILLIC -#define USE_LV_FONT_DEJAVU_30_CYRILLIC 4 -#endif -#ifndef USE_LV_FONT_SYMBOL_30 -#define USE_LV_FONT_SYMBOL_30 4 -#endif - -#ifndef USE_LV_FONT_DEJAVU_40 -#define USE_LV_FONT_DEJAVU_40 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_40_LATIN_SUP -#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 4 -#endif -#ifndef USE_LV_FONT_DEJAVU_40_CYRILLIC -#define USE_LV_FONT_DEJAVU_40_CYRILLIC 4 -#endif -#ifndef USE_LV_FONT_SYMBOL_40 -#define USE_LV_FONT_SYMBOL_40 4 -#endif - -#ifndef USE_LV_FONT_MONOSPACE_8 -#define USE_LV_FONT_MONOSPACE_8 1 -#endif - -/* Optionally declare your custom fonts here. - * You can use these fonts as default font too - * and they will be available globally. E.g. - * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ - * LV_FONT_DECLARE(my_font_2) \ - */ -#ifndef LV_FONT_CUSTOM_DECLARE -#define LV_FONT_CUSTOM_DECLARE -#endif - - -#ifndef LV_FONT_DEFAULT -#define LV_FONT_DEFAULT &lv_font_dejavu_20 /*Always set a default font from the built-in fonts*/ -#endif - -/*=================== - * LV_OBJ SETTINGS - *==================*/ -#ifndef LV_OBJ_FREE_NUM_TYPE -#define LV_OBJ_FREE_NUM_TYPE uint32_t /*Type of free number attribute (comment out disable free number)*/ -#endif -#ifndef LV_OBJ_FREE_PTR -#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/ -#endif -#ifndef LV_OBJ_REALIGN -#define LV_OBJ_REALIGN 1 /*Enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/ -#endif - -/*================== - * LV OBJ X USAGE - *================*/ -/* - * Documentation of the object types: https://docs.littlevgl.com/#Object-types - */ - -/***************** - * Simple object - *****************/ - -/*Label (dependencies: -*/ -#ifndef USE_LV_LABEL -#define USE_LV_LABEL 1 -#endif -#if USE_LV_LABEL != 0 -#ifndef LV_LABEL_SCROLL_SPEED -# define LV_LABEL_SCROLL_SPEED 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/ -#endif -#endif - -/*Image (dependencies: lv_label*/ -#ifndef USE_LV_IMG -#define USE_LV_IMG 1 -#endif -#if USE_LV_IMG != 0 -#ifndef LV_IMG_CF_INDEXED -# define LV_IMG_CF_INDEXED 1 /*Enable indexed (palette) images*/ -#endif -#ifndef LV_IMG_CF_ALPHA -# define LV_IMG_CF_ALPHA 1 /*Enable alpha indexed images*/ -#endif -#endif - -/*Line (dependencies: -*/ -#ifndef USE_LV_LINE -#define USE_LV_LINE 1 -#endif - -/*Arc (dependencies: -)*/ -#ifndef USE_LV_ARC -#define USE_LV_ARC 1 -#endif - -/******************* - * Container objects - *******************/ - -/*Container (dependencies: -*/ -#ifndef USE_LV_CONT -#define USE_LV_CONT 1 -#endif - -/*Page (dependencies: lv_cont)*/ -#ifndef USE_LV_PAGE -#define USE_LV_PAGE 1 -#endif - -/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ -#ifndef USE_LV_WIN -#define USE_LV_WIN 1 -#endif - -/*Tab (dependencies: lv_page, lv_btnm)*/ -#ifndef USE_LV_TABVIEW -#define USE_LV_TABVIEW 1 -#endif -# if USE_LV_TABVIEW != 0 -#ifndef LV_TABVIEW_ANIM_TIME -# define LV_TABVIEW_ANIM_TIME 300 /*Time of slide animation [ms] (0: no animation)*/ -#endif -#endif - -/*Tileview (dependencies: lv_page) */ -#ifndef USE_LV_TILEVIEW -#define USE_LV_TILEVIEW 1 -#endif -#if USE_LV_TILEVIEW -#ifndef LV_TILEVIEW_ANIM_TIME -# define LV_TILEVIEW_ANIM_TIME 300 /*Time of slide animation [ms] (0: no animation)*/ -#endif -#endif - -/************************* - * Data visualizer objects - *************************/ - -/*Bar (dependencies: -)*/ -#ifndef USE_LV_BAR -#define USE_LV_BAR 1 -#endif - -/*Line meter (dependencies: *;)*/ -#ifndef USE_LV_LMETER -#define USE_LV_LMETER 1 -#endif - -/*Gauge (dependencies:lv_bar, lv_lmeter)*/ -#ifndef USE_LV_GAUGE -#define USE_LV_GAUGE 1 -#endif - -/*Chart (dependencies: -)*/ -#ifndef USE_LV_CHART -#define USE_LV_CHART 1 -#endif - -/*Table (dependencies: lv_label)*/ -#ifndef USE_LV_TABLE -#define USE_LV_TABLE 1 -#endif -#if USE_LV_TABLE -#ifndef LV_TABLE_COL_MAX -# define LV_TABLE_COL_MAX 12 -#endif -#endif - -/*LED (dependencies: -)*/ -#ifndef USE_LV_LED -#define USE_LV_LED 1 -#endif - -/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ -#ifndef USE_LV_MBOX -#define USE_LV_MBOX 1 -#endif - -/*Text area (dependencies: lv_label, lv_page)*/ -#ifndef USE_LV_TA -#define USE_LV_TA 1 -#endif -#if USE_LV_TA != 0 -#ifndef LV_TA_CURSOR_BLINK_TIME -# define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/ -#endif -#ifndef LV_TA_PWD_SHOW_TIME -# define LV_TA_PWD_SHOW_TIME 1500 /*ms*/ -#endif -#endif - -/*Spinbox (dependencies: lv_ta)*/ -#ifndef USE_LV_SPINBOX -#define USE_LV_SPINBOX 1 -#endif - -/*Calendar (dependencies: -)*/ -#ifndef USE_LV_CALENDAR -#define USE_LV_CALENDAR 1 -#endif - -/*Preload (dependencies: lv_arc)*/ -#ifndef USE_LV_PRELOAD -#define USE_LV_PRELOAD 1 -#endif -#if USE_LV_PRELOAD != 0 -#ifndef LV_PRELOAD_DEF_ARC_LENGTH -# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/ -#endif -#ifndef LV_PRELOAD_DEF_SPIN_TIME -# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ -#endif -#ifndef LV_PRELOAD_DEF_ANIM -# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC -#endif -#endif - -/*Canvas (dependencies: lv_img)*/ -#ifndef USE_LV_CANVAS -#define USE_LV_CANVAS 1 -#endif -/************************* - * User input objects - *************************/ - -/*Button (dependencies: lv_cont*/ -#ifndef USE_LV_BTN -#define USE_LV_BTN 1 -#endif -#if USE_LV_BTN != 0 -#ifndef LV_BTN_INK_EFFECT -# define LV_BTN_INK_EFFECT 1 /*Enable button-state animations - draw a circle on click (dependencies: USE_LV_ANIMATION)*/ -#endif -#endif - -/*Image Button (dependencies: lv_btn*/ -#ifndef USE_LV_IMGBTN -#define USE_LV_IMGBTN 1 -#endif -#if USE_LV_IMGBTN -#ifndef LV_IMGBTN_TILED -# define LV_IMGBTN_TILED 0 /*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ -#endif -#endif - -/*Button matrix (dependencies: -)*/ -#ifndef USE_LV_BTNM -#define USE_LV_BTNM 1 -#endif - -/*Keyboard (dependencies: lv_btnm)*/ -#ifndef USE_LV_KB -#define USE_LV_KB 1 -#endif - -/*Check box (dependencies: lv_btn, lv_label)*/ -#ifndef USE_LV_CB -#define USE_LV_CB 1 -#endif - -/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ -#ifndef USE_LV_LIST -#define USE_LV_LIST 1 -#endif -#if USE_LV_LIST != 0 -#ifndef LV_LIST_FOCUS_TIME -# define LV_LIST_FOCUS_TIME 100 /*Default animation time of focusing to a list element [ms] (0: no animation) */ -#endif -#endif - -/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ -#ifndef USE_LV_DDLIST -#define USE_LV_DDLIST 1 -#endif -#if USE_LV_DDLIST != 0 -#ifndef LV_DDLIST_ANIM_TIME -# define LV_DDLIST_ANIM_TIME 200 /*Open and close default animation time [ms] (0: no animation)*/ -#endif -#endif - -/*Roller (dependencies: lv_ddlist)*/ -#ifndef USE_LV_ROLLER -#define USE_LV_ROLLER 1 -#endif -#if USE_LV_ROLLER != 0 -#ifndef LV_ROLLER_ANIM_TIME -# define LV_ROLLER_ANIM_TIME 200 /*Focus animation time [ms] (0: no animation)*/ -#endif -#endif - -/*Slider (dependencies: lv_bar)*/ -#ifndef USE_LV_SLIDER -#define USE_LV_SLIDER 1 -#endif - -/*Switch (dependencies: lv_slider)*/ -#ifndef USE_LV_SW -#define USE_LV_SW 1 -#endif - -/************************* - * Non-user section - *************************/ - -#if LV_INDEV_DRAG_THROW <= 0 -#warning "LV_INDEV_DRAG_THROW must be greater than 0" -#undef LV_INDEV_DRAG_THROW -#ifndef LV_INDEV_DRAG_THROW -#define LV_INDEV_DRAG_THROW 1 -#endif -#endif - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ -#ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -#endif -#endif - - -#endif /*LV_CONF_CHECKER_H*/ diff --git a/include/liblvgl/lv_conf_internal.h b/include/liblvgl/lv_conf_internal.h index 97807fe..c694dd6 100644 --- a/include/liblvgl/lv_conf_internal.h +++ b/include/liblvgl/lv_conf_internal.h @@ -38,7 +38,7 @@ #elif defined(LV_CONF_INCLUDE_SIMPLE) /*Or simply include lv_conf.h is enabled*/ #include "lv_conf.h" #else - #include "../../lv_conf.h" /*Else assume lv_conf.h is next to the lvgl folder*/ + #include "liblvgl/lv_conf.h" /*Else assume lv_conf.h is next to the lvgl folder*/ #endif #if !defined(LV_CONF_H) && !defined(LV_CONF_SUPPRESS_DEFINE_CHECK) /* #include will sometimes silently fail when __has_include is used */ @@ -253,6 +253,9 @@ #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ #endif #endif + /*If using lvgl as ESP32 component*/ + // #define LV_TICK_CUSTOM_INCLUDE "esp_timer.h" + // #define LV_TICK_CUSTOM_SYS_TIME_EXPR ((esp_timer_get_time() / 1000LL)) #endif /*LV_TICK_CUSTOM*/ /*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. @@ -432,7 +435,7 @@ #endif #if LV_USE_GPU_STM32_DMA2D /*Must be defined to include path of CMSIS header of target processor - e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ + e.g. "stm32f7xx.h" or "stm32f4xx.h"*/ #ifndef LV_GPU_DMA2D_CMSIS_INCLUDE #ifdef CONFIG_LV_GPU_DMA2D_CMSIS_INCLUDE #define LV_GPU_DMA2D_CMSIS_INCLUDE CONFIG_LV_GPU_DMA2D_CMSIS_INCLUDE diff --git a/include/liblvgl/lv_version.h b/include/liblvgl/lv_version.h deleted file mode 100644 index 1e62e1e..0000000 --- a/include/liblvgl/lv_version.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file lv_version.h - * - */ - -#ifndef LV_VERSION_H -#define LV_VERSION_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -/*Current version of LittlevGL*/ -#define LVGL_VERSION_MAJOR 5 -#define LVGL_VERSION_MINOR 3 -#define LVGL_VERSION_PATCH 0 -#define LVGL_VERSION_INFO "" - - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/********************** - * MACROS - **********************/ -/* Gives 1 if the x.y.z version is supported in the current version - * Usage: - * - * - Require v6 - * #if LV_VERSION_CHECK(6,0,0) - * new_func_in_v6(); - * #endif - * - * - * - Require at least v5.3 - * #if LV_VERSION_CHECK(5,3,0) - * new_feature_from_v5_3(); - * #endif - * - * - * - Require v5.3.2 bugfixes - * #if LV_VERSION_CHECK(5,3,2) - * bugfix_in_v5_3_2(); - * #endif - * - * */ -#define LV_VERSION_CHECK(x,y,z) (x == LVGL_VERSION_MAJOR && (y < LVGL_VERSION_MINOR || (y == LVGL_VERSION_MINOR && z <= LVGL_VERSION_PATCH))) - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /*LV_VERSION_H*/ diff --git a/include/liblvgl/lvgl.h b/include/liblvgl/lvgl.h index 60d29f5..c178c9e 100644 --- a/include/liblvgl/lvgl.h +++ b/include/liblvgl/lvgl.h @@ -15,8 +15,8 @@ extern "C" { ***************************/ #define LVGL_VERSION_MAJOR 8 #define LVGL_VERSION_MINOR 3 -#define LVGL_VERSION_PATCH 4 -#define LVGL_VERSION_INFO "dev" +#define LVGL_VERSION_PATCH 6 +#define LVGL_VERSION_INFO "" /********************* * INCLUDES diff --git a/include/liblvgl/misc/lv_anim.h b/include/liblvgl/misc/lv_anim.h index cb460ab..faef727 100644 --- a/include/liblvgl/misc/lv_anim.h +++ b/include/liblvgl/misc/lv_anim.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_area.h b/include/liblvgl/misc/lv_area.h index 036767b..137931a 100644 --- a/include/liblvgl/misc/lv_area.h +++ b/include/liblvgl/misc/lv_area.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_assert.h b/include/liblvgl/misc/lv_assert.h index 4625297..48db744 100644 --- a/include/liblvgl/misc/lv_assert.h +++ b/include/liblvgl/misc/lv_assert.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include "lv_log.h" #include "lv_mem.h" #include LV_ASSERT_HANDLER_INCLUDE diff --git a/include/liblvgl/misc/lv_bidi.h b/include/liblvgl/misc/lv_bidi.h index fafb4a2..a27b580 100644 --- a/include/liblvgl/misc/lv_bidi.h +++ b/include/liblvgl/misc/lv_bidi.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_color.h b/include/liblvgl/misc/lv_color.h index 8e80a61..2cc92f2 100644 --- a/include/liblvgl/misc/lv_color.h +++ b/include/liblvgl/misc/lv_color.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include "lv_assert.h" #include "lv_math.h" #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_fs.h b/include/liblvgl/misc/lv_fs.h index 13b2eeb..9f65e1b 100644 --- a/include/liblvgl/misc/lv_fs.h +++ b/include/liblvgl/misc/lv_fs.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_gc.h b/include/liblvgl/misc/lv_gc.h index 7a98d10..9d7d1bb 100644 --- a/include/liblvgl/misc/lv_gc.h +++ b/include/liblvgl/misc/lv_gc.h @@ -13,15 +13,15 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include "lv_mem.h" #include "lv_ll.h" #include "lv_timer.h" #include "lv_types.h" -#include "liblvgl/draw/lv_img_cache.h" -#include "liblvgl/draw/lv_draw_mask.h" -#include "liblvgl/core/lv_obj_pos.h" +#include "../draw/lv_img_cache.h" +#include "../draw/lv_draw_mask.h" +#include "../core/lv_obj_pos.h" /********************* * DEFINES diff --git a/include/liblvgl/misc/lv_log.h b/include/liblvgl/misc/lv_log.h index cd61905..9a00993 100644 --- a/include/liblvgl/misc/lv_log.h +++ b/include/liblvgl/misc/lv_log.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_lru.h b/include/liblvgl/misc/lv_lru.h index 3e9729e..2d0134e 100644 --- a/include/liblvgl/misc/lv_lru.h +++ b/include/liblvgl/misc/lv_lru.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_math.h b/include/liblvgl/misc/lv_math.h index 24f9ea6..4b2860a 100644 --- a/include/liblvgl/misc/lv_math.h +++ b/include/liblvgl/misc/lv_math.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include /********************* diff --git a/include/liblvgl/misc/lv_mem.h b/include/liblvgl/misc/lv_mem.h index fd202ab..7a83b3d 100644 --- a/include/liblvgl/misc/lv_mem.h +++ b/include/liblvgl/misc/lv_mem.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_misc.mk b/include/liblvgl/misc/lv_misc.mk new file mode 100644 index 0000000..1dfd4ee --- /dev/null +++ b/include/liblvgl/misc/lv_misc.mk @@ -0,0 +1,26 @@ +CSRCS += lv_anim.c +CSRCS += lv_anim_timeline.c +CSRCS += lv_area.c +CSRCS += lv_async.c +CSRCS += lv_bidi.c +CSRCS += lv_color.c +CSRCS += lv_fs.c +CSRCS += lv_gc.c +CSRCS += lv_ll.c +CSRCS += lv_log.c +CSRCS += lv_lru.c +CSRCS += lv_math.c +CSRCS += lv_mem.c +CSRCS += lv_printf.c +CSRCS += lv_style.c +CSRCS += lv_style_gen.c +CSRCS += lv_timer.c +CSRCS += lv_tlsf.c +CSRCS += lv_txt.c +CSRCS += lv_txt_ap.c +CSRCS += lv_utils.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc" diff --git a/include/liblvgl/misc/lv_style.h b/include/liblvgl/misc/lv_style.h index 44a542d..5cf0b19 100644 --- a/include/liblvgl/misc/lv_style.h +++ b/include/liblvgl/misc/lv_style.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include #include -#include "liblvgl/font/lv_font.h" +#include "../font/lv_font.h" #include "lv_color.h" #include "lv_area.h" #include "lv_anim.h" diff --git a/include/liblvgl/misc/lv_timer.h b/include/liblvgl/misc/lv_timer.h index 16572d3..a9a8e50 100644 --- a/include/liblvgl/misc/lv_timer.h +++ b/include/liblvgl/misc/lv_timer.h @@ -12,8 +12,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/hal/lv_hal_tick.h" +#include "../lv_conf_internal.h" +#include "../hal/lv_hal_tick.h" #include #include diff --git a/include/liblvgl/misc/lv_txt.h b/include/liblvgl/misc/lv_txt.h index ae60e8b..46050dc 100644 --- a/include/liblvgl/misc/lv_txt.h +++ b/include/liblvgl/misc/lv_txt.h @@ -13,12 +13,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #include #include #include "lv_area.h" -#include "liblvgl/font/lv_font.h" +#include "../font/lv_font.h" #include "lv_printf.h" #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_txt_ap.h b/include/liblvgl/misc/lv_txt_ap.h index 3519bb6..e2d94b8 100644 --- a/include/liblvgl/misc/lv_txt_ap.h +++ b/include/liblvgl/misc/lv_txt_ap.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include #include "lv_txt.h" -#include "liblvgl/draw/lv_draw.h" +#include "../draw/lv_draw.h" #if LV_USE_ARABIC_PERSIAN_CHARS == 1 diff --git a/include/liblvgl/widgets/lv_arc.h b/include/liblvgl/widgets/lv_arc.h index 96f4629..fd53fc1 100644 --- a/include/liblvgl/widgets/lv_arc.h +++ b/include/liblvgl/widgets/lv_arc.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_ARC != 0 -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_bar.h b/include/liblvgl/widgets/lv_bar.h index 55d1711..1726425 100644 --- a/include/liblvgl/widgets/lv_bar.h +++ b/include/liblvgl/widgets/lv_bar.h @@ -13,12 +13,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_BAR != 0 -#include "liblvgl/core/lv_obj.h" -#include "liblvgl/misc/lv_anim.h" +#include "../core/lv_obj.h" +#include "../misc/lv_anim.h" #include "lv_btn.h" #include "lv_label.h" diff --git a/include/liblvgl/widgets/lv_btn.h b/include/liblvgl/widgets/lv_btn.h index 893e6a0..1d471f9 100644 --- a/include/liblvgl/widgets/lv_btn.h +++ b/include/liblvgl/widgets/lv_btn.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_BTN != 0 -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_btnmatrix.h b/include/liblvgl/widgets/lv_btnmatrix.h index 31d62bb..780d57b 100644 --- a/include/liblvgl/widgets/lv_btnmatrix.h +++ b/include/liblvgl/widgets/lv_btnmatrix.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_BTNMATRIX != 0 -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_canvas.h b/include/liblvgl/widgets/lv_canvas.h index f92a1c5..71f0516 100644 --- a/include/liblvgl/widgets/lv_canvas.h +++ b/include/liblvgl/widgets/lv_canvas.h @@ -13,13 +13,13 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_CANVAS != 0 -#include "liblvgl/core/lv_obj.h" -#include "liblvgl/widgets/lv_img.h" -#include "liblvgl/draw/lv_draw_img.h" +#include "../core/lv_obj.h" +#include "../widgets/lv_img.h" +#include "../draw/lv_draw_img.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_checkbox.h b/include/liblvgl/widgets/lv_checkbox.h index 6b2bdc3..772f500 100644 --- a/include/liblvgl/widgets/lv_checkbox.h +++ b/include/liblvgl/widgets/lv_checkbox.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" -#include "liblvgl/core/lv_obj.h" +#include "../lv_conf_internal.h" +#include "../core/lv_obj.h" #if LV_USE_CHECKBOX != 0 diff --git a/include/liblvgl/widgets/lv_dropdown.h b/include/liblvgl/widgets/lv_dropdown.h index 9848b14..0c55e86 100644 --- a/include/liblvgl/widgets/lv_dropdown.h +++ b/include/liblvgl/widgets/lv_dropdown.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_DROPDOWN != 0 diff --git a/include/liblvgl/widgets/lv_img.h b/include/liblvgl/widgets/lv_img.h index 5513a26..eb76c8d 100644 --- a/include/liblvgl/widgets/lv_img.h +++ b/include/liblvgl/widgets/lv_img.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_IMG != 0 @@ -22,9 +22,9 @@ extern "C" { #error "lv_img: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" #endif -#include "liblvgl/core/lv_obj.h" -#include "liblvgl/misc/lv_fs.h" -#include "liblvgl/draw/lv_draw.h" +#include "../core/lv_obj.h" +#include "../misc/lv_fs.h" +#include "../draw/lv_draw.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_label.h b/include/liblvgl/widgets/lv_label.h index 39a68db..b31a63e 100644 --- a/include/liblvgl/widgets/lv_label.h +++ b/include/liblvgl/widgets/lv_label.h @@ -18,11 +18,11 @@ extern "C" { #if LV_USE_LABEL != 0 #include -#include "liblvgl/core/lv_obj.h" -#include "liblvgl/font/lv_font.h" -#include "liblvgl/font/lv_symbol_def.h" -#include "liblvgl/misc/lv_txt.h" -#include "liblvgl/draw/lv_draw.h" +#include "../core/lv_obj.h" +#include "../font/lv_font.h" +#include "../font/lv_symbol_def.h" +#include "../misc/lv_txt.h" +#include "../draw/lv_draw.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_line.h b/include/liblvgl/widgets/lv_line.h index 622ef81..54fa248 100644 --- a/include/liblvgl/widgets/lv_line.h +++ b/include/liblvgl/widgets/lv_line.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_LINE != 0 -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_objx_templ.h b/include/liblvgl/widgets/lv_objx_templ.h index f363df4..9de5285 100644 --- a/include/liblvgl/widgets/lv_objx_templ.h +++ b/include/liblvgl/widgets/lv_objx_templ.h @@ -20,11 +20,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_TEMPL != 0 -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_roller.h b/include/liblvgl/widgets/lv_roller.h index 4984c26..14411de 100644 --- a/include/liblvgl/widgets/lv_roller.h +++ b/include/liblvgl/widgets/lv_roller.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_ROLLER != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_roller: lv_label is required. Enable it in lv_conf.h (LV_USE_ROLLER 1)" #endif -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" #include "lv_label.h" /********************* diff --git a/include/liblvgl/widgets/lv_slider.h b/include/liblvgl/widgets/lv_slider.h index 20c940f..386950c 100644 --- a/include/liblvgl/widgets/lv_slider.h +++ b/include/liblvgl/widgets/lv_slider.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_SLIDER != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_slider: lv_bar is required. Enable it in lv_conf.h (LV_USE_BAR 1)" #endif -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" #include "lv_bar.h" /********************* diff --git a/include/liblvgl/widgets/lv_switch.h b/include/liblvgl/widgets/lv_switch.h index 63ec427..83ca81b 100644 --- a/include/liblvgl/widgets/lv_switch.h +++ b/include/liblvgl/widgets/lv_switch.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_SWITCH != 0 -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_table.h b/include/liblvgl/widgets/lv_table.h index 311d914..9106270 100644 --- a/include/liblvgl/widgets/lv_table.h +++ b/include/liblvgl/widgets/lv_table.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_TABLE != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_table: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" #endif -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" #include "lv_label.h" /********************* diff --git a/include/liblvgl/widgets/lv_textarea.h b/include/liblvgl/widgets/lv_textarea.h index cfa47e4..4b3289b 100644 --- a/include/liblvgl/widgets/lv_textarea.h +++ b/include/liblvgl/widgets/lv_textarea.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../lv_conf_internal.h" #if LV_USE_TEXTAREA != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_ta: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" #endif -#include "liblvgl/core/lv_obj.h" +#include "../core/lv_obj.h" #include "lv_label.h" /********************* diff --git a/include/liblvgl/widgets/lv_widgets.mk b/include/liblvgl/widgets/lv_widgets.mk new file mode 100644 index 0000000..4e62dc5 --- /dev/null +++ b/include/liblvgl/widgets/lv_widgets.mk @@ -0,0 +1,20 @@ +CSRCS += lv_arc.c +CSRCS += lv_bar.c +CSRCS += lv_btn.c +CSRCS += lv_btnmatrix.c +CSRCS += lv_canvas.c +CSRCS += lv_checkbox.c +CSRCS += lv_dropdown.c +CSRCS += lv_img.c +CSRCS += lv_label.c +CSRCS += lv_line.c +CSRCS += lv_roller.c +CSRCS += lv_slider.c +CSRCS += lv_switch.c +CSRCS += lv_table.c +CSRCS += lv_textarea.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets" diff --git a/src/liblvgl/core/lv_core.mk b/src/liblvgl/core/lv_core.mk new file mode 100644 index 0000000..677a9f6 --- /dev/null +++ b/src/liblvgl/core/lv_core.mk @@ -0,0 +1,20 @@ +CSRCS += lv_disp.c +CSRCS += lv_group.c +CSRCS += lv_indev.c +CSRCS += lv_indev_scroll.c +CSRCS += lv_obj.c +CSRCS += lv_obj_class.c +CSRCS += lv_obj_draw.c +CSRCS += lv_obj_pos.c +CSRCS += lv_obj_scroll.c +CSRCS += lv_obj_style.c +CSRCS += lv_obj_style_gen.c +CSRCS += lv_obj_tree.c +CSRCS += lv_event.c +CSRCS += lv_refr.c +CSRCS += lv_theme.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core" diff --git a/src/liblvgl/core/lv_group.c b/src/liblvgl/core/lv_group.c index 798bb46..1a9481c 100644 --- a/src/liblvgl/core/lv_group.c +++ b/src/liblvgl/core/lv_group.c @@ -92,6 +92,7 @@ void lv_group_del(lv_group_t * group) indev = lv_indev_get_next(indev); } + if(default_group == group) default_group = NULL; _lv_ll_clear(&(group->obj_ll)); _lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group); lv_mem_free(group); diff --git a/src/liblvgl/core/lv_indev.c b/src/liblvgl/core/lv_indev.c index 6e5aa03..0fb3e52 100644 --- a/src/liblvgl/core/lv_indev.c +++ b/src/liblvgl/core/lv_indev.c @@ -852,8 +852,6 @@ static void indev_proc_press(_lv_indev_proc_t * proc) if(indev_reset_check(proc)) return; } - lv_obj_transform_point(indev_obj_act, &proc->types.pointer.act_point, true, true); - /*If a new object was found reset some variables and send a pressed event handler*/ if(indev_obj_act != proc->types.pointer.act_obj) { proc->types.pointer.last_point.x = proc->types.pointer.act_point.x; @@ -987,6 +985,27 @@ static void indev_proc_release(_lv_indev_proc_t * proc) proc->pr_timestamp = 0; proc->longpr_rep_timestamp = 0; + + /*Get the transformed vector with this object*/ + if(scroll_obj) { + int16_t angle = 0; + int16_t zoom = 256; + lv_point_t pivot = { 0, 0 }; + lv_obj_t * parent = scroll_obj; + while(parent) { + angle += lv_obj_get_style_transform_angle(parent, 0); + zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256); + parent = lv_obj_get_parent(parent); + } + + if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) { + angle = -angle; + zoom = (256 * 256) / zoom; + lv_point_transform(&proc->types.pointer.scroll_throw_vect, angle, zoom, &pivot); + lv_point_transform(&proc->types.pointer.scroll_throw_vect_ori, angle, zoom, &pivot); + } + } + } /*The reset can be set in the Call the ancestor's event handler function. diff --git a/src/liblvgl/core/lv_indev_scroll.c b/src/liblvgl/core/lv_indev_scroll.c index c05e345..3a73183 100644 --- a/src/liblvgl/core/lv_indev_scroll.c +++ b/src/liblvgl/core/lv_indev_scroll.c @@ -45,12 +45,13 @@ static lv_coord_t elastic_diff(lv_obj_t * scroll_obj, lv_coord_t diff, lv_coord_ void _lv_indev_scroll_handler(_lv_indev_proc_t * proc) { + if(proc->types.pointer.vect.x == 0 && proc->types.pointer.vect.y == 0) { + return; + } + lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj; /*If there is no scroll object yet try to find one*/ if(scroll_obj == NULL) { - proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x; - proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y; - scroll_obj = find_scroll_obj(proc); if(scroll_obj == NULL) return; @@ -61,35 +62,50 @@ void _lv_indev_scroll_handler(_lv_indev_proc_t * proc) } /*Set new position or scroll if the vector is not zero*/ - if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) { - lv_coord_t diff_x = 0; - lv_coord_t diff_y = 0; + int16_t angle = 0; + int16_t zoom = 256; + lv_obj_t * parent = scroll_obj; + while(parent) { + angle += lv_obj_get_style_transform_angle(parent, 0); + zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256); + parent = lv_obj_get_parent(parent); + } - if(proc->types.pointer.scroll_dir == LV_DIR_HOR) { - lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); - lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); - diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR); - } - else { - lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); - lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); - diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER); - } + if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) { + angle = -angle; + zoom = (256 * 256) / zoom; + lv_point_t pivot = { 0, 0 }; + lv_point_transform(&proc->types.pointer.vect, angle, zoom, &pivot); + } - lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj); - if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; - if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; - if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; - if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0; - /*Respect the scroll limit area*/ - scroll_limit_diff(proc, &diff_x, &diff_y); - _lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y); - if(proc->reset_query) return; - proc->types.pointer.scroll_sum.x += diff_x; - proc->types.pointer.scroll_sum.y += diff_y; + lv_coord_t diff_x = 0; + lv_coord_t diff_y = 0; + if(proc->types.pointer.scroll_dir == LV_DIR_HOR) { + lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); + lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); + diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR); + } + else { + lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); + lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); + diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER); } + + lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj); + if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; + if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; + if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; + if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0; + + /*Respect the scroll limit area*/ + scroll_limit_diff(proc, &diff_x, &diff_y); + + _lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y); + if(proc->reset_query) return; + proc->types.pointer.scroll_sum.x += diff_x; + proc->types.pointer.scroll_sum.y += diff_y; } @@ -99,7 +115,6 @@ void _lv_indev_scroll_throw_handler(_lv_indev_proc_t * proc) if(scroll_obj == NULL) return; if(proc->types.pointer.scroll_dir == LV_DIR_NONE) return; - lv_indev_t * indev_act = lv_indev_get_act(); lv_coord_t scroll_throw = indev_act->driver->scroll_throw; @@ -259,14 +274,36 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc) /*Decide if it's a horizontal or vertical scroll*/ bool hor_en = false; bool ver_en = false; - if(LV_ABS(proc->types.pointer.scroll_sum.x) > LV_ABS(proc->types.pointer.scroll_sum.y)) { - hor_en = true; - } - else { - ver_en = true; - } + + proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x; + proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y; while(obj_act) { + /*Get the transformed scroll_sum with this object*/ + int16_t angle = 0; + int16_t zoom = 256; + lv_point_t pivot = { 0, 0 }; + lv_obj_t * parent = obj_act; + while(parent) { + angle += lv_obj_get_style_transform_angle(parent, 0); + zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256); + parent = lv_obj_get_parent(parent); + } + + lv_point_t obj_scroll_sum = proc->types.pointer.scroll_sum; + if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) { + angle = -angle; + zoom = (256 * 256) / zoom; + lv_point_transform(&obj_scroll_sum, angle, zoom, &pivot); + } + + if(LV_ABS(obj_scroll_sum.x) > LV_ABS(obj_scroll_sum.y)) { + hor_en = true; + } + else { + ver_en = true; + } + if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) { /*If this object don't want to chain the scroll to the parent stop searching*/ if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_HOR) == false && hor_en) break; @@ -300,15 +337,15 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc) *is propagated to this object it can show at least elastic scroll effect. *But if not hor/ver scrollable do not scroll it at all (so it's not a good candidate)*/ if((st > 0 || sb > 0) && - ((up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) || - (down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit))) { + ((up_en && obj_scroll_sum.y >= scroll_limit) || + (down_en && obj_scroll_sum.y <= - scroll_limit))) { obj_candidate = obj_act; dir_candidate = LV_DIR_VER; } if((sl > 0 || sr > 0) && - ((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) || - (right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit))) { + ((left_en && obj_scroll_sum.x >= scroll_limit) || + (right_en && obj_scroll_sum.x <= - scroll_limit))) { obj_candidate = obj_act; dir_candidate = LV_DIR_HOR; } @@ -318,11 +355,11 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc) if(sl <= 0) left_en = false; if(sr <= 0) right_en = false; - /*If the object really can be scrolled into the current direction the use it.*/ - if((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) || - (right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit) || - (up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) || - (down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit)) { + /*If the object really can be scrolled into the current direction then use it.*/ + if((left_en && obj_scroll_sum.x >= scroll_limit) || + (right_en && obj_scroll_sum.x <= - scroll_limit) || + (up_en && obj_scroll_sum.y >= scroll_limit) || + (down_en && obj_scroll_sum.y <= - scroll_limit)) { proc->types.pointer.scroll_dir = hor_en ? LV_DIR_HOR : LV_DIR_VER; break; } diff --git a/src/liblvgl/core/lv_obj_pos.c b/src/liblvgl/core/lv_obj_pos.c index b6cf144..567115b 100644 --- a/src/liblvgl/core/lv_obj_pos.c +++ b/src/liblvgl/core/lv_obj_pos.c @@ -1160,9 +1160,21 @@ static void transform_point(const lv_obj_t * obj, lv_point_t * p, bool inv) if(angle == 0 && zoom == LV_IMG_ZOOM_NONE) return; - lv_point_t pivot; - pivot.x = obj->coords.x1 + lv_obj_get_style_transform_pivot_x(obj, 0); - pivot.y = obj->coords.y1 + lv_obj_get_style_transform_pivot_y(obj, 0); + lv_point_t pivot = { + .x = lv_obj_get_style_transform_pivot_x(obj, 0), + .y = lv_obj_get_style_transform_pivot_y(obj, 0) + }; + + if(LV_COORD_IS_PCT(pivot.x)) { + pivot.x = (LV_COORD_GET_PCT(pivot.x) * lv_area_get_width(&obj->coords)) / 100; + } + if(LV_COORD_IS_PCT(pivot.y)) { + pivot.y = (LV_COORD_GET_PCT(pivot.y) * lv_area_get_height(&obj->coords)) / 100; + } + + pivot.x = obj->coords.x1 + pivot.x; + pivot.y = obj->coords.y1 + pivot.y; + if(inv) { angle = -angle; zoom = (256 * 256) / zoom; diff --git a/src/liblvgl/core/lv_refr.c b/src/liblvgl/core/lv_refr.c index d9c7e15..ecf496a 100644 --- a/src/liblvgl/core/lv_refr.c +++ b/src/liblvgl/core/lv_refr.c @@ -613,6 +613,9 @@ static void refr_area_part(lv_draw_ctx_t * draw_ctx) { lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr); + if(draw_ctx->init_buf) + draw_ctx->init_buf(draw_ctx); + /* Below the `area_p` area will be redrawn into the draw buffer. * In single buffered mode wait here until the buffer is freed. * In full double buffered mode wait here while the buffers are swapped and a buffer becomes available*/ @@ -914,6 +917,13 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj) .y = lv_obj_get_style_transform_pivot_y(obj, 0) }; + if(LV_COORD_IS_PCT(pivot.x)) { + pivot.x = (LV_COORD_GET_PCT(pivot.x) * lv_area_get_width(&obj->coords)) / 100; + } + if(LV_COORD_IS_PCT(pivot.y)) { + pivot.y = (LV_COORD_GET_PCT(pivot.y) * lv_area_get_height(&obj->coords)) / 100; + } + lv_draw_img_dsc_t draw_dsc; lv_draw_img_dsc_init(&draw_dsc); draw_dsc.opa = opa; diff --git a/src/liblvgl/draw/arm2d/lv_draw_arm2d.mk b/src/liblvgl/draw/arm2d/lv_draw_arm2d.mk new file mode 100644 index 0000000..17219b0 --- /dev/null +++ b/src/liblvgl/draw/arm2d/lv_draw_arm2d.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_arm2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d" diff --git a/src/liblvgl/draw/arm2d/lv_gpu_arm2d.c b/src/liblvgl/draw/arm2d/lv_gpu_arm2d.c index 1c68809..f294125 100644 --- a/src/liblvgl/draw/arm2d/lv_gpu_arm2d.c +++ b/src/liblvgl/draw/arm2d/lv_gpu_arm2d.c @@ -36,9 +36,10 @@ #include "lv_gpu_arm2d.h" -#include "liblvgl/core/lv_refr.h" +#include "../../core/lv_refr.h" #if LV_USE_GPU_ARM2D +#define __ARM_2D_IMPL__ #include "arm_2d.h" #include "__arm_2d_impl.h" @@ -89,10 +90,12 @@ #define __arm_2d_impl_cl_key_copy __arm_2d_impl_rgb16_cl_key_copy #define __arm_2d_impl_alpha_blending_colour_keying \ __arm_2d_impl_rgb565_alpha_blending_colour_keying -#define arm_2d_tile_transform_with_src_mask_and_opacity \ - arm_2d_rgb565_tile_transform_with_src_mask_and_opacity -#define arm_2d_tile_transform_with_opacity \ - arm_2d_rgb565_tile_transform_with_opacity +#define arm_2d_tile_transform_with_src_mask_and_opacity_prepare \ + arm_2dp_rgb565_tile_transform_with_src_mask_and_opacity_prepare +#define arm_2d_tile_transform_with_opacity_prepare \ + arm_2dp_rgb565_tile_transform_with_opacity_prepare +#define arm_2d_tile_transform_prepare \ + arm_2dp_rgb565_tile_transform_prepare #define __ARM_2D_PIXEL_BLENDING_OPA __ARM_2D_PIXEL_BLENDING_OPA_RGB565 @@ -124,10 +127,12 @@ #define __arm_2d_impl_cl_key_copy __arm_2d_impl_rgb32_cl_key_copy #define __arm_2d_impl_alpha_blending_colour_keying \ __arm_2d_impl_cccn888_alpha_blending_colour_keying -#define arm_2d_tile_transform_with_src_mask_and_opacity \ - arm_2d_cccn888_tile_transform_with_src_mask_and_opacity -#define arm_2d_tile_transform_with_opacity \ - arm_2d_cccn888_tile_transform_with_opacity +#define arm_2d_tile_transform_with_src_mask_and_opacity_prepare \ + arm_2dp_cccn888_tile_transform_with_src_mask_and_opacity_prepare +#define arm_2d_tile_transform_with_opacity_prepare \ + arm_2dp_cccn888_tile_transform_with_opacity_prepare +#define arm_2d_tile_transform_prepare \ + arm_2dp_cccn888_tile_transform_prepare #define __ARM_2D_PIXEL_BLENDING_OPA __ARM_2D_PIXEL_BLENDING_OPA_CCCN888 @@ -298,11 +303,88 @@ /* replace src_buf for the following operation */ \ src_buf = (const uint8_t *)rgb_tmp_buf; \ } \ - __VA_ARGS__ \ + do { \ + __VA_ARGS__ \ + } while(0); \ if (NULL != rgb_tmp_buf) { \ lv_mem_buf_release(rgb_tmp_buf); \ } \ - } while(0); + } while(0); \ + src_buf = src_buf_org; + +#define __RECOLOUR_BEGIN() \ + do { \ + lv_color_t *rgb_tmp_buf = NULL; \ + if(draw_dsc->recolor_opa > LV_OPA_MIN) { \ + rgb_tmp_buf \ + = lv_malloc(src_w * src_h * sizeof(lv_color_t)); \ + if (NULL == rgb_tmp_buf) { \ + LV_LOG_WARN( \ + "Failed to allocate memory for accelerating recolour, " \ + "use normal route instead."); \ + break; \ + } \ + lv_memcpy(rgb_tmp_buf, src_buf, src_w * src_h * sizeof(lv_color_t));\ + arm_2d_size_t copy_size = { \ + .iWidth = src_w, \ + .iHeight = src_h, \ + }; \ + /* apply re-colour */ \ + __arm_2d_impl_colour_filling_with_opacity( \ + (color_int *)rgb_tmp_buf, \ + src_w, \ + ©_size, \ + (color_int)draw_dsc->recolor.full, \ + draw_dsc->recolor_opa); \ + \ + /* replace src_buf for the following operation */ \ + src_buf = (const uint8_t *)rgb_tmp_buf; \ + } \ + do { + +#define __RECOLOUR_END() \ + } while(0); \ + if (NULL != rgb_tmp_buf) { \ + lv_free(rgb_tmp_buf); \ + } \ + } while(0); \ + src_buf = src_buf_org; + +#define __ARM_2D_PREPARE_TRANS_AND_TARGET_REGION(__TRANS_PREPARE, ...) \ + do { \ + __TRANS_PREPARE( \ + NULL, \ + __VA_ARGS__); \ + \ + target_region = (arm_2d_region_t) { \ + .tLocation = { \ + .iX = coords->x1 - draw_ctx->clip_area->x1, \ + .iY = coords->y1 - draw_ctx->clip_area->y1, \ + }, \ + .tSize = { \ + .iWidth = lv_area_get_width(coords), \ + .iHeight = lv_area_get_height(coords), \ + }, \ + }; \ + \ + arm_2d_size_t tTransSize \ + = ARM_2D_CTRL.DefaultOP \ + .tTransform.Source.ptTile->tRegion.tSize; \ + \ + if (target_region.tSize.iWidth < tTransSize.iWidth) { \ + int16_t iDelta = tTransSize.iWidth - target_region.tSize.iWidth;\ + target_region.tLocation.iX -= iDelta / 2; \ + target_region.tSize.iWidth = tTransSize.iWidth; \ + } \ + \ + if (target_region.tSize.iHeight < tTransSize.iHeight) { \ + int16_t iDelta \ + = tTransSize.iHeight - target_region.tSize.iHeight; \ + target_region.tLocation.iY -= iDelta / 2; \ + target_region.tSize.iHeight = tTransSize.iHeight; \ + } \ + } while(0) + /* *INDENT-ON* */ /********************** @@ -601,18 +683,26 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend lv_area_t blend_area; if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return; - lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + //lv_disp_t * disp = _lv_refr_get_disp_refreshing(); bool is_accelerated = false; do { - if(NULL != disp->driver->set_px_cb) { - break; - } + /* target buffer */ lv_color_t * dest_buf = draw_ctx->buf; - dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) - + (blend_area.x1 - draw_ctx->buf_area->x1); + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + if(disp->driver->screen_transp == 0) { + dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1); + } + else { + /*With LV_COLOR_DEPTH 16 it means ARGB8565 (3 bytes format)*/ + uint8_t * dest_buf8 = (uint8_t *) dest_buf; + dest_buf8 += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) * LV_IMG_PX_SIZE_ALPHA_BYTE; + dest_buf8 += (blend_area.x1 - draw_ctx->buf_area->x1) * LV_IMG_PX_SIZE_ALPHA_BYTE; + dest_buf = (lv_color_t *)dest_buf8; + } + /* source buffer */ const lv_color_t * src_buf = dsc->src_buf; lv_coord_t src_stride; if(src_buf) { @@ -634,7 +724,9 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); - + if(disp->driver->screen_transp) { + break; + } if(dsc->src_buf == NULL) { if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { is_accelerated = arm_2d_fill_normal(dest_buf, @@ -645,14 +737,8 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend mask, mask_stride); } -#if LV_DRAW_COMPLEX - else { - break; - } -#endif } else { - if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { is_accelerated = arm_2d_copy_normal(dest_buf, &blend_area, @@ -663,11 +749,6 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend mask, mask_stride); } -#if LV_DRAW_COMPLEX - else { - break; - } -#endif } } while(0); @@ -698,15 +779,11 @@ static bool arm_2d_fill_normal(lv_color_t * dest_buf, } /*Has opacity*/ else { -#if LV_COLOR_SCREEN_TRANSP - return false; -#else __arm_2d_impl_colour_filling_with_opacity((color_int *)dest_buf, dest_stride, &target_size, color.full, opa); -#endif } } /*Masked*/ @@ -722,9 +799,6 @@ static bool arm_2d_fill_normal(lv_color_t * dest_buf, } /*With opacity*/ else { -#if LV_COLOR_SCREEN_TRANSP - return false; -#else __arm_2d_impl_colour_filling_mask_opacity((color_int *)dest_buf, dest_stride, (uint8_t *)mask, @@ -732,7 +806,6 @@ static bool arm_2d_fill_normal(lv_color_t * dest_buf, &target_size, color.full, opa); -#endif } } @@ -759,10 +832,6 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf, .iHeight = lv_area_get_height(dest_area), }; -#if LV_COLOR_SCREEN_TRANSP - lv_disp_t * disp = _lv_refr_get_disp_refreshing(); -#endif - /*Simple fill (maybe with opacity), no masking*/ if(mask == NULL) { if(opa >= LV_OPA_MAX) { @@ -773,25 +842,18 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf, ©_size); } else { -#if LV_COLOR_SCREEN_TRANSP - return false; -#else __arm_2d_impl_alpha_blending((color_int *)src_buf, src_stride, (color_int *)dest_buf, dest_stride, ©_size, opa); -#endif } } /*Masked*/ else { /*Only the mask matters*/ if(opa > LV_OPA_MAX) { -#if LV_COLOR_SCREEN_TRANSP - return false; -#else __arm_2d_impl_src_msk_copy((color_int *)src_buf, src_stride, (uint8_t *)mask, @@ -800,13 +862,9 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf, (color_int *)dest_buf, dest_stride, ©_size); -#endif } /*Handle opa and mask values too*/ else { -#if LV_COLOR_SCREEN_TRANSP - return false; -#else __arm_2d_impl_gray8_alpha_blending((uint8_t *)mask, mask_stride, (uint8_t *)mask, @@ -822,7 +880,6 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf, (color_int *)dest_buf, dest_stride, ©_size); -#endif } } @@ -839,6 +896,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, /*Use the clip area as draw area*/ lv_area_t draw_area; lv_area_copy(&draw_area, draw_ctx->clip_area); + const uint8_t * src_buf_org = src_buf; bool mask_any = lv_draw_mask_is_any(&draw_area); bool transform = draw_dsc->angle != 0 || draw_dsc->zoom != LV_IMG_ZOOM_NONE ? true : false; @@ -851,6 +909,13 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, blend_dsc.blend_mode = draw_dsc->blend_mode; blend_dsc.blend_area = &blend_area; + if(lv_img_cf_is_chroma_keyed(cf)) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED; + else if(cf == LV_IMG_CF_ALPHA_8BIT) {} + else if(cf == LV_IMG_CF_RGB565A8) {} + else if(lv_img_cf_has_alpha(cf)) cf = LV_IMG_CF_TRUE_COLOR_ALPHA; + else cf = LV_IMG_CF_TRUE_COLOR; + + /*The simplest case just copy the pixels into the draw_buf*/ if(!mask_any && !transform && cf == LV_IMG_CF_TRUE_COLOR && draw_dsc->recolor_opa == LV_OPA_TRANSP) { blend_dsc.src_buf = (const lv_color_t *)src_buf; @@ -859,6 +924,9 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, lv_draw_sw_blend(draw_ctx, &blend_dsc); } else if(!mask_any && !transform && cf == LV_IMG_CF_ALPHA_8BIT) { + lv_area_t clipped_coords; + if(!_lv_area_intersect(&clipped_coords, coords, draw_ctx->clip_area)) return; + blend_dsc.mask_buf = (lv_opa_t *)src_buf; blend_dsc.mask_area = coords; blend_dsc.src_buf = NULL; @@ -869,7 +937,8 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, lv_draw_sw_blend(draw_ctx, &blend_dsc); } #if LV_COLOR_DEPTH == 16 - else if(!mask_any && !transform && cf == LV_IMG_CF_RGB565A8 && draw_dsc->recolor_opa == LV_OPA_TRANSP) { + else if(!mask_any && !transform && cf == LV_IMG_CF_RGB565A8 && draw_dsc->recolor_opa == LV_OPA_TRANSP && + blend_dsc.opa >= LV_OPA_MAX) { lv_coord_t src_w = lv_area_get_width(coords); lv_coord_t src_h = lv_area_get_height(coords); blend_dsc.src_buf = (const lv_color_t *)src_buf; @@ -922,6 +991,23 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER; blend_dsc.mask_res = mask_res_def; + if(cf == LV_IMG_CF_ALPHA_8BIT) { + /* original code: + lv_color_fill(rgb_buf, draw_dsc->recolor, buf_size); + */ + arm_2d_size_t copy_size = { + .iWidth = buf_w, + .iHeight = buf_h, + }; + + /* apply re-colour */ + __arm_2d_impl_colour_filling( + (color_int *)rgb_buf, + buf_w, + ©_size, + (color_int)draw_dsc->recolor.full); + } + bool is_accelerated = false; if(!transform) { @@ -968,7 +1054,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, } else if((LV_COLOR_DEPTH == 32) && !mask_any - && (cf == LV_IMG_CF_TRUE_COLOR_ALPHA)) { + && (LV_IMG_CF_TRUE_COLOR_ALPHA == cf)) { /* accelerate copy-with-source-masks-and-opacity */ /* *INDENT-OFF* */ @@ -1025,6 +1111,63 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, ) /* *INDENT-ON* */ } + else if(!mask_any + && (LV_IMG_CF_RGB565A8 == cf)) { + /* accelerate copy-with-source-masks-and-opacity */ + + uint8_t * mask_after_rgb = src_buf + sizeof(lv_color_t) * src_w * src_h; + /* *INDENT-OFF* */ + __RECOLOUR_WRAPPER( + __PREPARE_LL_ACCELERATION__(); + + uint8_t * mask_temp_buf = NULL; + if(blend_dsc.opa < LV_OPA_MAX) { + mask_temp_buf = lv_mem_buf_get(copy_size.iHeight * copy_size.iWidth); + if(NULL == mask_temp_buf) { + LV_LOG_WARN( + "Failed to allocate memory for alpha mask," + " use normal route instead."); + break; + } + lv_memset_00(mask_temp_buf, copy_size.iHeight * copy_size.iWidth); + + __arm_2d_impl_gray8_colour_filling_mask_opacity( + mask_temp_buf, + src_stride, + mask_after_rgb, + src_stride, + ©_size, + 0xFF, + blend_dsc.opa); + + __arm_2d_impl_src_msk_copy( + (color_int *)src_buf_tmp, + src_stride, + mask_temp_buf, + src_stride, + ©_size, + (color_int *)dest_buf, + dest_stride, + ©_size); + + lv_mem_buf_release(mask_temp_buf); + } + else { + __arm_2d_impl_src_msk_copy( + (color_int *)src_buf_tmp, + src_stride, + mask_after_rgb, + src_stride, + ©_size, + (color_int *)dest_buf, + dest_stride, + ©_size); + } + + is_accelerated = true; + ) + /* *INDENT-ON* */ + } else if(!mask_any && (cf == LV_IMG_CF_TRUE_COLOR)) { /* accelerate copy-with-source-masks-and-opacity */ @@ -1063,6 +1206,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, && (draw_dsc->recolor_opa == LV_OPA_TRANSP) && (((LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED == cf) || (LV_IMG_CF_TRUE_COLOR == cf)) + || (LV_IMG_CF_RGB565A8 == cf) #if defined(__ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__) && __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ || ((LV_IMG_CF_TRUE_COLOR_ALPHA == cf) && (LV_COLOR_DEPTH == 32)) @@ -1070,6 +1214,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, ) ) { + uint8_t * mask_after_rgb = src_buf + sizeof(lv_color_t) * src_w * src_h; /* *INDENT-OFF* */ __RECOLOUR_WRAPPER( /* accelerate transform without re-color */ @@ -1108,17 +1253,6 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, &target_tile, false); - target_region = (arm_2d_region_t) { - .tLocation = { - .iX = coords->x1 - draw_ctx->clip_area->x1, - .iY = coords->y1 - draw_ctx->clip_area->y1, - }, - .tSize = { - .iWidth = lv_area_get_width(coords), - .iHeight = lv_area_get_height(coords), - }, - }; - static arm_2d_tile_t source_tile; source_tile = (arm_2d_tile_t) { @@ -1132,45 +1266,81 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, .pchBuffer = (uint8_t *)src_buf, }; - static arm_2d_tile_t mask_tile; - mask_tile = source_tile; - - mask_tile.tInfo.bHasEnforcedColour = true; - mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_CHANNEL_8in32; - mask_tile.pchBuffer += 3; - static arm_2d_location_t source_center, target_center; source_center.iX = draw_dsc->pivot.x; source_center.iY = draw_dsc->pivot.y; - - if((LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED == cf) || + if((LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED == cf) || (LV_IMG_CF_TRUE_COLOR == cf)) { - arm_2d_tile_transform_with_opacity( + + __ARM_2D_PREPARE_TRANS_AND_TARGET_REGION( + arm_2d_tile_transform_with_opacity_prepare, &source_tile, - &target_tile, - &target_region, source_center, ARM_2D_ANGLE((draw_dsc->angle / 10.0f)), draw_dsc->zoom / 256.0f, (color_int)LV_COLOR_CHROMA_KEY.full, blend_dsc.opa); + arm_2d_tile_transform( + &target_tile, + &target_region, + NULL + ); + is_accelerated = true; + } + else if (LV_IMG_CF_RGB565A8 == cf) { + static arm_2d_tile_t mask_tile; + mask_tile = source_tile; + + mask_tile.tInfo.bHasEnforcedColour = true; + mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_GRAY8; + mask_tile.pchBuffer = mask_after_rgb; + + __ARM_2D_PREPARE_TRANS_AND_TARGET_REGION( + arm_2d_tile_transform_with_src_mask_and_opacity_prepare, + &source_tile, + &mask_tile, + source_center, + ARM_2D_ANGLE((draw_dsc->angle / 10.0f)), + draw_dsc->zoom / 256.0f, + blend_dsc.opa + ); + + arm_2d_tile_transform( + &target_tile, + &target_region, + NULL + ); + is_accelerated = true; } #if defined(__ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__) \ && __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ - else if((LV_IMG_CF_TRUE_COLOR_ALPHA == cf) && + else if((LV_IMG_CF_TRUE_COLOR_ALPHA == cf) && (LV_COLOR_DEPTH == 32)) { - arm_2d_tile_transform_with_src_mask_and_opacity( + static arm_2d_tile_t mask_tile; + mask_tile = source_tile; + + mask_tile.tInfo.bHasEnforcedColour = true; + mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_CHANNEL_8in32; + mask_tile.pchBuffer += 3; + + __ARM_2D_PREPARE_TRANS_AND_TARGET_REGION( + arm_2d_tile_transform_with_src_mask_and_opacity_prepare, &source_tile, &mask_tile, - &target_tile, - &target_region, source_center, ARM_2D_ANGLE((draw_dsc->angle / 10.0f)), draw_dsc->zoom / 256.0f, - blend_dsc.opa); + blend_dsc.opa + ); + + arm_2d_tile_transform( + &target_tile, + &target_region, + NULL + ); is_accelerated = true; } @@ -1208,7 +1378,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx, (color_int)draw_dsc->recolor.full, draw_dsc->recolor_opa); } -#if LV_DRAW_COMPLEX +#if LV_USE_DRAW_MASKS /*Apply the masks if any*/ if(mask_any) { lv_coord_t y; @@ -1275,7 +1445,7 @@ static void convert_cb(const lv_area_t * dest_area, const void * src_buf, lv_coo if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) { uint32_t px_cnt = lv_area_get_size(dest_area); - lv_memset_ff(abuf, px_cnt); + lv_memset(abuf, 0xff, px_cnt); src_tmp8 += (src_stride * dest_area->y1 * sizeof(lv_color_t)) + dest_area->x1 * sizeof(lv_color_t); uint32_t dest_w = lv_area_get_width(dest_area); diff --git a/src/liblvgl/draw/lv_draw.mk b/src/liblvgl/draw/lv_draw.mk new file mode 100644 index 0000000..f48f48f --- /dev/null +++ b/src/liblvgl/draw/lv_draw.mk @@ -0,0 +1,25 @@ +CSRCS += lv_draw_arc.c +CSRCS += lv_draw.c +CSRCS += lv_draw_img.c +CSRCS += lv_draw_label.c +CSRCS += lv_draw_line.c +CSRCS += lv_draw_mask.c +CSRCS += lv_draw_rect.c +CSRCS += lv_draw_transform.c +CSRCS += lv_draw_layer.c +CSRCS += lv_draw_triangle.c +CSRCS += lv_img_buf.c +CSRCS += lv_img_cache.c +CSRCS += lv_img_decoder.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw" + +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d/lv_draw_arm2d.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/lv_draw_nxp.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl/lv_draw_sdl.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw/lv_draw_sw.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk diff --git a/src/liblvgl/draw/lv_draw_img.c b/src/liblvgl/draw/lv_draw_img.c index b403899..b84ae07 100644 --- a/src/liblvgl/draw/lv_draw_img.c +++ b/src/liblvgl/draw/lv_draw_img.c @@ -69,18 +69,19 @@ void lv_draw_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, const if(dsc->opa <= LV_OPA_MIN) return; - lv_res_t res; + lv_res_t res = LV_RES_INV; + if(draw_ctx->draw_img) { res = draw_ctx->draw_img(draw_ctx, dsc, coords, src); } - else { + + if(res != LV_RES_OK) { res = decode_and_draw(draw_ctx, dsc, coords, src); } - if(res == LV_RES_INV) { + if(res != LV_RES_OK) { LV_LOG_WARN("Image draw error"); show_error(draw_ctx, coords, "No\ndata"); - return; } } diff --git a/src/liblvgl/draw/nxp/lv_draw_nxp.mk b/src/liblvgl/draw/nxp/lv_draw_nxp.mk new file mode 100644 index 0000000..18a751e --- /dev/null +++ b/src/liblvgl/draw/nxp/lv_draw_nxp.mk @@ -0,0 +1,7 @@ +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp" + +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp/lv_draw_nxp_pxp.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite/lv_draw_nxp_vglite.mk diff --git a/src/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk b/src/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk new file mode 100644 index 0000000..5c684bc --- /dev/null +++ b/src/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk @@ -0,0 +1,9 @@ +CSRCS += lv_draw_pxp.c +CSRCS += lv_draw_pxp_blend.c +CSRCS += lv_gpu_nxp_pxp_osa.c +CSRCS += lv_gpu_nxp_pxp.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp" diff --git a/src/liblvgl/draw/nxp/pxp/lv_draw_pxp.c b/src/liblvgl/draw/nxp/pxp/lv_draw_pxp.c new file mode 100644 index 0000000..a7084b4 --- /dev/null +++ b/src/liblvgl/draw/nxp/pxp/lv_draw_pxp.c @@ -0,0 +1,250 @@ +/** + * @file lv_draw_pxp.c + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_draw_pxp.h" + +#if LV_USE_GPU_NXP_PXP +#include "lv_draw_pxp_blend.h" + +#if LV_COLOR_DEPTH != 32 + #include "../../../core/lv_refr.h" +#endif + +/********************* + * DEFINES + *********************/ + +/* Minimum area (in pixels) for PXP blit/fill processing. */ +#ifndef LV_GPU_NXP_PXP_SIZE_LIMIT + #define LV_GPU_NXP_PXP_SIZE_LIMIT 5000 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_draw_pxp_wait_for_finish(lv_draw_ctx_t * draw_ctx); + +static void lv_draw_pxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, + const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf); + +static void lv_draw_pxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_pxp_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) +{ + lv_draw_sw_init_ctx(drv, draw_ctx); + + lv_draw_pxp_ctx_t * pxp_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx; + pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded; + pxp_draw_ctx->blend = lv_draw_pxp_blend; + pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish; +} + +void lv_draw_pxp_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) +{ + lv_draw_sw_deinit_ctx(drv, draw_ctx); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * During rendering, LVGL might initializes new draw_ctxs and start drawing into + * a separate buffer (called layer). If the content to be rendered has "holes", + * e.g. rounded corner, LVGL temporarily sets the disp_drv.screen_transp flag. + * It means the renderers should draw into an ARGB buffer. + * With 32 bit color depth it's not a big problem but with 16 bit color depth + * the target pixel format is ARGB8565 which is not supported by the GPU. + * In this case, the PXP callbacks should fallback to SW rendering. + */ +static inline bool need_argb8565_support() +{ +#if LV_COLOR_DEPTH != 32 + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + + if(disp->driver->screen_transp == 1) + return true; +#endif + + return false; +} + +static void lv_draw_pxp_wait_for_finish(lv_draw_ctx_t * draw_ctx) +{ + lv_gpu_nxp_pxp_wait(); + + lv_draw_sw_wait_for_finish(draw_ctx); +} + +static void lv_draw_pxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc) +{ + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + + if(need_argb8565_support()) { + lv_draw_sw_blend_basic(draw_ctx, dsc); + return; + } + + lv_area_t blend_area; + /*Let's get the blend area which is the intersection of the area to draw and the clip area*/ + if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) + return; /*Fully clipped, nothing to do*/ + + /*Make the blend area relative to the buffer*/ + lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + if(dsc->mask_buf != NULL || dsc->blend_mode != LV_BLEND_MODE_NORMAL || + lv_area_get_size(&blend_area) < LV_GPU_NXP_PXP_SIZE_LIMIT) { + lv_draw_sw_blend_basic(draw_ctx, dsc); + return; + } + + /*Fill/Blend only non masked, normal blended*/ + lv_color_t * dest_buf = draw_ctx->buf; + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + const lv_color_t * src_buf = dsc->src_buf; + + if(src_buf == NULL) { + lv_gpu_nxp_pxp_fill(dest_buf, &blend_area, dest_stride, dsc->color, dsc->opa); + } + else { + lv_area_t src_area; + src_area.x1 = blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1); + src_area.y1 = blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1); + src_area.x2 = src_area.x1 + lv_area_get_width(dsc->blend_area) - 1; + src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1; + lv_coord_t src_stride = lv_area_get_width(dsc->blend_area); + + lv_gpu_nxp_pxp_blit(dest_buf, &blend_area, dest_stride, src_buf, &src_area, src_stride, + dsc->opa, LV_DISP_ROT_NONE); + } +} + +static void lv_draw_pxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, + const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf) +{ + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + + if(need_argb8565_support()) { + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf); + return; + } + + const lv_color_t * src_buf = (const lv_color_t *)map_p; + if(!src_buf) { + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf); + return; + } + + lv_area_t blend_area; + /*Let's get the blend area which is the intersection of the area to draw and the clip area.*/ + if(!_lv_area_intersect(&blend_area, coords, draw_ctx->clip_area)) + return; /*Fully clipped, nothing to do*/ + + /*Make the blend area relative to the buffer*/ + lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_coord_t src_width = lv_area_get_width(coords); + lv_coord_t src_height = lv_area_get_height(coords); + + bool has_mask = lv_draw_mask_is_any(&blend_area); + bool has_scale = (dsc->zoom != LV_IMG_ZOOM_NONE); + bool has_rotation = (dsc->angle != 0); + bool unsup_rotation = false; + + if(has_rotation) { + /* + * PXP can only rotate at 90x angles. + */ + if(dsc->angle % 900) { + PXP_LOG_TRACE("Rotation angle %d is not supported. PXP can rotate only 90x angle.", dsc->angle); + unsup_rotation = true; + } + + /* + * PXP is set to process 16x16 blocks to optimize the system for memory + * bandwidth and image processing time. + * The output engine essentially truncates any output pixels after the + * desired number of pixels has been written. + * When rotating a source image and the output is not divisible by the block + * size, the incorrect pixels could be truncated and the final output image + * can look shifted. + */ + if(src_width % 16 || src_height % 16) { + PXP_LOG_TRACE("Rotation is not supported for image w/o alignment to block size 16x16."); + unsup_rotation = true; + } + } + + if(has_mask || has_scale || unsup_rotation || lv_area_get_size(&blend_area) < LV_GPU_NXP_PXP_SIZE_LIMIT +#if LV_COLOR_DEPTH != 32 + || lv_img_cf_has_alpha(cf) +#endif + ) { + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf); + return; + } + + lv_color_t * dest_buf = draw_ctx->buf; + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + + lv_area_t src_area; + src_area.x1 = blend_area.x1 - (coords->x1 - draw_ctx->buf_area->x1); + src_area.y1 = blend_area.y1 - (coords->y1 - draw_ctx->buf_area->y1); + src_area.x2 = src_area.x1 + src_width - 1; + src_area.y2 = src_area.y1 + src_height - 1; + lv_coord_t src_stride = lv_area_get_width(coords); + + lv_gpu_nxp_pxp_blit_transform(dest_buf, &blend_area, dest_stride, src_buf, &src_area, src_stride, + dsc, cf); +} + +#endif /*LV_USE_GPU_NXP_PXP*/ diff --git a/src/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.c b/src/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.c index c0a6eca..a32c917 100644 --- a/src/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.c +++ b/src/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.c @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2022 NXP + * Copyright 2020-2023 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 @@ -34,20 +34,23 @@ #include "lv_draw_pxp_blend.h" #if LV_USE_GPU_NXP_PXP +#include "lvgl_support.h" /********************* * DEFINES *********************/ +#define PXP_TEMP_BUF_SIZE LCD_WIDTH * LCD_HEIGHT * LCD_FB_BYTE_PER_PIXEL + #if LV_COLOR_16_SWAP #error Color swap not implemented. Disable LV_COLOR_16_SWAP feature. #endif -#if LV_COLOR_DEPTH==16 +#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 LV_COLOR_DEPTH==32 +#elif LV_COLOR_DEPTH == 32 #define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatARGB8888 #define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatARGB8888 #define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB888 @@ -55,13 +58,6 @@ #error Only 16bit and 32bit color depth are supported. Set LV_COLOR_DEPTH to 16 or 32. #endif -#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \ - || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__) - #define ALIGN_SIZE 8 -#else - #define ALIGN_SIZE 4 -#endif - /********************** * TYPEDEFS **********************/ @@ -70,63 +66,60 @@ * STATIC PROTOTYPES **********************/ +static LV_ATTRIBUTE_MEM_ALIGN uint8_t temp_buf[PXP_TEMP_BUF_SIZE]; + /** * BLock Image Transfer - copy rectangular image from src buffer to dst buffer * with combination of transformation (rotation, scale, recolor) and opacity, alpha channel * or color keying. This requires two steps. First step is used for transformation into * a temporary buffer and the second one will handle the color format or opacity. * - * @param[in/out] dest_buf destination buffer - * @param[in] dest_area area to be copied from src_buf to dst_buf - * @param[in] dest_stride width (stride) of destination buffer in pixels - * @param[in] src_buf source buffer - * @param[in] src_area source area with absolute coordinates to draw on destination buffer - * @param[in] dsc image descriptor - * @param[in] cf color format - * @retval LV_RES_OK Fill completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] dsc Image descriptor + * @param[in] cf Color format */ -static lv_res_t lv_gpu_nxp_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); +static void lv_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); /** * BLock Image Transfer - copy rectangular image from src buffer to dst buffer * with transformation and full opacity. * - * @param[in/out] dest_buf destination buffer - * @param[in] dest_area area to be copied from src_buf to dst_buf - * @param[in] dest_stride width (stride) of destination buffer in pixels - * @param[in] src_buf source buffer - * @param[in] src_area source area with absolute coordinates to draw on destination buffer - * @param[in] dsc image descriptor - * @param[in] cf color format - * @retval LV_RES_OK Fill completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] dsc Image descriptor + * @param[in] cf Color format */ -static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area, - lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); +static void lv_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); /** * BLock Image Transfer - copy rectangular image from src buffer to dst buffer * without transformation but handling color format or opacity. * - * @param[in/out] dest_buf destination buffer - * @param[in] dest_area area to be copied from src_buf to dst_buf - * @param[in] dest_stride width (stride) of destination buffer in pixels - * @param[in] src_buf source buffer - * @param[in] src_area source area with absolute coordinates to draw on destination buffer - * @param[in] dsc image descriptor - * @param[in] cf color format - * @retval LV_RES_OK Fill completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] dsc Image descriptor + * @param[in] cf Color format */ -static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area, - lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); +static void lv_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); /********************** * STATIC VARIABLES @@ -136,45 +129,27 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * * MACROS **********************/ -#define ROUND_UP(x, align) ((x + (align - 1)) & ~(align - 1)) - /********************** * GLOBAL FUNCTIONS **********************/ -lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area, - lv_color_t color, lv_opa_t opa) +void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + lv_color_t color, lv_opa_t opa) { - uint32_t area_size = lv_area_get_size(fill_area); - lv_coord_t area_w = lv_area_get_width(fill_area); - lv_coord_t area_h = lv_area_get_height(fill_area); - - if(opa >= (lv_opa_t)LV_OPA_MAX) { - if(area_size < LV_GPU_NXP_PXP_FILL_SIZE_LIMIT) { - PXP_LOG_TRACE("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_PXP_FILL_SIZE_LIMIT); - return LV_RES_INV; - } - } - else { - if(area_size < LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT) { - PXP_LOG_TRACE("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT); - return LV_RES_INV; - } - } + lv_coord_t dest_w = lv_area_get_width(dest_area); + lv_coord_t dest_h = lv_area_get_height(dest_area); - PXP_Init(LV_GPU_NXP_PXP_ID); - PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/ - PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/ + lv_gpu_nxp_pxp_reset(); /*OUT buffer configure*/ pxp_output_buffer_config_t outputConfig = { .pixelFormat = PXP_OUT_PIXEL_FORMAT, .interlacedMode = kPXP_OutputProgressive, - .buffer0Addr = (uint32_t)(dest_buf + dest_stride * fill_area->y1 + fill_area->x1), + .buffer0Addr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + dest_area->x1), .buffer1Addr = (uint32_t)NULL, .pitchBytes = dest_stride * sizeof(lv_color_t), - .width = area_w, - .height = area_h + .width = dest_w, + .height = dest_h }; PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputConfig); @@ -193,7 +168,7 @@ lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, cons }; PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig); - PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, area_w, area_h); + PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); } /*Disable PS, use as color generator*/ @@ -223,34 +198,19 @@ lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, cons PXP_SetPorterDuffConfig(LV_GPU_NXP_PXP_ID, &pdConfig); - lv_gpu_nxp_pxp_run(); /*Start PXP task*/ - - return LV_RES_OK; + lv_gpu_nxp_pxp_run(); } -lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, lv_opa_t opa, lv_disp_rot_t angle) +void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + lv_opa_t opa, lv_disp_rot_t angle) { - uint32_t dest_size = lv_area_get_size(dest_area); lv_coord_t dest_w = lv_area_get_width(dest_area); lv_coord_t dest_h = lv_area_get_height(dest_area); + lv_coord_t src_w = lv_area_get_width(src_area); + lv_coord_t src_h = lv_area_get_height(src_area); - if(opa >= (lv_opa_t)LV_OPA_MAX) { - if(dest_size < LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT) { - PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT); - return LV_RES_INV; - } - } - else { - if(dest_size < LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT) { - PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT); - return LV_RES_INV; - } - } - - PXP_Init(LV_GPU_NXP_PXP_ID); - PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/ - PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*block size 16x16 for higher performance*/ + lv_gpu_nxp_pxp_reset(); /* convert rotation angle */ pxp_rotate_degree_t pxp_rot; @@ -297,19 +257,17 @@ lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, asBlendConfig.alphaMode = kPXP_AlphaOverride; PXP_SetProcessSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &psBufferConfig); - PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1, dest_h - 1); + PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); } - lv_coord_t src_stride = lv_area_get_width(src_area); - /*AS buffer - source image*/ pxp_as_buffer_config_t asBufferConfig = { .pixelFormat = PXP_AS_PIXEL_FORMAT, - .bufferAddr = (uint32_t)src_buf, + .bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_area->x1), .pitchBytes = src_stride * sizeof(lv_color_t) }; PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig); - PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); + PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U); PXP_SetAlphaSurfaceBlendConfig(LV_GPU_NXP_PXP_ID, &asBlendConfig); PXP_EnableAlphaSurfaceOverlayColorKey(LV_GPU_NXP_PXP_ID, false); @@ -325,162 +283,102 @@ lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, }; PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig); - lv_gpu_nxp_pxp_run(); /* Start PXP task */ - - return LV_RES_OK; + lv_gpu_nxp_pxp_run(); } -lv_res_t lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) +void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) { - uint32_t dest_size = lv_area_get_size(dest_area); + bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP); + bool has_rotation = (dsc->angle != 0); - if(dsc->opa >= (lv_opa_t)LV_OPA_MAX) { - if(dest_size < LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT) { - PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT); - return LV_RES_INV; + if(has_recolor || has_rotation) { + if(dsc->opa >= (lv_opa_t)LV_OPA_MAX && !lv_img_cf_has_alpha(cf) && !lv_img_cf_is_chroma_keyed(cf)) { + lv_pxp_blit_cover(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf); + return; } - } - else { - if(dest_size < LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT) { - PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT); - return LV_RES_INV; - } - } - - bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP); - bool rotation = (dsc->angle != 0); - - if(rotation) { - if(dsc->angle != 0 && dsc->angle != 900 && dsc->angle != 1800 && dsc->angle != 2700) { - PXP_LOG_TRACE("Rotation angle %d is not supported. PXP can rotate only 90x angle.", dsc->angle); - return LV_RES_INV; - } - } - - if(recolor || rotation) { - if(dsc->opa >= (lv_opa_t)LV_OPA_MAX && !lv_img_cf_has_alpha(cf) && !lv_img_cf_is_chroma_keyed(cf)) - return lv_gpu_nxp_pxp_blit_cover(dest_buf, dest_area, dest_stride, src_buf, src_area, dsc, cf); - else + else { /*Recolor and/or rotation with alpha or opacity is done in two steps.*/ - return lv_gpu_nxp_pxp_blit_opa(dest_buf, dest_area, dest_stride, src_buf, src_area, dsc, cf); + lv_pxp_blit_opa(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf); + return; + } } - return lv_gpu_nxp_pxp_blit_cf(dest_buf, dest_area, dest_stride, src_buf, src_area, dsc, cf); + lv_pxp_blit_cf(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf); } /********************** * STATIC FUNCTIONS **********************/ -static lv_res_t lv_gpu_nxp_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) +static void lv_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) { - lv_coord_t dest_w = lv_area_get_width(dest_area); - lv_coord_t dest_h = lv_area_get_height(dest_area); - lv_res_t res; - uint32_t size = dest_w * dest_h * sizeof(lv_color_t); - - if(ROUND_UP(size, ALIGN_SIZE) >= LV_MEM_SIZE) - PXP_RETURN_INV("Insufficient memory for temporary buffer. Please increase LV_MEM_SIZE."); - - lv_color_t * tmp_buf = (lv_color_t *)lv_mem_buf_get(size); - if(!tmp_buf) - PXP_RETURN_INV("Allocating temporary buffer failed."); - - const lv_area_t tmp_area = { + lv_coord_t temp_area_w = lv_area_get_width(dest_area); + lv_coord_t temp_area_h = lv_area_get_height(dest_area); + const lv_area_t temp_area = { .x1 = 0, .y1 = 0, - .x2 = dest_w - 1, - .y2 = dest_h - 1 + .x2 = temp_area_w - 1, + .y2 = temp_area_h - 1 }; /*Step 1: Transform with full opacity to temporary buffer*/ - res = lv_gpu_nxp_pxp_blit_cover(tmp_buf, &tmp_area, dest_w, src_buf, src_area, dsc, cf); - if(res != LV_RES_OK) { - PXP_LOG_TRACE("Blit cover with full opacity failed."); - lv_mem_buf_release(tmp_buf); - - return res; - } - - /*Step 2: Blit temporary results with required opacity to output*/ - res = lv_gpu_nxp_pxp_blit_cf(dest_buf, dest_area, dest_stride, tmp_buf, &tmp_area, dsc, cf); + lv_pxp_blit_cover((lv_color_t *)temp_buf, &temp_area, temp_area_w, src_buf, src_area, src_stride, dsc, cf); - /*Clean-up memory*/ - lv_mem_buf_release(tmp_buf); - - return res; + /*Step 2: Blit temporary result with required opacity to output*/ + lv_pxp_blit_cf(dest_buf, dest_area, dest_stride, (lv_color_t *)temp_buf, &temp_area, temp_area_w, dsc, cf); } - -static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area, - lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) +static void lv_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) { lv_coord_t dest_w = lv_area_get_width(dest_area); lv_coord_t dest_h = lv_area_get_height(dest_area); + lv_coord_t src_w = lv_area_get_width(src_area); + lv_coord_t src_h = lv_area_get_height(src_area); - bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP); - bool rotation = (dsc->angle != 0); - - PXP_Init(LV_GPU_NXP_PXP_ID); - PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/ - PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*block size 16x16 for higher performance*/ - - if(rotation) { - /* - * PXP is set to process 16x16 blocks to optimize the system for memory - * bandwidth and image processing time. - * The output engine essentially truncates any output pixels after the - * desired number of pixels has been written. - * When rotating a source image and the output is not divisible by the block - * size, the incorrect pixels could be truncated and the final output image - * can look shifted. - */ - if(lv_area_get_width(src_area) % 16 || lv_area_get_height(src_area) % 16) { - PXP_LOG_TRACE("Rotation is not supported for image w/o alignment to block size 16x16."); - return LV_RES_INV; - } + bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP); + bool has_rotation = (dsc->angle != 0); + + lv_gpu_nxp_pxp_reset(); + if(has_rotation) { /*Convert rotation angle*/ - pxp_rotate_degree_t pxp_rot; + pxp_rotate_degree_t pxp_angle; switch(dsc->angle) { case 0: - pxp_rot = kPXP_Rotate0; + pxp_angle = kPXP_Rotate0; break; case 900: - pxp_rot = kPXP_Rotate90; + pxp_angle = kPXP_Rotate90; break; case 1800: - pxp_rot = kPXP_Rotate180; + pxp_angle = kPXP_Rotate180; break; case 2700: - pxp_rot = kPXP_Rotate270; + pxp_angle = kPXP_Rotate270; break; default: - PXP_LOG_TRACE("Rotation angle %d is not supported. PXP can rotate only 90x angle.", dsc->angle); - return LV_RES_INV; + pxp_angle = kPXP_Rotate0; } - PXP_SetRotateConfig(LV_GPU_NXP_PXP_ID, kPXP_RotateOutputBuffer, pxp_rot, kPXP_FlipDisable); + PXP_SetRotateConfig(LV_GPU_NXP_PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable); } - lv_coord_t src_stride = lv_area_get_width(src_area); - /*AS buffer - source image*/ pxp_as_buffer_config_t asBufferConfig = { .pixelFormat = PXP_AS_PIXEL_FORMAT, - .bufferAddr = (uint32_t)src_buf, + .bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_area->x1), .pitchBytes = src_stride * sizeof(lv_color_t) }; PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig); - PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); + PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U); /*Disable PS buffer*/ PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); - if(recolor) + if(has_recolor) /*Use as color generator*/ PXP_SetProcessSurfaceBackGroundColor(LV_GPU_NXP_PXP_ID, lv_color_to32(dsc->recolor)); @@ -496,7 +394,7 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t }; PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig); - if(recolor || lv_img_cf_has_alpha(cf)) { + if(has_recolor || lv_img_cf_has_alpha(cf)) { /** * Configure Porter-Duff blending. * @@ -512,7 +410,7 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t .srcGlobalAlphaMode = lv_img_cf_has_alpha(cf) ? kPXP_PorterDuffLocalAlpha : kPXP_PorterDuffGlobalAlpha, .dstFactorMode = kPXP_PorterDuffFactorStraight, .srcFactorMode = kPXP_PorterDuffFactorInversed, - .dstGlobalAlpha = recolor ? dsc->recolor_opa : 0x00, + .dstGlobalAlpha = has_recolor ? dsc->recolor_opa : 0x00, .srcGlobalAlpha = 0xff, .dstAlphaMode = kPXP_PorterDuffAlphaStraight, /*don't care*/ .srcAlphaMode = kPXP_PorterDuffAlphaStraight @@ -520,22 +418,19 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t PXP_SetPorterDuffConfig(LV_GPU_NXP_PXP_ID, &pdConfig); } - lv_gpu_nxp_pxp_run(); /*Start PXP task*/ - - return LV_RES_OK; + lv_gpu_nxp_pxp_run(); } -static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area, - lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) +static void lv_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf) { lv_coord_t dest_w = lv_area_get_width(dest_area); lv_coord_t dest_h = lv_area_get_height(dest_area); + lv_coord_t src_w = lv_area_get_width(src_area); + lv_coord_t src_h = lv_area_get_height(src_area); - PXP_Init(LV_GPU_NXP_PXP_ID); - PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/ - PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*block size 16x16 for higher performance*/ + lv_gpu_nxp_pxp_reset(); pxp_as_blend_config_t asBlendConfig = { .alpha = dsc->opa, @@ -566,28 +461,26 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * asBlendConfig.alphaMode = lv_img_cf_has_alpha(cf) ? kPXP_AlphaMultiply : kPXP_AlphaOverride; } PXP_SetProcessSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &psBufferConfig); - PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1, dest_h - 1); + PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); } - lv_coord_t src_stride = lv_area_get_width(src_area); - /*AS buffer - source image*/ pxp_as_buffer_config_t asBufferConfig = { .pixelFormat = PXP_AS_PIXEL_FORMAT, - .bufferAddr = (uint32_t)src_buf, + .bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_area->x1), .pitchBytes = src_stride * sizeof(lv_color_t) }; PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig); - PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); + PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U); PXP_SetAlphaSurfaceBlendConfig(LV_GPU_NXP_PXP_ID, &asBlendConfig); if(lv_img_cf_is_chroma_keyed(cf)) { lv_color_t colorKeyLow = LV_COLOR_CHROMA_KEY; lv_color_t colorKeyHigh = LV_COLOR_CHROMA_KEY; - bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP); + bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP); - if(recolor) { + if(has_recolor) { /* New color key after recoloring */ lv_color_t colorKey = lv_color_mix(dsc->recolor, LV_COLOR_CHROMA_KEY, dsc->recolor_opa); @@ -595,11 +488,11 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * LV_COLOR_SET_G(colorKeyLow, colorKey.ch.green != 0 ? colorKey.ch.green - 1 : 0); LV_COLOR_SET_B(colorKeyLow, colorKey.ch.blue != 0 ? colorKey.ch.blue - 1 : 0); -#if LV_COLOR_DEPTH==16 +#if LV_COLOR_DEPTH == 16 LV_COLOR_SET_R(colorKeyHigh, colorKey.ch.red != 0x1f ? colorKey.ch.red + 1 : 0x1f); LV_COLOR_SET_G(colorKeyHigh, colorKey.ch.green != 0x3f ? colorKey.ch.green + 1 : 0x3f); LV_COLOR_SET_B(colorKeyHigh, colorKey.ch.blue != 0x1f ? colorKey.ch.blue + 1 : 0x1f); -#else /*LV_COLOR_DEPTH==32*/ +#else /*LV_COLOR_DEPTH == 32*/ LV_COLOR_SET_R(colorKeyHigh, colorKey.ch.red != 0xff ? colorKey.ch.red + 1 : 0xff); LV_COLOR_SET_G(colorKeyHigh, colorKey.ch.green != 0xff ? colorKey.ch.green + 1 : 0xff); LV_COLOR_SET_B(colorKeyHigh, colorKey.ch.blue != 0xff ? colorKey.ch.blue + 1 : 0xff); @@ -624,9 +517,7 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * }; PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig); - lv_gpu_nxp_pxp_run(); /* Start PXP task */ - - return LV_RES_OK; + lv_gpu_nxp_pxp_run(); } #endif /*LV_USE_GPU_NXP_PXP*/ diff --git a/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.c b/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.c index b982e30..164216f 100644 --- a/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.c +++ b/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.c @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2022 NXP + * Copyright 2020-2023 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 @@ -35,7 +35,7 @@ #if LV_USE_GPU_NXP_PXP #include "lv_gpu_nxp_pxp_osa.h" -#include "liblvgl/core/lv_refr.h" +#include "../../../core/lv_refr.h" /********************* * DEFINES @@ -50,9 +50,9 @@ **********************/ /** - * Clean & invalidate cache. + * Clean and invalidate cache. */ -static void invalidate_cache(void); +static inline void invalidate_cache(void); /********************** * STATIC VARIABLES @@ -70,16 +70,23 @@ static lv_nxp_pxp_cfg_t * pxp_cfg; lv_res_t lv_gpu_nxp_pxp_init(void) { +#if LV_USE_GPU_NXP_PXP_AUTO_INIT pxp_cfg = lv_gpu_nxp_pxp_get_cfg(); +#endif - if(!pxp_cfg || !pxp_cfg->pxp_interrupt_deinit || !pxp_cfg->pxp_interrupt_init || !pxp_cfg->pxp_run) + if(!pxp_cfg || !pxp_cfg->pxp_interrupt_deinit || !pxp_cfg->pxp_interrupt_init || + !pxp_cfg->pxp_run || !pxp_cfg->pxp_wait) PXP_RETURN_INV("PXP configuration error."); PXP_Init(LV_GPU_NXP_PXP_ID); + PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/ + PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/ + PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable); if(pxp_cfg->pxp_interrupt_init() != LV_RES_OK) { + PXP_DisableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable); PXP_Deinit(LV_GPU_NXP_PXP_ID); PXP_RETURN_INV("PXP interrupt init failed."); } @@ -90,23 +97,38 @@ lv_res_t lv_gpu_nxp_pxp_init(void) void lv_gpu_nxp_pxp_deinit(void) { pxp_cfg->pxp_interrupt_deinit(); - PXP_DisableInterrupts(PXP, kPXP_CompleteInterruptEnable); + PXP_DisableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable); PXP_Deinit(LV_GPU_NXP_PXP_ID); } +void lv_gpu_nxp_pxp_reset(void) +{ + /* Wait for previous command to complete before resetting the registers. */ + lv_gpu_nxp_pxp_wait(); + + PXP_ResetControl(LV_GPU_NXP_PXP_ID); + + PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/ + PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/ +} + void lv_gpu_nxp_pxp_run(void) { - /*Clean & invalidate cache*/ invalidate_cache(); pxp_cfg->pxp_run(); } +void lv_gpu_nxp_pxp_wait(void) +{ + pxp_cfg->pxp_wait(); +} + /********************** * STATIC FUNCTIONS **********************/ -static void invalidate_cache(void) +static inline void invalidate_cache(void) { lv_disp_t * disp = _lv_refr_get_disp_refreshing(); if(disp->driver->clean_dcache_cb) diff --git a/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c b/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c index e5236fd..8e18840 100644 --- a/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c +++ b/src/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020, 2022 NXP + * Copyright 2020, 2022, 2023 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 @@ -34,7 +34,7 @@ #include "lv_gpu_nxp_pxp_osa.h" #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT -#include "liblvgl/misc/lv_log.h" +#include "../../../misc/lv_log.h" #include "fsl_pxp.h" #if defined(SDK_OS_FREE_RTOS) @@ -65,24 +65,29 @@ static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void); static void _lv_gpu_nxp_pxp_interrupt_deinit(void); /** - * Start the PXP job and wait for task completion. + * Start the PXP job. */ static void _lv_gpu_nxp_pxp_run(void); +/** + * Wait for PXP completion. + */ +static void _lv_gpu_nxp_pxp_wait(void); + /********************** * STATIC VARIABLES **********************/ #if defined(SDK_OS_FREE_RTOS) - static SemaphoreHandle_t s_pxpIdle; -#else - static volatile bool s_pxpIdle; + static SemaphoreHandle_t s_pxpIdleSem; #endif +static volatile bool s_pxpIdle; static 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 + .pxp_run = _lv_gpu_nxp_pxp_run, + .pxp_wait = _lv_gpu_nxp_pxp_wait, }; /********************** @@ -102,7 +107,7 @@ void PXP_IRQHandler(void) if(kPXP_CompleteFlag & PXP_GetStatusFlags(LV_GPU_NXP_PXP_ID)) { PXP_ClearStatusFlags(LV_GPU_NXP_PXP_ID, kPXP_CompleteFlag); #if defined(SDK_OS_FREE_RTOS) - xSemaphoreGiveFromISR(s_pxpIdle, &taskAwake); + xSemaphoreGiveFromISR(s_pxpIdleSem, &taskAwake); portYIELD_FROM_ISR(taskAwake); #else s_pxpIdle = true; @@ -122,14 +127,13 @@ lv_nxp_pxp_cfg_t * lv_gpu_nxp_pxp_get_cfg(void) static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void) { #if defined(SDK_OS_FREE_RTOS) - s_pxpIdle = xSemaphoreCreateBinary(); - if(s_pxpIdle == NULL) + s_pxpIdleSem = xSemaphoreCreateBinary(); + if(s_pxpIdleSem == NULL) return LV_RES_INV; NVIC_SetPriority(LV_GPU_NXP_PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); -#else - s_pxpIdle = true; #endif + s_pxpIdle = true; NVIC_EnableIRQ(LV_GPU_NXP_PXP_IRQ_ID); @@ -140,21 +144,33 @@ static void _lv_gpu_nxp_pxp_interrupt_deinit(void) { NVIC_DisableIRQ(LV_GPU_NXP_PXP_IRQ_ID); #if defined(SDK_OS_FREE_RTOS) - vSemaphoreDelete(s_pxpIdle); + vSemaphoreDelete(s_pxpIdleSem); #endif } +/** + * Function to start PXP job. + */ static void _lv_gpu_nxp_pxp_run(void) { -#if !defined(SDK_OS_FREE_RTOS) s_pxpIdle = false; -#endif PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable); PXP_Start(LV_GPU_NXP_PXP_ID); +} +/** + * Function to wait for PXP completion. + */ +static void _lv_gpu_nxp_pxp_wait(void) +{ #if defined(SDK_OS_FREE_RTOS) - PXP_COND_STOP(!xSemaphoreTake(s_pxpIdle, portMAX_DELAY), "xSemaphoreTake failed."); + /* Return if PXP was never started, otherwise the semaphore will lock forever. */ + if(s_pxpIdle == true) + return; + + if(xSemaphoreTake(s_pxpIdleSem, portMAX_DELAY) == pdTRUE) + s_pxpIdle = true; #else while(s_pxpIdle == false) { } diff --git a/src/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk b/src/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk new file mode 100644 index 0000000..c9473cc --- /dev/null +++ b/src/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk @@ -0,0 +1,12 @@ +CSRCS += lv_draw_vglite.c +CSRCS += lv_draw_vglite_arc.c +CSRCS += lv_draw_vglite_blend.c +CSRCS += lv_draw_vglite_line.c +CSRCS += lv_draw_vglite_rect.c +CSRCS += lv_vglite_buf.c +CSRCS += lv_vglite_utils.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite" diff --git a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite.c b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite.c new file mode 100644 index 0000000..eae1b8a --- /dev/null +++ b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite.c @@ -0,0 +1,508 @@ +/** + * @file lv_draw_vglite.c + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_draw_vglite.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include +#include "lv_draw_vglite_blend.h" +#include "lv_draw_vglite_line.h" +#include "lv_draw_vglite_rect.h" +#include "lv_draw_vglite_arc.h" +#include "lv_vglite_buf.h" + +#if LV_COLOR_DEPTH != 32 + #include "../../../core/lv_refr.h" +#endif + +/********************* + * DEFINES + *********************/ + +/* Minimum area (in pixels) for VG-Lite blit/fill processing. */ +#ifndef LV_GPU_NXP_VG_LITE_SIZE_LIMIT + #define LV_GPU_NXP_VG_LITE_SIZE_LIMIT 5000 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_draw_vglite_init_buf(lv_draw_ctx_t * draw_ctx); + +static void lv_draw_vglite_wait_for_finish(lv_draw_ctx_t * draw_ctx); + +static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, + const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf); + +static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); + +static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1, + const lv_point_t * point2); + +static void lv_draw_vglite_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); + +static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); + +static lv_res_t lv_draw_vglite_border(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, + const lv_area_t * coords); + +static lv_res_t lv_draw_vglite_outline(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, + const lv_area_t * coords); + +static void lv_draw_vglite_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, + uint16_t radius, uint16_t start_angle, uint16_t end_angle); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_vglite_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) +{ + lv_draw_sw_init_ctx(drv, draw_ctx); + + lv_draw_vglite_ctx_t * vglite_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx; + vglite_draw_ctx->base_draw.init_buf = lv_draw_vglite_init_buf; + vglite_draw_ctx->base_draw.draw_line = lv_draw_vglite_line; + vglite_draw_ctx->base_draw.draw_arc = lv_draw_vglite_arc; + vglite_draw_ctx->base_draw.draw_rect = lv_draw_vglite_rect; + vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded; + vglite_draw_ctx->blend = lv_draw_vglite_blend; + vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish; +} + +void lv_draw_vglite_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) +{ + lv_draw_sw_deinit_ctx(drv, draw_ctx); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * During rendering, LVGL might initializes new draw_ctxs and start drawing into + * a separate buffer (called layer). If the content to be rendered has "holes", + * e.g. rounded corner, LVGL temporarily sets the disp_drv.screen_transp flag. + * It means the renderers should draw into an ARGB buffer. + * With 32 bit color depth it's not a big problem but with 16 bit color depth + * the target pixel format is ARGB8565 which is not supported by the GPU. + * In this case, the VG-Lite callbacks should fallback to SW rendering. + */ +static inline bool need_argb8565_support() +{ +#if LV_COLOR_DEPTH != 32 + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + + if(disp->driver->screen_transp == 1) + return true; +#endif + + return false; +} + +static void lv_draw_vglite_init_buf(lv_draw_ctx_t * draw_ctx) +{ + lv_gpu_nxp_vglite_init_buf(draw_ctx->buf, draw_ctx->buf_area, lv_area_get_width(draw_ctx->buf_area)); +} + +static void lv_draw_vglite_wait_for_finish(lv_draw_ctx_t * draw_ctx) +{ + vg_lite_finish(); + + lv_draw_sw_wait_for_finish(draw_ctx); +} + +static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc) +{ + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + + if(need_argb8565_support()) { + lv_draw_sw_blend_basic(draw_ctx, dsc); + return; + } + + lv_area_t blend_area; + /*Let's get the blend area which is the intersection of the area to draw and the clip area*/ + if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) + return; /*Fully clipped, nothing to do*/ + + /*Make the blend area relative to the buffer*/ + lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + bool done = false; + /*Fill/Blend only non masked, normal blended*/ + if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL && + lv_area_get_size(&blend_area) >= LV_GPU_NXP_VG_LITE_SIZE_LIMIT) { + const lv_color_t * src_buf = dsc->src_buf; + + if(src_buf == NULL) { + done = (lv_gpu_nxp_vglite_fill(&blend_area, dsc->color, dsc->opa) == LV_RES_OK); + if(!done) + VG_LITE_LOG_TRACE("VG-Lite fill failed. Fallback."); + } + else { + lv_color_t * dest_buf = draw_ctx->buf; + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + + lv_area_t src_area; + src_area.x1 = blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1); + src_area.y1 = blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1); + src_area.x2 = src_area.x1 + lv_area_get_width(dsc->blend_area) - 1; + src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1; + lv_coord_t src_stride = lv_area_get_width(dsc->blend_area); + + done = (lv_gpu_nxp_vglite_blit(dest_buf, &blend_area, dest_stride, + src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK); + + if(!done) + VG_LITE_LOG_TRACE("VG-Lite blit failed. Fallback."); + } + } + + if(!done) + lv_draw_sw_blend_basic(draw_ctx, dsc); +} + +static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, + const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf) +{ + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + + if(need_argb8565_support()) { + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf); + return; + } + + const lv_color_t * src_buf = (const lv_color_t *)map_p; + if(!src_buf) { + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf); + return; + } + + lv_area_t blend_area; + /*Let's get the blend area which is the intersection of the area to draw and the clip area*/ + if(!_lv_area_intersect(&blend_area, coords, draw_ctx->clip_area)) + return; /*Fully clipped, nothing to do*/ + + /*Make the blend area relative to the buffer*/ + lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + bool has_mask = lv_draw_mask_is_any(&blend_area); + bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP); + + bool done = false; + if(!has_mask && !has_recolor && !lv_img_cf_is_chroma_keyed(cf) && + lv_area_get_size(&blend_area) >= LV_GPU_NXP_VG_LITE_SIZE_LIMIT +#if LV_COLOR_DEPTH != 32 + && !lv_img_cf_has_alpha(cf) +#endif + ) { + lv_color_t * dest_buf = draw_ctx->buf; + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + + lv_area_t src_area; + src_area.x1 = blend_area.x1 - (coords->x1 - draw_ctx->buf_area->x1); + src_area.y1 = blend_area.y1 - (coords->y1 - draw_ctx->buf_area->y1); + src_area.x2 = src_area.x1 + lv_area_get_width(coords) - 1; + src_area.y2 = src_area.y1 + lv_area_get_height(coords) - 1; + lv_coord_t src_stride = lv_area_get_width(coords); + + done = (lv_gpu_nxp_vglite_blit_transform(dest_buf, &blend_area, dest_stride, + src_buf, &src_area, src_stride, dsc) == LV_RES_OK); + + if(!done) + VG_LITE_LOG_TRACE("VG-Lite blit transform failed. Fallback."); + } + + if(!done) + lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf); +} + +static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1, + const lv_point_t * point2) +{ + if(dsc->width == 0) + return; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + if(point1->x == point2->x && point1->y == point2->y) + return; + + if(need_argb8565_support()) { + lv_draw_sw_line(draw_ctx, dsc, point1, point2); + return; + } + + lv_area_t rel_clip_area; + rel_clip_area.x1 = LV_MIN(point1->x, point2->x) - dsc->width / 2; + rel_clip_area.x2 = LV_MAX(point1->x, point2->x) + dsc->width / 2; + rel_clip_area.y1 = LV_MIN(point1->y, point2->y) - dsc->width / 2; + rel_clip_area.y2 = LV_MAX(point1->y, point2->y) + dsc->width / 2; + + bool is_common; + is_common = _lv_area_intersect(&rel_clip_area, &rel_clip_area, draw_ctx->clip_area); + if(!is_common) + return; + + /* Make coordinates relative to the draw buffer */ + lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_point_t rel_point1 = { point1->x - draw_ctx->buf_area->x1, point1->y - draw_ctx->buf_area->y1 }; + lv_point_t rel_point2 = { point2->x - draw_ctx->buf_area->x1, point2->y - draw_ctx->buf_area->y1 }; + + bool done = false; + bool mask_any = lv_draw_mask_is_any(&rel_clip_area); + + if(!mask_any) { + done = (lv_gpu_nxp_vglite_draw_line(&rel_point1, &rel_point2, &rel_clip_area, dsc) == LV_RES_OK); + if(!done) + VG_LITE_LOG_TRACE("VG-Lite draw line failed. Fallback."); + } + + if(!done) + lv_draw_sw_line(draw_ctx, dsc, point1, point2); +} + +static void lv_draw_vglite_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords) +{ + if(need_argb8565_support()) { + lv_draw_sw_rect(draw_ctx, dsc, coords); + return; + } + + lv_draw_rect_dsc_t vglite_dsc; + + lv_memcpy(&vglite_dsc, dsc, sizeof(vglite_dsc)); + vglite_dsc.bg_opa = 0; + vglite_dsc.bg_img_opa = 0; + vglite_dsc.border_opa = 0; + vglite_dsc.outline_opa = 0; +#if LV_DRAW_COMPLEX + /* Draw the shadow with CPU */ + lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords); + vglite_dsc.shadow_opa = 0; +#endif /*LV_DRAW_COMPLEX*/ + + /* Draw the background */ + vglite_dsc.bg_opa = dsc->bg_opa; + if(lv_draw_vglite_bg(draw_ctx, &vglite_dsc, coords) != LV_RES_OK) + lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords); + vglite_dsc.bg_opa = 0; + + /* Draw the background image + * It will be done once draw_ctx->draw_img_decoded() + * callback gets called from lv_draw_sw_rect(). + */ + vglite_dsc.bg_img_opa = dsc->bg_img_opa; + lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords); + vglite_dsc.bg_img_opa = 0; + + /* Draw the border */ + vglite_dsc.border_opa = dsc->border_opa; + if(lv_draw_vglite_border(draw_ctx, &vglite_dsc, coords) != LV_RES_OK) + lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords); + vglite_dsc.border_opa = 0; + + /* Draw the outline */ + vglite_dsc.outline_opa = dsc->outline_opa; + if(lv_draw_vglite_outline(draw_ctx, &vglite_dsc, coords) != LV_RES_OK) + lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords); +} + +static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->bg_opa <= (lv_opa_t)LV_OPA_MIN) + return LV_RES_INV; + + lv_area_t rel_coords; + lv_area_copy(&rel_coords, coords); + + /*If the border fully covers make the bg area 1px smaller to avoid artifacts on the corners*/ + if(dsc->border_width > 1 && dsc->border_opa >= (lv_opa_t)LV_OPA_MAX && dsc->radius != 0) { + rel_coords.x1 += (dsc->border_side & LV_BORDER_SIDE_LEFT) ? 1 : 0; + rel_coords.y1 += (dsc->border_side & LV_BORDER_SIDE_TOP) ? 1 : 0; + rel_coords.x2 -= (dsc->border_side & LV_BORDER_SIDE_RIGHT) ? 1 : 0; + rel_coords.y2 -= (dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? 1 : 0; + } + + /* Make coordinates relative to draw buffer */ + lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, draw_ctx->clip_area); + lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_area_t clipped_coords; + if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area)) + return LV_RES_INV; + + bool mask_any = lv_draw_mask_is_any(&rel_coords); + lv_grad_dir_t grad_dir = dsc->bg_grad.dir; + lv_color_t bg_color = (grad_dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) ? + dsc->bg_color : dsc->bg_grad.stops[0].color; + if(bg_color.full == dsc->bg_grad.stops[1].color.full) + grad_dir = LV_GRAD_DIR_NONE; + + /* + * Most simple case: just a plain rectangle (no mask, no radius, no gradient) + * shall be handled by draw_ctx->blend(). + * + * Complex case: gradient or radius but no mask. + */ + if(!mask_any && ((dsc->radius != 0) || (grad_dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE))) { + lv_res_t res = lv_gpu_nxp_vglite_draw_bg(&rel_coords, &rel_clip_area, dsc); + if(res != LV_RES_OK) + VG_LITE_LOG_TRACE("VG-Lite draw bg failed. Fallback."); + + return res; + } + + return LV_RES_INV; +} + +static lv_res_t lv_draw_vglite_border(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, + const lv_area_t * coords) +{ + if(dsc->border_opa <= (lv_opa_t)LV_OPA_MIN) + return LV_RES_INV; + if(dsc->border_width == 0) + return LV_RES_INV; + if(dsc->border_post) + return LV_RES_INV; + if(dsc->border_side != (lv_border_side_t)LV_BORDER_SIDE_FULL) + return LV_RES_INV; + + lv_area_t rel_coords; + lv_coord_t border_width = dsc->border_width; + + /* Move border inwards to align with software rendered border */ + rel_coords.x1 = coords->x1 + ceil(border_width / 2.0f); + rel_coords.x2 = coords->x2 - floor(border_width / 2.0f); + rel_coords.y1 = coords->y1 + ceil(border_width / 2.0f); + rel_coords.y2 = coords->y2 - floor(border_width / 2.0f); + + /* Make coordinates relative to the draw buffer */ + lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, draw_ctx->clip_area); + lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_res_t res = lv_gpu_nxp_vglite_draw_border_generic(&rel_coords, &rel_clip_area, dsc, true); + if(res != LV_RES_OK) + VG_LITE_LOG_TRACE("VG-Lite draw border failed. Fallback."); + + return res; +} + +static lv_res_t lv_draw_vglite_outline(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, + const lv_area_t * coords) +{ + if(dsc->outline_opa <= (lv_opa_t)LV_OPA_MIN) + return LV_RES_INV; + if(dsc->outline_width == 0) + return LV_RES_INV; + + /* Move outline outwards to align with software rendered outline */ + lv_coord_t outline_pad = dsc->outline_pad - 1; + lv_area_t rel_coords; + rel_coords.x1 = coords->x1 - outline_pad - floor(dsc->outline_width / 2.0f); + rel_coords.x2 = coords->x2 + outline_pad + ceil(dsc->outline_width / 2.0f); + rel_coords.y1 = coords->y1 - outline_pad - floor(dsc->outline_width / 2.0f); + rel_coords.y2 = coords->y2 + outline_pad + ceil(dsc->outline_width / 2.0f); + + /* Make coordinates relative to the draw buffer */ + lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, draw_ctx->clip_area); + lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + lv_res_t res = lv_gpu_nxp_vglite_draw_border_generic(&rel_coords, &rel_clip_area, dsc, false); + if(res != LV_RES_OK) + VG_LITE_LOG_TRACE("VG-Lite draw outline failed. Fallback."); + + return res; +} + +static void lv_draw_vglite_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, + uint16_t radius, uint16_t start_angle, uint16_t end_angle) +{ + bool done = false; + +#if LV_DRAW_COMPLEX + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + if(dsc->width == 0) + return; + if(start_angle == end_angle) + return; + + if(need_argb8565_support()) { + lv_draw_sw_arc(draw_ctx, dsc, center, radius, start_angle, end_angle); + return; + } + + /* Make coordinates relative to the draw buffer */ + lv_point_t rel_center = {center->x - draw_ctx->buf_area->x1, center->y - draw_ctx->buf_area->y1}; + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, draw_ctx->clip_area); + lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + + done = (lv_gpu_nxp_vglite_draw_arc(&rel_center, (int32_t)radius, (int32_t)start_angle, (int32_t)end_angle, + &rel_clip_area, dsc) == LV_RES_OK); + if(!done) + VG_LITE_LOG_TRACE("VG-Lite draw arc failed. Fallback."); +#endif/*LV_DRAW_COMPLEX*/ + + if(!done) + lv_draw_sw_arc(draw_ctx, dsc, center, radius, start_angle, end_angle); +} + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ diff --git a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.c b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.c index 194f03d..775bf73 100644 --- a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.c +++ b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.c @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2021, 2022 NXP + * Copyright 2021-2023 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 @@ -34,7 +34,8 @@ #include "lv_draw_vglite_arc.h" #if LV_USE_GPU_NXP_VG_LITE -#include "math.h" +#include "lv_vglite_buf.h" +#include /********************* * DEFINES @@ -88,7 +89,7 @@ typedef struct _cubic_cont_pt { static void rotate_point(int32_t angle, int32_t * x, int32_t * y); static void add_arc_path(int32_t * arc_path, int * pidx, int32_t radius, - int32_t start_angle, int32_t end_angle, lv_point_t center, bool cw); + int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw); /********************** * STATIC VARIABLES @@ -102,31 +103,20 @@ static void add_arc_path(int32_t * arc_path, int * pidx, int32_t radius, * GLOBAL FUNCTIONS **********************/ -lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, - int32_t radius, int32_t start_angle, int32_t end_angle) +lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, int32_t start_angle, int32_t end_angle, + const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc) { - - vg_lite_buffer_t vgbuf; vg_lite_error_t err = VG_LITE_SUCCESS; lv_color32_t col32 = {.full = lv_color_to32(dsc->color)}; /*Convert color to RGBA8888*/ - lv_coord_t dest_width = lv_area_get_width(draw_ctx->buf_area); - lv_coord_t dest_height = lv_area_get_height(draw_ctx->buf_area); vg_lite_path_t path; vg_lite_color_t vgcol; /* vglite takes ABGR */ - vg_lite_matrix_t matrix; - lv_opa_t opa = dsc->opa; bool donut = ((end_angle - start_angle) % 360 == 0) ? true : false; - lv_point_t clip_center = {center->x - draw_ctx->buf_area->x1, center->y - draw_ctx->buf_area->y1}; + vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf(); /* path: max size = 16 cubic bezier (7 words each) */ int32_t arc_path[16 * 7]; lv_memset_00(arc_path, sizeof(arc_path)); - /*** Init destination buffer ***/ - if(lv_vglite_init_buf(&vgbuf, (uint32_t)dest_width, (uint32_t)dest_height, (uint32_t)dest_width * sizeof(lv_color_t), - (const lv_color_t *)draw_ctx->buf, false) != LV_RES_OK) - VG_LITE_RETURN_INV("Init buffer failed."); - /*** Init path ***/ lv_coord_t width = dsc->width; /* inner arc radius = outer arc radius - width */ if(width > (lv_coord_t)radius) @@ -140,11 +130,11 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_ cp_y = 0; rotate_point(start_angle, &cp_x, &cp_y); arc_path[pidx++] = VLC_OP_MOVE; - arc_path[pidx++] = clip_center.x + cp_x; - arc_path[pidx++] = clip_center.y + cp_y; + arc_path[pidx++] = center->x + cp_x; + arc_path[pidx++] = center->y + cp_y; /* draw 1-5 outer quarters */ - add_arc_path(arc_path, &pidx, radius, start_angle, end_angle, clip_center, true); + add_arc_path(arc_path, &pidx, radius, start_angle, end_angle, center, true); if(donut) { /* close outer circle */ @@ -152,24 +142,24 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_ cp_y = 0; rotate_point(start_angle, &cp_x, &cp_y); arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = clip_center.x + cp_x; - arc_path[pidx++] = clip_center.y + cp_y; + arc_path[pidx++] = center->x + cp_x; + arc_path[pidx++] = center->y + cp_y; /* start inner circle */ cp_x = radius - width; cp_y = 0; rotate_point(start_angle, &cp_x, &cp_y); arc_path[pidx++] = VLC_OP_MOVE; - arc_path[pidx++] = clip_center.x + cp_x; - arc_path[pidx++] = clip_center.y + cp_y; + arc_path[pidx++] = center->x + cp_x; + arc_path[pidx++] = center->y + cp_y; } else if(dsc->rounded != 0U) { /* 1st rounded arc ending */ cp_x = radius - width / 2; cp_y = 0; rotate_point(end_angle, &cp_x, &cp_y); - lv_point_t round_center = {clip_center.x + cp_x, clip_center.y + cp_y}; + lv_point_t round_center = {center->x + cp_x, center->y + cp_y}; add_arc_path(arc_path, &pidx, width / 2, end_angle, (end_angle + 180), - round_center, true); + &round_center, true); } else { /* 1st flat ending */ @@ -177,12 +167,12 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_ cp_y = 0; rotate_point(end_angle, &cp_x, &cp_y); arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = clip_center.x + cp_x; - arc_path[pidx++] = clip_center.y + cp_y; + arc_path[pidx++] = center->x + cp_x; + arc_path[pidx++] = center->y + cp_y; } /* draw 1-5 inner quarters */ - add_arc_path(arc_path, &pidx, radius - width, start_angle, end_angle, clip_center, false); + add_arc_path(arc_path, &pidx, radius - width, start_angle, end_angle, center, false); /* last control point of curve */ if(donut) { /* close the loop */ @@ -190,17 +180,17 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_ cp_y = 0; rotate_point(start_angle, &cp_x, &cp_y); arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = clip_center.x + cp_x; - arc_path[pidx++] = clip_center.y + cp_y; + arc_path[pidx++] = center->x + cp_x; + arc_path[pidx++] = center->y + cp_y; } else if(dsc->rounded != 0U) { /* 2nd rounded arc ending */ cp_x = radius - width / 2; cp_y = 0; rotate_point(start_angle, &cp_x, &cp_y); - lv_point_t round_center = {clip_center.x + cp_x, clip_center.y + cp_y}; + lv_point_t round_center = {center->x + cp_x, center->y + cp_y}; add_arc_path(arc_path, &pidx, width / 2, (start_angle + 180), (start_angle + 360), - round_center, true); + &round_center, true); } else { /* 2nd flat ending */ @@ -208,46 +198,30 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_ cp_y = 0; rotate_point(start_angle, &cp_x, &cp_y); arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = clip_center.x + cp_x; - arc_path[pidx++] = clip_center.y + cp_y; + arc_path[pidx++] = center->x + cp_x; + arc_path[pidx++] = center->y + cp_y; } arc_path[pidx++] = VLC_OP_END; err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, (uint32_t)pidx * sizeof(int32_t), arc_path, - (vg_lite_float_t) draw_ctx->clip_area->x1, (vg_lite_float_t) draw_ctx->clip_area->y1, - ((vg_lite_float_t) draw_ctx->clip_area->x2) + 1.0f, ((vg_lite_float_t) draw_ctx->clip_area->y2) + 1.0f); + (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, + ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f); VG_LITE_ERR_RETURN_INV(err, "Init path failed."); - /* set rotation angle */ - vg_lite_identity(&matrix); + vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888; + if(lv_vglite_premult_and_swizzle(&vgcol, col32, dsc->opa, color_format) != LV_RES_OK) + VG_LITE_RETURN_INV("Premultiplication and swizzle failed."); - if(opa <= (lv_opa_t)LV_OPA_MAX) { - /* Only pre-multiply color if hardware pre-multiplication is not present */ - if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) { - col32.ch.red = (uint8_t)(((uint16_t)col32.ch.red * opa) >> 8); - col32.ch.green = (uint8_t)(((uint16_t)col32.ch.green * opa) >> 8); - col32.ch.blue = (uint8_t)(((uint16_t)col32.ch.blue * opa) >> 8); - } - col32.ch.alpha = opa; - } - -#if LV_COLOR_DEPTH==16 - vgcol = col32.full; -#else /*LV_COLOR_DEPTH==32*/ - vgcol = ((uint32_t)col32.ch.alpha << 24) | ((uint32_t)col32.ch.blue << 16) | ((uint32_t)col32.ch.green << 8) | - (uint32_t)col32.ch.red; -#endif - - /*Clean & invalidate cache*/ - lv_vglite_invalidate_cache(); + vg_lite_matrix_t matrix; + vg_lite_identity(&matrix); /*** Draw arc ***/ - err = vg_lite_draw(&vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol); + err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol); VG_LITE_ERR_RETURN_INV(err, "Draw arc failed."); - err = vg_lite_finish(); - VG_LITE_ERR_RETURN_INV(err, "Finish failed."); + if(lv_vglite_run() != LV_RES_OK) + VG_LITE_RETURN_INV("Run failed."); err = vg_lite_clear_path(&path); VG_LITE_ERR_RETURN_INV(err, "Clear path failed."); @@ -564,50 +538,50 @@ static void get_arc_control_points(vg_arc * arc, bool start) * center: (in) the center of the circle in draw coordinates * cw: (in) true if arc is clockwise */ -static void add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, lv_point_t center, bool cw) +static void add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, const lv_point_t * center, bool cw) { /* assumes first control point already in array arc_path[] */ int idx = *pidx; if(cw) { #if BEZIER_DBG_CONTROL_POINTS arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p1x + center.x; - arc_path[idx++] = q_arc->p1y + center.y; + arc_path[idx++] = q_arc->p1x + center->x; + arc_path[idx++] = q_arc->p1y + center->y; arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p2x + center.x; - arc_path[idx++] = q_arc->p2y + center.y; + arc_path[idx++] = q_arc->p2x + center->x; + arc_path[idx++] = q_arc->p2y + center->y; arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p3x + center.x; - arc_path[idx++] = q_arc->p3y + center.y; + arc_path[idx++] = q_arc->p3x + center->x; + arc_path[idx++] = q_arc->p3y + center->y; #else arc_path[idx++] = VLC_OP_CUBIC; - arc_path[idx++] = q_arc->p1x + center.x; - arc_path[idx++] = q_arc->p1y + center.y; - arc_path[idx++] = q_arc->p2x + center.x; - arc_path[idx++] = q_arc->p2y + center.y; - arc_path[idx++] = q_arc->p3x + center.x; - arc_path[idx++] = q_arc->p3y + center.y; + arc_path[idx++] = q_arc->p1x + center->x; + arc_path[idx++] = q_arc->p1y + center->y; + arc_path[idx++] = q_arc->p2x + center->x; + arc_path[idx++] = q_arc->p2y + center->y; + arc_path[idx++] = q_arc->p3x + center->x; + arc_path[idx++] = q_arc->p3y + center->y; #endif } else { /* reverse points order when counter-clockwise */ #if BEZIER_DBG_CONTROL_POINTS arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p2x + center.x; - arc_path[idx++] = q_arc->p2y + center.y; + arc_path[idx++] = q_arc->p2x + center->x; + arc_path[idx++] = q_arc->p2y + center->y; arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p1x + center.x; - arc_path[idx++] = q_arc->p1y + center.y; + arc_path[idx++] = q_arc->p1x + center->x; + arc_path[idx++] = q_arc->p1y + center->y; arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p0x + center.x; - arc_path[idx++] = q_arc->p0y + center.y; + arc_path[idx++] = q_arc->p0x + center->x; + arc_path[idx++] = q_arc->p0y + center->y; #else arc_path[idx++] = VLC_OP_CUBIC; - arc_path[idx++] = q_arc->p2x + center.x; - arc_path[idx++] = q_arc->p2y + center.y; - arc_path[idx++] = q_arc->p1x + center.x; - arc_path[idx++] = q_arc->p1y + center.y; - arc_path[idx++] = q_arc->p0x + center.x; - arc_path[idx++] = q_arc->p0y + center.y; + arc_path[idx++] = q_arc->p2x + center->x; + arc_path[idx++] = q_arc->p2y + center->y; + arc_path[idx++] = q_arc->p1x + center->x; + arc_path[idx++] = q_arc->p1y + center->y; + arc_path[idx++] = q_arc->p0x + center->x; + arc_path[idx++] = q_arc->p0y + center->y; #endif } /* update index i n path array*/ @@ -615,7 +589,7 @@ static void add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, l } static void add_arc_path(int32_t * arc_path, int * pidx, int32_t radius, - int32_t start_angle, int32_t end_angle, lv_point_t center, bool cw) + int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw) { /* set number of arcs to draw */ vg_arc q_arc; diff --git a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.c b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.c index b59b143..e1408b7 100644 --- a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.c +++ b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.c @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2022 NXP + * Copyright 2020-2023 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 @@ -34,12 +34,19 @@ #include "lv_draw_vglite_blend.h" #if LV_USE_GPU_NXP_VG_LITE +#include "lv_vglite_buf.h" /********************* * DEFINES *********************/ -/* Enable BLIT quality degradation workaround for RT595, recommended for screen's dimension > 352 pixels */ +/** Stride in px required by VG-Lite HW*/ +#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U + +/** + * Enable BLIT quality degradation workaround for RT595, + * recommended for screen's dimension > 352 pixels. + */ #define RT595_BLIT_WRKRND_ENABLED 1 /* Internal compound symbol */ @@ -51,12 +58,13 @@ #define VG_LITE_BLIT_SPLIT_ENABLED 0 #endif -/** - * BLIT split threshold - BLITs with width or height higher than this value will be done - * in multiple steps. Value must be 16-aligned. Don't change. - */ -#define LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR 352 - +#if VG_LITE_BLIT_SPLIT_ENABLED + /** + * BLIT split threshold - BLITs with width or height higher than this value will be done + * in multiple steps. Value must be 16-aligned. Don't change. + */ + #define LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR 352 +#endif /********************** * TYPEDEFS @@ -67,63 +75,87 @@ **********************/ /** - * BLock Image Transfer - single direct BLIT. + * Blit single image, with optional opacity. + * + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] src_area Source area with relative coordinates of source buffer + * @param[in] opa Opacity * - * @param[in] blit Description of the transfer * @retval LV_RES_OK Transfer complete * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * blit); +static lv_res_t lv_vglite_blit_single(const lv_area_t * dest_area, const lv_area_t * src_area, lv_opa_t opa); -#if VG_LITE_BLIT_SPLIT_ENABLED +/** + * Check source memory and stride alignment. + * + * @param[in] src_buf Source buffer + * @param[in] src_stride Stride of source buffer in pixels + * + * @retval LV_RES_OK Alignment OK + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + */ +static lv_res_t check_src_alignment(const lv_color_t * src_buf, lv_coord_t src_stride); - /** - * Move buffer pointer as close as possible to area, but with respect to alignment requirements. X-axis only. - * - * @param[in,out] area Area to be updated - * @param[in,out] buf Pointer to be updated - */ - static void _align_x(lv_area_t * area, lv_color_t ** buf); +/** + * Creates matrix that translates to origin of given destination area. + * + * @param[in] dest_area Area with relative coordinates of destination buffer + */ +static inline void lv_vglite_set_translation_matrix(const lv_area_t * dest_area); - /** - * Move buffer pointer to the area start and update variables, Y-axis only. - * - * @param[in,out] area Area to be updated - * @param[in,out] buf Pointer to be updated - * @param[in] stridePx Buffer stride in pixels - */ - static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx); +/** + * Creates matrix that translates to origin of given destination area with transformation (scale or rotate). + * + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dsc Image descriptor + */ +static inline void lv_vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_img_dsc_t * dsc); - /** - * Software BLIT as a fall-back scenario. - * - * @param[in] blit BLIT configuration - */ - static void _sw_blit(lv_gpu_nxp_vglite_blit_info_t * blit); +#if VG_LITE_BLIT_SPLIT_ENABLED - /** - * Verify BLIT structure - widths, stride, pointer alignment - * - * @param[in] blit BLIT configuration - * @retval LV_RES_OK - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) - */ - static lv_res_t _lv_gpu_nxp_vglite_check_blit(lv_gpu_nxp_vglite_blit_info_t * blit); +/** + * Move buffer pointer as close as possible to area, but with respect to alignment requirements. X-axis only. + * + * @param[in/out] area Area to be updated + * @param[in/out] buf Pointer to be updated + */ +static void align_x(lv_area_t * area, lv_color_t ** buf); - /** - * BLock Image Transfer - split BLIT. - * - * @param[in] blit BLIT configuration - * @retval LV_RES_OK Transfer complete - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) - */ - static lv_res_t _lv_gpu_nxp_vglite_blit_split(lv_gpu_nxp_vglite_blit_info_t * blit); +/** + * Move buffer pointer to the area start and update variables, Y-axis only. + * + * @param[in/out] area Area to be updated + * @param[in/out] buf Pointer to be updated + * @param[in] stride Buffer stride in pixels + */ +static void align_y(lv_area_t * area, lv_color_t ** buf, lv_coord_t stride); + +/** + * Blit image split in tiles, with optional opacity. + * + * @param[in/out] dest_buf Destination buffer + * @param[in] dest_area Area with relative coordinates of destination buffer + * @param[in] dest_stride Stride of destination buffer in pixels + * @param[in] src_buf Source buffer + * @param[in] src_area Source area with relative coordinates of source buffer + * @param[in] src_stride Stride of source buffer in pixels + * @param[in] opa Opacity + * + * @retval LV_RES_OK Transfer complete + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + */ +static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, + lv_opa_t opa); #endif /********************** * STATIC VARIABLES **********************/ +static vg_lite_matrix_t vgmatrix; + /********************** * MACROS **********************/ @@ -132,98 +164,57 @@ static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * b * GLOBAL FUNCTIONS **********************/ -lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height, - const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa) +lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, lv_opa_t opa) { - uint32_t area_size = lv_area_get_size(fill_area); - lv_coord_t area_w = lv_area_get_width(fill_area); - lv_coord_t area_h = lv_area_get_height(fill_area); - - if(opa >= (lv_opa_t)LV_OPA_MAX) { - if(area_size < LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT) - VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT); - } - else { - if(area_size < LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT) - VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT); - } - - vg_lite_buffer_t vgbuf; - vg_lite_rectangle_t rect; vg_lite_error_t err = VG_LITE_SUCCESS; lv_color32_t col32 = {.full = lv_color_to32(color)}; /*Convert color to RGBA8888*/ vg_lite_color_t vgcol; /* vglite takes ABGR */ + vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf(); - if(lv_vglite_init_buf(&vgbuf, (uint32_t)dest_width, (uint32_t)dest_height, (uint32_t)dest_width * sizeof(lv_color_t), - (const lv_color_t *)dest_buf, false) != LV_RES_OK) - VG_LITE_RETURN_INV("Init buffer failed."); + vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888; + if(lv_vglite_premult_and_swizzle(&vgcol, col32, opa, color_format) != LV_RES_OK) + VG_LITE_RETURN_INV("Premultiplication and swizzle failed."); if(opa >= (lv_opa_t)LV_OPA_MAX) { /*Opaque fill*/ - rect.x = fill_area->x1; - rect.y = fill_area->y1; - rect.width = area_w; - rect.height = area_h; - - /*Clean & invalidate cache*/ - lv_vglite_invalidate_cache(); - -#if LV_COLOR_DEPTH==16 - vgcol = col32.full; -#else /*LV_COLOR_DEPTH==32*/ - vgcol = ((uint32_t)col32.ch.alpha << 24) | ((uint32_t)col32.ch.blue << 16) | ((uint32_t)col32.ch.green << 8) | - (uint32_t)col32.ch.red; -#endif + vg_lite_rectangle_t rect = { + .x = dest_area->x1, + .y = dest_area->y1, + .width = lv_area_get_width(dest_area), + .height = lv_area_get_height(dest_area) + }; - err = vg_lite_clear(&vgbuf, &rect, vgcol); + err = vg_lite_clear(vgbuf, &rect, vgcol); VG_LITE_ERR_RETURN_INV(err, "Clear failed."); - err = vg_lite_finish(); - VG_LITE_ERR_RETURN_INV(err, "Finish failed."); + if(lv_vglite_run() != LV_RES_OK) + VG_LITE_RETURN_INV("Run failed."); } else { /*fill with transparency*/ vg_lite_path_t path; int32_t path_data[] = { /*VG rectangular path*/ - VLC_OP_MOVE, fill_area->x1, fill_area->y1, - VLC_OP_LINE, fill_area->x2 + 1, fill_area->y1, - VLC_OP_LINE, fill_area->x2 + 1, fill_area->y2 + 1, - VLC_OP_LINE, fill_area->x1, fill_area->y2 + 1, - VLC_OP_LINE, fill_area->x1, fill_area->y1, + VLC_OP_MOVE, dest_area->x1, dest_area->y1, + VLC_OP_LINE, dest_area->x2 + 1, dest_area->y1, + VLC_OP_LINE, dest_area->x2 + 1, dest_area->y2 + 1, + VLC_OP_LINE, dest_area->x1, dest_area->y2 + 1, + VLC_OP_LINE, dest_area->x1, dest_area->y1, VLC_OP_END }; err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_LOW, sizeof(path_data), path_data, - (vg_lite_float_t) fill_area->x1, (vg_lite_float_t) fill_area->y1, - ((vg_lite_float_t) fill_area->x2) + 1.0f, ((vg_lite_float_t) fill_area->y2) + 1.0f); + (vg_lite_float_t) dest_area->x1, (vg_lite_float_t) dest_area->y1, + ((vg_lite_float_t) dest_area->x2) + 1.0f, ((vg_lite_float_t) dest_area->y2) + 1.0f); VG_LITE_ERR_RETURN_INV(err, "Init path failed."); - /* Only pre-multiply color if hardware pre-multiplication is not present */ - if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) { - col32.ch.red = (uint8_t)(((uint16_t)col32.ch.red * opa) >> 8); - col32.ch.green = (uint8_t)(((uint16_t)col32.ch.green * opa) >> 8); - col32.ch.blue = (uint8_t)(((uint16_t)col32.ch.blue * opa) >> 8); - } - col32.ch.alpha = opa; - -#if LV_COLOR_DEPTH==16 - vgcol = col32.full; -#else /*LV_COLOR_DEPTH==32*/ - vgcol = ((uint32_t)col32.ch.alpha << 24) | ((uint32_t)col32.ch.blue << 16) | ((uint32_t)col32.ch.green << 8) | - (uint32_t)col32.ch.red; -#endif - - /*Clean & invalidate cache*/ - lv_vglite_invalidate_cache(); - vg_lite_matrix_t matrix; vg_lite_identity(&matrix); /*Draw rectangle*/ - err = vg_lite_draw(&vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol); + err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol); VG_LITE_ERR_RETURN_INV(err, "Draw rectangle failed."); - err = vg_lite_finish(); - VG_LITE_ERR_RETURN_INV(err, "Finish failed."); + if(lv_vglite_run() != LV_RES_OK) + VG_LITE_RETURN_INV("Run failed."); err = vg_lite_clear_path(&path); VG_LITE_ERR_RETURN_INV(err, "Clear path failed."); @@ -232,41 +223,64 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv return LV_RES_OK; } -lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit) +lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, + lv_opa_t opa) { - uint32_t dest_size = lv_area_get_size(&blit->dst_area); + /* Set vgmatrix. */ + lv_vglite_set_translation_matrix(dest_area); - if(blit->opa >= (lv_opa_t)LV_OPA_MAX) { - if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT) - VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT); - } - else { - if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT) - VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT); - } + /* Set src_vgbuf structure. */ + lv_vglite_set_src_buf(src_buf, src_area, src_stride); #if VG_LITE_BLIT_SPLIT_ENABLED - return _lv_gpu_nxp_vglite_blit_split(blit); -#endif /* non RT595 */ + lv_color_t * orig_dest_buf = dest_buf; + + lv_res_t rv = lv_vglite_blit_split(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, opa); + + /* Restore the original dest_vgbuf memory address. */ + lv_vglite_set_dest_buf_ptr(orig_dest_buf); + + return rv; +#else + LV_UNUSED(dest_buf); + LV_UNUSED(dest_stride); + + if(check_src_alignment(src_buf, src_stride) != LV_RES_OK) + VG_LITE_RETURN_INV("Check src alignment failed."); - /* Just pass down */ - return _lv_gpu_nxp_vglite_blit_single(blit); + return lv_vglite_blit_single(dest_area, src_area, opa); +#endif } -lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit) +lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, + const lv_draw_img_dsc_t * dsc) { - uint32_t dest_size = lv_area_get_size(&blit->dst_area); + /* Set vgmatrix. */ + lv_vglite_set_transformation_matrix(dest_area, dsc); - if(blit->opa >= (lv_opa_t)LV_OPA_MAX) { - if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT) - VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT); - } - else { - if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT) - VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT); - } + /* Set src_vgbuf structure. */ + lv_vglite_set_src_buf(src_buf, src_area, src_stride); + +#if VG_LITE_BLIT_SPLIT_ENABLED + lv_color_t * orig_dest_buf = dest_buf; + + lv_res_t rv = lv_vglite_blit_split(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc->opa); - return _lv_gpu_nxp_vglite_blit_single(blit); + /* Restore the original dest_vgbuf memory address. */ + lv_vglite_set_dest_buf_ptr(orig_dest_buf); + + return rv; +#else + LV_UNUSED(dest_buf); + LV_UNUSED(dest_stride); + + if(check_src_alignment(src_buf, src_stride) != LV_RES_OK) + VG_LITE_RETURN_INV("Check src alignment failed."); + + return lv_vglite_blit_single(dest_area, src_area, dsc->opa); +#endif } /********************** @@ -274,223 +288,196 @@ lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit) **********************/ #if VG_LITE_BLIT_SPLIT_ENABLED -static lv_res_t _lv_gpu_nxp_vglite_blit_split(lv_gpu_nxp_vglite_blit_info_t * blit) +static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, + lv_opa_t opa) { lv_res_t rv = LV_RES_INV; - if(_lv_gpu_nxp_vglite_check_blit(blit) != LV_RES_OK) { - PRINT_BLT("Blit check failed\n"); - return LV_RES_INV; - } - - PRINT_BLT("BLIT from: " - "Area: %03d,%03d - %03d,%03d " - "Addr: %d\n\n", - blit->src_area.x1, blit->src_area.y1, - blit->src_area.x2, blit->src_area.y2, - (uintptr_t) blit->src); - - PRINT_BLT("BLIT to: " - "Area: %03d,%03d - %03d,%03d " - "Addr: %d\n\n", - blit->dst_area.x1, blit->dst_area.y1, - blit->dst_area.x2, blit->dst_area.y2, - (uintptr_t) blit->src); - - /* Stage 1: Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible. */ - _align_x(&blit->src_area, (lv_color_t **)&blit->src); - _align_y(&blit->src_area, (lv_color_t **)&blit->src, blit->src_stride / sizeof(lv_color_t)); - _align_x(&blit->dst_area, (lv_color_t **)&blit->dst); - _align_y(&blit->dst_area, (lv_color_t **)&blit->dst, blit->dst_stride / sizeof(lv_color_t)); + VG_LITE_LOG_TRACE("Blit " + "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " + "Size: ([%dx%d] -> [%dx%d]) | " + "Addr: (0x%x -> 0x%x)", + src_area->x1, src_area->y1, src_area->x2, src_area->y2, + dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2, + lv_area_get_width(src_area), lv_area_get_height(src_area), + lv_area_get_width(dest_area), lv_area_get_height(dest_area), + (uintptr_t)src_buf, (uintptr_t)dest_buf); + + /* Stage 1: Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible. */ + align_x(src_area, (lv_color_t **)&src_buf); + align_y(src_area, (lv_color_t **)&src_buf, src_stride); + align_x(dest_area, (lv_color_t **)&dest_buf); + align_y(dest_area, (lv_color_t **)&dest_buf, dest_stride); /* Stage 2: If we're in limit, do a single BLIT */ - if((blit->src_area.x2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) && - (blit->src_area.y2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR)) { - PRINT_BLT("Simple blit!\n"); - return _lv_gpu_nxp_vglite_blit_single(blit); + if((src_area->x2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) && + (src_area->y2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR)) { + if(check_src_alignment(src_buf, src_stride) != LV_RES_OK) + VG_LITE_RETURN_INV("Check src alignment failed."); + + /* Set new dest_vgbuf and src_vgbuf memory addresses. */ + lv_vglite_set_dest_buf_ptr(dest_buf); + lv_vglite_set_src_buf_ptr(src_buf); + + /* Set vgmatrix. */ + lv_vglite_set_translation_matrix(dest_area); + + rv = lv_vglite_blit_single(dest_area, src_area, opa); + + VG_LITE_LOG_TRACE("Single " + "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " + "Size: ([%dx%d] -> [%dx%d]) | " + "Addr: (0x%x -> 0x%x) %s", + src_area->x1, src_area->y1, src_area->x2, src_area->y2, + dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2, + lv_area_get_width(src_area), lv_area_get_height(src_area), + lv_area_get_width(dest_area), lv_area_get_height(dest_area), + (uintptr_t)src_buf, (uintptr_t)dest_buf, + rv == LV_RES_OK ? "OK!" : "FAILED!"); + + return rv; }; /* Stage 3: Split the BLIT into multiple tiles */ - PRINT_BLT("Split blit!\n"); - - PRINT_BLT("Blit " - "([%03d,%03d], [%03d,%03d]) -> " - "([%03d,%03d], [%03d,%03d]) | " - "([%03dx%03d] -> [%03dx%03d]) | " - "A:(%d -> %d)\n", - blit->src_area.x1, blit->src_area.y1, blit->src_area.x2, blit->src_area.y2, - blit->dst_area.x1, blit->dst_area.y1, blit->dst_area.x2, blit->dst_area.y2, - lv_area_get_width(&blit->src_area), lv_area_get_height(&blit->src_area), - lv_area_get_width(&blit->dst_area), lv_area_get_height(&blit->dst_area), - (uintptr_t) blit->src, (uintptr_t) blit->dst); + VG_LITE_LOG_TRACE("Split " + "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " + "Size: ([%dx%d] -> [%dx%d]) | " + "Addr: (0x%x -> 0x%x)", + src_area->x1, src_area->y1, src_area->x2, src_area->y2, + dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2, + lv_area_get_width(src_area), lv_area_get_height(src_area), + lv_area_get_width(dest_area), lv_area_get_height(dest_area), + (uintptr_t)src_buf, (uintptr_t)dest_buf); - lv_coord_t totalWidth = lv_area_get_width(&blit->src_area); - lv_coord_t totalHeight = lv_area_get_height(&blit->src_area); - - lv_gpu_nxp_vglite_blit_info_t tileBlit; + lv_coord_t width = lv_area_get_width(src_area); + lv_coord_t height = lv_area_get_height(src_area); /* Number of tiles needed */ - int totalTilesX = (blit->src_area.x1 + totalWidth + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) / - LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; - int totalTilesY = (blit->src_area.y1 + totalHeight + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) / - LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; + int total_tiles_x = (src_area->x1 + width + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) / + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; + int total_tiles_y = (src_area->y1 + height + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) / + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; /* src and dst buffer shift against each other. Src buffer real data [0,0] may start actually at [3,0] in buffer, as * the buffer pointer has to be aligned, while dst buffer real data [0,0] may start at [1,0] in buffer. alignment may be * different */ - int shiftSrcX = (blit->src_area.x1 > blit->dst_area.x1) ? (blit->src_area.x1 - blit->dst_area.x1) : 0; - int shiftDstX = (blit->src_area.x1 < blit->dst_area.x1) ? (blit->dst_area.x1 - blit->src_area.x1) : 0; + int shift_src_x = (src_area->x1 > dest_area->x1) ? (src_area->x1 - dest_area->x1) : 0; + int shift_dest_x = (src_area->x1 < dest_area->x1) ? (dest_area->x1 - src_area->x1) : 0; - PRINT_BLT("\n"); - PRINT_BLT("Align shift: src: %d, dst: %d\n", shiftSrcX, shiftDstX); + VG_LITE_LOG_TRACE("X shift: src: %d, dst: %d", shift_src_x, shift_dest_x); - tileBlit = *blit; + lv_color_t * tile_dest_buf; + lv_area_t tile_dest_area; + const lv_color_t * tile_src_buf; + lv_area_t tile_src_area; - for(int tileY = 0; tileY < totalTilesY; tileY++) { + for(int y = 0; y < total_tiles_y; y++) { - tileBlit.src_area.y1 = 0; /* no vertical alignment, always start from 0 */ - tileBlit.src_area.y2 = totalHeight - tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; - if(tileBlit.src_area.y2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) { - tileBlit.src_area.y2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; /* Should never happen */ + tile_src_area.y1 = 0; /* no vertical alignment, always start from 0 */ + tile_src_area.y2 = height - y * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; + if(tile_src_area.y2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) { + tile_src_area.y2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; /* Should never happen */ } - tileBlit.src = blit->src + tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * blit->src_stride / sizeof( - lv_color_t); /* stride in px! */ + tile_src_buf = src_buf + y * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * src_stride; - tileBlit.dst_area.y1 = tileBlit.src_area.y1; /* y has no alignment, always in sync with src */ - tileBlit.dst_area.y2 = tileBlit.src_area.y2; + tile_dest_area.y1 = tile_src_area.y1; /* y has no alignment, always in sync with src */ + tile_dest_area.y2 = tile_src_area.y2; - tileBlit.dst = blit->dst + tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * blit->dst_stride / sizeof( - lv_color_t); /* stride in px! */ + tile_dest_buf = dest_buf + y * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * dest_stride; - for(int tileX = 0; tileX < totalTilesX; tileX++) { + for(int x = 0; x < total_tiles_x; x++) { - if(tileX == 0) { + if(x == 0) { /* 1st tile is special - there may be a gap between buffer start pointer * and area.x1 value, as the pointer has to be aligned. - * tileBlit.src pointer - keep init value from Y-loop. + * tile_src_buf pointer - keep init value from Y-loop. * Also, 1st tile start is not shifted! shift is applied from 2nd tile */ - tileBlit.src_area.x1 = blit->src_area.x1; - tileBlit.dst_area.x1 = blit->dst_area.x1; + tile_src_area.x1 = src_area->x1; + tile_dest_area.x1 = dest_area->x1; } else { /* subsequent tiles always starts from 0, but shifted*/ - tileBlit.src_area.x1 = 0 + shiftSrcX; - tileBlit.dst_area.x1 = 0 + shiftDstX; + tile_src_area.x1 = 0 + shift_src_x; + tile_dest_area.x1 = 0 + shift_dest_x; /* and advance start pointer + 1 tile size */ - tileBlit.src += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; - tileBlit.dst += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; + tile_src_buf += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; + tile_dest_buf += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR; } /* Clip tile end coordinates */ - tileBlit.src_area.x2 = totalWidth + blit->src_area.x1 - tileX * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; - if(tileBlit.src_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) { - tileBlit.src_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; + tile_src_area.x2 = width + src_area->x1 - x * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; + if(tile_src_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) { + tile_src_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; } - tileBlit.dst_area.x2 = totalWidth + blit->dst_area.x1 - tileX * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; - if(tileBlit.dst_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) { - tileBlit.dst_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; + tile_dest_area.x2 = width + dest_area->x1 - x * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; + if(tile_dest_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) { + tile_dest_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; } - if(tileX < (totalTilesX - 1)) { - /* And adjust end coords if shifted, but not for last tile! */ - tileBlit.src_area.x2 += shiftSrcX; - tileBlit.dst_area.x2 += shiftDstX; + if(x < (total_tiles_x - 1)) { + /* And adjust end coords if shifted, but not for last tile! */ + tile_src_area.x2 += shift_src_x; + tile_dest_area.x2 += shift_dest_x; } - rv = _lv_gpu_nxp_vglite_blit_single(&tileBlit); + if(check_src_alignment(tile_src_buf, src_stride) != LV_RES_OK) + VG_LITE_RETURN_INV("Check src alignment failed."); -#if BLIT_DBG_AREAS - lv_vglite_dbg_draw_rectangle((lv_color_t *) tileBlit.dst, tileBlit.dst_width, tileBlit.dst_height, &tileBlit.dst_area, - LV_COLOR_RED); - lv_vglite_dbg_draw_rectangle((lv_color_t *) tileBlit.src, tileBlit.src_width, tileBlit.src_height, &tileBlit.src_area, - LV_COLOR_GREEN); -#endif + /* Set vgmatrix. */ + lv_vglite_set_translation_matrix(&tile_dest_area); - PRINT_BLT("Tile [%d, %d]: " - "([%d,%d], [%d,%d]) -> " - "([%d,%d], [%d,%d]) | " - "([%dx%d] -> [%dx%d]) | " - "A:(0x%8X -> 0x%8X) %s\n", - tileX, tileY, - tileBlit.src_area.x1, tileBlit.src_area.y1, tileBlit.src_area.x2, tileBlit.src_area.y2, - tileBlit.dst_area.x1, tileBlit.dst_area.y1, tileBlit.dst_area.x2, tileBlit.dst_area.y2, - lv_area_get_width(&tileBlit.src_area), lv_area_get_height(&tileBlit.src_area), - lv_area_get_width(&tileBlit.dst_area), lv_area_get_height(&tileBlit.dst_area), - (uintptr_t) tileBlit.src, (uintptr_t) tileBlit.dst, - rv == LV_RES_OK ? "OK!" : "!!! FAILED !!!"); - - if(rv != LV_RES_OK) { /* if anything goes wrong... */ -#if LV_GPU_NXP_VG_LITE_LOG_ERRORS - LV_LOG_ERROR("Split blit failed. Trying SW blit instead."); -#endif - _sw_blit(&tileBlit); - rv = LV_RES_OK; /* Don't report error, as SW BLIT was performed */ - } + /* Set new dest_vgbuf and src_vgbuf memory addresses. */ + lv_vglite_set_dest_buf_ptr(tile_dest_buf); + lv_vglite_set_src_buf_ptr(tile_src_buf); + + rv = lv_vglite_blit_single(&tile_dest_area, &tile_src_area, opa); + VG_LITE_LOG_TRACE("Tile [%d, %d] " + "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " + "Size: ([%dx%d] -> [%dx%d]) | " + "Addr: (0x%x -> 0x%x) %s", + x, y, + tile_src_area.x1, tile_src_area.y1, tile_src_area.x2, tile_src_area.y2, + tile_dest_area.x1, tile_dest_area.y1, tile_dest_area.x2, tile_dest_area.y2, + lv_area_get_width(&tile_src_area), lv_area_get_height(&tile_src_area), + lv_area_get_width(&tile_dest_area), lv_area_get_height(&tile_dest_area), + (uintptr_t)tile_src_buf, (uintptr_t)tile_dest_buf, + rv == LV_RES_OK ? "OK!" : "FAILED!"); + + if(rv != LV_RES_OK) { + return rv; + } } - PRINT_BLT(" \n"); } - return rv; /* should never fail */ + return rv; } #endif /* VG_LITE_BLIT_SPLIT_ENABLED */ -static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * blit) +static lv_res_t lv_vglite_blit_single(const lv_area_t * dest_area, const lv_area_t * src_area, lv_opa_t opa) { - vg_lite_buffer_t src_vgbuf, dst_vgbuf; vg_lite_error_t err = VG_LITE_SUCCESS; - uint32_t rect[4]; - vg_lite_float_t scale = 1.0; - - if(blit == NULL) { - /*Wrong parameter*/ - return LV_RES_INV; - } - - if(blit->opa < (lv_opa_t) LV_OPA_MIN) { - return LV_RES_OK; /*Nothing to BLIT*/ - } - - /*Wrap src/dst buffer into VG-Lite buffer*/ - if(lv_vglite_init_buf(&src_vgbuf, (uint32_t)blit->src_width, (uint32_t)blit->src_height, (uint32_t)blit->src_stride, - blit->src, true) != LV_RES_OK) - VG_LITE_RETURN_INV("Init buffer failed."); - - if(lv_vglite_init_buf(&dst_vgbuf, (uint32_t)blit->dst_width, (uint32_t)blit->dst_height, (uint32_t)blit->dst_stride, - blit->dst, false) != LV_RES_OK) - VG_LITE_RETURN_INV("Init buffer failed."); - - rect[0] = (uint32_t)blit->src_area.x1; /* start x */ - rect[1] = (uint32_t)blit->src_area.y1; /* start y */ - rect[2] = (uint32_t)blit->src_area.x2 - (uint32_t)blit->src_area.x1 + 1U; /* width */ - rect[3] = (uint32_t)blit->src_area.y2 - (uint32_t)blit->src_area.y1 + 1U; /* height */ - - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - vg_lite_translate((vg_lite_float_t)blit->dst_area.x1, (vg_lite_float_t)blit->dst_area.y1, &matrix); - - if((blit->angle != 0) || (blit->zoom != LV_IMG_ZOOM_NONE)) { - vg_lite_translate(blit->pivot.x, blit->pivot.y, &matrix); - vg_lite_rotate(blit->angle / 10.0f, &matrix); /* angle is 1/10 degree */ - scale = 1.0f * blit->zoom / LV_IMG_ZOOM_NONE; - vg_lite_scale(scale, scale, &matrix); - vg_lite_translate(0.0f - blit->pivot.x, 0.0f - blit->pivot.y, &matrix); - } - - /*Clean & invalidate cache*/ - lv_vglite_invalidate_cache(); + vg_lite_buffer_t * dst_vgbuf = lv_vglite_get_dest_buf(); + vg_lite_buffer_t * src_vgbuf = lv_vglite_get_src_buf(); + + uint32_t rect[] = { + (uint32_t)src_area->x1, /* start x */ + (uint32_t)src_area->y1, /* start y */ + (uint32_t)lv_area_get_width(src_area), /* width */ + (uint32_t)lv_area_get_height(src_area) /* height */ + }; uint32_t color; vg_lite_blend_t blend; - if(blit->opa >= (lv_opa_t)LV_OPA_MAX) { + if(opa >= (lv_opa_t)LV_OPA_MAX) { color = 0xFFFFFFFFU; blend = VG_LITE_BLEND_SRC_OVER; - src_vgbuf.transparency_mode = VG_LITE_IMAGE_TRANSPARENT; + src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; } else { - uint32_t opa = (uint32_t)blit->opa; if(vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) { color = (opa << 24) | 0x00FFFFFFU; } @@ -498,94 +485,83 @@ static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * b color = (opa << 24) | (opa << 16) | (opa << 8) | opa; } blend = VG_LITE_BLEND_SRC_OVER; - src_vgbuf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - src_vgbuf.transparency_mode = VG_LITE_IMAGE_TRANSPARENT; + src_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; } - err = vg_lite_blit_rect(&dst_vgbuf, &src_vgbuf, rect, &matrix, blend, color, VG_LITE_FILTER_POINT); - VG_LITE_ERR_RETURN_INV(err, "Blit rectangle failed."); - - err = vg_lite_finish(); - VG_LITE_ERR_RETURN_INV(err, "Finish failed."); - - return LV_RES_OK; -} - -#if VG_LITE_BLIT_SPLIT_ENABLED - -static void _sw_blit(lv_gpu_nxp_vglite_blit_info_t * blit) -{ - int x, y; + bool scissoring = lv_area_get_width(dest_area) < lv_area_get_width(src_area) || + lv_area_get_height(dest_area) < lv_area_get_height(src_area); + if(scissoring) { + vg_lite_enable_scissor(); + vg_lite_set_scissor((int32_t)dest_area->x1, (int32_t)dest_area->y1, + (int32_t)lv_area_get_width(dest_area), + (int32_t)lv_area_get_height(dest_area)); + } - lv_coord_t w = lv_area_get_width(&blit->src_area); - lv_coord_t h = lv_area_get_height(&blit->src_area); + err = vg_lite_blit_rect(dst_vgbuf, src_vgbuf, rect, &vgmatrix, blend, color, VG_LITE_FILTER_POINT); + if(err != VG_LITE_SUCCESS) { + if(scissoring) + vg_lite_disable_scissor(); + VG_LITE_RETURN_INV("Blit rectangle failed."); + } - int32_t srcStridePx = blit->src_stride / (int32_t)sizeof(lv_color_t); - int32_t dstStridePx = blit->dst_stride / (int32_t)sizeof(lv_color_t); + if(lv_vglite_run() != LV_RES_OK) { + if(scissoring) + vg_lite_disable_scissor(); + VG_LITE_RETURN_INV("Run failed."); + } - lv_color_t * src = (lv_color_t *)blit->src + blit->src_area.y1 * srcStridePx + blit->src_area.x1; - lv_color_t * dst = (lv_color_t *)blit->dst + blit->dst_area.y1 * dstStridePx + blit->dst_area.x1; + if(scissoring) + vg_lite_disable_scissor(); - if(blit->opa >= (lv_opa_t)LV_OPA_MAX) { - /* simple copy */ - for(y = 0; y < h; y++) { - lv_memcpy(dst, src, (uint32_t)w * sizeof(lv_color_t)); - src += srcStridePx; - dst += dstStridePx; - } - } - else if(blit->opa >= LV_OPA_MIN) { - /* alpha blending */ - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - dst[x] = lv_color_mix(src[x], dst[x], blit->opa); - } - src += srcStridePx; - dst += dstStridePx; - } - } + return LV_RES_OK; } -static lv_res_t _lv_gpu_nxp_vglite_check_blit(lv_gpu_nxp_vglite_blit_info_t * blit) +static lv_res_t check_src_alignment(const lv_color_t * src_buf, lv_coord_t src_stride) { - - /* Test for minimal width */ - if(lv_area_get_width(&blit->src_area) < (lv_coord_t)LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) - VG_LITE_RETURN_INV("Src area width (%d) is smaller than required (%d).", lv_area_get_width(&blit->src_area), - LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX); - - /* Test for minimal width */ - if(lv_area_get_width(&blit->dst_area) < (lv_coord_t)LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) - VG_LITE_RETURN_INV("Dest area width (%d) is smaller than required (%d).", lv_area_get_width(&blit->dst_area), - LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX); - - /* Test for pointer alignment */ - if((((uintptr_t) blit->src) % LV_ATTRIBUTE_MEM_ALIGN_SIZE) != 0x0) - VG_LITE_RETURN_INV("Src buffer ptr (0x%X) not aligned to %d.", (size_t) blit->src, LV_ATTRIBUTE_MEM_ALIGN_SIZE); - /* No alignment requirement for destination pixel buffer when using mode VG_LITE_LINEAR */ - /* Test for stride alignment */ - if((blit->src_stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * LV_COLOR_DEPTH / 8)) != 0x0) - VG_LITE_RETURN_INV("Src buffer stride (%d px) not aligned to %d px.", blit->src_stride, - LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX); + /* Test for pointer alignment */ + if((((uintptr_t)src_buf) % (uintptr_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE) != (uintptr_t)0x0U) + VG_LITE_RETURN_INV("Src buffer ptr (0x%x) not aligned to 0x%x bytes.", + (size_t)src_buf, LV_ATTRIBUTE_MEM_ALIGN_SIZE); /* Test for stride alignment */ - if((blit->dst_stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * LV_COLOR_DEPTH / 8)) != 0x0) - VG_LITE_RETURN_INV("Dest buffer stride (%d px) not aligned to %d px.", blit->dst_stride, - LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX); - - if((lv_area_get_width(&blit->src_area) != lv_area_get_width(&blit->dst_area)) || - (lv_area_get_height(&blit->src_area) != lv_area_get_height(&blit->dst_area))) - VG_LITE_RETURN_INV("Src and dest buffer areas are not equal."); - + if((src_stride % (lv_coord_t)LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) != 0x0U) + VG_LITE_RETURN_INV("Src buffer stride (%d px) not aligned to %d px.", + src_stride, LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX); return LV_RES_OK; } -static void _align_x(lv_area_t * area, lv_color_t ** buf) +static inline void lv_vglite_set_translation_matrix(const lv_area_t * dest_area) { + vg_lite_identity(&vgmatrix); + vg_lite_translate((vg_lite_float_t)dest_area->x1, (vg_lite_float_t)dest_area->y1, &vgmatrix); +} + +static inline void lv_vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_img_dsc_t * dsc) +{ + lv_vglite_set_translation_matrix(dest_area); + + bool has_scale = (dsc->zoom != LV_IMG_ZOOM_NONE); + bool has_rotation = (dsc->angle != 0); + + if(has_scale || has_rotation) { + vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &vgmatrix); + if(has_rotation) + vg_lite_rotate(dsc->angle / 10.0f, &vgmatrix); /* angle is 1/10 degree */ + if(has_scale) { + vg_lite_float_t scale = 1.0f * dsc->zoom / LV_IMG_ZOOM_NONE; + vg_lite_scale(scale, scale, &vgmatrix); + } + vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &vgmatrix); + } +} - int alignedAreaStartPx = area->x1 - (area->x1 % (LV_ATTRIBUTE_MEM_ALIGN_SIZE * 8 / LV_COLOR_DEPTH)); +#if VG_LITE_BLIT_SPLIT_ENABLED +static void align_x(lv_area_t * area, lv_color_t ** buf) +{ + int alignedAreaStartPx = area->x1 - (area->x1 % (LV_ATTRIBUTE_MEM_ALIGN_SIZE / sizeof(lv_color_t))); VG_LITE_COND_STOP(alignedAreaStartPx < 0, "Negative X alignment."); area->x1 -= alignedAreaStartPx; @@ -593,17 +569,17 @@ static void _align_x(lv_area_t * area, lv_color_t ** buf) *buf += alignedAreaStartPx; } -static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx) +static void align_y(lv_area_t * area, lv_color_t ** buf, lv_coord_t stride) { int LineToAlignMem; int alignedAreaStartPy; /* find how many lines of pixels will respect memory alignment requirement */ - if(stridePx % (uint32_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE == 0U) { + if((stride % (lv_coord_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE) == 0x0U) { alignedAreaStartPy = area->y1; } else { - LineToAlignMem = LV_ATTRIBUTE_MEM_ALIGN_SIZE / (sizeof(lv_color_t) * LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX); - VG_LITE_COND_STOP(LV_ATTRIBUTE_MEM_ALIGN_SIZE % (sizeof(lv_color_t) * LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX), + LineToAlignMem = LV_ATTRIBUTE_MEM_ALIGN_SIZE / (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t)); + VG_LITE_COND_STOP(LV_ATTRIBUTE_MEM_ALIGN_SIZE % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t)), "Complex case: need gcd function."); alignedAreaStartPy = area->y1 - (area->y1 % LineToAlignMem); VG_LITE_COND_STOP(alignedAreaStartPy < 0, "Negative Y alignment."); @@ -611,7 +587,7 @@ static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx) area->y1 -= alignedAreaStartPy; area->y2 -= alignedAreaStartPy; - *buf += (uint32_t)alignedAreaStartPy * stridePx; + *buf += (uint32_t)(alignedAreaStartPy * stride); } #endif /*VG_LITE_BLIT_SPLIT_ENABLED*/ diff --git a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.c b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.c new file mode 100644 index 0000000..f6e1c43 --- /dev/null +++ b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.c @@ -0,0 +1,138 @@ +/** + * @file lv_draw_vglite_line.c + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_draw_vglite_line.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "lv_vglite_buf.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_res_t lv_gpu_nxp_vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2, + const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc) +{ + vg_lite_error_t err = VG_LITE_SUCCESS; + vg_lite_path_t path; + vg_lite_color_t vgcol; /* vglite takes ABGR */ + vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf(); + vg_lite_cap_style_t cap_style = (dsc->round_start || dsc->round_end) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT; + vg_lite_join_style_t join_style = (dsc->round_start || dsc->round_end) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER; + + bool is_dashed = (dsc->dash_width && dsc->dash_gap); + + vg_lite_float_t stroke_dash_pattern[2] = {0, 0}; + uint32_t stroke_dash_count = 0; + vg_lite_float_t stroke_dash_phase = 0; + if(is_dashed) { + stroke_dash_pattern[0] = (vg_lite_float_t)dsc->dash_width; + stroke_dash_pattern[1] = (vg_lite_float_t)dsc->dash_gap; + stroke_dash_count = sizeof(stroke_dash_pattern) / sizeof(vg_lite_float_t); + stroke_dash_phase = (vg_lite_float_t)dsc->dash_width / 2; + } + + /* Choose vglite blend mode based on given lvgl blend mode */ + vg_lite_blend_t vglite_blend_mode = lv_vglite_get_blend_mode(dsc->blend_mode); + + /*** Init path ***/ + lv_coord_t width = dsc->width; + + int32_t line_path[] = { /*VG line path*/ + VLC_OP_MOVE, point1->x, point1->y, + VLC_OP_LINE, point2->x, point2->y, + VLC_OP_END + }; + + err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(line_path), line_path, + (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, + ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f); + VG_LITE_ERR_RETURN_INV(err, "Init path failed."); + + vg_lite_matrix_t matrix; + vg_lite_identity(&matrix); + + lv_color32_t col32 = { .full = lv_color_to32(dsc->color) }; /*Convert color to RGBA8888*/ + vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888; + if(lv_vglite_premult_and_swizzle(&vgcol, col32, dsc->opa, color_format) != LV_RES_OK) + VG_LITE_RETURN_INV("Premultiplication and swizzle failed."); + + /*** Draw line ***/ + err = vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH); + VG_LITE_ERR_RETURN_INV(err, "Set draw path type failed."); + + err = vg_lite_set_stroke(&path, cap_style, join_style, width, 8, stroke_dash_pattern, stroke_dash_count, + stroke_dash_phase, vgcol); + VG_LITE_ERR_RETURN_INV(err, "Set stroke failed."); + + err = vg_lite_update_stroke(&path); + VG_LITE_ERR_RETURN_INV(err, "Update stroke failed."); + + err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vglite_blend_mode, vgcol); + VG_LITE_ERR_RETURN_INV(err, "Draw line failed."); + + if(lv_vglite_run() != LV_RES_OK) + VG_LITE_RETURN_INV("Run failed."); + + err = vg_lite_clear_path(&path); + VG_LITE_ERR_RETURN_INV(err, "Clear path failed."); + + return LV_RES_OK; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ diff --git a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.c b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.c index bc1d55c..39ccaa4 100644 --- a/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.c +++ b/src/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.c @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2021, 2022 NXP + * Copyright 2021-2023 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 @@ -34,11 +34,29 @@ #include "lv_draw_vglite_rect.h" #if LV_USE_GPU_NXP_VG_LITE +#include "lv_vglite_buf.h" +#include +/********************* + * DEFINES + *********************/ /********************* * DEFINES *********************/ +/* Path data sizes for different elements */ +#define CUBIC_PATH_DATA_SIZE 7 /* 1 opcode, 6 arguments */ +#define LINE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */ +#define MOVE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */ +#define END_PATH_DATA_SIZE 1 /* 1 opcode, 0 arguments */ +/* Maximum possible rectangle path size + * is in the rounded rectangle case: + * - 1 move for the path start + * - 4 cubics for the corners + * - 4 lines for the sides + * - 1 end for the path end */ +#define RECT_PATH_DATA_MAX_SIZE 1 * MOVE_PATH_DATA_SIZE + 4 * CUBIC_PATH_DATA_SIZE + 4 * LINE_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE + /********************** * TYPEDEFS **********************/ @@ -47,6 +65,18 @@ * STATIC PROTOTYPES **********************/ +/** + * Generates path data for rectangle drawing. + * + * @param[in/out] path The path data to initialize + * @param[in/out] path_size The resulting size of the created path data + * @param[in] dsc The style descriptor for the rectangle to be drawn + * @param[in] coords The coordinates of the rectangle to be drawn + */ +static void lv_vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size, + lv_coord_t radius, + const lv_area_t * coords); + /********************** * STATIC VARIABLES **********************/ @@ -59,94 +89,37 @@ * GLOBAL FUNCTIONS **********************/ -lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords) +lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * clip_area, + const lv_draw_rect_dsc_t * dsc) { - vg_lite_buffer_t vgbuf; vg_lite_error_t err = VG_LITE_SUCCESS; - lv_coord_t dest_width = lv_area_get_width(draw_ctx->buf_area); - lv_coord_t dest_height = lv_area_get_height(draw_ctx->buf_area); - vg_lite_path_t path; - vg_lite_color_t vgcol; /* vglite takes ABGR */ - vg_lite_matrix_t matrix; lv_coord_t width = lv_area_get_width(coords); lv_coord_t height = lv_area_get_height(coords); - vg_lite_linear_gradient_t gradient; - vg_lite_matrix_t * grad_matrix; + vg_lite_color_t vgcol; + lv_coord_t radius = dsc->radius; + vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf(); if(dsc->radius < 0) return LV_RES_INV; - /* Make areas relative to draw buffer */ - lv_area_t rel_coords; - lv_area_copy(&rel_coords, coords); - lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); - - lv_area_t rel_clip; - lv_area_copy(&rel_clip, draw_ctx->clip_area); - lv_area_move(&rel_clip, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); - - /*** Init destination buffer ***/ - if(lv_vglite_init_buf(&vgbuf, (uint32_t)dest_width, (uint32_t)dest_height, (uint32_t)dest_width * sizeof(lv_color_t), - (const lv_color_t *)draw_ctx->buf, false) != LV_RES_OK) - VG_LITE_RETURN_INV("Init buffer failed."); - /*** Init path ***/ - int32_t rad = dsc->radius; - if(dsc->radius == LV_RADIUS_CIRCLE) { - rad = (width > height) ? height / 2 : width / 2; - } - - if((dsc->radius == LV_RADIUS_CIRCLE) && (width == height)) { - float tang = ((float)rad * BEZIER_OPTIM_CIRCLE); - int32_t cpoff = (int32_t)tang; - int32_t circle_path[] = { /*VG circle path*/ - VLC_OP_MOVE, rel_coords.x1 + rad, rel_coords.y1, - VLC_OP_CUBIC_REL, cpoff, 0, rad, rad - cpoff, rad, rad, /* top-right */ - VLC_OP_CUBIC_REL, 0, cpoff, cpoff - rad, rad, 0 - rad, rad, /* bottom-right */ - VLC_OP_CUBIC_REL, 0 - cpoff, 0, 0 - rad, cpoff - rad, 0 - rad, 0 - rad, /* bottom-left */ - VLC_OP_CUBIC_REL, 0, 0 - cpoff, rad - cpoff, 0 - rad, rad, 0 - rad, /* top-left */ - VLC_OP_END - }; - err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(circle_path), circle_path, - (vg_lite_float_t) rel_clip.x1, (vg_lite_float_t) rel_clip.y1, - ((vg_lite_float_t) rel_clip.x2) + 1.0f, ((vg_lite_float_t) rel_clip.y2) + 1.0f); - } - else if(dsc->radius > 0) { - float tang = ((float)rad * BEZIER_OPTIM_CIRCLE); - int32_t cpoff = (int32_t)tang; - int32_t rounded_path[] = { /*VG rounded rectangular path*/ - VLC_OP_MOVE, rel_coords.x1 + rad, rel_coords.y1, - VLC_OP_LINE, rel_coords.x2 - rad + 1, rel_coords.y1, /* top */ - VLC_OP_CUBIC_REL, cpoff, 0, rad, rad - cpoff, rad, rad, /* top-right */ - VLC_OP_LINE, rel_coords.x2 + 1, rel_coords.y2 - rad + 1, /* right */ - VLC_OP_CUBIC_REL, 0, cpoff, cpoff - rad, rad, 0 - rad, rad, /* bottom-right */ - VLC_OP_LINE, rel_coords.x1 + rad, rel_coords.y2 + 1, /* bottom */ - VLC_OP_CUBIC_REL, 0 - cpoff, 0, 0 - rad, cpoff - rad, 0 - rad, 0 - rad, /* bottom-left */ - VLC_OP_LINE, rel_coords.x1, rel_coords.y1 + rad, /* left */ - VLC_OP_CUBIC_REL, 0, 0 - cpoff, rad - cpoff, 0 - rad, rad, 0 - rad, /* top-left */ - VLC_OP_END - }; - err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(rounded_path), rounded_path, - (vg_lite_float_t) rel_clip.x1, (vg_lite_float_t) rel_clip.y1, - ((vg_lite_float_t) rel_clip.x2) + 1.0f, ((vg_lite_float_t) rel_clip.y2) + 1.0f); - } - else { - int32_t rect_path[] = { /*VG rectangular path*/ - VLC_OP_MOVE, rel_coords.x1, rel_coords.y1, - VLC_OP_LINE, rel_coords.x2 + 1, rel_coords.y1, - VLC_OP_LINE, rel_coords.x2 + 1, rel_coords.y2 + 1, - VLC_OP_LINE, rel_coords.x1, rel_coords.y2 + 1, - VLC_OP_LINE, rel_coords.x1, rel_coords.y1, - VLC_OP_END - }; - err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_LOW, sizeof(rect_path), rect_path, - (vg_lite_float_t) rel_clip.x1, (vg_lite_float_t) rel_clip.y1, - ((vg_lite_float_t) rel_clip.x2) + 1.0f, ((vg_lite_float_t) rel_clip.y2) + 1.0f); - } + int32_t path_data[RECT_PATH_DATA_MAX_SIZE]; + uint32_t path_data_size; + lv_vglite_create_rect_path_data(path_data, &path_data_size, radius, coords); + vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_LOW; + vg_lite_path_t path; + err = vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data, + (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, + ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f); VG_LITE_ERR_RETURN_INV(err, "Init path failed."); + + vg_lite_matrix_t matrix; vg_lite_identity(&matrix); + vg_lite_matrix_t * grad_matrix; + vg_lite_linear_gradient_t gradient; + /*** Init Color/Gradient ***/ if(dsc->bg_grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE) { uint32_t colors[2]; @@ -154,18 +127,14 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_ lv_color32_t col32[2]; /* Gradient setup */ - uint8_t cnt = MAX(dsc->bg_grad.stops_count, 2); + uint8_t cnt = LV_MAX(dsc->bg_grad.stops_count, 2); for(uint8_t i = 0; i < cnt; i++) { col32[i].full = lv_color_to32(dsc->bg_grad.stops[i].color); /*Convert color to RGBA8888*/ stops[i] = dsc->bg_grad.stops[i].frac; -#if LV_COLOR_DEPTH==16 - colors[i] = ((uint32_t)col32[i].ch.alpha << 24) | ((uint32_t)col32[i].ch.blue << 16) | - ((uint32_t)col32[i].ch.green << 8) | (uint32_t)col32[i].ch.red; -#else /*LV_COLOR_DEPTH==32*/ - /* watchout: red and blue color components are inverted versus vg_lite_color_t order */ - colors[i] = ((uint32_t)col32[i].ch.alpha << 24) | ((uint32_t)col32[i].ch.red << 16) | - ((uint32_t)col32[i].ch.green << 8) | (uint32_t)col32[i].ch.blue; -#endif + + vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_ABGR8888 : VG_LITE_ARGB8888; + if(lv_vglite_premult_and_swizzle(&colors[i], col32[i], dsc->bg_opa, color_format) != LV_RES_OK) + VG_LITE_RETURN_INV("Premultiplication and swizzle failed."); } lv_memset_00(&gradient, sizeof(vg_lite_linear_gradient_t)); @@ -181,7 +150,7 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_ grad_matrix = vg_lite_get_grad_matrix(&gradient); vg_lite_identity(grad_matrix); - vg_lite_translate((float)rel_coords.x1, (float)rel_coords.y1, grad_matrix); + vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix); if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) { vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix); @@ -192,39 +161,22 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_ } } - lv_opa_t bg_opa = dsc->bg_opa; lv_color32_t bg_col32 = {.full = lv_color_to32(dsc->bg_color)}; /*Convert color to RGBA8888*/ - if(bg_opa <= (lv_opa_t)LV_OPA_MAX) { - /* Only pre-multiply color if hardware pre-multiplication is not present */ - if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) { - bg_col32.ch.red = (uint8_t)(((uint16_t)bg_col32.ch.red * bg_opa) >> 8); - bg_col32.ch.green = (uint8_t)(((uint16_t)bg_col32.ch.green * bg_opa) >> 8); - bg_col32.ch.blue = (uint8_t)(((uint16_t)bg_col32.ch.blue * bg_opa) >> 8); - } - bg_col32.ch.alpha = bg_opa; - } - -#if LV_COLOR_DEPTH==16 - vgcol = bg_col32.full; -#else /*LV_COLOR_DEPTH==32*/ - vgcol = ((uint32_t)bg_col32.ch.alpha << 24) | ((uint32_t)bg_col32.ch.blue << 16) | - ((uint32_t)bg_col32.ch.green << 8) | (uint32_t)bg_col32.ch.red; -#endif - - /*Clean & invalidate cache*/ - lv_vglite_invalidate_cache(); + vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888; + if(lv_vglite_premult_and_swizzle(&vgcol, bg_col32, dsc->bg_opa, color_format) != LV_RES_OK) + VG_LITE_RETURN_INV("Premultiplication and swizzle failed."); /*** Draw rectangle ***/ if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) { - err = vg_lite_draw(&vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol); + err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol); } else { - err = vg_lite_draw_gradient(&vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient, VG_LITE_BLEND_SRC_OVER); + err = vg_lite_draw_gradient(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient, VG_LITE_BLEND_SRC_OVER); } VG_LITE_ERR_RETURN_INV(err, "Draw gradient failed."); - err = vg_lite_finish(); - VG_LITE_ERR_RETURN_INV(err, "Finish failed."); + if(lv_vglite_run() != LV_RES_OK) + VG_LITE_RETURN_INV("Run failed."); err = vg_lite_clear_path(&path); VG_LITE_ERR_RETURN_INV(err, "Clear path failed."); @@ -237,6 +189,261 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_ return LV_RES_OK; } +lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const lv_area_t * clip_area, + const lv_draw_rect_dsc_t * dsc, bool border) +{ + vg_lite_error_t err = VG_LITE_SUCCESS; + vg_lite_color_t vgcol; /* vglite takes ABGR */ + lv_coord_t radius = dsc->radius; + vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf(); + + if(radius < 0) + return LV_RES_INV; + + if(border) { + /* Draw border - only has radius if object has radius*/ + lv_coord_t border_half = (lv_coord_t)floor(dsc->border_width / 2.0f); + if(radius > border_half) + radius = radius - border_half; + } + else { + /* Draw outline - always has radius, leave the same radius in the circle case */ + lv_coord_t outline_half = (lv_coord_t)ceil(dsc->outline_width / 2.0f); + if(radius < (lv_coord_t)LV_RADIUS_CIRCLE - outline_half) + radius = radius + outline_half; + } + + vg_lite_cap_style_t cap_style = (radius) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT; + vg_lite_join_style_t join_style = (radius) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER; + + /* Choose vglite blend mode based on given lvgl blend mode */ + vg_lite_blend_t vglite_blend_mode = lv_vglite_get_blend_mode(dsc->blend_mode); + + /*** Init path ***/ + int32_t path_data[RECT_PATH_DATA_MAX_SIZE]; + uint32_t path_data_size; + lv_vglite_create_rect_path_data(path_data, &path_data_size, radius, coords); + vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_LOW; + + vg_lite_path_t path; + err = vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data, + (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, + ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f); + VG_LITE_ERR_RETURN_INV(err, "Init path failed."); + + vg_lite_matrix_t matrix; + vg_lite_identity(&matrix); + + lv_opa_t opa; + lv_color32_t col32; + lv_coord_t line_width; + + if(border) { + opa = dsc->border_opa; + col32.full = lv_color_to32(dsc->border_color); /*Convert color to RGBA8888*/ + line_width = dsc->border_width; + } + else { + opa = dsc->outline_opa; + col32.full = lv_color_to32(dsc->outline_color); /*Convert color to RGBA8888*/ + line_width = dsc->outline_width; + } + + vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888; + if(lv_vglite_premult_and_swizzle(&vgcol, col32, opa, color_format) != LV_RES_OK) + VG_LITE_RETURN_INV("Premultiplication and swizzle failed."); + + /*** Draw border ***/ + err = vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH); + VG_LITE_ERR_RETURN_INV(err, "Set draw path type failed."); + + err = vg_lite_set_stroke(&path, cap_style, join_style, line_width, 8, NULL, 0, 0, vgcol); + VG_LITE_ERR_RETURN_INV(err, "Set stroke failed."); + + err = vg_lite_update_stroke(&path); + VG_LITE_ERR_RETURN_INV(err, "Update stroke failed."); + + err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vglite_blend_mode, vgcol); + VG_LITE_ERR_RETURN_INV(err, "Draw border failed."); + + if(lv_vglite_run() != LV_RES_OK) + VG_LITE_RETURN_INV("Run failed."); + + err = vg_lite_clear_path(&path); + VG_LITE_ERR_RETURN_INV(err, "Clear path failed."); + + return LV_RES_OK; + +} + +static void lv_vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size, + lv_coord_t radius, + const lv_area_t * coords) +{ + lv_coord_t rect_width = lv_area_get_width(coords); + lv_coord_t rect_height = lv_area_get_height(coords); + + /* Get the final radius. Can't be larger than the half of the shortest side */ + int32_t shortest_side = LV_MIN(rect_width, rect_height); + int32_t final_radius = LV_MIN(radius, shortest_side / 2); + + /* Path data element index */ + uint8_t pidx = 0; + + if((radius == (lv_coord_t)LV_RADIUS_CIRCLE) && (rect_width == rect_height)) { + + /* Get the control point offset for rounded cases */ + int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE); + + /* Circle case */ + /* Starting point */ + path_data[pidx++] = VLC_OP_MOVE; + path_data[pidx++] = coords->x1 + final_radius; + path_data[pidx++] = coords->y1; + + /* Top-right arc */ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = cpoff; + path_data[pidx++] = 0; + path_data[pidx++] = final_radius; + path_data[pidx++] = final_radius - cpoff; + path_data[pidx++] = final_radius; + path_data[pidx++] = final_radius; + + /* Bottom-right arc*/ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = 0; + path_data[pidx++] = cpoff; + path_data[pidx++] = cpoff - final_radius; + path_data[pidx++] = final_radius; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = final_radius; + + /* Bottom-left arc */ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = 0 - cpoff; + path_data[pidx++] = 0; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = cpoff - final_radius; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = 0 - final_radius; + + /* Top-left arc*/ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = 0; + path_data[pidx++] = 0 - cpoff; + path_data[pidx++] = final_radius - cpoff; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = final_radius; + path_data[pidx++] = 0 - final_radius; + + /* Ending point */ + path_data[pidx++] = VLC_OP_END; + } + else if(radius > 0) { + /* Get the control point offset for rounded cases */ + int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE); + + /* Rounded rectangle case */ + /* Starting point */ + path_data[pidx++] = VLC_OP_MOVE; + path_data[pidx++] = coords->x1 + final_radius; + path_data[pidx++] = coords->y1; + + /* Top side */ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x2 - final_radius + 1; // Extended for VGLite + path_data[pidx++] = coords->y1; + + /* Top-right corner */ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = cpoff; + path_data[pidx++] = 0; + path_data[pidx++] = final_radius; + path_data[pidx++] = final_radius - cpoff; + path_data[pidx++] = final_radius; + path_data[pidx++] = final_radius; + + /* Right side */ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x2 + 1; // Extended for VGLite + path_data[pidx++] = coords->y2 - final_radius + 1; // Extended for VGLite + + /* Bottom-right corner*/ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = 0; + path_data[pidx++] = cpoff; + path_data[pidx++] = cpoff - final_radius; + path_data[pidx++] = final_radius; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = final_radius; + + /* Bottom side */ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x1 + final_radius; + path_data[pidx++] = coords->y2 + 1; // Extended for VGLite + + /* Bottom-left corner */ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = 0 - cpoff; + path_data[pidx++] = 0; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = cpoff - final_radius; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = 0 - final_radius; + + /* Left side*/ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x1; + path_data[pidx++] = coords->y1 + final_radius; + + /* Top-left corner */ + path_data[pidx++] = VLC_OP_CUBIC_REL; + path_data[pidx++] = 0; + path_data[pidx++] = 0 - cpoff; + path_data[pidx++] = final_radius - cpoff; + path_data[pidx++] = 0 - final_radius; + path_data[pidx++] = final_radius; + path_data[pidx++] = 0 - final_radius; + + /* Ending point */ + path_data[pidx++] = VLC_OP_END; + } + else { + /* Non-rounded rectangle case */ + /* Starting point */ + path_data[pidx++] = VLC_OP_MOVE; + path_data[pidx++] = coords->x1; + path_data[pidx++] = coords->y1; + + /* Top side */ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x2 + 1; // Extended for VGLite + path_data[pidx++] = coords->y1; + + /* Right side */ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x2 + 1; // Extended for VGLite + path_data[pidx++] = coords->y2 + 1; // Extended for VGLite + + /* Bottom side */ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x1; + path_data[pidx++] = coords->y2 + 1; // Extended for VGLite + + /* Left side*/ + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = coords->x1; + path_data[pidx++] = coords->y1; + + /* Ending point */ + path_data[pidx++] = VLC_OP_END; + } + + /* Resulting path size */ + *path_data_size = pidx * sizeof(int32_t); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/liblvgl/draw/nxp/vglite/lv_vglite_buf.c b/src/liblvgl/draw/nxp/vglite/lv_vglite_buf.c new file mode 100644 index 0000000..f6325ab --- /dev/null +++ b/src/liblvgl/draw/nxp/vglite/lv_vglite_buf.c @@ -0,0 +1,143 @@ +/** + * @file lv_vglite_buf.c + * + */ + +/** + * MIT License + * + * Copyright 2023 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_vglite_buf.h" + +#if LV_USE_GPU_NXP_VG_LITE + +/********************* + * DEFINES + *********************/ + +#if LV_COLOR_DEPTH == 16 + #define VG_LITE_PX_FMT VG_LITE_RGB565 +#elif LV_COLOR_DEPTH == 32 + #define VG_LITE_PX_FMT VG_LITE_BGRA8888 +#else + #error Only 16bit and 32bit color depth are supported. Set LV_COLOR_DEPTH to 16 or 32. +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride); +static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf); +static inline void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf, + const lv_area_t * area, lv_coord_t stride); + +/********************** + * STATIC VARIABLES + **********************/ + +static vg_lite_buffer_t dest_vgbuf; +static vg_lite_buffer_t src_vgbuf; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_gpu_nxp_vglite_init_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride) +{ + lv_vglite_set_dest_buf(buf, area, stride); +} + +vg_lite_buffer_t * lv_vglite_get_dest_buf(void) +{ + return &dest_vgbuf; +} + +vg_lite_buffer_t * lv_vglite_get_src_buf(void) +{ + return &src_vgbuf; +} + +void lv_vglite_set_dest_buf_ptr(const lv_color_t * buf) +{ + lv_vglite_set_buf_ptr(&dest_vgbuf, buf); +} + +void lv_vglite_set_src_buf_ptr(const lv_color_t * buf) +{ + lv_vglite_set_buf_ptr(&src_vgbuf, buf); +} + +void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride) +{ + if(src_vgbuf.memory != (void *)buf) + lv_vglite_set_buf(&src_vgbuf, buf, area, stride); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride) +{ + lv_vglite_set_buf(&dest_vgbuf, buf, area, stride); +} + +static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf) +{ + vgbuf->memory = (void *)buf; + vgbuf->address = (uint32_t)vgbuf->memory; +} + +static inline void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf, + const lv_area_t * area, lv_coord_t stride) +{ + vgbuf->format = VG_LITE_PX_FMT; + vgbuf->tiled = VG_LITE_LINEAR; + vgbuf->image_mode = VG_LITE_NORMAL_IMAGE_MODE; + vgbuf->transparency_mode = VG_LITE_IMAGE_OPAQUE; + + vgbuf->width = (int32_t)lv_area_get_width(area); + vgbuf->height = (int32_t)lv_area_get_height(area); + vgbuf->stride = (int32_t)(stride) * sizeof(lv_color_t); + + lv_memset_00(&vgbuf->yuv, sizeof(vgbuf->yuv)); + + vgbuf->memory = (void *)buf; + vgbuf->address = (uint32_t)vgbuf->memory; + vgbuf->handle = NULL; +} + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ diff --git a/src/liblvgl/draw/nxp/vglite/lv_vglite_utils.c b/src/liblvgl/draw/nxp/vglite/lv_vglite_utils.c new file mode 100644 index 0000000..adc9f77 --- /dev/null +++ b/src/liblvgl/draw/nxp/vglite/lv_vglite_utils.c @@ -0,0 +1,149 @@ +/** + * @file lv_vglite_utils.c + * + */ + +/** + * MIT License + * + * Copyright 2022, 2023 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_vglite_utils.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "../../../core/lv_refr.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/** + * Clean and invalidate cache. + */ +static inline void invalidate_cache(void); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_res_t lv_vglite_run(void) +{ + invalidate_cache(); + + VG_LITE_ERR_RETURN_INV(vg_lite_flush(), "Flush failed."); + + return LV_RES_OK; +} + +lv_res_t lv_vglite_premult_and_swizzle(vg_lite_color_t * vg_col32, lv_color32_t lv_col32, lv_opa_t opa, + vg_lite_buffer_format_t vg_col_format) +{ + + lv_color32_t lv_col32_premul = lv_col32; + if(opa <= (lv_opa_t)LV_OPA_MAX) { + /* Only pre-multiply color if hardware pre-multiplication is not present */ + if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) { + lv_col32_premul.ch.red = (uint8_t)(((uint16_t)lv_col32.ch.red * opa) >> 8); + lv_col32_premul.ch.green = (uint8_t)(((uint16_t)lv_col32.ch.green * opa) >> 8); + lv_col32_premul.ch.blue = (uint8_t)(((uint16_t)lv_col32.ch.blue * opa) >> 8); + } + lv_col32_premul.ch.alpha = opa; + } + + switch(vg_col_format) { + case VG_LITE_BGRA8888: + *vg_col32 = lv_col32_premul.full; + break; + case VG_LITE_RGBA8888: + *vg_col32 = ((uint32_t)lv_col32_premul.ch.red << 24) | ((uint32_t)lv_col32_premul.ch.green << 16) | + ((uint32_t)lv_col32_premul.ch.blue << 8) | (uint32_t)lv_col32_premul.ch.alpha; + break; + case VG_LITE_ABGR8888: + *vg_col32 = ((uint32_t)lv_col32_premul.ch.alpha << 24) | ((uint32_t)lv_col32_premul.ch.blue << 16) | + ((uint32_t)lv_col32_premul.ch.green << 8) | (uint32_t)lv_col32_premul.ch.red; + break; + case VG_LITE_ARGB8888: + *vg_col32 = ((uint32_t)lv_col32_premul.ch.alpha << 24) | ((uint32_t)lv_col32_premul.ch.red << 16) | + ((uint32_t)lv_col32_premul.ch.green << 8) | (uint32_t)lv_col32_premul.ch.blue; + break; + default: + return LV_RES_INV; + } + + return LV_RES_OK; +} + +vg_lite_blend_t lv_vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode) +{ + vg_lite_blend_t vg_blend_mode; + switch(lv_blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + vg_blend_mode = VG_LITE_BLEND_ADDITIVE; + break; + case LV_BLEND_MODE_SUBTRACTIVE: + vg_blend_mode = VG_LITE_BLEND_SUBTRACT; + break; + case LV_BLEND_MODE_MULTIPLY: + vg_blend_mode = VG_LITE_BLEND_MULTIPLY; + break; + case LV_BLEND_MODE_REPLACE: + vg_blend_mode = VG_LITE_BLEND_NONE; + break; + default: + vg_blend_mode = VG_LITE_BLEND_SRC_OVER; + break; + } + return vg_blend_mode; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static inline void invalidate_cache(void) +{ + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + if(disp->driver->clean_dcache_cb) + disp->driver->clean_dcache_cb(disp->driver); +} + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ diff --git a/src/liblvgl/draw/sdl/README.md b/src/liblvgl/draw/sdl/README.md new file mode 100644 index 0000000..4415ffa --- /dev/null +++ b/src/liblvgl/draw/sdl/README.md @@ -0,0 +1,28 @@ +# SDL_Renderer Based Drawing Functions + +In LVGL, drawing was performed by CPU. To improve drawing performance on platforms with GPU, +we should perform drawing operations on GPU if possible. + +This implementation has moved most bitmap blending and drawing procedures to utilize SDL_Renderer, +which takes advantages of hardware acceleration APIs like DirectX or OpenGL. + +This implementation can be also considered as a reference implementation, for contributors wants to +develop accelerated drawing functions with other APIs such as OpenGL/OpenGL ES. + +## Caveats +`lv_draw_arc`, `lv_draw_line` is not enabled, due to incomplete implementation. So lines and arcs will +have significant impact to drawing performances. + +Performance of this implementation still has room to improve. Or we should use more powerful APIs +such as OpenGL. + +## Notices for files + +### `lv_draw_sdl_stack_blur.c` + +Contains modified code from [android-stackblur](https://github.com/kikoso/android-stackblur) project. +Apache License 2.0 + +### `lv_draw_sdl_lru.c`/`lv_draw_sdl_lru.h` + +Contains modified code from [C-LRU-Cache](https://github.com/willcannings/C-LRU-Cache) project. No license defined. \ No newline at end of file diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl.c b/src/liblvgl/draw/sdl/lv_draw_sdl.c index 93cca48..e3cdf57 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl.c @@ -8,7 +8,7 @@ *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl.mk b/src/liblvgl/draw/sdl/lv_draw_sdl.mk new file mode 100644 index 0000000..c5c28b6 --- /dev/null +++ b/src/liblvgl/draw/sdl/lv_draw_sdl.mk @@ -0,0 +1,19 @@ +CSRCS += lv_draw_sdl.c +CSRCS += lv_draw_sdl_arc.c +CSRCS += lv_draw_sdl_bg.c +CSRCS += lv_draw_sdl_composite.c +CSRCS += lv_draw_sdl_img.c +CSRCS += lv_draw_sdl_label.c +CSRCS += lv_draw_sdl_line.c +CSRCS += lv_draw_sdl_mask.c +CSRCS += lv_draw_sdl_polygon.c +CSRCS += lv_draw_sdl_rect.c +CSRCS += lv_draw_sdl_stack_blur.c +CSRCS += lv_draw_sdl_texture_cache.c +CSRCS += lv_draw_sdl_utils.c +CSRCS += lv_draw_sdl_layer.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_arc.c b/src/liblvgl/draw/sdl/lv_draw_sdl_arc.c index 7319b35..5786eae 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_arc.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_arc.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_bg.c b/src/liblvgl/draw/sdl/lv_draw_sdl_bg.c index bc77ee7..48e0f6b 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_bg.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_bg.c @@ -7,15 +7,15 @@ * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL -#include "liblvgl/lv_draw_rect.h" -#include "liblvgl/lv_draw_img.h" -#include "liblvgl/lv_draw_label.h" -#include "liblvgl/lv_draw_mask.h" -#include "liblvgl/core/lv_refr.h" +#include "../lv_draw_rect.h" +#include "../lv_draw_img.h" +#include "../lv_draw_label.h" +#include "../lv_draw_mask.h" +#include "../../core/lv_refr.h" #include "lv_draw_sdl_utils.h" #include "lv_draw_sdl_texture_cache.h" #include "lv_draw_sdl_composite.h" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_composite.c b/src/liblvgl/draw/sdl/lv_draw_sdl_composite.c index 76f1a77..4d0603d 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_composite.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_composite.c @@ -6,12 +6,12 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL -#include "liblvgl/misc/lv_gc.h" -#include "liblvgl/core/lv_refr.h" +#include "../../misc/lv_gc.h" +#include "../../core/lv_refr.h" #include "lv_draw_sdl_composite.h" #include "lv_draw_sdl_utils.h" #include "lv_draw_sdl_priv.h" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_img.c b/src/liblvgl/draw/sdl/lv_draw_sdl_img.c index 349a778..3c955d8 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_img.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_img.c @@ -7,15 +7,15 @@ * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL -#include "liblvgl/lv_draw_img.h" -#include "liblvgl/lv_img_cache.h" -#include "liblvgl/lv_draw_mask.h" -#include "liblvgl/misc/lv_lru.h" -#include "liblvgl/misc/lv_gc.h" +#include "../lv_draw_img.h" +#include "../lv_img_cache.h" +#include "../lv_draw_mask.h" +#include "../../misc/lv_lru.h" +#include "../../misc/lv_gc.h" #include "lv_draw_sdl_img.h" #include "lv_draw_sdl_utils.h" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_label.c b/src/liblvgl/draw/sdl/lv_draw_sdl_label.c index 59a1fdd..b8c79ae 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_label.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_label.c @@ -7,14 +7,14 @@ * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL #include LV_GPU_SDL_INCLUDE_PATH -#include "liblvgl/lv_draw_label.h" -#include "liblvgl/misc/lv_utils.h" +#include "../lv_draw_label.h" +#include "../../misc/lv_utils.h" #include "lv_draw_sdl_utils.h" #include "lv_draw_sdl_texture_cache.h" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_layer.c b/src/liblvgl/draw/sdl/lv_draw_sdl_layer.c index 438376f..ae5c327 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_layer.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_layer.c @@ -6,11 +6,11 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL -#include "liblvgl/core/lv_refr.h" +#include "../../core/lv_refr.h" #include "lv_draw_sdl.h" #include "lv_draw_sdl_priv.h" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_line.c b/src/liblvgl/draw/sdl/lv_draw_sdl_line.c index 63c195a..3a15d6d 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_line.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_line.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_mask.c b/src/liblvgl/draw/sdl/lv_draw_sdl_mask.c index f793c2e..7bb5bbb 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_mask.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_mask.c @@ -6,11 +6,11 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL -#include "liblvgl/misc/lv_gc.h" +#include "../../misc/lv_gc.h" #include "lv_draw_sdl_mask.h" #include "lv_draw_sdl_utils.h" diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_polygon.c b/src/liblvgl/draw/sdl/lv_draw_sdl_polygon.c index d651aeb..c5df50c 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_polygon.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_polygon.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_rect.c b/src/liblvgl/draw/sdl/lv_draw_sdl_rect.c index 557baf9..6418a0a 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_rect.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_rect.c @@ -7,15 +7,15 @@ * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL -#include "liblvgl/draw/lv_draw_rect.h" -#include "liblvgl/draw/lv_draw_img.h" -#include "liblvgl/draw/lv_draw_label.h" -#include "liblvgl/draw/lv_draw_mask.h" -#include "liblvgl/core/lv_refr.h" +#include "../lv_draw_rect.h" +#include "../lv_draw_img.h" +#include "../lv_draw_label.h" +#include "../lv_draw_mask.h" +#include "../../core/lv_refr.h" #include "lv_draw_sdl_utils.h" #include "lv_draw_sdl_texture_cache.h" #include "lv_draw_sdl_composite.h" @@ -27,6 +27,8 @@ * DEFINES *********************/ +#define FRAG_SPACING 3 + /********************** * TYPEDEFS **********************/ @@ -37,6 +39,23 @@ typedef struct { lv_coord_t size; } lv_draw_rect_bg_key_t; +typedef struct { + lv_sdl_cache_key_magic_t magic; + lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; + uint8_t stops_count; + lv_grad_dir_t dir; +} lv_draw_rect_grad_strip_key_t; + +typedef struct { + lv_sdl_cache_key_magic_t magic; + lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; + uint8_t stops_count; + lv_grad_dir_t dir; + lv_coord_t w; + lv_coord_t h; + lv_coord_t radius; +} lv_draw_rect_grad_frag_key_t; + typedef struct { lv_sdl_cache_key_magic_t magic; lv_coord_t radius; @@ -57,6 +76,12 @@ typedef struct { static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, const lv_draw_rect_dsc_t * dsc); +static void draw_bg_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, + const lv_grad_dsc_t * grad, bool blend_mod); + +static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, + const lv_draw_rect_dsc_t * dsc); + static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, const lv_draw_rect_dsc_t * dsc); @@ -81,6 +106,11 @@ static void frag_render_center(SDL_Renderer * renderer, SDL_Texture * frag, lv_c static lv_draw_rect_bg_key_t rect_bg_key_create(lv_coord_t radius, lv_coord_t size); +static lv_draw_rect_grad_frag_key_t rect_grad_frag_key_create(const lv_grad_dsc_t * grad, lv_coord_t w, lv_coord_t h, + lv_coord_t radius); + +static lv_draw_rect_grad_strip_key_t rect_grad_strip_key_create(const lv_grad_dsc_t * grad); + static lv_draw_rect_shadow_key_t rect_shadow_key_create(lv_coord_t radius, lv_coord_t size, lv_coord_t blur); static lv_draw_rect_border_key_t rect_border_key_create(lv_coord_t rout, lv_coord_t rin, const lv_area_t * outer_area, @@ -148,16 +178,93 @@ void lv_draw_sdl_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius) { lv_draw_rect_bg_key_t key = rect_bg_key_create(radius, radius); - lv_area_t coords = {0, 0, radius * 2 - 1, radius * 2 - 1}; - lv_area_t coords_frag = {0, 0, radius - 1, radius - 1}; SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL); if(texture == NULL) { + lv_area_t coords = {0, 0, radius * 2 - 1, radius * 2 - 1}; + lv_area_t coords_frag = {0, 0, radius - 1, radius - 1}; lv_draw_mask_radius_param_t mask_rout_param; lv_draw_mask_radius_init(&mask_rout_param, &coords, radius, false); int16_t mask_id = lv_draw_mask_add(&mask_rout_param, NULL); texture = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords_frag, &mask_id, 1); + SDL_assert(texture != NULL); lv_draw_mask_remove_id(mask_id); - SDL_assert(texture); + lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture); + } + return texture; +} + +SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w, + lv_coord_t h, lv_coord_t radius) +{ + lv_draw_rect_grad_frag_key_t key = rect_grad_frag_key_create(grad, w, h, radius); + SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL); + if(texture == NULL) { + lv_area_t coords = {0, 0, radius * 2 + FRAG_SPACING - 1, radius * 2 + FRAG_SPACING - 1}; + texture = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET, + lv_area_get_width(&coords), lv_area_get_height(&coords)); + SDL_assert(texture != NULL); + + lv_draw_mask_radius_param_t mask_rout_param; + lv_draw_mask_radius_init(&mask_rout_param, &coords, radius, false); + int16_t mask_id = lv_draw_mask_add(&mask_rout_param, NULL); + SDL_Texture * mask = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords, &mask_id, 1); + SDL_assert(mask != NULL); + SDL_SetTextureBlendMode(mask, SDL_BLENDMODE_NONE); + lv_draw_mask_remove_id(mask_id); + + SDL_Texture * target_backup = SDL_GetRenderTarget(ctx->renderer); + SDL_SetRenderTarget(ctx->renderer, texture); + SDL_RenderCopy(ctx->renderer, mask, NULL, NULL); + SDL_DestroyTexture(mask); + + lv_area_t blend_coords = {.x1 = 0, .y1 = 0, .x2 = w - 1, .y2 = h - 1}; + lv_area_t draw_area = {.x1 = 0, .y1 = 0, .x2 = radius - 1, .y2 = radius - 1}; + /* Align to top left */ + lv_area_align(&coords, &draw_area, LV_ALIGN_TOP_LEFT, 0, 0); + lv_area_align(&coords, &blend_coords, LV_ALIGN_TOP_LEFT, 0, 0); + draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true); + + /* Align to top right */ + lv_area_align(&coords, &draw_area, LV_ALIGN_TOP_RIGHT, 0, 0); + lv_area_align(&coords, &blend_coords, LV_ALIGN_TOP_RIGHT, 0, 0); + draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true); + + /* Align to bottom right */ + lv_area_align(&coords, &draw_area, LV_ALIGN_BOTTOM_RIGHT, 0, 0); + lv_area_align(&coords, &blend_coords, LV_ALIGN_BOTTOM_RIGHT, 0, 0); + draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true); + + /* Align to bottom left */ + lv_area_align(&coords, &draw_area, LV_ALIGN_BOTTOM_LEFT, 0, 0); + lv_area_align(&coords, &blend_coords, LV_ALIGN_BOTTOM_LEFT, 0, 0); + draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true); + + SDL_SetRenderTarget(ctx->renderer, target_backup); + lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture); + } + return texture; +} + +SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad) +{ + lv_draw_rect_grad_strip_key_t key = rect_grad_strip_key_create(grad); + SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL); + if(texture == NULL) { + Uint32 amask = 0xFF000000; + Uint32 rmask = 0x00FF0000; + Uint32 gmask = 0x0000FF00; + Uint32 bmask = 0x000000FF; + lv_color_t pixels[256]; + for(int i = 0; i < 256; i++) { + pixels[i] = lv_gradient_calculate(grad, 256, i); + } + int width = grad->dir == LV_GRAD_DIR_VER ? 1 : 256; + int height = grad->dir == LV_GRAD_DIR_VER ? 256 : 1; + SDL_Surface * surface = SDL_CreateRGBSurfaceFrom(pixels, width, height, LV_COLOR_DEPTH, width * LV_COLOR_DEPTH / 8, + rmask, gmask, bmask, amask); + texture = SDL_CreateTextureFromSurface(ctx->renderer, surface); + SDL_assert(texture != NULL); + SDL_FreeSurface(surface); lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture); } return texture; @@ -193,7 +300,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture if(full) { lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), sy = (lv_coord_t)(dst_area.y1 - corner_area.y1); - SDL_Rect src_rect = {frag_size + 3 + sx, sy, dw, dh}; + SDL_Rect src_rect = {frag_size + FRAG_SPACING + sx, sy, dw, dh}; SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect); } else { @@ -212,7 +319,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture if(full) { lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), sy = (lv_coord_t)(dst_area.y1 - corner_area.y1); - SDL_Rect src_rect = {frag_size + 3 + sx, frag_size + 3 + sy, dw, dh}; + SDL_Rect src_rect = {frag_size + FRAG_SPACING + sx, frag_size + FRAG_SPACING + sy, dw, dh}; SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect); } else { @@ -220,7 +327,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture SDL_RenderCopyEx(ctx->renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); } } - /* Lower left, right edge should not be clip */ + /* Lower left, right edge should not be clipped */ corner_area.x1 = coords->x1; corner_area.x2 = coords->x1 + frag_size - 1; if(_lv_area_intersect(&dst_area, &corner_area, clip)) { @@ -231,7 +338,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture if(full) { lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), sy = (lv_coord_t)(dst_area.y1 - corner_area.y1); - SDL_Rect src_rect = {sx, frag_size + 3 + sy, dw, dh}; + SDL_Rect src_rect = {sx, frag_size + FRAG_SPACING + sy, dw, dh}; SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect); } else { @@ -252,9 +359,23 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con if(dsc->bg_opa == 0) { return; } - SDL_Color bg_color; - lv_color_to_sdl_color(&dsc->bg_color, &bg_color); lv_coord_t radius = dsc->radius; + SDL_Color bg_color; + if(dsc->bg_grad.dir == LV_GRAD_DIR_NONE) { + lv_color_to_sdl_color(&dsc->bg_color, &bg_color); + } + else if(dsc->bg_grad.stops_count == 1) { + lv_color_to_sdl_color(&dsc->bg_grad.stops[0].color, &bg_color); + } + else { + if(radius <= 0) { + draw_bg_grad_simple(ctx, coords, draw_area, &dsc->bg_grad, false); + } + else { + draw_bg_grad_radius(ctx, coords, draw_area, dsc); + } + return; + } if(radius <= 0) { SDL_Rect rect; lv_area_to_sdl_rect(draw_area, &rect); @@ -277,9 +398,111 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con frag_render_center(ctx->renderer, texture, real_radius, coords, draw_area, false); } +static void draw_bg_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, + const lv_grad_dsc_t * grad, bool blend_mod) +{ + SDL_Rect dstrect; + lv_area_to_sdl_rect(draw_area, &dstrect); + SDL_Rect srcrect; + if(grad->dir == LV_GRAD_DIR_VER) { + lv_coord_t coords_h = lv_area_get_height(coords); + srcrect.x = 0; + srcrect.y = (draw_area->y1 - coords->y1) * 255 / coords_h; + srcrect.w = 1; + srcrect.h = dstrect.h * 256 / coords_h; + + if(srcrect.y < 0 || srcrect.y > 255) { + return; + } + } + else { + lv_coord_t coords_w = lv_area_get_width(coords); + srcrect.x = (draw_area->x1 - coords->x1) * 255 / coords_w; + srcrect.y = 0; + srcrect.w = dstrect.w * 256 / coords_w; + srcrect.h = 1; + + if(srcrect.x < 0 || srcrect.x > 255) { + return; + } + } + + SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_strip_obtain(ctx, grad); + if(blend_mod) { + SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_MOD); + } + else { + SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_BLEND); + } + + SDL_RenderCopy(ctx->renderer, grad_texture, &srcrect, &dstrect); +} + +static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, + const lv_draw_rect_dsc_t * dsc) +{ + lv_coord_t radius = dsc->radius; + /*A small texture with a quarter of the rect is enough*/ + lv_coord_t bg_w = lv_area_get_width(coords), bg_h = lv_area_get_height(coords); + lv_coord_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, radius); + SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_frag_obtain(ctx, &dsc->bg_grad, bg_w, bg_h, radius); + SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_BLEND); + + lv_draw_sdl_rect_bg_frag_draw_corners(ctx, grad_texture, real_radius, coords, draw_area, true); + lv_area_t part_coords; + lv_area_t part_area; + if(bg_w > radius * 2) { + /*Draw left, middle, right*/ + part_coords.x1 = 0; + part_coords.x2 = radius - 1; + part_coords.y1 = radius; + part_coords.y2 = bg_h - radius - 1; + + lv_area_align(coords, &part_coords, LV_ALIGN_LEFT_MID, 0, 0); + _lv_area_intersect(&part_area, &part_coords, draw_area); + draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false); + + lv_area_align(coords, &part_coords, LV_ALIGN_RIGHT_MID, 0, 0); + _lv_area_intersect(&part_area, &part_coords, draw_area); + draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false); + + part_coords.x1 = radius; + part_coords.x2 = bg_w - radius - 1; + part_coords.y1 = 0; + part_coords.y2 = bg_h - 1; + lv_area_align(coords, &part_coords, LV_ALIGN_CENTER, 0, 0); + _lv_area_intersect(&part_area, &part_coords, draw_area); + draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false); + } + else if(bg_h > radius * 2) { + /*Draw top, middle, bottom*/ + part_coords.x1 = radius; + part_coords.x2 = bg_w - radius - 1; + part_coords.y1 = 0; + part_coords.y2 = radius - 1; + + lv_area_align(coords, &part_coords, LV_ALIGN_TOP_MID, 0, 0); + _lv_area_intersect(&part_area, &part_coords, draw_area); + draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false); + + lv_area_align(coords, &part_coords, LV_ALIGN_BOTTOM_MID, 0, 0); + _lv_area_intersect(&part_area, &part_coords, draw_area); + draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false); + + part_coords.x1 = 0; + part_coords.x2 = bg_w - 1; + part_coords.y1 = radius; + part_coords.y2 = bg_h - radius - 1; + lv_area_align(coords, &part_coords, LV_ALIGN_CENTER, 0, 0); + _lv_area_intersect(&part_area, &part_coords, draw_area); + draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false); + } +} + static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, const lv_draw_rect_dsc_t * dsc) { + LV_UNUSED(draw_area); if(SKIP_IMAGE(dsc)) return; lv_img_src_t src_type = lv_img_src_get_type(dsc->bg_img_src); @@ -521,8 +744,8 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer lv_coord_t frag_size = LV_MAX(radius, max_side); SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL); if(texture == NULL) { - /* Create a mask texture with size of (frag_size * 2 + 3) */ - const lv_area_t frag_area = {0, 0, frag_size * 2 + 2, frag_size * 2 + 2}; + /* Create a mask texture with size of (frag_size * 2 + FRAG_SPACING) */ + const lv_area_t frag_area = {0, 0, frag_size * 2 + FRAG_SPACING - 1, frag_size * 2 + FRAG_SPACING - 1}; /*Create mask for the outer area*/ int16_t mask_ids[2] = {LV_MASK_ID_INV, LV_MASK_ID_INV}; @@ -595,7 +818,7 @@ static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_ lv_coord_t dh = lv_area_get_height(&dst_area); if(full) { lv_coord_t sy = (lv_coord_t)(dst_area.y1 - border_area.y1); - SDL_Rect src_rect = {frag_size + 1, frag_size + 3 + sy, 1, dh}; + SDL_Rect src_rect = {frag_size + 1, frag_size + FRAG_SPACING + sy, 1, dh}; SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect); } else { @@ -634,7 +857,7 @@ static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_ lv_coord_t dw = lv_area_get_width(&dst_area); if(full) { lv_coord_t sx = (lv_coord_t)(dst_area.x1 - border_area.x1); - SDL_Rect src_rect = {frag_size + 3 + sx, frag_size + 1, dw, 1}; + SDL_Rect src_rect = {frag_size + FRAG_SPACING + sx, frag_size + 1, dw, 1}; SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect); } else { @@ -682,6 +905,38 @@ static lv_draw_rect_bg_key_t rect_bg_key_create(lv_coord_t radius, lv_coord_t si return key; } +static lv_draw_rect_grad_frag_key_t rect_grad_frag_key_create(const lv_grad_dsc_t * grad, lv_coord_t w, lv_coord_t h, + lv_coord_t radius) +{ + lv_draw_rect_grad_frag_key_t key; + SDL_memset(&key, 0, sizeof(key)); + key.magic = LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD; + key.stops_count = grad->stops_count; + key.dir = grad->dir; + for(uint8_t i = 0; i < grad->stops_count; i++) { + key.stops[i].frac = grad->stops[i].frac; + key.stops[i].color = grad->stops[i].color; + } + key.w = w; + key.h = h; + key.radius = radius; + return key; +} + +static lv_draw_rect_grad_strip_key_t rect_grad_strip_key_create(const lv_grad_dsc_t * grad) +{ + lv_draw_rect_grad_strip_key_t key; + SDL_memset(&key, 0, sizeof(key)); + key.magic = LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD; + key.stops_count = grad->stops_count; + key.dir = grad->dir; + for(uint8_t i = 0; i < grad->stops_count; i++) { + key.stops[i].frac = grad->stops[i].frac; + key.stops[i].color = grad->stops[i].color; + } + return key; +} + static lv_draw_rect_shadow_key_t rect_shadow_key_create(lv_coord_t radius, lv_coord_t size, lv_coord_t blur) { lv_draw_rect_shadow_key_t key; diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.c b/src/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.c index b6e8a60..6845add 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/src/liblvgl/draw/sdl/lv_draw_sdl_utils.c b/src/liblvgl/draw/sdl/lv_draw_sdl_utils.c index 735b5ac..3ca0fad 100644 --- a/src/liblvgl/draw/sdl/lv_draw_sdl_utils.c +++ b/src/liblvgl/draw/sdl/lv_draw_sdl_utils.c @@ -6,15 +6,15 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_GPU_SDL #include "lv_draw_sdl_utils.h" -#include "liblvgl/draw/lv_draw.h" -#include "liblvgl/draw/lv_draw_label.h" -#include "liblvgl/core/lv_refr.h" +#include "../lv_draw.h" +#include "../lv_draw_label.h" +#include "../../core/lv_refr.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk b/src/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk new file mode 100644 index 0000000..8ed00b0 --- /dev/null +++ b/src/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_stm32_dma2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d" diff --git a/src/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c b/src/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c index 887f9fa..908909d 100644 --- a/src/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c +++ b/src/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c @@ -7,104 +7,75 @@ * INCLUDES *********************/ #include "lv_gpu_stm32_dma2d.h" -#include "liblvgl/core/lv_refr.h" +#include "../../core/lv_refr.h" #if LV_USE_GPU_STM32_DMA2D -#include LV_GPU_DMA2D_CMSIS_INCLUDE - /********************* * DEFINES *********************/ - #if LV_COLOR_16_SWAP - // TODO: F7 has red blue swap bit in control register for all layers and output - #error "Can't use DMA2D with LV_COLOR_16_SWAP 1" + // Note: DMA2D red/blue swap (RBS) works for all color modes + #define RBS_BIT 1U +#else + #define RBS_BIT 0U #endif -#if LV_COLOR_DEPTH == 8 - #error "Can't use DMA2D with LV_COLOR_DEPTH == 8" -#endif +#define CACHE_ROW_SIZE 32U // cache row size in Bytes + +// For code/implementation discussion refer to https://github.com/lvgl/lvgl/issues/3714#issuecomment-1365187036 +// astyle --options=lvgl/scripts/code-format.cfg --ignore-exclude-errors lvgl/src/draw/stm32_dma2d/*.c lvgl/src/draw/stm32_dma2d/*.h #if LV_COLOR_DEPTH == 16 - #define LV_DMA2D_COLOR_FORMAT LV_DMA2D_RGB565 + const dma2d_color_format_t LvglColorFormat = RGB565; #elif LV_COLOR_DEPTH == 32 - #define LV_DMA2D_COLOR_FORMAT LV_DMA2D_ARGB8888 + const dma2d_color_format_t LvglColorFormat = ARGB8888; #else - /*Can't use GPU with other formats*/ + #error "Cannot use DMA2D with LV_COLOR_DEPTH other than 16 or 32" #endif -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -static void lv_draw_stm32_dma2d_blend_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area, - lv_color_t color); - - -static void lv_draw_stm32_dma2d_blend_map(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, lv_coord_t src_stride, lv_opa_t opa); - -static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw, const lv_draw_img_dsc_t * dsc, - const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format); - - -static void invalidate_cache(void); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ +static bool isDma2dInProgess = false; // indicates whether DMA2D transfer *initiated here* is in progress /** * Turn on the peripheral and set output color mode, this only needs to be done once */ void lv_draw_stm32_dma2d_init(void) { - /*Enable DMA2D clock*/ + // Enable DMA2D clock #if defined(STM32F4) || defined(STM32F7) - RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN; + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN; // enable DMA2D #elif defined(STM32H7) RCC->AHB3ENR |= RCC_AHB3ENR_DMA2DEN; #else # warning "LVGL can't enable the clock of DMA2D" #endif - /*Wait for hardware access to complete*/ + // Wait for hardware access to complete __asm volatile("DSB\n"); - /*Delay after setting peripheral clock*/ + // Delay after setting peripheral clock volatile uint32_t temp = RCC->AHB1ENR; LV_UNUSED(temp); - /*set output colour mode*/ - DMA2D->OPFCCR = LV_DMA2D_COLOR_FORMAT; + // AHB master timer configuration + DMA2D->AMTCR = 0; // AHB bus guaranteed dead time disabled +#if defined(LV_STM32_DMA2D_TEST) + _lv_gpu_stm32_dwt_init(); // init µs timer +#endif } - void lv_draw_stm32_dma2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) { - lv_draw_sw_init_ctx(drv, draw_ctx); lv_draw_stm32_dma2d_ctx_t * dma2d_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx; dma2d_draw_ctx->blend = lv_draw_stm32_dma2d_blend; - // dma2d_draw_ctx->base_draw.draw_img_decoded = lv_draw_stm32_dma2d_img_decoded; - dma2d_draw_ctx->base_draw.wait_for_finish = lv_gpu_stm32_dma2d_wait_cb; + dma2d_draw_ctx->base_draw.draw_img_decoded = lv_draw_stm32_dma2d_img_decoded; + //dma2d_draw_ctx->base_draw.draw_img = lv_draw_stm32_dma2d_img; + // Note: currently it does not make sense use lv_gpu_stm32_dma2d_wait_cb() since waiting starts right after the dma2d transfer + //dma2d_draw_ctx->base_draw.wait_for_finish = lv_gpu_stm32_dma2d_wait_cb; dma2d_draw_ctx->base_draw.buffer_copy = lv_draw_stm32_dma2d_buffer_copy; - } void lv_draw_stm32_dma2d_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx) @@ -113,153 +84,660 @@ void lv_draw_stm32_dma2d_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ct LV_UNUSED(draw_ctx); } - -void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc) +static void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc) { - lv_area_t blend_area; - if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return; - - bool done = false; - - if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL && lv_area_get_size(&blend_area) > 100) { - lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + if(dsc->blend_mode != LV_BLEND_MODE_NORMAL) { + lv_draw_sw_blend_basic(draw_ctx, dsc); + return; + } + // Note: x1 must be zero. Otherwise, there is no way to correctly calculate dest_stride. + //LV_ASSERT_MSG(draw_ctx->buf_area->x1 == 0); // critical? + // Both draw buffer start address and buffer size *must* be 32-byte aligned since draw buffer cache is being invalidated. + //uint32_t drawBufferLength = lv_area_get_size(draw_ctx->buf_area) * sizeof(lv_color_t); + //LV_ASSERT_MSG(drawBufferLength % CACHE_ROW_SIZE == 0); // critical, but this is not the way to test it + //LV_ASSERT_MSG((uint32_t)draw_ctx->buf % CACHE_ROW_SIZE == 0, "draw_ctx.buf is not 32B aligned"); // critical? + + if(dsc->src_buf) { + // For performance reasons, both source buffer start address and buffer size *should* be 32-byte aligned since source buffer cache is being cleaned. + //uint32_t srcBufferLength = lv_area_get_size(dsc->blend_area) * sizeof(lv_color_t); + //LV_ASSERT_MSG(srcBufferLength % CACHE_ROW_SIZE == 0); // FIXME: assert fails (performance, non-critical) + //LV_ASSERT_MSG((uint32_t)dsc->src_buf % CACHE_ROW_SIZE == 0); // FIXME: assert fails (performance, non-critical) + } - lv_color_t * dest_buf = draw_ctx->buf; - dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1); - - const lv_color_t * src_buf = dsc->src_buf; - if(src_buf) { - lv_draw_sw_blend_basic(draw_ctx, dsc); - lv_coord_t src_stride; - src_stride = lv_area_get_width(dsc->blend_area); - src_buf += src_stride * (blend_area.y1 - dsc->blend_area->y1) + (blend_area.x1 - dsc->blend_area->x1); - lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); - lv_draw_stm32_dma2d_blend_map(dest_buf, &blend_area, dest_stride, src_buf, src_stride, dsc->opa); - done = true; + lv_area_t draw_area; + if(!_lv_area_intersect(&draw_area, dsc->blend_area, draw_ctx->clip_area)) return; + // + draw_ctx->buf_area has the entire draw buffer location + // + draw_ctx->clip_area has the current draw buffer location + // + dsc->blend_area has the location of the area intended to be painted - image etc. + // + draw_area has the area actually being painted + // All coordinates are relative to the screen. + + const lv_opa_t * mask = dsc->mask_buf; + + if(dsc->mask_buf && dsc->mask_res == LV_DRAW_MASK_RES_TRANSP) return; + else if(dsc->mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask = NULL; + + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + if(mask != NULL) { + // For performance reasons, both mask buffer start address and buffer size *should* be 32-byte aligned since mask buffer cache is being cleaned. + //uint32_t srcBufferLength = lv_area_get_size(dsc->mask_area) * sizeof(lv_opa_t); + //LV_ASSERT_MSG(srcBufferLength % CACHE_ROW_SIZE == 0); // FIXME: assert fails (performance, non-critical) + //LV_ASSERT_MSG((uint32_t)mask % CACHE_ROW_SIZE == 0); // FIXME: assert fails (performance, non-critical) + + lv_coord_t mask_stride = lv_area_get_width(dsc->mask_area); + lv_point_t mask_offset = lv_area_get_offset(dsc->mask_area, &draw_area); // mask offset in relation to draw_area + + if(dsc->src_buf == NULL) { // 93.5% + lv_area_move(&draw_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + _lv_draw_stm32_dma2d_blend_paint(draw_ctx->buf, dest_stride, &draw_area, mask, mask_stride, &mask_offset, dsc->color, + dsc->opa); } - else if(dsc->opa >= LV_OPA_MAX) { - lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); - lv_draw_stm32_dma2d_blend_fill(dest_buf, dest_stride, &blend_area, dsc->color); - done = true; + else { // 0.2% + // note: (x)RGB dsc->src_buf does not carry alpha channel bytes, + // alpha channel bytes are carried in dsc->mask_buf +#if LV_COLOR_DEPTH == 32 + lv_coord_t src_stride = lv_area_get_width(dsc->blend_area); + lv_point_t src_offset = lv_area_get_offset(dsc->blend_area, &draw_area); // source image offset in relation to draw_area + lv_coord_t draw_width = lv_area_get_width(&draw_area); + lv_coord_t draw_height = lv_area_get_height(&draw_area); + + // merge mask alpha bytes with src RGB bytes + // TODO: optimize by reading 4 or 8 mask bytes at a time + mask += (mask_stride * mask_offset.y) + mask_offset.x; + lv_color_t * src_buf = (lv_color_t *)dsc->src_buf; + src_buf += (src_stride * src_offset.y) + src_offset.x; + uint16_t mask_buffer_offset = mask_stride - draw_width; + uint16_t src_buffer_offset = src_stride - draw_width; + while(draw_height > 0) { + draw_height--; + for(uint16_t x = 0; x < draw_width; x++) { + (*src_buf).ch.alpha = *mask; + src_buf++; + mask++; + } + mask += mask_buffer_offset; + src_buf += src_buffer_offset; + } + + lv_area_move(&draw_area, -draw_ctx->buf_area->x1, + -draw_ctx->buf_area->y1); // translate the screen draw area to the origin of the buffer area + _lv_draw_stm32_dma2d_blend_map(draw_ctx->buf, dest_stride, &draw_area, dsc->src_buf, src_stride, &src_offset, dsc->opa, + ARGB8888, false); +#else + // Note: 16-bit bitmap hardware blending with mask and background is possible, but requires a temp 24 or 32-bit buffer to combine bitmap with mask first. + + lv_draw_sw_blend_basic(draw_ctx, dsc); // (e.g. Shop Items) + // clean cache after software drawing - this does not help since this is not the only place where buffer is written without dma2d + // lv_coord_t draw_width = lv_area_get_width(&draw_area); + // lv_coord_t draw_height = lv_area_get_height(&draw_area); + // uint32_t dest_address = (uint32_t)(draw_ctx->buf + (dest_stride * draw_area.y1) + draw_area.x1); + // _lv_gpu_stm32_dma2d_clean_cache(dest_address, dest_stride - draw_width, draw_width, draw_height, sizeof(lv_color_t)); +#endif + } + } + else { + if(dsc->src_buf == NULL) { // 6.1% + lv_area_move(&draw_area, -draw_ctx->buf_area->x1, + -draw_ctx->buf_area->y1); // translate the screen draw area to the origin of the buffer area + _lv_draw_stm32_dma2d_blend_fill(draw_ctx->buf, dest_stride, &draw_area, dsc->color, dsc->opa); + } + else { // 0.2% + lv_coord_t src_stride = lv_area_get_width(dsc->blend_area); + lv_point_t src_offset = lv_area_get_offset(dsc->blend_area, &draw_area); // source image offset in relation to draw_area + lv_area_move(&draw_area, -draw_ctx->buf_area->x1, + -draw_ctx->buf_area->y1); // translate the screen draw area to the origin of the buffer area + _lv_draw_stm32_dma2d_blend_map(draw_ctx->buf, dest_stride, &draw_area, dsc->src_buf, src_stride, &src_offset, dsc->opa, + LvglColorFormat, true); } } - - if(!done) lv_draw_sw_blend_basic(draw_ctx, dsc); } -void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx, - void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area, - void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area) +// Does dest_area = intersect(draw_ctx->clip_area, src_area) ? +// See: https://github.com/lvgl/lvgl/issues/3714#issuecomment-1331710788 +static void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx, void * dest_buf, lv_coord_t dest_stride, + const lv_area_t * dest_area, void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area) { + // Both draw buffer start address and buffer size *must* be 32-byte aligned since draw buffer cache is being invalidated. + //uint32_t drawBufferLength = lv_area_get_size(draw_ctx->buf_area) * sizeof(lv_color_t); + //LV_ASSERT_MSG(drawBufferLength % CACHE_ROW_SIZE == 0); // critical, but this is not the way to test it + //LV_ASSERT_MSG((uint32_t)draw_ctx->buf % CACHE_ROW_SIZE == 0, "draw_ctx.buf is not 32B aligned"); // critical? + // FIXME: + // 1. Both src_buf and dest_buf pixel size *must* be known to use DMA2D. + // 2. Verify both buffers start addresses and lengths are 32-byte (cache row size) aligned. LV_UNUSED(draw_ctx); - lv_draw_stm32_dma2d_blend_map(dest_buf, dest_area, dest_stride, src_buf, src_stride, LV_OPA_MAX); + lv_point_t src_offset = lv_area_get_offset(src_area, dest_area); + // FIXME: use lv_area_move(dest_area, -dest_area->x1, -dest_area->y1) here ? + // TODO: It is assumed that dest_buf and src_buf buffers are of lv_color_t type. Verify it, this assumption may be incorrect. + _lv_draw_stm32_dma2d_blend_map((const lv_color_t *)dest_buf, dest_stride, dest_area, (const lv_color_t *)src_buf, + src_stride, &src_offset, 0xff, LvglColorFormat, true); + // TODO: Investigate if output buffer cache needs to be invalidated. It depends on what the destination buffer is and how it is used next - by dma2d or not. + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(NULL); // TODO: is this line needed here? } - -static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, - const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format) +static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc, + const lv_area_t * coords, const uint8_t * src_buf, lv_img_cf_t color_format) { - /*TODO basic ARGB8888 image can be handles here*/ + if(draw_ctx->draw_img_decoded == NULL) return; + lv_area_t draw_area; + lv_area_copy(&draw_area, draw_ctx->clip_area); + + bool mask_any = lv_draw_mask_is_any(&draw_area); + bool transform = img_dsc->angle != 0 || img_dsc->zoom != LV_IMG_ZOOM_NONE; + const dma2d_color_format_t bitmapColorFormat = lv_color_format_to_dma2d_color_format(color_format); + const bool ignoreBitmapAlpha = (color_format == LV_IMG_CF_RGBX8888); - lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, color_format); + if(!mask_any && !transform && bitmapColorFormat != UNSUPPORTED && img_dsc->recolor_opa == LV_OPA_TRANSP) { + // simple bitmap blending, optionally with supported color format conversion - handle directly by dma2d + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + lv_coord_t src_stride = lv_area_get_width(coords); + lv_point_t src_offset = lv_area_get_offset(coords, &draw_area); // source image offset in relation to draw_area + lv_area_move(&draw_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + _lv_draw_stm32_dma2d_blend_map(draw_ctx->buf, dest_stride, &draw_area, src_buf, src_stride, &src_offset, + img_dsc->opa, bitmapColorFormat, ignoreBitmapAlpha); + } + else { + // all more complex cases which require additional image transformations + lv_draw_sw_img_decoded(draw_ctx, img_dsc, coords, src_buf, color_format); + + } } -static void lv_draw_stm32_dma2d_blend_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area, - lv_color_t color) +static lv_point_t lv_area_get_offset(const lv_area_t * area1, const lv_area_t * area2) { - /*Simply fill an area*/ - int32_t area_w = lv_area_get_width(fill_area); - int32_t area_h = lv_area_get_height(fill_area); - invalidate_cache(); + lv_point_t offset = {x: area2->x1 - area1->x1, y: area2->y1 - area1->y1}; + return offset; +} - DMA2D->CR = 0x30000; - DMA2D->OMAR = (uint32_t)dest_buf; - /*as input color mode is same as output we don't need to convert here do we?*/ - DMA2D->OCOLR = color.full; - DMA2D->OOR = dest_stride - area_w; - DMA2D->NLR = (area_w << DMA2D_NLR_PL_Pos) | (area_h << DMA2D_NLR_NL_Pos); +static dma2d_color_format_t lv_color_format_to_dma2d_color_format(lv_img_cf_t color_format) +{ + switch(color_format) { + case LV_IMG_CF_RGBA8888: + // note: LV_IMG_CF_RGBA8888 is actually ARGB8888 + return ARGB8888; + case LV_IMG_CF_RGBX8888: + // note: LV_IMG_CF_RGBX8888 is actually XRGB8888 + return ARGB8888; + case LV_IMG_CF_RGB565: + return RGB565; + case LV_IMG_CF_TRUE_COLOR: + return LvglColorFormat; + case LV_IMG_CF_TRUE_COLOR_ALPHA: +#if LV_COLOR_DEPTH == 16 + // bitmap color format is 24b ARGB8565 - dma2d unsupported + return UNSUPPORTED; +#elif LV_COLOR_DEPTH == 32 + return ARGB8888; +#else + // unknown bitmap color format + return UNSUPPORTED; +#endif + default: + return UNSUPPORTED; + } +} - /*start transfer*/ - DMA2D->CR |= DMA2D_CR_START_Msk; +static lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc, + const lv_area_t * src_area, + const void * src) +{ + //if(lv_img_src_get_type(src) != LV_IMG_SRC_VARIABLE) return LV_RES_INV; + return LV_RES_INV; + if(img_dsc->opa <= LV_OPA_MIN) return LV_RES_OK; + const lv_img_dsc_t * img = src; + const dma2d_color_format_t bitmapColorFormat = lv_color_format_to_dma2d_color_format(img->header.cf); + const bool ignoreBitmapAlpha = (img->header.cf == LV_IMG_CF_RGBX8888); + + if(bitmapColorFormat == UNSUPPORTED || img_dsc->angle != 0 || img_dsc->zoom != LV_IMG_ZOOM_NONE) { + return LV_RES_INV; // sorry, dma2d can handle this + } + // FIXME: handle dsc.pivot, dsc.recolor, dsc.blend_mode + // FIXME: src pixel size *must* be known to use DMA2D + // FIXME: If image is drawn by SW, then output cache needs to be cleaned next. Currently it is not possible. + // Both draw buffer start address and buffer size *must* be 32-byte aligned since draw buffer cache is being invalidated. + //uint32_t drawBufferLength = lv_area_get_size(draw_ctx->buf_area) * sizeof(lv_color_t); + //LV_ASSERT_MSG(drawBufferLength % CACHE_ROW_SIZE == 0); // critical, but this is not the way to test it + //LV_ASSERT_MSG((uint32_t)draw_ctx->buf % CACHE_ROW_SIZE == 0, "draw_ctx.buf is not 32B aligned"); // critical? + + // For performance reasons, both source buffer start address and buffer size *should* be 32-byte aligned since source buffer cache is being cleaned. + //uint32_t srcBufferLength = lv_area_get_size(src_area) * sizeof(lv_color_t); // TODO: verify src pixel size = sizeof(lv_color_t) + //LV_ASSERT_MSG(srcBufferLength % CACHE_ROW_SIZE == 0); // FIXME: assert fails (performance, non-critical) + //LV_ASSERT_MSG((uint32_t)src % CACHE_ROW_SIZE == 0); // FIXME: assert fails (performance, non-critical) + + lv_area_t draw_area; + if(!_lv_area_intersect(&draw_area, src_area, draw_ctx->clip_area)) return LV_RES_OK; + + lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); + lv_point_t src_offset = lv_area_get_offset(src_area, &draw_area); // source image offset in relation to draw_area + lv_area_move(&draw_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1); + _lv_draw_stm32_dma2d_blend_map(draw_ctx->buf, dest_stride, &draw_area, img->data, img->header.w, + &src_offset, img_dsc->opa, bitmapColorFormat, ignoreBitmapAlpha); + return LV_RES_OK; } +static void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx) +{ + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(disp->driver); + lv_draw_sw_wait_for_finish(draw_ctx); +} + +/********************** + * STATIC FUNCTIONS + **********************/ -static void lv_draw_stm32_dma2d_blend_map(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, lv_coord_t src_stride, lv_opa_t opa) +/** + * @brief Fills draw_area with specified color. + * @param color color to be painted, note: alpha is ignored + */ +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_fill(const lv_color_t * dest_buf, lv_coord_t dest_stride, + const lv_area_t * draw_area, lv_color_t color, lv_opa_t opa) { + LV_ASSERT_MSG(!isDma2dInProgess, "dma2d transfer has not finished"); // critical + lv_coord_t draw_width = lv_area_get_width(draw_area); + lv_coord_t draw_height = lv_area_get_height(draw_area); - /*Simple copy*/ - int32_t dest_w = lv_area_get_width(dest_area); - int32_t dest_h = lv_area_get_height(dest_area); + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(NULL); - invalidate_cache(); if(opa >= LV_OPA_MAX) { - DMA2D->CR = 0; - /*copy output colour mode, this register controls both input and output colour format*/ - DMA2D->FGPFCCR = LV_DMA2D_COLOR_FORMAT; - DMA2D->FGMAR = (uint32_t)src_buf; - DMA2D->FGOR = src_stride - dest_w; - DMA2D->OMAR = (uint32_t)dest_buf; - DMA2D->OOR = dest_stride - dest_w; - DMA2D->NLR = (dest_w << DMA2D_NLR_PL_Pos) | (dest_h << DMA2D_NLR_NL_Pos); - - /*start transfer*/ - DMA2D->CR |= DMA2D_CR_START_Msk; + DMA2D->CR = 0x3UL << DMA2D_CR_MODE_Pos; // Register-to-memory (no FG nor BG, only output stage active) + + DMA2D->OPFCCR = LvglColorFormat; +#if defined(DMA2D_OPFCCR_RBS_Pos) + DMA2D->OPFCCR |= (RBS_BIT << DMA2D_OPFCCR_RBS_Pos); +#endif + DMA2D->OMAR = (uint32_t)(dest_buf + (dest_stride * draw_area->y1) + draw_area->x1); + DMA2D->OOR = dest_stride - draw_width; // out buffer offset + // Note: unlike FGCOLR and BGCOLR, OCOLR bits must match DMA2D_OUTPUT_COLOR, alpha can be specified +#if RBS_BIT + // swap red/blue bits + DMA2D->OCOLR = (color.ch.blue << 11) | (color.ch.green_l << 5 | color.ch.green_h << 8) | (color.ch.red); +#else + DMA2D->OCOLR = color.full; +#endif } else { - DMA2D->CR = 0x20000; - - DMA2D->BGPFCCR = LV_DMA2D_COLOR_FORMAT; - DMA2D->BGMAR = (uint32_t)dest_buf; - DMA2D->BGOR = dest_stride - dest_w; - - DMA2D->FGPFCCR = (uint32_t)LV_DMA2D_COLOR_FORMAT - /*alpha mode 2, replace with foreground * alpha value*/ - | (2 << DMA2D_FGPFCCR_AM_Pos) - /*alpha value*/ - | (opa << DMA2D_FGPFCCR_ALPHA_Pos); - DMA2D->FGMAR = (uint32_t)src_buf; - DMA2D->FGOR = src_stride - dest_w; - - DMA2D->OMAR = (uint32_t)dest_buf; - DMA2D->OOR = dest_stride - dest_w; - DMA2D->NLR = (dest_w << DMA2D_NLR_PL_Pos) | (dest_h << DMA2D_NLR_NL_Pos); - - /*start transfer*/ - DMA2D->CR |= DMA2D_CR_START_Msk; + DMA2D->CR = 0x2UL << DMA2D_CR_MODE_Pos; // Memory-to-memory with blending (FG and BG fetch with PFC and blending) + + DMA2D->FGPFCCR = A8; + DMA2D->FGPFCCR |= (opa << DMA2D_FGPFCCR_ALPHA_Pos); + // Alpha Mode 1: Replace original foreground image alpha channel value by FGPFCCR.ALPHA + DMA2D->FGPFCCR |= (0x1UL << DMA2D_FGPFCCR_AM_Pos); + //DMA2D->FGPFCCR |= (RBS_BIT << DMA2D_FGPFCCR_RBS_Pos); + + // Note: in Alpha Mode 1 FGMAR and FGOR are not used to supply foreground A8 bytes, + // those bytes are replaced by constant ALPHA defined in FGPFCCR + DMA2D->FGMAR = (uint32_t)dest_buf; + DMA2D->FGOR = dest_stride; + DMA2D->FGCOLR = lv_color_to32(color) & 0x00ffffff; // swap FGCOLR R/B bits if FGPFCCR.RBS (RBS_BIT) bit is set + + DMA2D->BGPFCCR = LvglColorFormat; +#if defined(DMA2D_BGPFCCR_RBS_Pos) + DMA2D->BGPFCCR |= (RBS_BIT << DMA2D_BGPFCCR_RBS_Pos); +#endif + DMA2D->BGMAR = (uint32_t)(dest_buf + (dest_stride * draw_area->y1) + draw_area->x1); + DMA2D->BGOR = dest_stride - draw_width; + DMA2D->BGCOLR = 0; // used in A4 and A8 modes only + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->BGMAR, DMA2D->BGOR, draw_width, draw_height, sizeof(lv_color_t)); + + DMA2D->OPFCCR = LvglColorFormat; +#if defined(DMA2D_OPFCCR_RBS_Pos) + DMA2D->OPFCCR |= (RBS_BIT << DMA2D_OPFCCR_RBS_Pos); +#endif + DMA2D->OMAR = DMA2D->BGMAR; + DMA2D->OOR = DMA2D->BGOR; + DMA2D->OCOLR = 0; } + // PL - pixel per lines (14 bit), NL - number of lines (16 bit) + DMA2D->NLR = (draw_width << DMA2D_NLR_PL_Pos) | (draw_height << DMA2D_NLR_NL_Pos); + + _lv_gpu_stm32_dma2d_start_dma_transfer(); } -void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx) +/** + * @brief Draws src (foreground) map on dst (background) map. + * @param src_offset src offset in relation to dst, useful when src is larger than draw_area + * @param opa constant opacity to be applied + * @param bitmapColorCode bitmap color type + * @param ignoreAlpha if TRUE, bitmap src alpha channel is ignored + */ +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_map(const lv_color_t * dest_buf, lv_coord_t dest_stride, + const lv_area_t * draw_area, const void * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset, lv_opa_t opa, + dma2d_color_format_t src_color_format, bool ignore_src_alpha) { - lv_disp_t * disp = _lv_refr_get_disp_refreshing(); - if(disp->driver && disp->driver->wait_cb) { - while(DMA2D->CR & DMA2D_CR_START_Msk) { - disp->driver->wait_cb(disp->driver); + LV_ASSERT_MSG(!isDma2dInProgess, "dma2d transfer has not finished"); // critical + if(opa <= LV_OPA_MIN || src_color_format == UNSUPPORTED) return; + lv_coord_t draw_width = lv_area_get_width(draw_area); + lv_coord_t draw_height = lv_area_get_height(draw_area); + bool bitmapHasOpacity = !ignore_src_alpha && (src_color_format == ARGB8888 || src_color_format == ARGB1555 || + src_color_format == ARGB4444); + + if(opa >= LV_OPA_MAX) opa = 0xff; + + uint8_t srcBpp; // source bytes per pixel + switch(src_color_format) { + case ARGB8888: + srcBpp = 4; + break; + case RGB888: + srcBpp = 3; + break; + case RGB565: + case ARGB1555: + case ARGB4444: + srcBpp = 2; + break; + default: + LV_LOG_ERROR("unsupported color format"); + return; + } + + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(NULL); + + DMA2D->FGPFCCR = src_color_format; + + if(opa == 0xff && !bitmapHasOpacity) { + // no need to blend + if(src_color_format == LvglColorFormat) { + // no need to convert pixel format (PFC) either + DMA2D->CR = 0x0UL; + } + else { + DMA2D->CR = 0x1UL << DMA2D_CR_MODE_Pos; // Memory-to-memory with PFC (FG fetch only with FG PFC active) } + // Alpha Mode 0: No modification of the foreground image alpha channel value } else { - while(DMA2D->CR & DMA2D_CR_START_Msk); + // blend + DMA2D->CR = 0x2UL << DMA2D_CR_MODE_Pos; // Memory-to-memory with blending (FG and BG fetch with PFC and blending) + DMA2D->FGPFCCR |= (opa << DMA2D_FGPFCCR_ALPHA_Pos); + if(bitmapHasOpacity) { + // Alpha Mode 2: Replace original foreground image alpha channel value by FGPFCCR.ALPHA multiplied with original alpha channel value + DMA2D->FGPFCCR |= (0x2UL << DMA2D_FGPFCCR_AM_Pos); + } + else { + // Alpha Mode 1: Replace original foreground image alpha channel value by FGPFCCR.ALPHA + DMA2D->FGPFCCR |= (0x1UL << DMA2D_FGPFCCR_AM_Pos); + } + } +#if defined(DMA2D_FGPFCCR_RBS_Pos) + DMA2D->FGPFCCR |= (RBS_BIT << DMA2D_FGPFCCR_RBS_Pos); +#endif + DMA2D->FGMAR = ((uint32_t)src_buf) + srcBpp * ((src_stride * src_offset->y) + src_offset->x); + DMA2D->FGOR = src_stride - draw_width; + DMA2D->FGCOLR = 0; // used in A4 and A8 modes only + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->FGMAR, DMA2D->FGOR, draw_width, draw_height, srcBpp); + + DMA2D->OPFCCR = LvglColorFormat; +#if defined(DMA2D_OPFCCR_RBS_Pos) + DMA2D->OPFCCR |= (RBS_BIT << DMA2D_OPFCCR_RBS_Pos); +#endif + DMA2D->OMAR = (uint32_t)(dest_buf + (dest_stride * draw_area->y1) + draw_area->x1); + DMA2D->OOR = dest_stride - draw_width; + DMA2D->OCOLR = 0; + + if(opa != 0xff || bitmapHasOpacity) { + // use background (BG*) registers + DMA2D->BGPFCCR = LvglColorFormat; +#if defined(DMA2D_BGPFCCR_RBS_Pos) + DMA2D->BGPFCCR |= (RBS_BIT << DMA2D_BGPFCCR_RBS_Pos); +#endif + DMA2D->BGMAR = DMA2D->OMAR; + DMA2D->BGOR = DMA2D->OOR; + DMA2D->BGCOLR = 0; // used in A4 and A8 modes only + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->BGMAR, DMA2D->BGOR, draw_width, draw_height, sizeof(lv_color_t)); } - lv_draw_sw_wait_for_finish(draw_ctx); + // PL - pixel per lines (14 bit), NL - number of lines (16 bit) + DMA2D->NLR = (draw_width << DMA2D_NLR_PL_Pos) | (draw_height << DMA2D_NLR_NL_Pos); + + _lv_gpu_stm32_dma2d_start_dma_transfer(); } -/********************** - * STATIC FUNCTIONS - **********************/ +/** + * @brief Paints solid color with alpha mask with additional constant opacity. Useful e.g. for painting anti-aliased fonts. + * @param src_offset src offset in relation to dst, useful when src (alpha mask) is larger than draw_area + * @param color color to paint, note: alpha is ignored + * @param opa constant opacity to be applied + */ +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_paint(const lv_color_t * dest_buf, lv_coord_t dest_stride, + const lv_area_t * draw_area, const lv_opa_t * mask_buf, lv_coord_t mask_stride, const lv_point_t * mask_offset, + lv_color_t color, lv_opa_t opa) +{ + LV_ASSERT_MSG(!isDma2dInProgess, "dma2d transfer has not finished"); // critical + lv_coord_t draw_width = lv_area_get_width(draw_area); + lv_coord_t draw_height = lv_area_get_height(draw_area); -static void invalidate_cache(void) + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(NULL); + + DMA2D->CR = 0x2UL << DMA2D_CR_MODE_Pos; // Memory-to-memory with blending (FG and BG fetch with PFC and blending) + + DMA2D->FGPFCCR = A8; + if(opa < LV_OPA_MAX) { + DMA2D->FGPFCCR |= (opa << DMA2D_FGPFCCR_ALPHA_Pos); + DMA2D->FGPFCCR |= (0x2UL << + DMA2D_FGPFCCR_AM_Pos); // Alpha Mode: Replace original foreground image alpha channel value by FGPFCCR.ALPHA multiplied with original alpha channel value + } + //DMA2D->FGPFCCR |= (RBS_BIT << DMA2D_FGPFCCR_RBS_Pos); + DMA2D->FGMAR = (uint32_t)(mask_buf + (mask_stride * mask_offset->y) + mask_offset->x); + DMA2D->FGOR = mask_stride - draw_width; + DMA2D->FGCOLR = lv_color_to32(color) & 0x00ffffff; // swap FGCOLR R/B bits if FGPFCCR.RBS (RBS_BIT) bit is set + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->FGMAR, DMA2D->FGOR, draw_width, draw_height, sizeof(lv_opa_t)); + + DMA2D->BGPFCCR = LvglColorFormat; +#if defined(DMA2D_BGPFCCR_RBS_Pos) + DMA2D->BGPFCCR |= (RBS_BIT << DMA2D_BGPFCCR_RBS_Pos); +#endif + DMA2D->BGMAR = (uint32_t)(dest_buf + (dest_stride * draw_area->y1) + draw_area->x1); + DMA2D->BGOR = dest_stride - draw_width; + DMA2D->BGCOLR = 0; // used in A4 and A8 modes only + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->BGMAR, DMA2D->BGOR, draw_width, draw_height, sizeof(lv_color_t)); + + DMA2D->OPFCCR = LvglColorFormat; +#if defined(DMA2D_OPFCCR_RBS_Pos) + DMA2D->OPFCCR |= (RBS_BIT << DMA2D_OPFCCR_RBS_Pos); +#endif + DMA2D->OMAR = DMA2D->BGMAR; + DMA2D->OOR = DMA2D->BGOR; + DMA2D->OCOLR = 0; + // PL - pixel per lines (14 bit), NL - number of lines (16 bit) + DMA2D->NLR = (draw_width << DMA2D_NLR_PL_Pos) | (draw_height << DMA2D_NLR_NL_Pos); + + _lv_gpu_stm32_dma2d_start_dma_transfer(); +} + +/** + * @brief Copies src (foreground) map to the dst (background) map. + * @param src_offset src offset in relation to dst, useful when src is larger than draw_area + */ +LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_copy_buffer(const lv_color_t * dest_buf, lv_coord_t dest_stride, + const lv_area_t * draw_area, const lv_color_t * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset) { - lv_disp_t * disp = _lv_refr_get_disp_refreshing(); - if(disp->driver->clean_dcache_cb) disp->driver->clean_dcache_cb(disp->driver); + LV_ASSERT_MSG(!isDma2dInProgess, "dma2d transfer has not finished"); // critical + lv_coord_t draw_width = lv_area_get_width(draw_area); + lv_coord_t draw_height = lv_area_get_height(draw_area); + + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(NULL); + + DMA2D->CR = 0x0UL; // Memory-to-memory (FG fetch only) + + DMA2D->FGPFCCR = LvglColorFormat; +#if defined(DMA2D_FGPFCCR_RBS_Pos) + DMA2D->FGPFCCR |= (RBS_BIT << DMA2D_FGPFCCR_RBS_Pos); +#endif + DMA2D->FGMAR = (uint32_t)(src_buf + (src_stride * src_offset->y) + src_offset->x); + DMA2D->FGOR = src_stride - draw_width; + DMA2D->FGCOLR = 0; // used in A4 and A8 modes only + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->FGMAR, DMA2D->FGOR, draw_width, draw_height, sizeof(lv_color_t)); + + // Note BG* registers do not need to be set up since BG is not used + + DMA2D->OPFCCR = LvglColorFormat; +#if defined(DMA2D_OPFCCR_RBS_Pos) + DMA2D->OPFCCR |= (RBS_BIT << DMA2D_OPFCCR_RBS_Pos); +#endif + DMA2D->OMAR = (uint32_t)(dest_buf + (dest_stride * draw_area->y1) + draw_area->x1); + DMA2D->OOR = dest_stride - draw_width; + DMA2D->OCOLR = 0; + + // PL - pixel per lines (14 bit), NL - number of lines (16 bit) + DMA2D->NLR = (draw_width << DMA2D_NLR_PL_Pos) | (draw_height << DMA2D_NLR_NL_Pos); + + _lv_gpu_stm32_dma2d_start_dma_transfer(); +} + +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_start_dma_transfer(void) +{ + LV_ASSERT_MSG(!isDma2dInProgess, "dma2d transfer has not finished"); + isDma2dInProgess = true; + DMA2D->IFCR = 0x3FU; // trigger ISR flags reset + // Note: cleaning output buffer cache is needed only when buffer may be misaligned or adjacent area may have been drawn in sw-fashion, e.g. using lv_draw_sw_blend_basic() +#if LV_COLOR_DEPTH == 16 + _lv_gpu_stm32_dma2d_clean_cache(DMA2D->OMAR, DMA2D->OOR, (DMA2D->NLR & DMA2D_NLR_PL_Msk) >> DMA2D_NLR_PL_Pos, + (DMA2D->NLR & DMA2D_NLR_NL_Msk) >> DMA2D_NLR_NL_Pos, sizeof(lv_color_t)); +#endif + DMA2D->CR |= DMA2D_CR_START; + // Note: for some reason mask buffer gets damaged during transfer if waiting is postponed + _lv_gpu_stm32_dma2d_await_dma_transfer_finish(NULL); // FIXME: this line should not be needed here, but it is +} + +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_await_dma_transfer_finish(lv_disp_drv_t * disp_drv) +{ + if(disp_drv && disp_drv->wait_cb) { + while((DMA2D->CR & DMA2D_CR_START) != 0U) { + disp_drv->wait_cb(disp_drv); + } + } else { -#if __CORTEX_M >= 0x07 - if((SCB->CCR) & (uint32_t)SCB_CCR_DC_Msk) - SCB_CleanInvalidateDCache(); + while((DMA2D->CR & DMA2D_CR_START) != 0U); + } + + __IO uint32_t isrFlags = DMA2D->ISR; + + if(isrFlags & DMA2D_ISR_CEIF) { + LV_LOG_ERROR("DMA2D config error"); + } + + if(isrFlags & DMA2D_ISR_TEIF) { + LV_LOG_ERROR("DMA2D transfer error"); + } + + DMA2D->IFCR = 0x3FU; // trigger ISR flags reset + + if(isDma2dInProgess) { + // invalidate output buffer cached memory ONLY after DMA2D transfer + //_lv_gpu_stm32_dma2d_invalidate_cache(DMA2D->OMAR, DMA2D->OOR, (DMA2D->NLR & DMA2D_NLR_PL_Msk) >> DMA2D_NLR_PL_Pos, (DMA2D->NLR & DMA2D_NLR_NL_Msk) >> DMA2D_NLR_NL_Pos, sizeof(lv_color_t)); + isDma2dInProgess = false; + } +} + +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_invalidate_cache(uint32_t address, lv_coord_t offset, lv_coord_t width, + lv_coord_t height, uint8_t pixel_size) +{ +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if(((SCB->CCR) & SCB_CCR_DC_Msk) == 0) return; // L1 data cache is disabled + uint16_t stride = pixel_size * (width + offset); // in bytes + uint16_t ll = pixel_size * width; // line length in bytes + uint32_t n = 0; // address of the next cache row after the last invalidated row + lv_coord_t h = 0; + + __DSB(); + + while(h < height) { + uint32_t a = address + (h * stride); + uint32_t e = a + ll; // end address, address of the first byte after the current line + a &= ~(CACHE_ROW_SIZE - 1U); + if(a < n) a = n; // prevent the previous last cache row from being invalidated again + + while(a < e) { + SCB->DCIMVAC = a; + a += CACHE_ROW_SIZE; + } + + n = a; + h++; + }; + + __DSB(); + __ISB(); #endif +} + +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_clean_cache(uint32_t address, lv_coord_t offset, lv_coord_t width, + lv_coord_t height, uint8_t pixel_size) +{ +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if(((SCB->CCR) & SCB_CCR_DC_Msk) == 0) return; // L1 data cache is disabled + uint16_t stride = pixel_size * (width + offset); // in bytes + uint16_t ll = pixel_size * width; // line length in bytes + uint32_t n = 0; // address of the next cache row after the last cleaned row + lv_coord_t h = 0; + __DSB(); + + while(h < height) { + uint32_t a = address + (h * stride); + uint32_t e = a + ll; // end address, address of the first byte after the current line + a &= ~(CACHE_ROW_SIZE - 1U); + if(a < n) a = n; // prevent the previous last cache row from being cleaned again + + while(a < e) { + SCB->DCCMVAC = a; + a += CACHE_ROW_SIZE; + } + + n = a; + h++; + }; + + __DSB(); + __ISB(); +#endif +} + +// initialize µs timer +LV_STM32_DMA2D_STATIC bool _lv_gpu_stm32_dwt_init(void) +{ + // disable TRC + CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; + // enable TRC + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + +#if defined(__CORTEX_M) && (__CORTEX_M == 7U) + DWT->LAR = 0xC5ACCE55; +#endif + // disable clock cycle counter + DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; + // enable clock cycle counter + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + + // reset the clock cycle counter value + DWT->CYCCNT = 0; + + // 3 NO OPERATION instructions + __ASM volatile("NOP"); + __ASM volatile("NOP"); + __ASM volatile("NOP"); + + // check if clock cycle counter has started + if(DWT->CYCCNT) { + return true; // clock cycle counter started } + else { + return false; // clock cycle counter not started + } +} + +// get elapsed µs since reset +LV_STM32_DMA2D_STATIC uint32_t _lv_gpu_stm32_dwt_get_us(void) +{ + uint32_t us = (DWT->CYCCNT * 1000000) / HAL_RCC_GetHCLKFreq(); + return us; +} + +// reset µs timer +LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dwt_reset(void) +{ + DWT->CYCCNT = 0; } #endif diff --git a/src/liblvgl/draw/sw/lv_draw_sw.c b/src/liblvgl/draw/sw/lv_draw_sw.c index a05d461..1c0c6d4 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw.c +++ b/src/liblvgl/draw/sw/lv_draw_sw.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/draw/lv_draw.h" +#include "../lv_draw.h" #include "lv_draw_sw.h" /********************* diff --git a/src/liblvgl/draw/sw/lv_draw_sw.mk b/src/liblvgl/draw/sw/lv_draw_sw.mk new file mode 100644 index 0000000..4625cbc --- /dev/null +++ b/src/liblvgl/draw/sw/lv_draw_sw.mk @@ -0,0 +1,17 @@ +CSRCS += lv_draw_sw.c +CSRCS += lv_draw_sw_arc.c +CSRCS += lv_draw_sw_blend.c +CSRCS += lv_draw_sw_dither.c +CSRCS += lv_draw_sw_gradient.c +CSRCS += lv_draw_sw_img.c +CSRCS += lv_draw_sw_letter.c +CSRCS += lv_draw_sw_line.c +CSRCS += lv_draw_sw_polygon.c +CSRCS += lv_draw_sw_rect.c +CSRCS += lv_draw_sw_transform.c +CSRCS += lv_draw_sw_layer.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw" diff --git a/src/liblvgl/draw/sw/lv_draw_sw_arc.c b/src/liblvgl/draw/sw/lv_draw_sw_arc.c index 71df4e5..3ed62b6 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_arc.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_arc.c @@ -7,10 +7,10 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/misc/lv_log.h" -#include "liblvgl/misc/lv_mem.h" -#include "liblvgl/draw/lv_draw.h" +#include "../../misc/lv_math.h" +#include "../../misc/lv_log.h" +#include "../../misc/lv_mem.h" +#include "../lv_draw.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_blend.c b/src/liblvgl/draw/sw/lv_draw_sw_blend.c index a617805..bff0a8f 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_blend.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_blend.c @@ -7,9 +7,9 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/core/lv_refr.h" +#include "../../misc/lv_math.h" +#include "../../hal/lv_hal_disp.h" +#include "../../core/lv_refr.h" /********************* * DEFINES @@ -103,7 +103,7 @@ void lv_draw_sw_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * d LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_basic(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc) { - const lv_opa_t * mask; + lv_opa_t * mask; if(dsc->mask_buf == NULL) mask = NULL; if(dsc->mask_buf && dsc->mask_res == LV_DRAW_MASK_RES_TRANSP) return; else if(dsc->mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask = NULL; @@ -129,7 +129,6 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_basic(lv_draw_ctx_t * draw_ctx, cons } } - const lv_color_t * src_buf = dsc->src_buf; lv_coord_t src_stride; if(src_buf) { @@ -142,8 +141,18 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_basic(lv_draw_ctx_t * draw_ctx, cons lv_coord_t mask_stride; if(mask) { + /*Round the values in the mask if anti-aliasing is disabled*/ + if(disp->driver->antialiasing == 0) { + int32_t mask_size = lv_area_get_size(dsc->mask_area); + int32_t i; + for(i = 0; i < mask_size; i++) { + mask[i] = mask[i] > 128 ? LV_OPA_COVER : LV_OPA_TRANSP; + } + } + mask_stride = lv_area_get_width(dsc->mask_area); mask += mask_stride * (blend_area.y1 - dsc->mask_area->y1) + (blend_area.x1 - dsc->mask_area->x1); + } else { mask_stride = 0; diff --git a/src/liblvgl/draw/sw/lv_draw_sw_dither.c b/src/liblvgl/draw/sw/lv_draw_sw_dither.c index 64afb8f..ff9ebf3 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_dither.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_dither.c @@ -8,7 +8,7 @@ *********************/ #include "lv_draw_sw_dither.h" #include "lv_draw_sw_gradient.h" -#include "liblvgl/misc/lv_color.h" +#include "../../misc/lv_color.h" /********************** * STATIC FUNCTIONS diff --git a/src/liblvgl/draw/sw/lv_draw_sw_gradient.c b/src/liblvgl/draw/sw/lv_draw_sw_gradient.c index fbbdbaf..4e46632 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_gradient.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_gradient.c @@ -7,8 +7,8 @@ * INCLUDES *********************/ #include "lv_draw_sw_gradient.h" -#include "liblvgl/misc/lv_gc.h" -#include "liblvgl/misc/lv_types.h" +#include "../../misc/lv_gc.h" +#include "../../misc/lv_types.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_img.c b/src/liblvgl/draw/sw/lv_draw_sw_img.c index 74a4fa7..9578bc7 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_img.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_img.c @@ -7,12 +7,12 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/draw/lv_img_cache.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/misc/lv_log.h" -#include "liblvgl/core/lv_refr.h" -#include "liblvgl/misc/lv_mem.h" -#include "liblvgl/misc/lv_math.h" +#include "../lv_img_cache.h" +#include "../../hal/lv_hal_disp.h" +#include "../../misc/lv_log.h" +#include "../../core/lv_refr.h" +#include "../../misc/lv_mem.h" +#include "../../misc/lv_math.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_layer.c b/src/liblvgl/draw/sw/lv_draw_sw_layer.c index 734443e..b53c662 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_layer.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_layer.c @@ -7,9 +7,9 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/core/lv_refr.h" +#include "../../hal/lv_hal_disp.h" +#include "../../misc/lv_area.h" +#include "../../core/lv_refr.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_letter.c b/src/liblvgl/draw/sw/lv_draw_sw_letter.c index 3269230..7caa749 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_letter.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_letter.c @@ -7,13 +7,13 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/hal/lv_hal_disp.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/misc/lv_assert.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_style.h" -#include "liblvgl/font/lv_font.h" -#include "liblvgl/core/lv_refr.h" +#include "../../hal/lv_hal_disp.h" +#include "../../misc/lv_math.h" +#include "../../misc/lv_assert.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_style.h" +#include "../../font/lv_font.h" +#include "../../core/lv_refr.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_line.c b/src/liblvgl/draw/sw/lv_draw_sw_line.c index 5bc5514..73833c1 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_line.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_line.c @@ -8,8 +8,8 @@ *********************/ #include #include "lv_draw_sw.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/core/lv_refr.h" +#include "../../misc/lv_math.h" +#include "../../core/lv_refr.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_polygon.c b/src/liblvgl/draw/sw/lv_draw_sw_polygon.c index 38cc2c6..a05b471 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_polygon.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_polygon.c @@ -7,11 +7,11 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/misc/lv_mem.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/misc/lv_color.h" -#include "liblvgl/draw/lv_draw_rect.h" +#include "../../misc/lv_math.h" +#include "../../misc/lv_mem.h" +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" +#include "../lv_draw_rect.h" /********************* * DEFINES diff --git a/src/liblvgl/draw/sw/lv_draw_sw_rect.c b/src/liblvgl/draw/sw/lv_draw_sw_rect.c index ec6e66c..706ec6b 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_rect.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_rect.c @@ -7,10 +7,10 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/misc/lv_txt_ap.h" -#include "liblvgl/core/lv_refr.h" -#include "liblvgl/misc/lv_assert.h" +#include "../../misc/lv_math.h" +#include "../../misc/lv_txt_ap.h" +#include "../../core/lv_refr.h" +#include "../../misc/lv_assert.h" #include "lv_draw_sw_dither.h" /********************* diff --git a/src/liblvgl/draw/sw/lv_draw_sw_transform.c b/src/liblvgl/draw/sw/lv_draw_sw_transform.c index 68582ae..204503a 100644 --- a/src/liblvgl/draw/sw/lv_draw_sw_transform.c +++ b/src/liblvgl/draw/sw/lv_draw_sw_transform.c @@ -7,9 +7,9 @@ * INCLUDES *********************/ #include "lv_draw_sw.h" -#include "liblvgl/misc/lv_assert.h" -#include "liblvgl/misc/lv_area.h" -#include "liblvgl/core/lv_refr.h" +#include "../../misc/lv_assert.h" +#include "../../misc/lv_area.h" +#include "../../core/lv_refr.h" #if LV_DRAW_COMPLEX /********************* @@ -122,8 +122,8 @@ void lv_draw_sw_transform(lv_draw_ctx_t * draw_ctx, const lv_area_t * dest_area, xs_step_256 = (256 * xs_diff) / (dest_w - 1); ys_step_256 = (256 * ys_diff) / (dest_w - 1); } - int32_t xs_ups = xs1_ups; - int32_t ys_ups = ys1_ups; + int32_t xs_ups = xs1_ups + 0x80; + int32_t ys_ups = ys1_ups + 0x80; if(draw_dsc->antialias == 0) { switch(cf) { @@ -180,7 +180,7 @@ static void rgb_no_aa(const uint8_t * src, lv_coord_t src_w, lv_coord_t src_h, l } else { -#if LV_COLOR_DEPTH == 8 +#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8 const uint8_t * src_tmp = src; src_tmp += ys_int * src_stride + xs_int; cbuf[x].full = src_tmp[0]; @@ -221,7 +221,7 @@ static void argb_no_aa(const uint8_t * src, lv_coord_t src_w, lv_coord_t src_h, const uint8_t * src_tmp = src; src_tmp += (ys_int * src_stride * LV_IMG_PX_SIZE_ALPHA_BYTE) + xs_int * LV_IMG_PX_SIZE_ALPHA_BYTE; -#if LV_COLOR_DEPTH == 8 +#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8 cbuf[x].full = src_tmp[0]; #elif LV_COLOR_DEPTH == 16 cbuf[x].full = src_tmp[0] + (src_tmp[1] << 8); @@ -396,7 +396,7 @@ static void argb_and_rgb_aa(const uint8_t * src, lv_coord_t src_w, lv_coord_t sr if(abuf[x] == 0x00) continue; -#if LV_COLOR_DEPTH == 8 +#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8 c_base.full = px_base[0]; c_ver.full = px_ver[0]; c_hor.full = px_hor[0]; @@ -429,7 +429,7 @@ static void argb_and_rgb_aa(const uint8_t * src, lv_coord_t src_w, lv_coord_t sr } /*Partially out of the image*/ else { -#if LV_COLOR_DEPTH == 8 +#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8 cbuf[x].full = src_tmp[0]; #elif LV_COLOR_DEPTH == 16 cbuf[x].full = src_tmp[0] + (src_tmp[1] << 8); diff --git a/src/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk b/src/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk new file mode 100644 index 0000000..bc19e38 --- /dev/null +++ b/src/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_swm341_dma2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d" diff --git a/src/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c b/src/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c index f4ddc53..74a5394 100644 --- a/src/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c +++ b/src/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_gpu_swm341_dma2d.h" -#include "liblvgl/core/lv_refr.h" +#include "../../core/lv_refr.h" #if LV_USE_GPU_SWM341_DMA2D diff --git a/src/liblvgl/extra/README.md b/src/liblvgl/extra/README.md new file mode 100644 index 0000000..80bb49d --- /dev/null +++ b/src/liblvgl/extra/README.md @@ -0,0 +1,31 @@ +# Extra components + +This directory contains extra (optional) components to lvgl. +It's a good place for contributions as there are less strict expectations about the completeness and flexibility of the components here. + +In other words, if you have created a complex widget from other widgets, or modified an existing widget with special events, styles or animations, or have a new feature that could work as a plugin to lvgl feel free to the share it here. + +## How to contribute +- Create a [Pull request](https://docs.lvgl.io/8.0/CONTRIBUTING.html#pull-request) with your new content +- Please and follow the [Coding style](https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md) of LVGL +- Add setter/getter functions in pair +- Update [lv_conf_template.h](https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h) +- Add description in the [docs](https://github.com/lvgl/lvgl/tree/master/docs) +- Add [examples](https://github.com/lvgl/lvgl/tree/master/examples) +- Update the [changelog](https://github.com/lvgl/lvgl/tree/master/docs/CHANGELOG.md) +- Add yourself to the [Contributors](#contributors) section below. + +## Ideas +Here some ideas as inspiration feel free to contribute with ideas too. +- New [Calendar headers](https://github.com/lvgl/lvgl/tree/master/src/extra/widgets/calendar) +- Color picker with RGB and or HSV bars +- Ruler, horizontal or vertical with major and minor ticks and labels +- New [List items types](https://github.com/lvgl/lvgl/tree/master/src/extra/widgets/list) +- [Preloaders](https://www.google.com/search?q=preloader&sxsrf=ALeKk01ddA4YB0WEgLLN1bZNSm8YER7pkg:1623080551559&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiwoN6d7oXxAhVuw4sKHVedBB4Q_AUoAXoECAEQAw&biw=952&bih=940) +- Drop-down list with a container to which content can be added +- 9 patch button: Similar to [lv_imgbtn](https://docs.lvgl.io/8.0/widgets/extra/imgbtn.html) but 9 images for 4 corner, 4 sides and the center + +## Contributors +- lv_animimg: @ZhaoQiang-b45475 +- lv_span: @guoweilkd +- lv_menu: @HX2003 \ No newline at end of file diff --git a/src/liblvgl/extra/layouts/flex/lv_flex.c b/src/liblvgl/extra/layouts/flex/lv_flex.c index 422fb7d..a53c95e 100644 --- a/src/liblvgl/extra/layouts/flex/lv_flex.c +++ b/src/liblvgl/extra/layouts/flex/lv_flex.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/extra/layouts/lv_layouts.h" +#include "../lv_layouts.h" #if LV_USE_FLEX @@ -470,8 +470,14 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i } } - if(f->row) item->w_layout = 1; - else item->h_layout = 1; + if(f->row) { + item->w_layout = 1; + item->h_layout = 0; + } + else { + item->h_layout = 1; + item->w_layout = 0; + } if(s != area_get_main_size(&item->coords)) { lv_obj_invalidate(item); diff --git a/src/liblvgl/extra/layouts/grid/lv_grid.c b/src/liblvgl/extra/layouts/grid/lv_grid.c index 441ffc3..74f8e95 100644 --- a/src/liblvgl/extra/layouts/grid/lv_grid.c +++ b/src/liblvgl/extra/layouts/grid/lv_grid.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/extra/layouts/lv_layouts.h" +#include "../lv_layouts.h" #if LV_USE_GRID diff --git a/src/liblvgl/extra/libs/bmp/lv_bmp.c b/src/liblvgl/extra/libs/bmp/lv_bmp.c index 0898379..f89a0a8 100644 --- a/src/liblvgl/extra/libs/bmp/lv_bmp.c +++ b/src/liblvgl/extra/libs/bmp/lv_bmp.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_BMP #include diff --git a/src/liblvgl/extra/libs/fsdrv/lv_fs_fatfs.c b/src/liblvgl/extra/libs/fsdrv/lv_fs_fatfs.c index b06adb4..cc1d2e6 100644 --- a/src/liblvgl/extra/libs/fsdrv/lv_fs_fatfs.c +++ b/src/liblvgl/extra/libs/fsdrv/lv_fs_fatfs.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_FS_FATFS #include "ff.h" diff --git a/src/liblvgl/extra/libs/fsdrv/lv_fs_posix.c b/src/liblvgl/extra/libs/fsdrv/lv_fs_posix.c index eb96a10..e656288 100644 --- a/src/liblvgl/extra/libs/fsdrv/lv_fs_posix.c +++ b/src/liblvgl/extra/libs/fsdrv/lv_fs_posix.c @@ -7,7 +7,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_FS_POSIX @@ -104,15 +104,15 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) LV_UNUSED(drv); uint32_t flags = 0; - if(mode == LV_FS_MODE_WR) flags = O_WRONLY; + if(mode == LV_FS_MODE_WR) flags = O_WRONLY | O_CREAT; else if(mode == LV_FS_MODE_RD) flags = O_RDONLY; - else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = O_RDWR; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = O_RDWR | O_CREAT; /*Make the path relative to the current directory (the projects root folder)*/ char buf[256]; lv_snprintf(buf, sizeof(buf), LV_FS_POSIX_PATH "%s", path); - int f = open(buf, flags); + int f = open(buf, flags, 0666); if(f < 0) return NULL; return (void *)(lv_uintptr_t)f; diff --git a/src/liblvgl/extra/libs/fsdrv/lv_fs_stdio.c b/src/liblvgl/extra/libs/fsdrv/lv_fs_stdio.c index 6ce70dd..c2de688 100644 --- a/src/liblvgl/extra/libs/fsdrv/lv_fs_stdio.c +++ b/src/liblvgl/extra/libs/fsdrv/lv_fs_stdio.c @@ -7,7 +7,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_FS_STDIO != '\0' #include diff --git a/src/liblvgl/extra/libs/fsdrv/lv_fs_win32.c b/src/liblvgl/extra/libs/fsdrv/lv_fs_win32.c index f2ad681..1a59aa4 100644 --- a/src/liblvgl/extra/libs/fsdrv/lv_fs_win32.c +++ b/src/liblvgl/extra/libs/fsdrv/lv_fs_win32.c @@ -7,7 +7,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_FS_WIN32 != '\0' #include diff --git a/src/liblvgl/extra/libs/gif/gifdec.c b/src/liblvgl/extra/libs/gif/gifdec.c index 5be94e9..3ee9b71 100644 --- a/src/liblvgl/extra/libs/gif/gifdec.c +++ b/src/liblvgl/extra/libs/gif/gifdec.c @@ -1,7 +1,7 @@ #include "gifdec.h" -#include "liblvgl/misc/lv_log.h" -#include "liblvgl/misc/lv_mem.h" -#include "liblvgl/misc/lv_color.h" +#include "../../../misc/lv_log.h" +#include "../../../misc/lv_mem.h" +#include "../../../misc/lv_color.h" #if LV_USE_GIF #include @@ -160,6 +160,7 @@ static gd_GIF * gif_open(gd_GIF * gif_base) #endif } gif->anim_start = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); + gif->loop_count = -1; goto ok; fail: f_gif_close(gif_base); @@ -239,6 +240,7 @@ read_application_ext(gd_GIF *gif) { char app_id[8]; char app_auth_code[3]; + uint16_t loop_count; /* Discard block size (always 0x0B). */ f_gif_seek(gif, 1, LV_FS_SEEK_CUR); @@ -249,7 +251,15 @@ read_application_ext(gd_GIF *gif) if (!strncmp(app_id, "NETSCAPE", sizeof(app_id))) { /* Discard block size (0x03) and constant byte (0x01). */ f_gif_seek(gif, 2, LV_FS_SEEK_CUR); - gif->loop_count = read_num(gif); + loop_count = read_num(gif); + if(gif->loop_count < 0) { + if(loop_count == 0) { + gif->loop_count = 0; + } + else{ + gif->loop_count = loop_count + 1; + } + } /* Skip block terminator. */ f_gif_seek(gif, 1, LV_FS_SEEK_CUR); } else if (gif->application) { @@ -568,9 +578,16 @@ gd_get_frame(gd_GIF *gif) dispose(gif); f_gif_read(gif, &sep, 1); while (sep != ',') { - if (sep == ';') - return 0; - if (sep == '!') + if (sep == ';') { + f_gif_seek(gif, gif->anim_start, LV_FS_SEEK_SET); + if(gif->loop_count == 1 || gif->loop_count < 0) { + return 0; + } + else if(gif->loop_count > 1) { + gif->loop_count--; + } + } + else if (sep == '!') read_ext(gif); else return -1; f_gif_read(gif, &sep, 1); @@ -598,6 +615,7 @@ gd_render_frame(gd_GIF *gif, uint8_t *buffer) void gd_rewind(gd_GIF *gif) { + gif->loop_count = -1; f_gif_seek(gif, gif->anim_start, LV_FS_SEEK_SET); } diff --git a/src/liblvgl/extra/libs/gif/lv_gif.c b/src/liblvgl/extra/libs/gif/lv_gif.c index 4cb2955..2bd9e01 100644 --- a/src/liblvgl/extra/libs/gif/lv_gif.c +++ b/src/liblvgl/extra/libs/gif/lv_gif.c @@ -99,6 +99,8 @@ void lv_gif_restart(lv_obj_t * obj) { lv_gif_t * gifobj = (lv_gif_t *) obj; gd_rewind(gifobj->gif); + lv_timer_resume(gifobj->timer); + lv_timer_reset(gifobj->timer); } /********************** @@ -111,6 +113,7 @@ static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_gif_t * gifobj = (lv_gif_t *) obj; + gifobj->gif = NULL; gifobj->timer = lv_timer_create(next_frame_task_cb, 10, obj); lv_timer_pause(gifobj->timer); } @@ -120,7 +123,8 @@ static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) LV_UNUSED(class_p); lv_gif_t * gifobj = (lv_gif_t *) obj; lv_img_cache_invalidate_src(&gifobj->imgdsc); - gd_close_gif(gifobj->gif); + if(gifobj->gif) + gd_close_gif(gifobj->gif); lv_timer_del(gifobj->timer); } @@ -136,14 +140,9 @@ static void next_frame_task_cb(lv_timer_t * t) int has_next = gd_get_frame(gifobj->gif); if(has_next == 0) { /*It was the last repeat*/ - if(gifobj->gif->loop_count == 1) { - lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL); - if(res != LV_FS_RES_OK) return; - } - else { - if(gifobj->gif->loop_count > 1) gifobj->gif->loop_count--; - gd_rewind(gifobj->gif); - } + lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL); + lv_timer_pause(t); + if(res != LV_FS_RES_OK) return; } gd_render_frame(gifobj->gif, (uint8_t *)gifobj->imgdsc.data); diff --git a/src/liblvgl/extra/libs/png/lv_png.c b/src/liblvgl/extra/libs/png/lv_png.c index da79316..d067ef5 100644 --- a/src/liblvgl/extra/libs/png/lv_png.c +++ b/src/liblvgl/extra/libs/png/lv_png.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_PNG #include "lv_png.h" diff --git a/src/liblvgl/extra/libs/sjpg/lv_sjpg.c b/src/liblvgl/extra/libs/sjpg/lv_sjpg.c index 12449e5..5a12ea2 100644 --- a/src/liblvgl/extra/libs/sjpg/lv_sjpg.c +++ b/src/liblvgl/extra/libs/sjpg/lv_sjpg.c @@ -45,12 +45,12 @@ * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_SJPG #include "tjpgd.h" #include "lv_sjpg.h" -#include "liblvgl/misc/lv_fs.h" +#include "../../../misc/lv_fs.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/lv_extra.mk b/src/liblvgl/extra/lv_extra.mk new file mode 100644 index 0000000..1afcc7b --- /dev/null +++ b/src/liblvgl/extra/lv_extra.mk @@ -0,0 +1 @@ +CSRCS += $(shell find -L $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra -name \*.c) diff --git a/src/liblvgl/extra/others/fragment/README.md b/src/liblvgl/extra/others/fragment/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/liblvgl/extra/others/fragment/lv_fragment_manager.c b/src/liblvgl/extra/others/fragment/lv_fragment_manager.c index c1dd21e..ade7215 100644 --- a/src/liblvgl/extra/others/fragment/lv_fragment_manager.c +++ b/src/liblvgl/extra/others/fragment/lv_fragment_manager.c @@ -11,7 +11,7 @@ #if LV_USE_FRAGMENT -#include "liblvgl/misc/lv_ll.h" +#include "../../../misc/lv_ll.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/others/gridnav/lv_gridnav.c b/src/liblvgl/extra/others/gridnav/lv_gridnav.c index ee883f7..505a977 100644 --- a/src/liblvgl/extra/others/gridnav/lv_gridnav.c +++ b/src/liblvgl/extra/others/gridnav/lv_gridnav.c @@ -9,9 +9,9 @@ #include "lv_gridnav.h" #if LV_USE_GRIDNAV -#include "liblvgl/misc/lv_assert.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/core/lv_indev.h" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_math.h" +#include "../../../core/lv_indev.h" /********************* * DEFINES @@ -217,6 +217,7 @@ static void gridnav_event_cb(lv_event_t * e) if(dsc->focused_obj == NULL) dsc->focused_obj = find_first_focusable(obj); if(dsc->focused_obj) { lv_obj_add_state(dsc->focused_obj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_clear_state(dsc->focused_obj, LV_STATE_PRESSED); /*Be sure the focuses obj is not stuck in pressed state*/ lv_obj_scroll_to_view(dsc->focused_obj, LV_ANIM_OFF); } } diff --git a/src/liblvgl/extra/others/msg/lv_msg.c b/src/liblvgl/extra/others/msg/lv_msg.c index 597c763..d54279c 100644 --- a/src/liblvgl/extra/others/msg/lv_msg.c +++ b/src/liblvgl/extra/others/msg/lv_msg.c @@ -9,8 +9,8 @@ #include "lv_msg.h" #if LV_USE_MSG -#include "liblvgl/misc/lv_assert.h" -#include "liblvgl/misc/lv_ll.h" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_ll.h" /********************* * DEFINES @@ -94,6 +94,25 @@ void lv_msg_unsubscribe(void * s) lv_mem_free(s); } +uint32_t lv_msg_unsubscribe_obj(uint32_t msg_id, lv_obj_t * obj) +{ + uint32_t cnt = 0; + sub_dsc_t * s = _lv_ll_get_head(&subs_ll); + while(s) { + sub_dsc_t * s_next = _lv_ll_get_next(&subs_ll, s); + if(s->callback == obj_notify_cb && + (s->msg_id == LV_MSG_ID_ANY || s->msg_id == msg_id) && + (obj == NULL || s->_priv_data == obj)) { + lv_msg_unsubscribe(s); + cnt++; + } + + s = s_next; + } + + return cnt; +} + void lv_msg_send(uint32_t msg_id, const void * payload) { lv_msg_t m; @@ -129,8 +148,6 @@ lv_msg_t * lv_event_get_msg(lv_event_t * e) } } - - /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/liblvgl/extra/others/snapshot/lv_snapshot.c b/src/liblvgl/extra/others/snapshot/lv_snapshot.c index c17c12d..1b22751 100644 --- a/src/liblvgl/extra/others/snapshot/lv_snapshot.c +++ b/src/liblvgl/extra/others/snapshot/lv_snapshot.c @@ -10,8 +10,8 @@ #if LV_USE_SNAPSHOT #include -#include "liblvgl/core/lv_disp.h" -#include "liblvgl/core/lv_refr.h" +#include "../../../core/lv_disp.h" +#include "../../../core/lv_refr.h" /********************* * DEFINES *********************/ diff --git a/src/liblvgl/extra/themes/basic/lv_theme_basic.c b/src/liblvgl/extra/themes/basic/lv_theme_basic.c index 9c02232..d342455 100644 --- a/src/liblvgl/extra/themes/basic/lv_theme_basic.c +++ b/src/liblvgl/extra/themes/basic/lv_theme_basic.c @@ -6,12 +6,12 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" /*To see all the widgets*/ +#include "../../../lvgl.h" /*To see all the widgets*/ #if LV_USE_THEME_BASIC #include "lv_theme_basic.h" -#include "liblvgl/misc/lv_gc.h" +#include "../../../misc/lv_gc.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/themes/default/lv_theme_default.c b/src/liblvgl/extra/themes/default/lv_theme_default.c index 4a8a713..47392b0 100644 --- a/src/liblvgl/extra/themes/default/lv_theme_default.c +++ b/src/liblvgl/extra/themes/default/lv_theme_default.c @@ -6,12 +6,12 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" /*To see all the widgets*/ +#include "../../../lvgl.h" /*To see all the widgets*/ #if LV_USE_THEME_DEFAULT #include "lv_theme_default.h" -#include "liblvgl/misc/lv_gc.h" +#include "../../../misc/lv_gc.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/themes/mono/lv_theme_mono.c b/src/liblvgl/extra/themes/mono/lv_theme_mono.c index 365f52c..b249e76 100644 --- a/src/liblvgl/extra/themes/mono/lv_theme_mono.c +++ b/src/liblvgl/extra/themes/mono/lv_theme_mono.c @@ -6,12 +6,12 @@ /********************* * INCLUDES *********************/ -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_THEME_MONO #include "lv_theme_mono.h" -#include "liblvgl/misc/lv_gc.h" +#include "../../../misc/lv_gc.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/animimg/lv_animimg.c b/src/liblvgl/extra/widgets/animimg/lv_animimg.c index 03e8f7e..072d02e 100644 --- a/src/liblvgl/extra/widgets/animimg/lv_animimg.c +++ b/src/liblvgl/extra/widgets/animimg/lv_animimg.c @@ -14,13 +14,13 @@ #error "lv_animimg: lv_img is required. Enable it in lv_conf.h (LV_USE_IMG 1) " #endif -#include "liblvgl/misc/lv_assert.h" -#include "liblvgl/draw/lv_img_decoder.h" -#include "liblvgl/misc/lv_fs.h" -#include "liblvgl/misc/lv_txt.h" -#include "liblvgl/misc/lv_math.h" -#include "liblvgl/misc/lv_log.h" -#include "liblvgl/misc/lv_anim.h" +#include "../../../misc/lv_assert.h" +#include "../../../draw/lv_img_decoder.h" +#include "../../../misc/lv_fs.h" +#include "../../../misc/lv_txt.h" +#include "../../../misc/lv_math.h" +#include "../../../misc/lv_log.h" +#include "../../../misc/lv_anim.h" /********************* * DEFINES @@ -64,7 +64,7 @@ lv_obj_t * lv_animimg_create(lv_obj_t * parent) return obj; } -void lv_animimg_set_src(lv_obj_t * obj, lv_img_dsc_t * dsc[], uint8_t num) +void lv_animimg_set_src(lv_obj_t * obj, const void * dsc[], uint8_t num) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_animimg_t * animimg = (lv_animimg_t *)obj; diff --git a/src/liblvgl/extra/widgets/calendar/lv_calendar.c b/src/liblvgl/extra/widgets/calendar/lv_calendar.c index 8ac7794..b806d25 100644 --- a/src/liblvgl/extra/widgets/calendar/lv_calendar.c +++ b/src/liblvgl/extra/widgets/calendar/lv_calendar.c @@ -7,10 +7,10 @@ * INCLUDES *********************/ #include "lv_calendar.h" -#include "liblvgl/lvgl.h" +#include "../../../lvgl.h" #if LV_USE_CALENDAR -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/calendar/lv_calendar_header_arrow.c b/src/liblvgl/extra/widgets/calendar/lv_calendar_header_arrow.c index 88e01d1..fecb139 100644 --- a/src/liblvgl/extra/widgets/calendar/lv_calendar_header_arrow.c +++ b/src/liblvgl/extra/widgets/calendar/lv_calendar_header_arrow.c @@ -10,9 +10,9 @@ #if LV_USE_CALENDAR_HEADER_ARROW #include "lv_calendar.h" -#include "liblvgl/widgets/lv_btn.h" -#include "liblvgl/widgets/lv_label.h" -#include "liblvgl/extra/layouts/flex/lv_flex.h" +#include "../../../widgets/lv_btn.h" +#include "../../../widgets/lv_label.h" +#include "../../layouts/flex/lv_flex.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/calendar/lv_calendar_header_dropdown.c b/src/liblvgl/extra/widgets/calendar/lv_calendar_header_dropdown.c index 6ad56dc..5e8f90d 100644 --- a/src/liblvgl/extra/widgets/calendar/lv_calendar_header_dropdown.c +++ b/src/liblvgl/extra/widgets/calendar/lv_calendar_header_dropdown.c @@ -10,8 +10,8 @@ #if LV_USE_CALENDAR_HEADER_DROPDOWN #include "lv_calendar.h" -#include "liblvgl/widgets/lv_dropdown.h" -#include "liblvgl/extra/layouts/flex/lv_flex.h" +#include "../../../widgets/lv_dropdown.h" +#include "../../layouts/flex/lv_flex.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/chart/lv_chart.c b/src/liblvgl/extra/widgets/chart/lv_chart.c index e0bbbef..c5afb8b 100644 --- a/src/liblvgl/extra/widgets/chart/lv_chart.c +++ b/src/liblvgl/extra/widgets/chart/lv_chart.c @@ -9,7 +9,7 @@ #include "lv_chart.h" #if LV_USE_CHART != 0 -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES @@ -1182,7 +1182,6 @@ static void draw_series_bar(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx) const lv_area_t * clip_area_ori = draw_ctx->clip_area; draw_ctx->clip_area = &clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; uint16_t i; @@ -1200,6 +1199,7 @@ static void draw_series_bar(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx) int32_t ser_gap = ((int32_t)lv_obj_get_style_pad_column(obj, LV_PART_ITEMS) * chart->zoom_x) >> 8; /*Gap between the columns on the ~same X*/ lv_coord_t col_w = (block_w - (ser_cnt - 1) * ser_gap) / ser_cnt; + if(col_w < 1) col_w = 1; lv_coord_t border_w = lv_obj_get_style_border_width(obj, LV_PART_MAIN); lv_coord_t x_ofs = pad_left - lv_obj_get_scroll_left(obj) + border_w; @@ -1531,16 +1531,16 @@ static void draw_x_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis lv_coord_t label_gap; if(axis == LV_CHART_AXIS_PRIMARY_X) { label_gap = t->label_en ? lv_obj_get_style_pad_bottom(obj, LV_PART_TICKS) : 0; - y_ofs = obj->coords.y2; + y_ofs = obj->coords.y2 + 1; } else { label_gap = t->label_en ? lv_obj_get_style_pad_top(obj, LV_PART_TICKS) : 0; - y_ofs = obj->coords.y1; + y_ofs = obj->coords.y1 - 1; } if(axis == LV_CHART_AXIS_PRIMARY_X) { if(y_ofs > draw_ctx->clip_area->y2) return; - if(y_ofs + label_gap + label_dsc.font->line_height + t->major_len < draw_ctx->clip_area->y1) return; + if(y_ofs + label_gap + label_dsc.font->line_height + t->major_len < draw_ctx->clip_area->y1) return; } lv_draw_line_dsc_t line_dsc; @@ -1634,7 +1634,6 @@ static void draw_x_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_draw_dsc); } - if(p1.x + line_dsc.width / 2 >= obj->coords.x1 && p2.x - line_dsc.width / 2 <= obj->coords.x2) { lv_draw_line(draw_ctx, &line_dsc, &p1, &p2); diff --git a/src/liblvgl/extra/widgets/colorwheel/lv_colorwheel.c b/src/liblvgl/extra/widgets/colorwheel/lv_colorwheel.c index 4666775..daf112e 100644 --- a/src/liblvgl/extra/widgets/colorwheel/lv_colorwheel.c +++ b/src/liblvgl/extra/widgets/colorwheel/lv_colorwheel.c @@ -10,7 +10,7 @@ #include "lv_colorwheel.h" #if LV_USE_COLORWHEEL -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/keyboard/lv_keyboard.c b/src/liblvgl/extra/widgets/keyboard/lv_keyboard.c index eddfb6f..8e052e3 100644 --- a/src/liblvgl/extra/widgets/keyboard/lv_keyboard.c +++ b/src/liblvgl/extra/widgets/keyboard/lv_keyboard.c @@ -10,8 +10,8 @@ #include "lv_keyboard.h" #if LV_USE_KEYBOARD -#include "liblvgl/widgets/lv_textarea.h" -#include "liblvgl/misc/lv_assert.h" +#include "../../../widgets/lv_textarea.h" +#include "../../../misc/lv_assert.h" #include diff --git a/src/liblvgl/extra/widgets/led/lv_led.c b/src/liblvgl/extra/widgets/led/lv_led.c index fdee199..88b7b87 100644 --- a/src/liblvgl/extra/widgets/led/lv_led.c +++ b/src/liblvgl/extra/widgets/led/lv_led.c @@ -9,7 +9,7 @@ #include "lv_led.h" #if LV_USE_LED -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/list/lv_list.c b/src/liblvgl/extra/widgets/list/lv_list.c index 4ab10ac..29355fd 100644 --- a/src/liblvgl/extra/widgets/list/lv_list.c +++ b/src/liblvgl/extra/widgets/list/lv_list.c @@ -7,10 +7,10 @@ * INCLUDES *********************/ #include "lv_list.h" -#include "liblvgl/core/lv_disp.h" -#include "liblvgl/widgets/lv_label.h" -#include "liblvgl/widgets/lv_img.h" -#include "liblvgl/widgets/lv_btn.h" +#include "../../../core/lv_disp.h" +#include "../../../widgets/lv_label.h" +#include "../../../widgets/lv_img.h" +#include "../../../widgets/lv_btn.h" #if LV_USE_LIST diff --git a/src/liblvgl/extra/widgets/menu/lv_menu.c b/src/liblvgl/extra/widgets/menu/lv_menu.c index 378a114..78577e7 100644 --- a/src/liblvgl/extra/widgets/menu/lv_menu.c +++ b/src/liblvgl/extra/widgets/menu/lv_menu.c @@ -15,11 +15,11 @@ *********************/ #define MY_CLASS &lv_menu_class -#include "liblvgl/core/lv_obj.h" -#include "liblvgl/extra/layouts/flex/lv_flex.h" -#include "liblvgl/widgets/lv_label.h" -#include "liblvgl/widgets/lv_btn.h" -#include "liblvgl/widgets/lv_img.h" +#include "../../../core/lv_obj.h" +#include "../../layouts/flex/lv_flex.h" +#include "../../../widgets/lv_label.h" +#include "../../../widgets/lv_btn.h" +#include "../../../widgets/lv_img.h" /********************** * TYPEDEFS diff --git a/src/liblvgl/extra/widgets/meter/lv_meter.c b/src/liblvgl/extra/widgets/meter/lv_meter.c index 2cda1db..1e651b5 100644 --- a/src/liblvgl/extra/widgets/meter/lv_meter.c +++ b/src/liblvgl/extra/widgets/meter/lv_meter.c @@ -9,7 +9,7 @@ #include "lv_meter.h" #if LV_USE_METER != 0 -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES @@ -612,6 +612,7 @@ static void draw_needles(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, const lv_area if(angle > 3600) angle -= 3600; img_dsc.angle = angle; + part_draw_dsc.id = LV_METER_DRAW_PART_NEEDLE_IMG; part_draw_dsc.img_dsc = &img_dsc; lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_draw_dsc); diff --git a/src/liblvgl/extra/widgets/msgbox/lv_msgbox.c b/src/liblvgl/extra/widgets/msgbox/lv_msgbox.c index ae5fa83..8db5df7 100644 --- a/src/liblvgl/extra/widgets/msgbox/lv_msgbox.c +++ b/src/liblvgl/extra/widgets/msgbox/lv_msgbox.c @@ -9,7 +9,7 @@ #include "lv_msgbox.h" #if LV_USE_MSGBOX -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/span/lv_span.c b/src/liblvgl/extra/widgets/span/lv_span.c index 5f48235..96f0447 100644 --- a/src/liblvgl/extra/widgets/span/lv_span.c +++ b/src/liblvgl/extra/widgets/span/lv_span.c @@ -10,7 +10,7 @@ #if LV_USE_SPAN != 0 -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/spinbox/lv_spinbox.c b/src/liblvgl/extra/widgets/spinbox/lv_spinbox.c index b10607e..3469105 100644 --- a/src/liblvgl/extra/widgets/spinbox/lv_spinbox.c +++ b/src/liblvgl/extra/widgets/spinbox/lv_spinbox.c @@ -9,7 +9,7 @@ #include "lv_spinbox.h" #if LV_USE_SPINBOX -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/tabview/lv_tabview.c b/src/liblvgl/extra/widgets/tabview/lv_tabview.c index 9892e04..81addc6 100644 --- a/src/liblvgl/extra/widgets/tabview/lv_tabview.c +++ b/src/liblvgl/extra/widgets/tabview/lv_tabview.c @@ -9,7 +9,7 @@ #include "lv_tabview.h" #if LV_USE_TABVIEW -#include "liblvgl/misc/lv_assert.h" +#include "../../../misc/lv_assert.h" /********************* * DEFINES diff --git a/src/liblvgl/extra/widgets/tileview/lv_tileview.c b/src/liblvgl/extra/widgets/tileview/lv_tileview.c index 37def59..17fdb51 100644 --- a/src/liblvgl/extra/widgets/tileview/lv_tileview.c +++ b/src/liblvgl/extra/widgets/tileview/lv_tileview.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_tileview.h" -#include "liblvgl/core/lv_indev.h" +#include "../../../core/lv_indev.h" #if LV_USE_TILEVIEW /********************* diff --git a/src/liblvgl/font/lv_font.mk b/src/liblvgl/font/lv_font.mk new file mode 100644 index 0000000..2201b73 --- /dev/null +++ b/src/liblvgl/font/lv_font.mk @@ -0,0 +1,36 @@ +CSRCS += lv_font.c +CSRCS += lv_font_fmt_txt.c +CSRCS += lv_font_loader.c + +CSRCS += lv_font_dejavu_16_persian_hebrew.c +CSRCS += lv_font_montserrat_8.c +CSRCS += lv_font_montserrat_10.c +CSRCS += lv_font_montserrat_12.c +CSRCS += lv_font_montserrat_12_subpx.c +CSRCS += lv_font_montserrat_14.c +CSRCS += lv_font_montserrat_16.c +CSRCS += lv_font_montserrat_18.c +CSRCS += lv_font_montserrat_20.c +CSRCS += lv_font_montserrat_22.c +CSRCS += lv_font_montserrat_24.c +CSRCS += lv_font_montserrat_26.c +CSRCS += lv_font_montserrat_28.c +CSRCS += lv_font_montserrat_28_compressed.c +CSRCS += lv_font_montserrat_30.c +CSRCS += lv_font_montserrat_32.c +CSRCS += lv_font_montserrat_34.c +CSRCS += lv_font_montserrat_36.c +CSRCS += lv_font_montserrat_38.c +CSRCS += lv_font_montserrat_40.c +CSRCS += lv_font_montserrat_42.c +CSRCS += lv_font_montserrat_44.c +CSRCS += lv_font_montserrat_46.c +CSRCS += lv_font_montserrat_48.c +CSRCS += lv_font_simsun_16_cjk.c +CSRCS += lv_font_unscii_8.c +CSRCS += lv_font_unscii_16.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font" diff --git a/src/liblvgl/font/lv_font_dejavu_16_persian_hebrew.c b/src/liblvgl/font/lv_font_dejavu_16_persian_hebrew.c index c2a9891..4815755 100644 --- a/src/liblvgl/font/lv_font_dejavu_16_persian_hebrew.c +++ b/src/liblvgl/font/lv_font_dejavu_16_persian_hebrew.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_10.c b/src/liblvgl/font/lv_font_montserrat_10.c index 895fc98..9e8896b 100644 --- a/src/liblvgl/font/lv_font_montserrat_10.c +++ b/src/liblvgl/font/lv_font_montserrat_10.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_12.c b/src/liblvgl/font/lv_font_montserrat_12.c index 743e325..3880175 100644 --- a/src/liblvgl/font/lv_font_montserrat_12.c +++ b/src/liblvgl/font/lv_font_montserrat_12.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_12_subpx.c b/src/liblvgl/font/lv_font_montserrat_12_subpx.c index 201bb1b..b565c16 100644 --- a/src/liblvgl/font/lv_font_montserrat_12_subpx.c +++ b/src/liblvgl/font/lv_font_montserrat_12_subpx.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_14.c b/src/liblvgl/font/lv_font_montserrat_14.c index 5a6f5a3..739efcd 100644 --- a/src/liblvgl/font/lv_font_montserrat_14.c +++ b/src/liblvgl/font/lv_font_montserrat_14.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_16.c b/src/liblvgl/font/lv_font_montserrat_16.c index 3c83142..d7b6274 100644 --- a/src/liblvgl/font/lv_font_montserrat_16.c +++ b/src/liblvgl/font/lv_font_montserrat_16.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_18.c b/src/liblvgl/font/lv_font_montserrat_18.c index 361e21c..b80495b 100644 --- a/src/liblvgl/font/lv_font_montserrat_18.c +++ b/src/liblvgl/font/lv_font_montserrat_18.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_20.c b/src/liblvgl/font/lv_font_montserrat_20.c index 4120c5c..f5f4c9d 100644 --- a/src/liblvgl/font/lv_font_montserrat_20.c +++ b/src/liblvgl/font/lv_font_montserrat_20.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_22.c b/src/liblvgl/font/lv_font_montserrat_22.c index 654d05e..388bdea 100644 --- a/src/liblvgl/font/lv_font_montserrat_22.c +++ b/src/liblvgl/font/lv_font_montserrat_22.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_24.c b/src/liblvgl/font/lv_font_montserrat_24.c index c10ed6e..10d9b39 100644 --- a/src/liblvgl/font/lv_font_montserrat_24.c +++ b/src/liblvgl/font/lv_font_montserrat_24.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_26.c b/src/liblvgl/font/lv_font_montserrat_26.c index d0cb7e5..6279992 100644 --- a/src/liblvgl/font/lv_font_montserrat_26.c +++ b/src/liblvgl/font/lv_font_montserrat_26.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_28.c b/src/liblvgl/font/lv_font_montserrat_28.c index 7e57568..fab38d2 100644 --- a/src/liblvgl/font/lv_font_montserrat_28.c +++ b/src/liblvgl/font/lv_font_montserrat_28.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_28_compressed.c b/src/liblvgl/font/lv_font_montserrat_28_compressed.c index fded4b8..85f2cc6 100644 --- a/src/liblvgl/font/lv_font_montserrat_28_compressed.c +++ b/src/liblvgl/font/lv_font_montserrat_28_compressed.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_30.c b/src/liblvgl/font/lv_font_montserrat_30.c index 8bc42aa..7e5c275 100644 --- a/src/liblvgl/font/lv_font_montserrat_30.c +++ b/src/liblvgl/font/lv_font_montserrat_30.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_32.c b/src/liblvgl/font/lv_font_montserrat_32.c index d601fb9..cbec718 100644 --- a/src/liblvgl/font/lv_font_montserrat_32.c +++ b/src/liblvgl/font/lv_font_montserrat_32.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_34.c b/src/liblvgl/font/lv_font_montserrat_34.c index 7a82105..fc8c896 100644 --- a/src/liblvgl/font/lv_font_montserrat_34.c +++ b/src/liblvgl/font/lv_font_montserrat_34.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_36.c b/src/liblvgl/font/lv_font_montserrat_36.c index 303bce4..6d67b44 100644 --- a/src/liblvgl/font/lv_font_montserrat_36.c +++ b/src/liblvgl/font/lv_font_montserrat_36.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_38.c b/src/liblvgl/font/lv_font_montserrat_38.c index 3b80ec0..8bb5ad7 100644 --- a/src/liblvgl/font/lv_font_montserrat_38.c +++ b/src/liblvgl/font/lv_font_montserrat_38.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_40.c b/src/liblvgl/font/lv_font_montserrat_40.c index 1be41a4..6ac1b83 100644 --- a/src/liblvgl/font/lv_font_montserrat_40.c +++ b/src/liblvgl/font/lv_font_montserrat_40.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_42.c b/src/liblvgl/font/lv_font_montserrat_42.c index 5015c88..3151a17 100644 --- a/src/liblvgl/font/lv_font_montserrat_42.c +++ b/src/liblvgl/font/lv_font_montserrat_42.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_44.c b/src/liblvgl/font/lv_font_montserrat_44.c index a54359f..ec4b44b 100644 --- a/src/liblvgl/font/lv_font_montserrat_44.c +++ b/src/liblvgl/font/lv_font_montserrat_44.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_46.c b/src/liblvgl/font/lv_font_montserrat_46.c index 9747f5f..595f287 100644 --- a/src/liblvgl/font/lv_font_montserrat_46.c +++ b/src/liblvgl/font/lv_font_montserrat_46.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_48.c b/src/liblvgl/font/lv_font_montserrat_48.c index ab4ceb9..044dd46 100644 --- a/src/liblvgl/font/lv_font_montserrat_48.c +++ b/src/liblvgl/font/lv_font_montserrat_48.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_montserrat_8.c b/src/liblvgl/font/lv_font_montserrat_8.c index 7ccb99c..64812f2 100644 --- a/src/liblvgl/font/lv_font_montserrat_8.c +++ b/src/liblvgl/font/lv_font_montserrat_8.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_simsun_16_cjk.c b/src/liblvgl/font/lv_font_simsun_16_cjk.c index 5fbcdaa..e8e4618 100644 --- a/src/liblvgl/font/lv_font_simsun_16_cjk.c +++ b/src/liblvgl/font/lv_font_simsun_16_cjk.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_unscii_16.c b/src/liblvgl/font/lv_font_unscii_16.c index b290ee7..e9d4c10 100644 --- a/src/liblvgl/font/lv_font_unscii_16.c +++ b/src/liblvgl/font/lv_font_unscii_16.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/font/lv_font_unscii_8.c b/src/liblvgl/font/lv_font_unscii_8.c index ab35dfb..31975ff 100644 --- a/src/liblvgl/font/lv_font_unscii_8.c +++ b/src/liblvgl/font/lv_font_unscii_8.c @@ -5,7 +5,7 @@ ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "liblvgl/lvgl.h" + #include "lvgl.h" #else #include "liblvgl/lvgl.h" #endif diff --git a/src/liblvgl/hal/lv_hal.mk b/src/liblvgl/hal/lv_hal.mk new file mode 100644 index 0000000..c35ec2d --- /dev/null +++ b/src/liblvgl/hal/lv_hal.mk @@ -0,0 +1,8 @@ +CSRCS += lv_hal_disp.c +CSRCS += lv_hal_indev.c +CSRCS += lv_hal_tick.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal" diff --git a/src/liblvgl/hal/lv_hal_disp.c b/src/liblvgl/hal/lv_hal_disp.c index ea6a94c..14c51f5 100644 --- a/src/liblvgl/hal/lv_hal_disp.c +++ b/src/liblvgl/hal/lv_hal_disp.c @@ -23,9 +23,8 @@ #include "liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h" #include "liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h" #include "liblvgl/draw/arm2d/lv_gpu_arm2d.h" -#if LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE - #include "liblvgl/draw/nxp/lv_gpu_nxp.h" -#endif +#include "liblvgl/draw/nxp/vglite/lv_draw_vglite.h" +#include "liblvgl/draw/nxp/pxp/lv_draw_pxp.h" #if LV_USE_THEME_DEFAULT #include "liblvgl/extra/themes/default/lv_theme_default.h" @@ -85,8 +84,8 @@ void lv_disp_drv_init(lv_disp_drv_t * driver) { lv_memset_00(driver, sizeof(lv_disp_drv_t)); - driver->hor_res = LV_HOR_RES_MAX; - driver->ver_res = LV_VER_RES_MAX; + driver->hor_res = 320; + driver->ver_res = 240; driver->physical_hor_res = -1; driver->physical_ver_res = -1; driver->offset_x = 0; @@ -105,10 +104,14 @@ void lv_disp_drv_init(lv_disp_drv_t * driver) driver->draw_ctx_init = lv_draw_swm341_dma2d_ctx_init; driver->draw_ctx_deinit = lv_draw_swm341_dma2d_ctx_init; driver->draw_ctx_size = sizeof(lv_draw_swm341_dma2d_ctx_t); -#elif LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE - driver->draw_ctx_init = lv_draw_nxp_ctx_init; - driver->draw_ctx_deinit = lv_draw_nxp_ctx_deinit; - driver->draw_ctx_size = sizeof(lv_draw_nxp_ctx_t); +#elif LV_USE_GPU_NXP_VG_LITE + driver->draw_ctx_init = lv_draw_vglite_ctx_init; + driver->draw_ctx_deinit = lv_draw_vglite_ctx_deinit; + driver->draw_ctx_size = sizeof(lv_draw_vglite_ctx_t); +#elif LV_USE_GPU_NXP_PXP + driver->draw_ctx_init = lv_draw_pxp_ctx_init; + driver->draw_ctx_deinit = lv_draw_pxp_ctx_deinit; + driver->draw_ctx_size = sizeof(lv_draw_pxp_ctx_t); #elif LV_USE_GPU_SDL driver->draw_ctx_init = lv_draw_sdl_init_ctx; driver->draw_ctx_deinit = lv_draw_sdl_deinit_ctx; diff --git a/src/liblvgl/misc/lv_misc.mk b/src/liblvgl/misc/lv_misc.mk new file mode 100644 index 0000000..1dfd4ee --- /dev/null +++ b/src/liblvgl/misc/lv_misc.mk @@ -0,0 +1,26 @@ +CSRCS += lv_anim.c +CSRCS += lv_anim_timeline.c +CSRCS += lv_area.c +CSRCS += lv_async.c +CSRCS += lv_bidi.c +CSRCS += lv_color.c +CSRCS += lv_fs.c +CSRCS += lv_gc.c +CSRCS += lv_ll.c +CSRCS += lv_log.c +CSRCS += lv_lru.c +CSRCS += lv_math.c +CSRCS += lv_mem.c +CSRCS += lv_printf.c +CSRCS += lv_style.c +CSRCS += lv_style_gen.c +CSRCS += lv_timer.c +CSRCS += lv_tlsf.c +CSRCS += lv_txt.c +CSRCS += lv_txt_ap.c +CSRCS += lv_utils.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc" diff --git a/src/liblvgl/widgets/lv_arc.c b/src/liblvgl/widgets/lv_arc.c index e238907..a4c2a66 100644 --- a/src/liblvgl/widgets/lv_arc.c +++ b/src/liblvgl/widgets/lv_arc.c @@ -39,6 +39,7 @@ static void get_center(const lv_obj_t * obj, lv_point_t * center, lv_coord_t * a static lv_coord_t get_angle(const lv_obj_t * obj); static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area); static void value_update(lv_obj_t * arc); +static lv_coord_t knob_get_extra_size(lv_obj_t * obj); /********************** * STATIC VARIABLES @@ -600,8 +601,11 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_coord_t knob_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_KNOB); lv_coord_t knob_pad = LV_MAX4(knob_left, knob_right, knob_top, knob_bottom) + 2; + lv_coord_t knob_extra_size = knob_pad - bg_pad; + knob_extra_size += knob_get_extra_size(obj); + lv_coord_t * s = lv_event_get_param(e); - *s = LV_MAX(*s, knob_pad - bg_pad); + *s = LV_MAX(*s, knob_extra_size); } else if(code == LV_EVENT_DRAW_MAIN) { lv_arc_draw(e); @@ -716,6 +720,7 @@ static void inv_arc_area(lv_obj_t * obj, uint16_t start_angle, uint16_t end_angl lv_area_t inv_area; lv_draw_arc_get_area(c.x, c.y, r, start_angle, end_angle, w, rounded, &inv_area); + lv_obj_invalidate_area(obj, &inv_area); } @@ -727,6 +732,13 @@ static void inv_knob_area(lv_obj_t * obj) lv_area_t a; get_knob_area(obj, &c, r, &a); + + lv_coord_t knob_extra_size = knob_get_extra_size(obj); + + if(knob_extra_size > 0) { + lv_area_increase(&a, knob_extra_size, knob_extra_size); + } + lv_obj_invalidate_area(obj, &a); } @@ -841,4 +853,19 @@ static void value_update(lv_obj_t * obj) arc->last_angle = angle; /*Cache angle for slew rate limiting*/ } +static lv_coord_t knob_get_extra_size(lv_obj_t * obj) +{ + lv_coord_t knob_shadow_size = 0; + knob_shadow_size += lv_obj_get_style_shadow_width(obj, LV_PART_KNOB); + knob_shadow_size += lv_obj_get_style_shadow_spread(obj, LV_PART_KNOB); + knob_shadow_size += LV_ABS(lv_obj_get_style_shadow_ofs_x(obj, LV_PART_KNOB)); + knob_shadow_size += LV_ABS(lv_obj_get_style_shadow_ofs_y(obj, LV_PART_KNOB)); + + lv_coord_t knob_outline_size = 0; + knob_outline_size += lv_obj_get_style_outline_width(obj, LV_PART_KNOB); + knob_outline_size += lv_obj_get_style_outline_pad(obj, LV_PART_KNOB); + + return LV_MAX(knob_shadow_size, knob_outline_size); +} + #endif diff --git a/src/liblvgl/widgets/lv_bar.c b/src/liblvgl/widgets/lv_bar.c index 68c011f..07a54e1 100644 --- a/src/liblvgl/widgets/lv_bar.c +++ b/src/liblvgl/widgets/lv_bar.c @@ -571,6 +571,8 @@ static void lv_bar_set_value_with_anim(lv_obj_t * obj, int32_t new_value, int32_ _lv_bar_anim_t * anim_info, lv_anim_enable_t en) { if(en == LV_ANIM_OFF) { + lv_anim_del(anim_info, NULL); + anim_info->anim_state = LV_BAR_ANIM_STATE_INV; *value_ptr = new_value; lv_obj_invalidate((lv_obj_t *)obj); } diff --git a/src/liblvgl/widgets/lv_img.c b/src/liblvgl/widgets/lv_img.c index 31d9908..8b4963e 100644 --- a/src/liblvgl/widgets/lv_img.c +++ b/src/liblvgl/widgets/lv_img.c @@ -166,8 +166,6 @@ void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x) lv_img_t * img = (lv_img_t *)obj; - x = x % img->w; - img->offset.x = x; lv_obj_invalidate(obj); } @@ -178,15 +176,14 @@ void lv_img_set_offset_y(lv_obj_t * obj, lv_coord_t y) lv_img_t * img = (lv_img_t *)obj; - y = y % img->h; - img->offset.y = y; lv_obj_invalidate(obj); } void lv_img_set_angle(lv_obj_t * obj, int16_t angle) { - if(angle < 0 || angle >= 3600) angle = angle % 3600; + while(angle >= 3600) angle -= 3600; + while(angle < 0) angle += 3600; lv_img_t * img = (lv_img_t *)obj; if(angle == img->angle) return; @@ -659,12 +656,14 @@ static void draw_img(lv_event_t * e) draw_ctx->clip_area = &img_clip_area; lv_area_t coords_tmp; - coords_tmp.y1 = img_max_area.y1 + img->offset.y; + lv_coord_t offset_x = img->offset.x % img->w; + lv_coord_t offset_y = img->offset.y % img->h; + coords_tmp.y1 = img_max_area.y1 + offset_y; if(coords_tmp.y1 > img_max_area.y1) coords_tmp.y1 -= img->h; coords_tmp.y2 = coords_tmp.y1 + img->h - 1; for(; coords_tmp.y1 < img_max_area.y2; coords_tmp.y1 += img_size_final.y, coords_tmp.y2 += img_size_final.y) { - coords_tmp.x1 = img_max_area.x1 + img->offset.x; + coords_tmp.x1 = img_max_area.x1 + offset_x; if(coords_tmp.x1 > img_max_area.x1) coords_tmp.x1 -= img->w; coords_tmp.x2 = coords_tmp.x1 + img->w - 1; diff --git a/src/liblvgl/widgets/lv_roller.c b/src/liblvgl/widgets/lv_roller.c index d5552fe..54637be 100644 --- a/src/liblvgl/widgets/lv_roller.c +++ b/src/liblvgl/widgets/lv_roller.c @@ -477,6 +477,7 @@ static void draw_main(lv_event_t * e) area_ok = _lv_area_intersect(&mask_sel, draw_ctx->clip_area, &sel_area); if(area_ok) { lv_obj_t * label = get_label(obj); + if(lv_label_get_recolor(label)) label_dsc.flag |= LV_TEXT_FLAG_RECOLOR; /*Get the size of the "selected text"*/ lv_point_t res_p; @@ -529,6 +530,8 @@ static void draw_label(lv_event_t * e) lv_draw_label_dsc_t label_draw_dsc; lv_draw_label_dsc_init(&label_draw_dsc); lv_obj_init_draw_label_dsc(roller, LV_PART_MAIN, &label_draw_dsc); + if(lv_label_get_recolor(label_obj)) label_draw_dsc.flag |= LV_TEXT_FLAG_RECOLOR; + lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e); /*If the roller has shadow or outline it has some ext. draw size diff --git a/src/liblvgl/widgets/lv_slider.c b/src/liblvgl/widgets/lv_slider.c index b3df13c..56cd9f0 100644 --- a/src/liblvgl/widgets/lv_slider.c +++ b/src/liblvgl/widgets/lv_slider.c @@ -239,8 +239,12 @@ static void lv_slider_event(const lv_obj_class_t * class_p, lv_event_t * e) new_value = LV_CLAMP(real_min_value, new_value, real_max_value); if(*slider->value_to_set != new_value) { - *slider->value_to_set = new_value; - lv_obj_invalidate(obj); + if(slider->value_to_set == &slider->bar.start_value) { + lv_bar_set_start_value(obj, new_value, LV_ANIM_ON); + } + else { + lv_bar_set_value(obj, new_value, LV_ANIM_ON); + } res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return; } diff --git a/src/liblvgl/widgets/lv_table.c b/src/liblvgl/widgets/lv_table.c index eb9e40f..093530b 100644 --- a/src/liblvgl/widgets/lv_table.c +++ b/src/liblvgl/widgets/lv_table.c @@ -42,6 +42,7 @@ static lv_res_t get_pressed_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col) static size_t get_cell_txt_len(const char * txt); static void copy_cell_txt(char * dst, const char * txt); static void get_cell_area(lv_obj_t * obj, uint16_t row, uint16_t col, lv_area_t * area); +static void scroll_to_selected_cell(lv_obj_t * obj); static inline bool is_cell_empty(void * cell) { @@ -516,6 +517,7 @@ static void lv_table_event(const lv_obj_class_t * class_p, lv_event_t * e) if(col == LV_TABLE_CELL_NONE || row == LV_TABLE_CELL_NONE) { table->col_act = 0; table->row_act = 0; + scroll_to_selected_cell(obj); lv_obj_invalidate(obj); return; } @@ -560,6 +562,8 @@ static void lv_table_event(const lv_obj_class_t * class_p, lv_event_t * e) table->row_act = row; lv_obj_invalidate(obj); + scroll_to_selected_cell(obj); + res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return; } @@ -1004,4 +1008,26 @@ static void get_cell_area(lv_obj_t * obj, uint16_t row, uint16_t col, lv_area_t } + +static void scroll_to_selected_cell(lv_obj_t * obj) +{ + lv_table_t * table = (lv_table_t *)obj; + + lv_area_t a; + get_cell_area(obj, table->row_act, table->col_act, &a); + if(a.x1 < 0) { + lv_obj_scroll_by_bounded(obj, -a.x1, 0, LV_ANIM_ON); + } + else if(a.x2 > lv_obj_get_width(obj)) { + lv_obj_scroll_by_bounded(obj, lv_obj_get_width(obj) - a.x2, 0, LV_ANIM_ON); + } + + if(a.y1 < 0) { + lv_obj_scroll_by_bounded(obj, 0, -a.y1, LV_ANIM_ON); + } + else if(a.y2 > lv_obj_get_height(obj)) { + lv_obj_scroll_by_bounded(obj, 0, lv_obj_get_height(obj) - a.y2, LV_ANIM_ON); + } + +} #endif diff --git a/src/liblvgl/widgets/lv_widgets.mk b/src/liblvgl/widgets/lv_widgets.mk new file mode 100644 index 0000000..4e62dc5 --- /dev/null +++ b/src/liblvgl/widgets/lv_widgets.mk @@ -0,0 +1,20 @@ +CSRCS += lv_arc.c +CSRCS += lv_bar.c +CSRCS += lv_btn.c +CSRCS += lv_btnmatrix.c +CSRCS += lv_canvas.c +CSRCS += lv_checkbox.c +CSRCS += lv_dropdown.c +CSRCS += lv_img.c +CSRCS += lv_label.c +CSRCS += lv_line.c +CSRCS += lv_roller.c +CSRCS += lv_slider.c +CSRCS += lv_switch.c +CSRCS += lv_table.c +CSRCS += lv_textarea.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets"