diff --git a/lvgl.mk b/lvgl.mk index 0c578a810..bbea98d35 100644 --- a/lvgl.mk +++ b/lvgl.mk @@ -5,5 +5,6 @@ include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_font/lv_font.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_misc/lv_misc.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_themes/lv_themes.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_draw/lv_draw.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_gpu/lv_gpu.mk diff --git a/src/lv_draw/lv_draw_blend.c b/src/lv_draw/lv_draw_blend.c index e754a1ba5..8b1c781f3 100644 --- a/src/lv_draw/lv_draw_blend.c +++ b/src/lv_draw/lv_draw_blend.c @@ -11,30 +11,14 @@ #include "../lv_misc/lv_math.h" #include "../lv_hal/lv_hal_disp.h" #include "../lv_core/lv_refr.h" -#include LV_GPU_INCLUDE -static DMA2D_HandleTypeDef hdma2d; +#include "../lv_gpu/lv_gpu_stm32_dma2d.h" /********************* * DEFINES *********************/ #define GPU_SIZE_LIMIT 240 -#if LV_USE_GPU_STM32_DMA2D -#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP -#define DMA2D_OUTPUT_FORMAT DMA2D_OUTPUT_RGB565 -#define DMA2D_INPUT_FORMAT DMA2D_INPUT_RGB565 -#elif LV_COLOR_DEPTH == 32 -#define DMA2D_OUTPUT_FORMAT DMA2D_OUTPUT_ARGB8888 -#define DMA2D_INPUT_FORMAT DMA2D_INPUT_ARGB8888 -#else -/*Can't use GPU with other formats*/ -#undef LV_USE_GPU_STM32_DMA2D -#endif -#endif - -//#undef LV_USE_GPU_STM32_CHROM_ART - /********************** * TYPEDEFS **********************/ @@ -332,24 +316,7 @@ static void fill_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, con } #if LV_USE_GPU_STM32_DMA2D if(lv_area_get_size(draw_area) >= 240) { -#if __DCACHE_PRESENT - SCB_CleanInvalidateDCache(); -#endif - hdma2d.Instance = DMA2D; - hdma2d.Init.Mode = DMA2D_R2M; - hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; - hdma2d.Init.OutputOffset = disp_w - draw_area_w; - hdma2d.LayerCfg[1].InputAlpha = DMA2D_NO_MODIF_ALPHA; - hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT; - hdma2d.LayerCfg[1].InputOffset = 0; - - /* DMA2D Initialization */ - if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { - if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { - HAL_DMA2D_Start(&hdma2d, (uint32_t)lv_color_to32(color), (uint32_t)disp_buf_first, draw_area_w, draw_area_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); - } - } + lv_gpu_stm32_dma2d_fill(disp_buf_first, disp_w, color, draw_area_w, draw_area_h); return; } #endif @@ -405,39 +372,10 @@ static void fill_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, con } /*Masked*/ else { - /*DMA2D could be used here but it's much slower than software rendering*/ #if LV_USE_GPU_STM32_DMA2D && 0 if(lv_area_get_size(draw_area) > 240) { -#if __DCACHE_PRESENT - SCB_CleanInvalidateDCache(); -#endif - /* Configure the DMA2D Mode, Color Mode and line output offset */ - hdma2d.Init.Mode = DMA2D_M2M_BLEND; - hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; - hdma2d.Init.OutputOffset = disp_w - draw_area_w; - - /* Configure the foreground -> The character */ - lv_color32_t c32; - c32.full = lv_color_to32(color); - c32.ch.alpha = opa; - hdma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA; - hdma2d.LayerCfg[1].InputAlpha = c32.full; - hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_A8; - hdma2d.LayerCfg[1].InputOffset = 0; - - /* Configure the background -> Display buffer */ - hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA; - hdma2d.LayerCfg[0].InputAlpha = 0x00; - hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_FORMAT; - hdma2d.LayerCfg[0].InputOffset = disp_w - draw_area_w; - - /* DMA2D Initialization */ - HAL_DMA2D_Init(&hdma2d); - HAL_DMA2D_ConfigLayer(&hdma2d, 0); - HAL_DMA2D_ConfigLayer(&hdma2d, 1); - HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t) mask, (uint32_t) disp_buf_first, (uint32_t)disp_buf_first, draw_area_w, draw_area_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); + lv_gpu_stm32_dma2d_fill_mask(disp_buf_first, disp_w, color, mask, opa, draw_area_w, draw_area_h); return; } #endif @@ -749,29 +687,7 @@ static void map_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, cons if(opa > LV_OPA_MAX) { #if LV_USE_GPU_STM32_DMA2D if(lv_area_get_size(draw_area) >= 240) { -#if __DCACHE_PRESENT - SCB_CleanInvalidateDCache(); -#endif - hdma2d.Instance = DMA2D; - hdma2d.Init.Mode = DMA2D_M2M; - hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; - hdma2d.Init.OutputOffset = disp_w - draw_area_w; - - /* Foreground layer */ - hdma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA; - hdma2d.LayerCfg[1].InputAlpha = opa; - hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT; - hdma2d.LayerCfg[1].InputOffset = map_w - draw_area_w; - hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; - - /* DMA2D Initialization */ - if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { - HAL_DMA2D_ConfigLayer(&hdma2d, 0); - if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { - HAL_DMA2D_Start(&hdma2d, (uint32_t)map_buf_first, (uint32_t)disp_buf_first, draw_area_w, draw_area_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); - } - } + lv_gpu_stm32_dma2d_blend_normal_cover(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h); return; } #endif @@ -785,36 +701,8 @@ static void map_normal(const lv_area_t * disp_area, lv_color_t * disp_buf, cons } else { #if LV_USE_GPU_STM32_DMA2D - if(lv_area_get_size(draw_area) >= 256) { -#if __DCACHE_PRESENT - SCB_CleanInvalidateDCache(); -#endif - hdma2d.Instance = DMA2D; - hdma2d.Init.Mode = DMA2D_M2M_BLEND; - hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; - hdma2d.Init.OutputOffset = disp_w - draw_area_w; - - /* Background layer */ - hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA; - hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_FORMAT; - hdma2d.LayerCfg[0].InputOffset = disp_w - draw_area_w; - hdma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA; - - /* Foreground layer */ - hdma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA; - hdma2d.LayerCfg[1].InputAlpha = opa; - hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT; - hdma2d.LayerCfg[1].InputOffset = map_w - draw_area_w; - hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; - - /* DMA2D Initialization */ - if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { - HAL_DMA2D_ConfigLayer(&hdma2d, 0); - if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { - HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t)map_buf_first, (uint32_t)disp_buf_first, (uint32_t)disp_buf_first, draw_area_w, draw_area_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); - } - } + if(lv_area_get_size(draw_area) >= 240) { + lv_gpu_stm32_dma2d_blend_normal_opa(disp_buf_first, disp_w, map_buf_first, opa, map_w, draw_area_w, draw_area_h); return; } #endif diff --git a/src/lv_gpu/lv_draw.mk b/src/lv_gpu/lv_draw.mk new file mode 100644 index 000000000..cff89c686 --- /dev/null +++ b/src/lv_gpu/lv_draw.mk @@ -0,0 +1,6 @@ +CSRCS += lv_gpu_stm32_dma2d.c + +DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_gpu +VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_gpu + +CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/lv_gpu" diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.c b/src/lv_gpu/lv_gpu_stm32_dma2d.c new file mode 100644 index 000000000..77cda0b5b --- /dev/null +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.c @@ -0,0 +1,168 @@ +/** + * @file lv_gpu_stm32_dma2d.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_gpu_stm32_dma2d.h" + +#if LV_USE_GPU_STM32_DMA2D +#include "stm32f7xx_hal.h" + +/********************* + * DEFINES + *********************/ + +#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP +#define DMA2D_OUTPUT_FORMAT DMA2D_OUTPUT_RGB565 +#define DMA2D_INPUT_FORMAT DMA2D_INPUT_RGB565 +#elif LV_COLOR_DEPTH == 32 +#define DMA2D_OUTPUT_FORMAT DMA2D_OUTPUT_ARGB8888 +#define DMA2D_INPUT_FORMAT DMA2D_INPUT_ARGB8888 +#else +/*Can't use GPU with other formats*/ +#undef LV_USE_GPU_STM32_DMA2D +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static DMA2D_HandleTypeDef hdma2d; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, lv_coord_t fill_w, lv_coord_t fill_h) +{ +#if __DCACHE_PRESENT + SCB_CleanInvalidateDCache(); +#endif + hdma2d.Instance = DMA2D; + hdma2d.Init.Mode = DMA2D_R2M; + hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; + hdma2d.Init.OutputOffset = buf_w - fill_w; + hdma2d.LayerCfg[1].InputAlpha = DMA2D_NO_MODIF_ALPHA; + hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT; + hdma2d.LayerCfg[1].InputOffset = 0; + + /* DMA2D Initialization */ + if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { + if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { + HAL_DMA2D_Start(&hdma2d, (uint32_t)lv_color_to32(color), (uint32_t)buf, fill_w, fill_h); + HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); + } + } +} + +void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, const lv_opa_t * mask, lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h) +{ +#if __DCACHE_PRESENT + SCB_CleanInvalidateDCache(); +#endif + /* Configure the DMA2D Mode, Color Mode and line output offset */ + hdma2d.Init.Mode = DMA2D_M2M_BLEND; + hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; + hdma2d.Init.OutputOffset = buf_w - fill_w; + + /* Configure the foreground -> The character */ + lv_color32_t c32; + c32.full = lv_color_to32(color); + c32.ch.alpha = opa; + hdma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA; + hdma2d.LayerCfg[1].InputAlpha = c32.full; + hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_A8; + hdma2d.LayerCfg[1].InputOffset = 0; + + /* Configure the background -> Display buffer */ + hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA; + hdma2d.LayerCfg[0].InputAlpha = 0x00; + hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_FORMAT; + hdma2d.LayerCfg[0].InputOffset = buf_w - fill_w; + + /* DMA2D Initialization */ + HAL_DMA2D_Init(&hdma2d); + HAL_DMA2D_ConfigLayer(&hdma2d, 0); + HAL_DMA2D_ConfigLayer(&hdma2d, 1); + HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t) mask, (uint32_t) buf, (uint32_t)buf, fill_w, fill_h); + HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); +} + +void lv_gpu_stm32_dma2d_blend_normal_cover(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h) +{ +#if __DCACHE_PRESENT + SCB_CleanInvalidateDCache(); +#endif + hdma2d.Instance = DMA2D; + hdma2d.Init.Mode = DMA2D_M2M; + hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; + hdma2d.Init.OutputOffset = buf_w - copy_w; + + /* Foreground layer */ + hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; + hdma2d.LayerCfg[1].InputAlpha = 0xFF; + hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT; + hdma2d.LayerCfg[1].InputOffset = map_w - copy_w; + hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; + + /* DMA2D Initialization */ + if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { + HAL_DMA2D_ConfigLayer(&hdma2d, 0); + if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { + HAL_DMA2D_Start(&hdma2d, (uint32_t)map, (uint32_t)buf, copy_w, copy_h); + HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); + } + } +} + +void lv_gpu_stm32_dma2d_blend_normal_opa(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_opa_t opa, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h) +{ +#if __DCACHE_PRESENT + SCB_CleanInvalidateDCache(); +#endif + hdma2d.Instance = DMA2D; + hdma2d.Init.Mode = DMA2D_M2M_BLEND; + hdma2d.Init.ColorMode = DMA2D_OUTPUT_FORMAT; + hdma2d.Init.OutputOffset = buf_w - copy_w; + + /* Background layer */ + hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA; + hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_FORMAT; + hdma2d.LayerCfg[0].InputOffset = buf_w - copy_w; + hdma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA; + + /* Foreground layer */ + hdma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA; + hdma2d.LayerCfg[1].InputAlpha = opa; + hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_FORMAT; + hdma2d.LayerCfg[1].InputOffset = map_w - copy_w; + hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; + + /* DMA2D Initialization */ + if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { + HAL_DMA2D_ConfigLayer(&hdma2d, 0); + if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { + HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t)map, (uint32_t)buf, (uint32_t)buf, copy_w, copy_h); + HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); + } + } +} +/********************** + * STATIC FUNCTIONS + **********************/ + + +#endif diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.h b/src/lv_gpu/lv_gpu_stm32_dma2d.h new file mode 100644 index 000000000..5a6985af7 --- /dev/null +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.h @@ -0,0 +1,43 @@ +/** + * @file lv_gpu_stm32_dma2d.h + * + */ + +#ifndef LV_GPU_STM32_DMA2D_H +#define LV_GPU_STM32_DMA2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_misc/lv_area.h" +#include "../lv_misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, lv_coord_t fill_w, lv_coord_t fill_h); +void lv_gpu_stm32_dma2d_blend_normal_cover(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h); +void lv_gpu_stm32_dma2d_blend_normal_opa(lv_color_t * buf, lv_coord_t buf_w, const lv_color_t * map, lv_opa_t opa, lv_coord_t map_w, lv_coord_t copy_w, lv_coord_t copy_h); +void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t color, const lv_opa_t * mask, lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_GPU_STM32_DMA2D_H*/