From d151a6789fec0c804fb766558fdb3cb8bf5f3bf8 Mon Sep 17 00:00:00 2001 From: _VIFEXTech <1290176185@qq.com> Date: Fri, 27 May 2022 04:46:55 +0800 Subject: [PATCH] feat(disp): add a temporary invalidation disable interface (#3378) * feat(disp): add a temporary disable invalidation interface * minor adjustments * remove forgotten comment Co-authored-by: pengyiqiang Co-authored-by: Gabor Kiss-Vamosi --- src/core/lv_disp.c | 32 ++++++++++++++++++++++++++++++++ src/core/lv_disp.h | 14 ++++++++++++++ src/core/lv_obj_pos.c | 3 +++ src/core/lv_refr.c | 1 + src/hal/lv_hal_disp.c | 2 ++ src/hal/lv_hal_disp.h | 1 + src/widgets/lv_img.c | 19 +++++++++++++++++++ 7 files changed, 72 insertions(+) diff --git a/src/core/lv_disp.c b/src/core/lv_disp.c index 06f83e011..a1022b56c 100644 --- a/src/core/lv_disp.c +++ b/src/core/lv_disp.c @@ -413,6 +413,38 @@ void lv_disp_clean_dcache(lv_disp_t * disp) disp->driver->clean_dcache_cb(disp->driver); } +/** + * Temporarily enable and disable the invalidation of the display. + * @param disp pointer to a display (NULL to use the default display) + * @param en true: enable invalidation; false: invalidation + */ +void lv_disp_enable_invalidation(lv_disp_t * disp, bool en) +{ + if(!disp) disp = lv_disp_get_default(); + if(!disp) { + LV_LOG_WARN("no display registered"); + return; + } + + disp->inv_en_cnt += en ? 1 : -1; +} + +/** + * Get display invalidation is enabled. + * @param disp pointer to a display (NULL to use the default display) + * @return return true if invalidation is enabled + */ +bool lv_disp_is_invalidation_enabled(lv_disp_t * disp) +{ + if(!disp) disp = lv_disp_get_default(); + if(!disp) { + LV_LOG_WARN("no display registered"); + return false; + } + + return (disp->inv_en_cnt > 0); +} + /** * Get a pointer to the screen refresher timer to * modify its parameters with `lv_timer_...` functions. diff --git a/src/core/lv_disp.h b/src/core/lv_disp.h index 3b58e6237..7854cb7f2 100644 --- a/src/core/lv_disp.h +++ b/src/core/lv_disp.h @@ -148,6 +148,20 @@ void lv_disp_trig_activity(lv_disp_t * disp); */ void lv_disp_clean_dcache(lv_disp_t * disp); +/** + * Temporarily enable and disable the invalidation of the display. + * @param disp pointer to a display (NULL to use the default display) + * @param en true: enable invalidation; false: invalidation + */ +void lv_disp_enable_invalidation(lv_disp_t * disp, bool en); + +/** + * Get display invalidation is enabled. + * @param disp pointer to a display (NULL to use the default display) + * @return return true if invalidation is enabled + */ +bool lv_disp_is_invalidation_enabled(lv_disp_t * disp); + /** * Get a pointer to the screen refresher timer to * modify its parameters with `lv_timer_...` functions. diff --git a/src/core/lv_obj_pos.c b/src/core/lv_obj_pos.c index 03951cb2c..a31c11db8 100644 --- a/src/core/lv_obj_pos.c +++ b/src/core/lv_obj_pos.c @@ -838,6 +838,9 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area) { LV_ASSERT_OBJ(obj, MY_CLASS); + lv_disp_t * disp = lv_obj_get_disp(obj); + if(!lv_disp_is_invalidation_enabled(disp)) return; + lv_area_t area_tmp; lv_area_copy(&area_tmp, area); if(!lv_obj_area_is_visible(obj, &area_tmp)) return; diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 09a30282d..f6e3d4169 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -206,6 +206,7 @@ void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p) { if(!disp) disp = lv_disp_get_default(); if(!disp) return; + if(!lv_disp_is_invalidation_enabled(disp)) return; if(disp->rendering_in_progress) { LV_LOG_ERROR("detected modifying dirty areas in render"); diff --git a/src/hal/lv_hal_disp.c b/src/hal/lv_hal_disp.c index a9ea0de8e..0dd8f6b30 100644 --- a/src/hal/lv_hal_disp.c +++ b/src/hal/lv_hal_disp.c @@ -177,6 +177,8 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver) disp->driver = driver; + disp->inv_en_cnt = 1; + lv_disp_t * disp_def_tmp = disp_def; disp_def = disp; /*Temporarily change the default screen to create the default screens on the new display*/ diff --git a/src/hal/lv_hal_disp.h b/src/hal/lv_hal_disp.h index 75ddd869f..d3425fe4e 100644 --- a/src/hal/lv_hal_disp.h +++ b/src/hal/lv_hal_disp.h @@ -187,6 +187,7 @@ uint8_t del_prev : lv_area_t inv_areas[LV_INV_BUF_SIZE]; uint8_t inv_area_joined[LV_INV_BUF_SIZE]; uint16_t inv_p; + int32_t inv_en_cnt; /*Miscellaneous data*/ uint32_t last_activity_time; /**< Last time when there was activity on this display*/ diff --git a/src/widgets/lv_img.c b/src/widgets/lv_img.c index b6df70807..f47a789e7 100644 --- a/src/widgets/lv_img.c +++ b/src/widgets/lv_img.c @@ -9,6 +9,7 @@ #include "lv_img.h" #if LV_USE_IMG != 0 +#include "../core/lv_disp.h" #include "../misc/lv_assert.h" #include "../draw/lv_img_decoder.h" #include "../misc/lv_fs.h" @@ -202,7 +203,13 @@ void lv_img_set_angle(lv_obj_t * obj, int16_t angle) lv_obj_invalidate_area(obj, &a); img->angle = angle; + + /* Disable invalidations because lv_obj_refresh_ext_draw_size would invalidate + * the whole ext draw area */ + lv_disp_t * disp = lv_obj_get_disp(obj); + lv_disp_enable_invalidation(disp, false); lv_obj_refresh_ext_draw_size(obj); + lv_disp_enable_invalidation(disp, true); _lv_img_buf_get_transformed_area(&a, w, h, img->angle, img->zoom, &img->pivot); a.x1 += obj->coords.x1; @@ -230,7 +237,13 @@ void lv_img_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) img->pivot.x = x; img->pivot.y = y; + + /* Disable invalidations because lv_obj_refresh_ext_draw_size would invalidate + * the whole ext draw area */ + lv_disp_t * disp = lv_obj_get_disp(obj); + lv_disp_enable_invalidation(disp, false); lv_obj_refresh_ext_draw_size(obj); + lv_disp_enable_invalidation(disp, true); _lv_img_buf_get_transformed_area(&a, w, h, img->angle, img->zoom, &img->pivot); a.x1 += obj->coords.x1; @@ -259,7 +272,13 @@ void lv_img_set_zoom(lv_obj_t * obj, uint16_t zoom) lv_obj_invalidate_area(obj, &a); img->zoom = zoom; + + /* Disable invalidations because lv_obj_refresh_ext_draw_size would invalidate + * the whole ext draw area */ + lv_disp_t * disp = lv_obj_get_disp(obj); + lv_disp_enable_invalidation(disp, false); lv_obj_refresh_ext_draw_size(obj); + lv_disp_enable_invalidation(disp, true); _lv_img_buf_get_transformed_area(&a, w, h, img->angle, img->zoom, &img->pivot); a.x1 += obj->coords.x1 - 1;