lv_mem_realloc: just truncate mem if smaller then then the old

This commit is contained in:
Gabor Kiss-Vamosi 2017-12-03 00:36:31 +01:00
parent 03d076197f
commit 43646b78ef
11 changed files with 109 additions and 63 deletions

View File

@ -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 <stdlib.h> /*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

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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'

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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" */