From 43646b78ef3021e5a6cf58921d4ece45bf21c8dd Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 3 Dec 2017 00:36:31 +0100 Subject: [PATCH] lv_mem_realloc: just truncate mem if smaller then then the old --- lv_conf_templ.h | 3 ++- lv_core/lv_group.c | 4 +++- lv_core/lv_obj.c | 36 +++++++++++++++-------------- lv_core/lv_refr.c | 13 +++++------ lv_core/lv_style.c | 52 +++++++++++++++++++++++++++--------------- lv_hal/lv_hal_indev.c | 3 +++ lv_misc/lv_anim.c | 2 +- lv_misc/lv_anim.h | 2 +- lv_misc/lv_mem.c | 53 +++++++++++++++++++++++++++++++------------ lv_misc/lv_mem.h | 3 +-- lv_themes/lv_theme.h | 1 + 11 files changed, 109 insertions(+), 63 deletions(-) diff --git a/lv_conf_templ.h b/lv_conf_templ.h index 1f819d7d9..4677d5e63 100644 --- a/lv_conf_templ.h +++ b/lv_conf_templ.h @@ -15,11 +15,12 @@ #if LV_MEM_CUSTOM == 0 #define LV_MEM_SIZE (32U * 1024U) /*Size memory used by mem_alloc (in bytes)*/ #define LV_MEM_ATTR /*Complier prefix for big array declaration*/ +#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ #else /*LV_MEM_CUSTOM*/ #define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ #define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ #define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ -#endif /*DM_CUSTOM*/ +#endif /*LV_MEM_CUSTOM*/ /*=================== Graphical settings diff --git a/lv_core/lv_group.c b/lv_core/lv_group.c index 72b3b1b28..84c5d3beb 100644 --- a/lv_core/lv_group.c +++ b/lv_core/lv_group.c @@ -77,11 +77,13 @@ void lv_group_remove_obj(lv_obj_t * obj) { lv_group_t * g = obj->group_p; if(g == NULL) return; - lv_obj_t ** i; + /*Search the object and remove it from its group */ + lv_obj_t ** i; LL_READ(g->obj_ll, i) { if(*i == obj) { lv_ll_rem(&g->obj_ll, i); + obj->group_p = NULL; break; } } diff --git a/lv_core/lv_obj.c b/lv_core/lv_obj.c index 0644db547..f463a44f6 100644 --- a/lv_core/lv_obj.c +++ b/lv_core/lv_obj.c @@ -278,23 +278,8 @@ lv_res_t lv_obj_del(lv_obj_t * obj) /*Remove the animations from this object*/ lv_anim_del(obj, NULL); #endif - /*Remove the object from parent's children list*/ - lv_obj_t * par = lv_obj_get_parent(obj); - if(par == NULL) { /*It is a screen*/ - lv_ll_rem(&scr_ll, obj); - } else { - lv_ll_rem(&(par->child_ll), obj); - } - - /* All children deleted. - * Now clean up the object specific data*/ - obj->signal_func(obj, LV_SIGNAL_CLEANUP, NULL); - /*Delete the base objects*/ - if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr); - lv_mem_free(obj); /*Free the object itself*/ - - /* Reset all display input (indev_proc) if + /* Reset all input devices if * the currently pressed object is deleted*/ lv_indev_t * indev = lv_indev_next(NULL); lv_obj_t * dpar; @@ -312,6 +297,22 @@ lv_res_t lv_obj_del(lv_obj_t * obj) indev = lv_indev_next(indev); } + /*Remove the object from parent's children list*/ + lv_obj_t * par = lv_obj_get_parent(obj); + if(par == NULL) { /*It is a screen*/ + lv_ll_rem(&scr_ll, obj); + } else { + lv_ll_rem(&(par->child_ll), obj); + } + + /* All children deleted. + * Now clean up the object specific data*/ + obj->signal_func(obj, LV_SIGNAL_CLEANUP, NULL); + + /*Delete the base objects*/ + if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr); + lv_mem_free(obj); /*Free the object itself*/ + /*Send a signal to the parent to notify it about the child delete*/ if(par != NULL) { par->signal_func(par, LV_SIGNAL_CHILD_CHG, NULL); @@ -861,7 +862,7 @@ void lv_obj_set_design_func(lv_obj_t * obj, lv_design_func_t fp) */ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size) { - obj->ext_attr = lv_mem_realloc(obj->ext_attr, ext_size); + obj->ext_attr = lv_mem_realloc(obj->ext_attr, ext_size); return (void*)obj->ext_attr; } @@ -1416,6 +1417,7 @@ static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_m lv_style_t * style = lv_obj_get_style(obj); lv_draw_rect(&obj->coords, mask_p, style); } + return true; } diff --git a/lv_core/lv_refr.c b/lv_core/lv_refr.c index ac4153317..3078a11d1 100644 --- a/lv_core/lv_refr.c +++ b/lv_core/lv_refr.c @@ -40,7 +40,7 @@ static void lv_refr_area_with_vdb(const lv_area_t * area_p); static void lv_refr_area_part_vdb(const lv_area_t * area_p); #endif static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj); -static void lv_refr_make(lv_obj_t * top_p, const lv_area_t * mask_p); +static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p); static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p); /********************** @@ -246,7 +246,7 @@ static void lv_refr_area_no_vdb(const lv_area_t * area_p) top_p = lv_refr_get_top_obj(area_p, lv_scr_act()); /*Do the refreshing*/ - lv_refr_make(top_p, area_p); + lv_refr_obj_and_children(top_p, area_p); } #else @@ -314,12 +314,11 @@ static void lv_refr_area_part_vdb(const lv_area_t * area_p) top_p = lv_refr_get_top_obj(&start_mask, lv_scr_act()); /*Do the refreshing from the top object*/ - lv_refr_make(top_p, &start_mask); + lv_refr_obj_and_children(top_p, &start_mask); /*Also refresh top and sys layer unconditionally*/ - lv_refr_make(lv_layer_top(), &start_mask); - lv_refr_make(lv_layer_sys(), &start_mask); - + lv_refr_obj_and_children(lv_layer_top(), &start_mask); + lv_refr_obj_and_children(lv_layer_sys(), &start_mask); /*Flush the content of the VDB*/ lv_vdb_flush(); @@ -368,7 +367,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) * @param top_p pointer to an objects. Start the drawing from it. * @param mask_p pointer to an area, the objects will be drawn only here */ -static void lv_refr_make(lv_obj_t * top_p, const lv_area_t * mask_p) +static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p) { /* Normally always will be a top_obj (at least the screen) * but in special cases (e.g. if the screen has alpha) it won't. diff --git a/lv_core/lv_style.c b/lv_core/lv_style.c index cf6f6c670..9a6605613 100644 --- a/lv_core/lv_style.c +++ b/lv_core/lv_style.c @@ -15,7 +15,7 @@ * DEFINES *********************/ #if LV_NO_ANIM == 0 -#define LV_STYLE_ANIM_RES 255 /*Animation max in 1024 steps*/ +#define LV_STYLE_ANIM_RES 256 #define LV_STYLE_ANIM_SHIFT 8 /*log2(LV_STYLE_ANIM_RES)*/ #define VAL_PROP(v1, v2, r) v1 + (((v2-v1) * r) >> LV_STYLE_ANIM_SHIFT) @@ -27,9 +27,10 @@ **********************/ #if LV_NO_ANIM == 0 typedef struct { - lv_style_t style_start; /*Save not only pointers because if same as 'style_anim' then it will be modified too*/ + lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it will be modified too*/ lv_style_t style_end; - lv_style_t * style_anim; + lv_style_t *style_anim; + void (*end_cb)(void *); }lv_style_anim_dsc_t; #endif @@ -37,7 +38,8 @@ typedef struct { * STATIC PROTOTYPES **********************/ #if LV_NO_ANIM == 0 -static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val); +static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val); +static void style_animation_common_end_cb(void *ptr); #endif /********************** @@ -226,14 +228,16 @@ void lv_style_anim_create(lv_style_anim_t * anim) dsc->style_anim = anim->style_anim; memcpy(&dsc->style_start, anim->style_start, sizeof(lv_style_t)); memcpy(&dsc->style_end, anim->style_end, sizeof(lv_style_t)); + dsc->end_cb = anim->end_cb; + lv_anim_t a; a.var = (void*)dsc; a.start = 0; a.end = LV_STYLE_ANIM_RES; - a.fp = (lv_anim_fp_t)lv_style_aimator; + a.fp = (lv_anim_fp_t)style_animator; a.path = lv_anim_get_path(LV_ANIM_PATH_LIN); - a.end_cb = anim->end_cb; + a.end_cb = style_animation_common_end_cb; a.act_time = anim->act_time; a.time = anim->time; a.playback = anim->playback; @@ -253,7 +257,7 @@ void lv_style_anim_create(lv_style_anim_t * anim) * @param dsc the 'animated variable' set by lv_style_anim_create() * @param val the current state of the animation between 0 and LV_STYLE_ANIM_RES */ -static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val) +static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val) { const lv_style_t * start = &dsc->style_start; const lv_style_t * end = &dsc->style_end; @@ -271,14 +275,15 @@ static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val) STYLE_ATTR_ANIM(line.width, val); STYLE_ATTR_ANIM(image.intense, val); - act->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, val); - act->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, val); - act->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, val); - act->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, val); - act->text.color = lv_color_mix(end->text.color, start->text.color, val); - act->image.color = lv_color_mix(end->image.color, start->image.color, val); - act->line.color = lv_color_mix(end->line.color, start->line.color, val); + lv_opa_t opa = val == LV_STYLE_ANIM_RES ? LV_OPA_COVER : val; + act->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa); + act->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa); + act->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa); + act->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa); + act->text.color = lv_color_mix(end->text.color, start->text.color, opa); + act->image.color = lv_color_mix(end->image.color, start->image.color, opa); + act->line.color = lv_color_mix(end->line.color, start->line.color, opa); if(val == 0) { act->body.empty = start->body.empty; @@ -295,9 +300,20 @@ static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val) } lv_obj_report_style_mod(dsc->style_anim); - - if(val == LV_STYLE_ANIM_RES) { - lv_mem_free(dsc); - } } + +/** + * Called when a style animation is ready + * It called the user defined call back and free the allocated memories + * @param ptr the 'animated variable' set by lv_style_anim_create() + */ +static void style_animation_common_end_cb(void *ptr) +{ + lv_style_anim_dsc_t *dsc = ptr; /*To avoid casting*/ + + if(dsc->end_cb) dsc->end_cb(dsc); + + lv_mem_free(dsc); +} + #endif diff --git a/lv_hal/lv_hal_indev.c b/lv_hal/lv_hal_indev.c index a00111596..26b789adc 100644 --- a/lv_hal/lv_hal_indev.c +++ b/lv_hal/lv_hal_indev.c @@ -63,6 +63,9 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t *driver) memcpy(&node->driver, driver, sizeof(lv_indev_drv_t)); node->next = NULL; + node->proc.reset_query = 1; + node->cursor = NULL; + node->group = NULL; if (indev_list == NULL) { indev_list = node; diff --git a/lv_misc/lv_anim.c b/lv_misc/lv_anim.c index ebd5d2eeb..d1cbfd6df 100644 --- a/lv_misc/lv_anim.c +++ b/lv_misc/lv_anim.c @@ -92,7 +92,7 @@ void lv_anim_create(lv_anim_t * anim_p) } /** - * Delete an animation for a variable with a given animatior function + * Delete an animation for a variable with a given animator function * @param var pointer to variable * @param fp a function pointer which is animating 'var', * or NULL to delete all animations of 'var' diff --git a/lv_misc/lv_anim.h b/lv_misc/lv_anim.h index 973e154ed..dfd4984ba 100644 --- a/lv_misc/lv_anim.h +++ b/lv_misc/lv_anim.h @@ -63,7 +63,7 @@ a.var = obj; a.start = lv_obj_get_height(obj); a.end = new_height; a.fp = (lv_anim_fp_t)lv_obj_set_height; -a.path = anim_get_path(LV_ANIM_PATH_LIN); +a.path = lv_anim_get_path(LV_ANIM_PATH_LIN); a.end_cb = NULL; a.act_time = 0; a.time = 200; diff --git a/lv_misc/lv_mem.c b/lv_misc/lv_mem.c index 6a880ebee..dc5dbe466 100644 --- a/lv_misc/lv_mem.c +++ b/lv_misc/lv_mem.c @@ -19,6 +19,7 @@ /********************* * DEFINES *********************/ +#define LV_MEM_ADD_JUNK 0 /*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/ /********************** * TYPEDEFS @@ -47,7 +48,7 @@ typedef struct #if LV_MEM_CUSTOM == 0 static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e); static void * ent_alloc(lv_mem_ent_t * e, uint32_t size); -static lv_mem_ent_t * ent_trunc(lv_mem_ent_t * e, uint32_t size); +static void ent_trunc(lv_mem_ent_t * e, uint32_t size); #endif /********************** @@ -113,6 +114,11 @@ void * lv_mem_alloc(uint32_t size) } //End if there is not next entry OR the alloc. is successful }while(e != NULL && alloc == NULL); + +#if LV_MEM_ADD_JUNK + if(alloc != NULL) memset(alloc, 0xaa, size); +#endif + #else /*Use custom, user defined malloc function*/ /*Allocate a header too to store the size*/ alloc = LV_MEM_CUSTOM_ALLOC(size + sizeof(lv_mem_header_t)); @@ -135,11 +141,17 @@ void lv_mem_free(const void * data) if(data == &zero_mem) return; if(data == NULL) return; + +#if LV_MEM_ADD_JUNK + memset((void*)data, 0xbb, lv_mem_get_size(data)); +#endif + /*e points to the header*/ lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data - sizeof(lv_mem_header_t)); e->header.used = 0; -#if LV_MEM_CUSTOM == 0 /*Use the free from dyn_mem*/ +#if LV_MEM_CUSTOM == 0 +#if LV_MEM_AUTO_DEFRAG /* Make a simple defrag. * Join the following free entries after this*/ lv_mem_ent_t * e_next; @@ -152,6 +164,7 @@ void lv_mem_free(const void * data) } e_next = ent_get_next(e_next); } +#endif #else /*Use custom, user defined free function*/ LV_MEM_CUSTOM_FREE(e); #endif @@ -169,11 +182,21 @@ void * lv_mem_realloc(void * data_p, uint32_t new_size) /*data_p could be previously freed pointer (in this case it is invalid)*/ if(data_p != NULL) { lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data_p - sizeof(lv_mem_header_t)); - if(e->header.used == 0) data_p = NULL; + if(e->header.used == 0) { + data_p = NULL; + } } uint32_t old_size = lv_mem_get_size(data_p); - if(old_size == new_size) return data_p; + if(old_size == new_size) return data_p; /*Also avoid reallocating the same memory*/ + + /* Only truncate the memory is possible + * If the 'old_size' was extended by a header size in 'ent_trunc' it avoids reallocating this same memory */ + if(new_size < old_size) { + lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *) data_p - sizeof(lv_mem_header_t)); + ent_trunc(e, new_size); + return &e->first_data; + } void * new_p; new_p = lv_mem_alloc(new_size); @@ -271,7 +294,7 @@ void lv_mem_monitor(lv_mem_monitor_t * mon_p) * @param data pointer to an allocated memory * @return the size of data memory in bytes */ -uint32_t lv_mem_get_size(void * data) +uint32_t lv_mem_get_size(const void * data) { if(data == NULL) return 0; if(data == &zero_mem) return 0; @@ -320,7 +343,7 @@ static void * ent_alloc(lv_mem_ent_t * e, uint32_t size) { void * alloc = NULL; - /*If the memory is free and big enough ten use it */ + /*If the memory is free and big enough then use it */ if(e->header.used == 0 && e->header.d_size >= size) { /*Truncate the entry to the desired size */ ent_trunc(e, size), @@ -338,15 +361,18 @@ static void * ent_alloc(lv_mem_ent_t * e, uint32_t size) * Truncate the data of entry to the given size * @param e Pointer to an entry * @param size new size in bytes - * @return the new entry created from the remaining memory */ -static lv_mem_ent_t * ent_trunc(lv_mem_ent_t * e, uint32_t size) +static void ent_trunc(lv_mem_ent_t * e, uint32_t size) { - lv_mem_ent_t * new_e; + /*Round the size up to 4*/ + if(size & 0x3 ) { + size = size & (~0x3); + size += 4; + } - /*Do let empty space only for a header withot data*/ + /*Don't let empty space only for a header without data*/ if(e->header.d_size == size + sizeof(lv_mem_header_t)) { - size += sizeof(lv_mem_header_t); + size = e->header.d_size; } /* Create the new entry after the current if there is space for it */ @@ -356,12 +382,9 @@ static lv_mem_ent_t * ent_trunc(lv_mem_ent_t * e, uint32_t size) after_new_e->header.used = 0; after_new_e->header.d_size = e->header.d_size - size - sizeof(lv_mem_header_t); } - + /* Set the new size for the original entry */ e->header.d_size = size; - new_e = e; - - return new_e; } #endif diff --git a/lv_misc/lv_mem.h b/lv_misc/lv_mem.h index 333a43813..0dc3e9c5d 100644 --- a/lv_misc/lv_mem.h +++ b/lv_misc/lv_mem.h @@ -85,8 +85,7 @@ void lv_mem_monitor(lv_mem_monitor_t * mon_p); * @param data pointer to an allocated memory * @return the size of data memory in bytes */ -uint32_t lv_mem_get_size(void * data); - +uint32_t lv_mem_get_size(const void * data); /** * Halt o NULL pointer diff --git a/lv_themes/lv_theme.h b/lv_themes/lv_theme.h index 272af91b7..ed05a41a2 100644 --- a/lv_themes/lv_theme.h +++ b/lv_themes/lv_theme.h @@ -258,6 +258,7 @@ lv_theme_t * lv_theme_get_current(void); #include "lv_theme_default.h" #include "lv_theme_alien.h" #include "lv_theme_night.h" +#include "lv_theme_mono.h" #ifdef __cplusplus } /* extern "C" */