mirror of
https://github.com/lvgl/lvgl.git
synced 2024-11-23 09:43:41 +08:00
lv_mem_realloc: just truncate mem if smaller then then the old
This commit is contained in:
parent
03d076197f
commit
43646b78ef
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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'
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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" */
|
||||
|
Loading…
Reference in New Issue
Block a user