1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

fix: lv_deinit/lv_init crash or hang (#2910)

* Fix themes that are not correctly initialized after lv_deinit

* Fix performance & memory monitoring not correctly initialized after lv_deinit & lv_init

* Apply code formatting fixes

* Fix build errors

* Fix build errors

* Fix formatting

Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
geert-KLA-BE 2021-12-20 14:05:06 +01:00 committed by GitHub
parent e24a9fdf18
commit 6e00724797
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 49 deletions

View File

@ -29,6 +29,23 @@
/**********************
* TYPEDEFS
**********************/
typedef struct {
uint32_t perf_last_time;
uint32_t elaps_sum;
uint32_t frame_cnt;
uint32_t fps_sum_cnt;
uint32_t fps_sum_all;
#if LV_USE_LABEL
lv_obj_t * perf_label;
#endif
} perf_monitor_t;
typedef struct {
uint32_t mem_last_time;
#if LV_USE_LABEL
lv_obj_t * mem_label;
#endif
} mem_monitor_t;
/**********************
* STATIC PROTOTYPES
@ -43,14 +60,25 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
static void draw_buf_flush(void);
static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
#if LV_USE_PERF_MONITOR
static void perf_monitor_init(perf_monitor_t * perf_monitor);
#endif
#if LV_USE_MEM_MONITOR
static void mem_monitor_init(mem_monitor_t * mem_monitor);
#endif
/**********************
* STATIC VARIABLES
**********************/
static uint32_t px_num;
static lv_disp_t * disp_refr; /*Display being refreshed*/
#if LV_USE_PERF_MONITOR
static uint32_t fps_sum_cnt;
static uint32_t fps_sum_all;
static perf_monitor_t perf_monitor;
#endif
#if LV_USE_MEM_MONITOR
static mem_monitor_t mem_monitor;
#endif
/**********************
@ -71,7 +99,12 @@ static lv_disp_t * disp_refr; /*Display being refreshed*/
*/
void _lv_refr_init(void)
{
/*Nothing to do*/
#if LV_USE_PERF_MONITOR
perf_monitor_init(&perf_monitor);
#endif
#if LV_USE_MEM_MONITOR
mem_monitor_init(&mem_monitor);
#endif
}
/**
@ -245,7 +278,7 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
#endif
#if LV_USE_PERF_MONITOR && LV_USE_LABEL
static lv_obj_t * perf_label = NULL;
lv_obj_t * perf_label = perf_monitor.perf_label;
if(perf_label == NULL) {
perf_label = lv_label_create(lv_layer_sys());
lv_obj_set_style_bg_opa(perf_label, LV_OPA_50, 0);
@ -260,36 +293,41 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
lv_obj_align(perf_label, LV_USE_PERF_MONITOR_POS, 0, 0);
}
static uint32_t perf_last_time = 0;
static uint32_t elaps_sum = 0;
static uint32_t frame_cnt = 0;
if(lv_tick_elaps(perf_last_time) < 300) {
if(lv_tick_elaps(perf_monitor.perf_last_time) < 300) {
if(px_num > 5000) {
elaps_sum += elaps;
frame_cnt ++;
perf_monitor.elaps_sum += elaps;
perf_monitor.frame_cnt ++;
}
}
else {
perf_last_time = lv_tick_get();
perf_monitor.perf_last_time = lv_tick_get();
uint32_t fps_limit = 1000 / disp_refr->refr_timer->period;
uint32_t fps;
if(elaps_sum == 0) elaps_sum = 1;
if(frame_cnt == 0) fps = fps_limit;
else fps = (1000 * frame_cnt) / elaps_sum;
elaps_sum = 0;
frame_cnt = 0;
if(fps > fps_limit) fps = fps_limit;
if(perf_monitor.elaps_sum == 0) {
perf_monitor.elaps_sum = 1;
}
if(perf_monitor.frame_cnt == 0) {
fps = fps_limit;
}
else {
fps = (1000 * perf_monitor.frame_cnt) / perf_monitor.elaps_sum;
}
perf_monitor.elaps_sum = 0;
perf_monitor.frame_cnt = 0;
if(fps > fps_limit) {
fps = fps_limit;
}
fps_sum_all += fps;
fps_sum_cnt ++;
perf_monitor.fps_sum_all += fps;
perf_monitor.fps_sum_cnt ++;
uint32_t cpu = 100 - lv_timer_get_idle();
lv_label_set_text_fmt(perf_label, "%"LV_PRIu32" FPS\n%"LV_PRIu32"%% CPU", fps, cpu);
}
#endif
#if LV_USE_MEM_MONITOR && LV_MEM_CUSTOM == 0 && LV_USE_LABEL
static lv_obj_t * mem_label = NULL;
lv_obj_t * mem_label = mem_monitor.mem_label;
if(mem_label == NULL) {
mem_label = lv_label_create(lv_layer_sys());
lv_obj_set_style_bg_opa(mem_label, LV_OPA_50, 0);
@ -303,9 +341,8 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
lv_obj_align(mem_label, LV_USE_MEM_MONITOR_POS, 0, 0);
}
static uint32_t mem_last_time = 0;
if(lv_tick_elaps(mem_last_time) > 300) {
mem_last_time = lv_tick_get();
if(lv_tick_elaps(mem_monitor.mem_last_time) > 300) {
mem_monitor.mem_last_time = lv_tick_get();
lv_mem_monitor_t mon;
lv_mem_monitor(&mon);
uint32_t used_size = mon.total_size - mon.free_size;;
@ -323,16 +360,16 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
#if LV_USE_PERF_MONITOR
void lv_refr_reset_fps_counter(void)
{
fps_sum_all = 0;
fps_sum_cnt = 0;
perf_monitor.fps_sum_all = 0;
perf_monitor.fps_sum_cnt = 0;
}
uint32_t lv_refr_get_fps_avg(void)
{
if(fps_sum_cnt == 0)
if(perf_monitor.fps_sum_cnt == 0) {
return 0;
return fps_sum_all / fps_sum_cnt;
}
return perf_monitor.fps_sum_all / perf_monitor.fps_sum_cnt;
}
#endif
@ -1002,3 +1039,26 @@ static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_
drv->flush_cb(drv, &offset_area, color_p);
}
#if LV_USE_PERF_MONITOR
static void perf_monitor_init(perf_monitor_t * _perf_monitor)
{
LV_ASSERT_NULL(_perf_monitor);
_perf_monitor->elaps_sum = 0;
_perf_monitor->fps_sum_all = 0;
_perf_monitor->fps_sum_cnt = 0;
_perf_monitor->frame_cnt = 0;
_perf_monitor->perf_last_time = 0;
_perf_monitor->perf_label = NULL;
}
#endif
#if LV_USE_MEM_MONITOR
static void mem_monitor_init(mem_monitor_t * _mem_monitor)
{
LV_ASSERT_NULL(_mem_monitor);
_mem_monitor->mem_last_time = 0;
_mem_monitor->mem_label = NULL;
}
#endif

View File

@ -50,7 +50,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj);
**********************/
static my_theme_styles_t * styles;
static lv_theme_t theme;
static bool inited;
/**********************
* MACROS
@ -120,13 +119,18 @@ static void style_init(void)
* GLOBAL FUNCTIONS
**********************/
bool lv_theme_basic_is_inited(void)
{
return LV_GC_ROOT(_lv_theme_default_styles) == NULL ? false : true;
}
lv_theme_t * lv_theme_basic_init(lv_disp_t * disp)
{
/*This trick is required only to avoid the garbage collection of
*styles' data if LVGL is used in a binding (e.g. Micropython)
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
if(!inited) {
if(!lv_theme_basic_is_inited()) {
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
}
@ -139,9 +143,9 @@ lv_theme_t * lv_theme_basic_init(lv_disp_t * disp)
style_init();
inited = true;
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
if(disp == NULL || lv_disp_get_theme(disp) == &theme) {
lv_obj_report_style_change(NULL);
}
return (lv_theme_t *)&theme;
}
@ -375,8 +379,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
static void style_init_reset(lv_style_t * style)
{
if(inited) lv_style_reset(style);
else lv_style_init(style);
if(lv_theme_basic_is_inited()) {
lv_style_reset(style);
}
else {
lv_style_init(style);
}
}
#endif

View File

@ -36,6 +36,12 @@ extern "C" {
*/
lv_theme_t * lv_theme_basic_init(lv_disp_t * disp);
/**
* Check if the theme is initialized
* @return true if default theme is initialized, false otherwise
*/
bool lv_theme_basic_is_inited(void);
/**********************
* MACROS
**********************/

View File

@ -173,7 +173,6 @@ static void style_init_reset(lv_style_t * style);
static my_theme_styles_t * styles;
static lv_theme_t theme;
static disp_size_t disp_size;
static bool inited;
static lv_color_t color_scr;
static lv_color_t color_text;
static lv_color_t color_card;
@ -647,7 +646,7 @@ lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, l
/*This trick is required only to avoid the garbage collection of
*styles' data if LVGL is used in a binding (e.g. Micropython)
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
if(!inited) {
if(!lv_theme_default_is_inited()) {
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
}
@ -667,8 +666,6 @@ lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, l
style_init();
inited = true;
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
return (lv_theme_t *)&theme;
@ -676,14 +673,16 @@ lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, l
lv_theme_t * lv_theme_default_get(void)
{
if(!inited) return NULL;
if(!lv_theme_default_is_inited()) {
return NULL;
}
return (lv_theme_t *)&theme;
}
bool lv_theme_default_is_inited(void)
{
return inited;
return LV_GC_ROOT(_lv_theme_default_styles) == NULL ? false : true;
}
@ -1161,8 +1160,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
static void style_init_reset(lv_style_t * style)
{
if(inited) lv_style_reset(style);
else lv_style_init(style);
if(lv_theme_default_is_inited()) {
lv_style_reset(style);
}
else {
lv_style_init(style);
}
}
#endif

View File

@ -64,7 +64,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj);
**********************/
static my_theme_styles_t * styles;
static lv_theme_t theme;
static bool inited;
/**********************
* MACROS
@ -164,13 +163,18 @@ static void style_init(bool dark_bg, const lv_font_t * font)
* GLOBAL FUNCTIONS
**********************/
bool lv_theme_mono_is_inited(void)
{
return LV_GC_ROOT(_lv_theme_default_styles) == NULL ? false : true;
}
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font)
{
/*This trick is required only to avoid the garbage collection of
*styles' data if LVGL is used in a binding (e.g. Micropython)
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
if(!inited) {
if(!lv_theme_mono_is_inited()) {
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
}
@ -183,8 +187,6 @@ lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t
style_init(dark_bg, font);
inited = true;
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
return (lv_theme_t *)&theme;
@ -487,8 +489,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
static void style_init_reset(lv_style_t * style)
{
if(inited) lv_style_reset(style);
else lv_style_init(style);
if(lv_theme_mono_is_inited()) {
lv_style_reset(style);
}
else {
lv_style_init(style);
}
}
#endif

View File

@ -38,6 +38,12 @@ extern "C" {
*/
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font);
/**
* Check if the theme is initialized
* @return true if default theme is initialized, false otherwise
*/
bool lv_theme_mono_is_inited(void);
/**********************
* MACROS
**********************/