From 24c2921c2194bffae40d99be627f38eb00339200 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 21 Aug 2020 09:52:13 -0400 Subject: [PATCH 1/4] lv_disp: add `clean_dcache_cb` callback --- src/lv_core/lv_disp.c | 15 +++++++++++++++ src/lv_core/lv_disp.h | 6 ++++++ src/lv_gpu/lv_gpu_stm32_dma2d.c | 19 +++++-------------- src/lv_hal/lv_hal_disp.h | 3 +++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index 6cf6283ef..0cdb7dc28 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -352,6 +352,21 @@ void lv_disp_trig_activity(lv_disp_t * disp) disp->last_activity_time = lv_tick_get(); } +/** + * Invalidate any CPU cache that is related to the display. + * @param disp pointer to an display (NULL to use the default display) + */ +void lv_disp_invalidate_cache(lv_disp_t * disp) +{ + if(!disp) disp = lv_disp_get_default(); + if(!disp) { + LV_LOG_WARN("lv_disp_invalidate_cache: no display registered"); + return; + } + + if(disp->driver.clean_dcache_cb) + disp->driver.clean_dcache_cb(&disp->driver); +} /** * Get a pointer to the screen refresher task to diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index 888a0c093..8eb571d38 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -133,6 +133,12 @@ uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp); */ void lv_disp_trig_activity(lv_disp_t * disp); +/** + * Invalidate any CPU cache that is related to the display. + * @param disp pointer to an display (NULL to use the default display) + */ +void lv_disp_invalidate_cache(lv_disp_t * disp); + /** * Get a pointer to the screen refresher task to * modify its parameters with `lv_task_...` functions. diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.c b/src/lv_gpu/lv_gpu_stm32_dma2d.c index d5c8e40dc..0e09016e7 100644 --- a/src/lv_gpu/lv_gpu_stm32_dma2d.c +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_gpu_stm32_dma2d.h" +#include "../lv_core/lv_disp.h" #include "../lv_core/lv_refr.h" #if LV_USE_GPU_STM32_DMA2D @@ -41,7 +42,6 @@ /********************** * STATIC PROTOTYPES **********************/ -static void invalidate_cache(void); static void dma2d_wait(void); /********************** @@ -82,7 +82,7 @@ void lv_gpu_stm32_dma2d_init(void) */ 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) { - invalidate_cache(); + lv_disp_invalidate_cache(NULL); DMA2D->CR = 0x30000; DMA2D->OMAR = (uint32_t)buf; @@ -112,7 +112,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h) { #if 0 - invalidate_cache(); + lv_disp_invalidate_cache(NULL); /* Configure the DMA2D Mode, Color Mode and line output offset */ hdma2d.Init.Mode = DMA2D_M2M_BLEND; @@ -156,7 +156,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t void lv_gpu_stm32_dma2d_copy(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) { - invalidate_cache(); + lv_disp_invalidate_cache(NULL); DMA2D->CR = 0; /* copy output colour mode, this register controls both input and output colour format */ @@ -186,7 +186,7 @@ void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_ void lv_gpu_stm32_dma2d_blend(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) { - invalidate_cache(); + lv_disp_invalidate_cache(NULL); DMA2D->CR = 0x20000; DMA2D->BGPFCCR = LV_DMA2D_COLOR_FORMAT; @@ -214,15 +214,6 @@ void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color * STATIC FUNCTIONS **********************/ -static void invalidate_cache(void) -{ -#if __DCACHE_PRESENT - if(SCB->CCR & (uint32_t)SCB_CCR_DC_Msk) { - SCB_CleanInvalidateDCache(); - } -#endif -} - static void dma2d_wait(void) { lv_disp_t * disp = _lv_refr_get_disp_refreshing(); diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index e99830b19..04ea3efdf 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -111,6 +111,9 @@ typedef struct _disp_drv_t { * User can execute very simple tasks here or yield the task */ void (*wait_cb)(struct _disp_drv_t * disp_drv); + /** OPTIONAL: Called when lvgl needs any CPU cache that affects rendering to be cleaned */ + void (*clean_dcache_cb)(struct _disp_drv_t * disp_drv); + #if LV_USE_GPU /** OPTIONAL: Blend two memories using opacity (GPU only)*/ void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, From 36433c2144e2738314399105d5866dcd8970d9c0 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Mon, 24 Aug 2020 07:36:44 -0400 Subject: [PATCH 2/4] Rename function to `lv_disp_clean_dcache` and use currently refreshing display --- src/lv_core/lv_disp.c | 6 +++--- src/lv_core/lv_disp.h | 4 ++-- src/lv_gpu/lv_gpu_stm32_dma2d.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index 0cdb7dc28..2b24c1d0b 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -353,14 +353,14 @@ void lv_disp_trig_activity(lv_disp_t * disp) } /** - * Invalidate any CPU cache that is related to the display. + * Clean any CPU cache that is related to the display. * @param disp pointer to an display (NULL to use the default display) */ -void lv_disp_invalidate_cache(lv_disp_t * disp) +void lv_disp_clean_dcache(lv_disp_t * disp) { if(!disp) disp = lv_disp_get_default(); if(!disp) { - LV_LOG_WARN("lv_disp_invalidate_cache: no display registered"); + LV_LOG_WARN("lv_disp_clean_dcache: no display registered"); return; } diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index 8eb571d38..3083c46d2 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -134,10 +134,10 @@ uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp); void lv_disp_trig_activity(lv_disp_t * disp); /** - * Invalidate any CPU cache that is related to the display. + * Clean any CPU cache that is related to the display. * @param disp pointer to an display (NULL to use the default display) */ -void lv_disp_invalidate_cache(lv_disp_t * disp); +void lv_disp_clean_dcache(lv_disp_t * disp); /** * Get a pointer to the screen refresher task to diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.c b/src/lv_gpu/lv_gpu_stm32_dma2d.c index 0e09016e7..205b3d645 100644 --- a/src/lv_gpu/lv_gpu_stm32_dma2d.c +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.c @@ -82,7 +82,7 @@ void lv_gpu_stm32_dma2d_init(void) */ 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) { - lv_disp_invalidate_cache(NULL); + lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); DMA2D->CR = 0x30000; DMA2D->OMAR = (uint32_t)buf; @@ -112,7 +112,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h) { #if 0 - lv_disp_invalidate_cache(NULL); + lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); /* Configure the DMA2D Mode, Color Mode and line output offset */ hdma2d.Init.Mode = DMA2D_M2M_BLEND; @@ -156,7 +156,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t void lv_gpu_stm32_dma2d_copy(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) { - lv_disp_invalidate_cache(NULL); + lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); DMA2D->CR = 0; /* copy output colour mode, this register controls both input and output colour format */ @@ -186,7 +186,7 @@ void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_ void lv_gpu_stm32_dma2d_blend(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) { - lv_disp_invalidate_cache(NULL); + lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); DMA2D->CR = 0x20000; DMA2D->BGPFCCR = LV_DMA2D_COLOR_FORMAT; From 7ca806ddff3820dee844ef53e297b0ac32dbaf3f Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Mon, 24 Aug 2020 10:51:09 -0400 Subject: [PATCH 3/4] Use CMSIS cache functions if custom callback is not registered --- src/lv_gpu/lv_gpu_stm32_dma2d.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.c b/src/lv_gpu/lv_gpu_stm32_dma2d.c index 205b3d645..f11c4c6a4 100644 --- a/src/lv_gpu/lv_gpu_stm32_dma2d.c +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.c @@ -42,6 +42,7 @@ /********************** * STATIC PROTOTYPES **********************/ +static void invalidate_cache(void); static void dma2d_wait(void); /********************** @@ -82,7 +83,7 @@ void lv_gpu_stm32_dma2d_init(void) */ 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) { - lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); + invalidate_cache(); DMA2D->CR = 0x30000; DMA2D->OMAR = (uint32_t)buf; @@ -112,7 +113,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t lv_opa_t opa, lv_coord_t fill_w, lv_coord_t fill_h) { #if 0 - lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); + invalidate_cache(); /* Configure the DMA2D Mode, Color Mode and line output offset */ hdma2d.Init.Mode = DMA2D_M2M_BLEND; @@ -156,7 +157,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t void lv_gpu_stm32_dma2d_copy(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) { - lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); + invalidate_cache(); DMA2D->CR = 0; /* copy output colour mode, this register controls both input and output colour format */ @@ -186,7 +187,7 @@ void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_ void lv_gpu_stm32_dma2d_blend(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) { - lv_disp_clean_dcache(_lv_refr_get_disp_refreshing()); + invalidate_cache(); DMA2D->CR = 0x20000; DMA2D->BGPFCCR = LV_DMA2D_COLOR_FORMAT; @@ -214,6 +215,14 @@ void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color * STATIC FUNCTIONS **********************/ +static 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); + else + SCB_CleanInvalidateDCache(); +} + static void dma2d_wait(void) { lv_disp_t * disp = _lv_refr_get_disp_refreshing(); From 350269c3d43e05f1ea3d1a184684a5ef0b909c6c Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Tue, 25 Aug 2020 07:38:08 -0400 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83ca3fe6f..5f0863028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Add `lv_font_load()` function - Loads a `lv_font_t` object from a binary font file - Add `lv_font_free()` function - Frees the memory allocated by the `lv_font_load()` function - Add style caching to reduce acces time of properties with default value +- Add `clean_dcache_cb` and `lv_disp_clean_dcache` to enable users to use their own cache management function ### Bugfixes - Fix color bleeding on border drawing