Compare commits

...

12 Commits

Author SHA1 Message Date
Gabor Kiss-Vamosi
d0a9e8b817 update lv_conf_internal.h 2024-04-22 18:13:02 +02:00
Gabor Kiss-Vamosi
08087cccd8 fix test build error 2024-04-17 10:55:53 +02:00
Gabor Kiss-Vamosi
de366cc4aa enable sysmon in CI 2024-04-17 10:02:03 +02:00
Gabor Kiss-Vamosi
f3ab9dfeb0 fix warnings 2024-04-16 09:34:39 +02:00
Gabor Kiss-Vamosi
2bfa8ae1f5 works with multi display 2024-04-15 21:06:42 +02:00
Gabor Peresztegi
75e759e3ba fix(sysmon): fix CI build 2024-03-24 10:09:00 +01:00
Gabor Peresztegi
4b914a3f10 fix(sysmon): add sysmon prototype 2024-03-24 10:01:55 +01:00
Gabor Peresztegi
db2605064e fix(sysmon): fix system monitor CI build 2024-03-24 09:51:40 +01:00
Gabor Peresztegi
2b0b3bdaad chore(sysmon): fix code formatting 2024-03-22 15:27:13 +01:00
Gabor Peresztegi
ec8012dd61 fix(sysmon): add sysmon performance and memory show/hide functions 2024-03-22 13:30:12 +01:00
Gabor Peresztegi
f7acf1e4ce fix(sysmon): fix system monitor CI build error 2024-03-21 17:57:45 +01:00
Gabor Peresztegi
57ad8017dd fix(sysmon): fix MicroPython compilation error when system monitor is enabled 2024-03-21 17:48:54 +01:00
16 changed files with 218 additions and 74 deletions

View File

@@ -189,6 +189,11 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#define LV_LOG_TRACE_ANIM 0
#endif /*LV_USE_LOG*/
#if LV_USE_SYSMON == 0
#define LV_USE_PERF_MONITOR 0
#define LV_USE_MEM_MONITOR 0
#endif /*LV_USE_SYSMON*/
#ifndef LV_USE_LZ4
#define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
#endif

View File

@@ -191,11 +191,11 @@ typedef struct _lv_global_t {
lv_style_t fe_list_button_style;
#endif
#if LV_USE_SYSMON && LV_USE_PERF_MONITOR
#if LV_USE_PERF_MONITOR
lv_sysmon_backend_data_t sysmon_perf;
#endif
#if LV_USE_SYSMON && LV_USE_MEM_MONITOR
#if LV_USE_MEM_MONITOR
lv_sysmon_backend_data_t sysmon_mem;
#endif

View File

@@ -331,7 +331,7 @@ void _lv_display_refr_timer(lv_timer_t * tmr)
/* Ensure the timer does not run again automatically.
* This is done before refreshing in case refreshing invalidates something else.
* However if the performance monitor is enabled keep the timer running to count the FPS.*/
#if !(defined(LV_USE_PERF_MONITOR) && LV_USE_PERF_MONITOR)
#if LV_USE_PERF_MONITOR
lv_timer_pause(tmr);
#endif
}

View File

@@ -13,6 +13,7 @@
#include "../stdlib/lv_string.h"
#include "../themes/lv_theme.h"
#include "../core/lv_global.h"
#include "../others/sysmon/lv_sysmon.h"
#if LV_USE_DRAW_SW
#include "../draw/sw/lv_draw_sw.h"
@@ -139,6 +140,14 @@ lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res)
lv_timer_ready(disp->refr_timer); /*Be sure the screen will be refreshed immediately on start up*/
#if LV_USE_PERF_MONITOR
lv_sysmon_show_performance(disp);
#endif
#if LV_USE_MEM_MONITOR
lv_sysmon_show_memory(disp);
#endif
return disp;
}

View File

@@ -18,6 +18,10 @@ extern "C" {
#include "../draw/lv_draw.h"
#include "lv_display.h"
#if LV_USE_PERF_MONITOR
#include "../others/sysmon/lv_sysmon.h"
#endif
/*********************
* DEFINES
*********************/
@@ -148,6 +152,17 @@ struct _lv_display_t {
/** The area being refreshed*/
lv_area_t refreshed_area;
#if LV_USE_PERF_MONITOR
lv_obj_t * perf_label;
lv_sysmon_backend_data_t perf_sysmon_backend;
lv_sysmon_perf_info_t perf_sysmon_info;
#endif
#if LV_USE_MEM_MONITOR
lv_obj_t * mem_label;
#endif
};
/**********************

View File

@@ -349,7 +349,7 @@
#define LV_USE_NATIVE_HELIUM_ASM 0
#endif
#endif
/* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only
* 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */
#ifndef LV_DRAW_SW_COMPLEX
@@ -3283,6 +3283,11 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#define LV_LOG_TRACE_ANIM 0
#endif /*LV_USE_LOG*/
#if LV_USE_SYSMON == 0
#define LV_USE_PERF_MONITOR 0
#define LV_USE_MEM_MONITOR 0
#endif /*LV_USE_SYSMON*/
#ifndef LV_USE_LZ4
#define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
#endif

View File

@@ -148,6 +148,18 @@ typedef struct _lv_font_t lv_font_t;
struct _lv_image_decoder_t;
typedef struct _lv_image_decoder_t lv_image_decoder_t;
#if LV_USE_SYSMON
struct _lv_sysmon_backend_data_t;
typedef struct _lv_sysmon_backend_data_t lv_sysmon_backend_data_t;
#if LV_USE_PERF_MONITOR
struct _lv_sysmon_perf_info_t;
typedef struct _lv_sysmon_perf_info_t lv_sysmon_perf_info_t;
#endif /*LV_USE_PERF_MONITOR*/
#endif /*LV_USE_SYSMON*/
#endif /*__ASSEMBLY__*/
/**********************

View File

@@ -197,6 +197,7 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
return LV_RESULT_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@@ -265,6 +265,24 @@ void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32
}
}
void lv_subject_deinit(lv_subject_t * subject)
{
lv_observer_t * observer = _lv_ll_get_head(&subject->subs_ll);
while(observer) {
lv_observer_t * observer_next = _lv_ll_get_next(&subject->subs_ll, observer);
if(observer->for_obj) {
lv_obj_remove_event_cb(observer->target, unsubscribe_on_delete_cb);
lv_obj_remove_event_cb_with_user_data(observer->target, NULL, subject);
}
lv_observer_remove(observer);
observer = observer_next;
}
_lv_ll_clear(&subject->subs_ll);
}
lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index)
{
if(subject->type != LV_SUBJECT_TYPE_GROUP) {
@@ -280,6 +298,9 @@ lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t inde
lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t cb, void * user_data)
{
lv_observer_t * observer = lv_subject_add_observer_obj(subject, cb, NULL, user_data);
if(observer == NULL) return NULL;
observer->for_obj = 0;
return observer;
}
@@ -301,6 +322,7 @@ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_
observer->cb = cb;
observer->user_data = user_data;
observer->target = obj;
observer->for_obj = 1;
/* subscribe to delete event of the object */
if(obj != NULL) {
lv_obj_add_event_cb(obj, unsubscribe_on_delete_cb, LV_EVENT_DELETE, observer);

View File

@@ -77,6 +77,7 @@ struct _lv_observer_t {
void * user_data; /**< Additional parameter supplied when subscribing*/
uint32_t auto_free_user_data : 1; /**< Automatically free user data when the observer is removed */
uint32_t notified : 1; /**< Mark if this observer was already notified*/
uint32_t for_obj : 1; /**< `target` is an `lv_obj_t *`*/
};
/**********************
@@ -209,6 +210,14 @@ lv_color_t lv_subject_get_previous_color(lv_subject_t * subject);
*/
void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len);
/**
* Remove all the observers from a subject and free all allocated memories in it
* @param subject pointer to the subject
* @note objects added with `lv_subject_add_observer_obj` should be already deleted or
* removed manually.
*/
void lv_subject_deinit(lv_subject_t * subject);
/**
* Get an element from the subject group's list
* @param subject pointer to the subject

View File

@@ -15,26 +15,16 @@
#include "../../misc/lv_async.h"
#include "../../stdlib/lv_string.h"
#include "../../widgets/label/lv_label.h"
#include "../../display/lv_display_private.h"
/*********************
* DEFINES
*********************/
#define MY_CLASS (&lv_sysmon_class)
#define SYSMON_REFR_PERIOD_DEF 300 /* ms */
#if defined(LV_USE_PERF_MONITOR) && LV_USE_PERF_MONITOR
#define sysmon_perf LV_GLOBAL_DEFAULT()->sysmon_perf
#define _USE_PERF_MONITOR 1
#else
#define _USE_PERF_MONITOR 0
#endif
#if defined(LV_USE_MEM_MONITOR) && LV_USE_MEM_MONITOR
#define sysmon_mem LV_GLOBAL_DEFAULT()->sysmon_mem
#define _USE_MEM_MONITOR 1
#else
#define _USE_MEM_MONITOR 0
#endif
/**********************
@@ -45,12 +35,13 @@
* STATIC PROTOTYPES
**********************/
#if _USE_PERF_MONITOR
#if LV_USE_PERF_MONITOR
static void perf_update_timer_cb(lv_timer_t * t);
static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
static void perf_monitor_disp_event_cb(lv_event_t * e);
#endif
#if _USE_MEM_MONITOR
#if LV_USE_MEM_MONITOR
static void mem_update_timer_cb(lv_timer_t * t);
static void mem_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
#endif
@@ -69,13 +60,8 @@
void _lv_sysmon_builtin_init(void)
{
#if _USE_PERF_MONITOR
static lv_sysmon_perf_info_t perf_info;
lv_subject_init_pointer(&sysmon_perf.subject, &perf_info);
sysmon_perf.timer = lv_timer_create(perf_update_timer_cb, SYSMON_REFR_PERIOD_DEF, &perf_info);
#endif
#if _USE_MEM_MONITOR
#if LV_USE_MEM_MONITOR
static lv_mem_monitor_t mem_info;
lv_subject_init_pointer(&sysmon_mem.subject, &mem_info);
sysmon_mem.timer = lv_timer_create(mem_update_timer_cb, SYSMON_REFR_PERIOD_DEF, &mem_info);
@@ -84,19 +70,16 @@ void _lv_sysmon_builtin_init(void)
void _lv_sysmon_builtin_deinit(void)
{
#if _USE_PERF_MONITOR
lv_timer_delete(sysmon_perf.timer);
#endif
#if _USE_MEM_MONITOR
#if LV_USE_MEM_MONITOR
lv_timer_delete(sysmon_mem.timer);
#endif
}
lv_obj_t * lv_sysmon_create(lv_obj_t * parent)
lv_obj_t * lv_sysmon_create(lv_display_t * disp)
{
LV_LOG_INFO("begin");
lv_obj_t * label = lv_label_create(parent);
if(disp == NULL) disp = lv_display_get_default();
lv_obj_t * label = lv_label_create(lv_display_get_layer_sys(disp));
lv_obj_set_style_bg_opa(label, LV_OPA_50, 0);
lv_obj_set_style_bg_color(label, lv_color_black(), 0);
lv_obj_set_style_text_color(label, lv_color_white(), 0);
@@ -105,16 +88,64 @@ lv_obj_t * lv_sysmon_create(lv_obj_t * parent)
return label;
}
#if LV_USE_PERF_MONITOR
void lv_sysmon_show_performance(lv_display_t * disp)
{
if(disp == NULL) disp = lv_display_get_default();
disp->perf_label = lv_sysmon_create(disp);
lv_subject_init_pointer(&disp->perf_sysmon_backend.subject, &disp->perf_sysmon_info);
lv_obj_align(disp->perf_label, LV_USE_PERF_MONITOR_POS, 0, 0);
lv_subject_add_observer_obj(&disp->perf_sysmon_backend.subject, perf_observer_cb, disp->perf_label, NULL);
disp->perf_sysmon_backend.timer = lv_timer_create(perf_update_timer_cb, SYSMON_REFR_PERIOD_DEF, disp);
lv_display_add_event_cb(disp, perf_monitor_disp_event_cb, LV_EVENT_ALL, NULL);
#if LV_USE_PERF_MONITOR_LOG_MODE
lv_obj_add_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN);
#else
lv_obj_remove_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN);
#endif
}
void lv_sysmon_hide_performance(lv_display_t * disp)
{
if(disp == NULL) disp = lv_display_get_default();
lv_obj_add_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN);
}
#endif
#if LV_USE_MEM_MONITOR
void lv_sysmon_show_memory(lv_display_t * disp)
{
if(disp == NULL) disp = lv_display_get_default();
disp->mem_label = lv_sysmon_create(disp);
lv_obj_align(disp->mem_label, LV_USE_MEM_MONITOR_POS, 0, 0);
lv_subject_add_observer_obj(&sysmon_mem.subject, mem_observer_cb, disp->mem_label, NULL);
lv_obj_remove_flag(disp->mem_label, LV_OBJ_FLAG_HIDDEN);
}
void lv_sysmon_hide_memory(lv_display_t * disp)
{
if(disp == NULL) disp = lv_display_get_default();
lv_obj_add_flag(disp->mem_label, LV_OBJ_FLAG_HIDDEN);
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
#if _USE_PERF_MONITOR
#if LV_USE_PERF_MONITOR
static void perf_monitor_disp_event_cb(lv_event_t * e)
{
lv_display_t * disp = lv_event_get_target(e);
lv_event_code_t code = lv_event_get_code(e);
lv_sysmon_perf_info_t * info = (lv_sysmon_perf_info_t *)lv_subject_get_pointer(&sysmon_perf.subject);
lv_sysmon_perf_info_t * info = &disp->perf_sysmon_info;
switch(code) {
case LV_EVENT_REFR_START:
@@ -152,6 +183,10 @@ static void perf_monitor_disp_event_cb(lv_event_t * e)
info->measured.flush_not_in_render_elaps_sum += lv_tick_elaps(info->measured.flush_not_in_render_start);
}
break;
case LV_EVENT_DELETE:
lv_timer_delete(disp->perf_sysmon_backend.timer);
lv_subject_deinit(&disp->perf_sysmon_backend.subject);
break;
default:
break;
}
@@ -159,24 +194,11 @@ static void perf_monitor_disp_event_cb(lv_event_t * e)
static void perf_update_timer_cb(lv_timer_t * t)
{
/*Wait for a display*/
if(!sysmon_perf.inited && lv_display_get_default()) {
lv_display_add_event_cb(lv_display_get_default(), perf_monitor_disp_event_cb, LV_EVENT_ALL, NULL);
lv_obj_t * obj1 = lv_sysmon_create(lv_layer_sys());
lv_obj_align(obj1, LV_USE_PERF_MONITOR_POS, 0, 0);
lv_subject_add_observer_obj(&sysmon_perf.subject, perf_observer_cb, obj1, NULL);
#if LV_USE_PERF_MONITOR_LOG_MODE
lv_obj_add_flag(obj1, LV_OBJ_FLAG_HIDDEN);
#endif
sysmon_perf.inited = true;
}
if(!sysmon_perf.inited) return;
lv_display_t * disp = lv_timer_get_user_data(t);
uint32_t LV_SYSMON_GET_IDLE(void);
lv_sysmon_perf_info_t * info = lv_timer_get_user_data(t);
lv_sysmon_perf_info_t * info = &disp->perf_sysmon_info;
info->calculated.run_cnt++;
uint32_t time_since_last_report = lv_tick_elaps(info->measured.last_report_timestamp);
@@ -204,7 +226,7 @@ static void perf_update_timer_cb(lv_timer_t * t)
info->calculated.fps_avg_total = ((info->calculated.fps_avg_total * (info->calculated.run_cnt - 1)) +
info->calculated.fps) / info->calculated.run_cnt;
lv_subject_set_pointer(&sysmon_perf.subject, info);
lv_subject_set_pointer(&disp->perf_sysmon_backend.subject, info);
lv_sysmon_perf_info_t prev_info = *info;
lv_memzero(info, sizeof(lv_sysmon_perf_info_t));
@@ -244,20 +266,10 @@ static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
#endif
#if _USE_MEM_MONITOR
#if LV_USE_MEM_MONITOR
static void mem_update_timer_cb(lv_timer_t * t)
{
/*Wait for a display*/
if(!sysmon_mem.inited && lv_display_get_default()) {
lv_obj_t * obj2 = lv_sysmon_create(lv_layer_sys());
lv_obj_align(obj2, LV_USE_MEM_MONITOR_POS, 0, 0);
lv_subject_add_observer_obj(&sysmon_mem.subject, mem_observer_cb, obj2, NULL);
sysmon_mem.inited = true;
}
if(!sysmon_mem.inited) return;
lv_mem_monitor_t * mem_mon = lv_timer_get_user_data(t);
lv_mem_monitor(mem_mon);
lv_subject_set_pointer(&sysmon_mem.subject, mem_mon);

View File

@@ -35,14 +35,13 @@ extern "C" {
* TYPEDEFS
**********************/
typedef struct {
struct _lv_sysmon_backend_data_t {
lv_subject_t subject;
lv_timer_t * timer;
bool inited;
} lv_sysmon_backend_data_t;
};
#if LV_USE_PERF_MONITOR
typedef struct {
struct _lv_sysmon_perf_info_t {
struct {
bool inited;
uint32_t refr_start;
@@ -71,7 +70,7 @@ typedef struct {
uint32_t run_cnt;
} calculated;
} lv_sysmon_perf_info_t;
};
#endif
/**********************
@@ -79,18 +78,43 @@ typedef struct {
**********************/
/**
* Create a system monitor object.
* @param parent pointer to an object, it will be the parent of the new system monitor
* @return pointer to the new system monitor object
* Create a new system monitor label
* @param disp create the sys. mon. on this display's system layer
* @return the create label
*/
lv_obj_t * lv_sysmon_create(lv_obj_t * parent);
lv_obj_t * lv_sysmon_create(lv_display_t * disp);
#if LV_USE_PERF_MONITOR
/**
* Set the refresh period of the system monitor object
* @param obj pointer to a system monitor object
* @param period the refresh period in milliseconds
* Show system performance monitor: CPU usage and FPS count
* @param disp target display, NULL: use the default displays
*/
void lv_sysmon_set_refr_period(lv_obj_t * obj, uint32_t period);
void lv_sysmon_show_performance(lv_display_t * disp);
/**
* Hide system performance monitor
* @param disp target display, NULL: use the default
*/
void lv_sysmon_hide_performance(lv_display_t * disp);
#endif /*LV_USE_PERF_MONITOR*/
#if LV_USE_MEM_MONITOR
/**
* Show system memory monitor: used memory and the memory fragmentation
* @param disp target display, NULL: use the default displays
*/
void lv_sysmon_show_memory(lv_display_t * disp);
/**
* Hide system memory monitor
* @param disp target display, NULL: use the default displays
*/
void lv_sysmon_hide_memory(lv_display_t * disp);
#endif /*LV_USE_MEM_MONITOR*/
/**
* Initialize built-in system monitor, such as performance and memory monitor.

View File

@@ -116,8 +116,6 @@ typedef void * lv_user_data_t;
#define LV_DRAW_BUF_ALIGN 852
/*For screenshots*/
#undef LV_USE_PERF_MONITOR
#undef LV_USE_MEM_MONITOR
#undef LV_DPI_DEF
#define LV_DPI_DEF 130
#endif

View File

@@ -73,6 +73,8 @@
#define LV_USE_FILE_EXPLORER 1
#define LV_USE_TINY_TTF 1
#define LV_USE_SYSMON 1
#define LV_USE_MEM_MONITOR 1
#define LV_USE_PERF_MONITOR 1
#define LV_USE_SNAPSHOT 1
#define LV_USE_THORVG_INTERNAL 1
#define LV_USE_LZ4_INTERNAL 1

View File

@@ -21,6 +21,14 @@ void lv_test_init(void)
{
lv_init();
hal_init();
#if LV_USE_SYSMON
#if LV_USE_MEM_MONITOR
lv_sysmon_hide_memory(NULL);
#endif
#if LV_USE_PERF_MONITOR
lv_sysmon_hide_performance(NULL);
#endif
#endif
}
void lv_test_deinit(void)

View File

@@ -504,4 +504,26 @@ void test_observer_dropdown_value(void)
TEST_ASSERT_EQUAL(0, lv_subject_get_int(&subject));
}
void test_observer_deinit(void)
{
static lv_subject_t subject;
uint32_t mem = lv_test_get_free_mem();
uint32_t i;
for(i = 0; i < 64; i++) {
lv_obj_t * obj1 = lv_slider_create(lv_screen_active());
lv_obj_t * obj2 = lv_slider_create(lv_screen_active());
lv_subject_init_int(&subject, 30);
lv_slider_bind_value(obj1, &subject);
lv_slider_bind_value(obj2, &subject);
lv_subject_add_observer(&subject, observer_int, NULL);
lv_obj_delete(obj1);
lv_subject_deinit(&subject);
lv_obj_delete(obj2);
}
TEST_ASSERT_MEM_LEAK_LESS_THAN(mem, 32);
}
#endif