From 67d268b3ee114817fb5d6902dc3c52ff01540ace Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 31 Aug 2020 09:33:44 +0200 Subject: [PATCH] gird optimization --- src/lv_core/lv_core.mk | 1 + src/lv_core/{lv_align.c => lv_grid.c} | 152 ++++++++++++++----- src/lv_core/{lv_align.h => lv_grid.h} | 6 +- src/lv_core/lv_obj.c | 203 ++++++++++++++++++-------- src/lv_core/lv_obj.h | 2 +- src/lv_core/lv_refr.c | 2 +- src/lv_core/lv_style.c | 7 + src/lv_core/lv_style.h | 3 +- src/lv_misc/lv_anim.c | 4 +- src/lv_misc/lv_ll.c | 35 ----- src/lv_misc/lv_ll.h | 10 +- src/lv_misc/lv_mem.c | 51 +++---- 12 files changed, 308 insertions(+), 168 deletions(-) rename src/lv_core/{lv_align.c => lv_grid.c} (54%) rename src/lv_core/{lv_align.h => lv_grid.h} (98%) diff --git a/src/lv_core/lv_core.mk b/src/lv_core/lv_core.mk index b46c01625..9f15199bd 100644 --- a/src/lv_core/lv_core.mk +++ b/src/lv_core/lv_core.mk @@ -1,3 +1,4 @@ +CSRCS += lv_grid.c CSRCS += lv_group.c CSRCS += lv_indev.c CSRCS += lv_disp.c diff --git a/src/lv_core/lv_align.c b/src/lv_core/lv_grid.c similarity index 54% rename from src/lv_core/lv_align.c rename to src/lv_core/lv_grid.c index 2a7d35ca7..6d4b3665b 100644 --- a/src/lv_core/lv_align.c +++ b/src/lv_core/lv_grid.c @@ -6,12 +6,13 @@ /********************* * INCLUDES *********************/ -#include "lv_align.h" +#include "lv_grid.h" #include "lv_obj.h" /********************* * DEFINES *********************/ +#define CALC_DSC_BUF_SIZE 8 /********************** * TYPEDEFS @@ -20,16 +21,18 @@ /********************** * STATIC PROTOTYPES **********************/ -static void calc_explicit(lv_obj_t * obj, _lv_grid_calc_t * calc); -static void calc_flow_row(lv_obj_t * obj, _lv_grid_calc_t * calc); - static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc); static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc); +static void calc_implicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc); static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc); /********************** * STATIC VARIABLES **********************/ +static lv_coord_t col_dsc_calc_buf[CALC_DSC_BUF_SIZE]; +static lv_coord_t row_dsc_calc_buf[CALC_DSC_BUF_SIZE]; +static bool col_dsc_buf_used; +static bool row_dsc_buf_used; /********************** * MACROS @@ -41,14 +44,24 @@ static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc); void grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc) { - static uint32_t cnt = 0; - cnt++; if(obj->grid == NULL) return; - printf("calc: %d (size: %d)\n", cnt, obj->grid->col_dsc_len); +// static uint32_t cnt = 0; +// cnt++; +// printf("calc: %d (size: %d)\n", cnt, obj->grid->col_dsc_len); - if(obj->grid->col_dsc && obj->grid->row_dsc) calc_explicit(obj, calc); - else if(obj->grid->col_dsc && !obj->grid->row_dsc) calc_flow_row(obj, calc); + if(obj->grid->col_dsc && obj->grid->row_dsc) { + calc_explicit_rows(obj, calc); + calc_explicit_cols(obj, calc); + } + else if(obj->grid->col_dsc && !obj->grid->row_dsc) { + calc_explicit_cols(obj, calc); + calc_implicit_rows(obj, calc); + } + else if(!obj->grid->col_dsc && obj->grid->row_dsc) { + calc_implicit_cols(obj, calc); + calc_explicit_rows(obj, calc); + } } @@ -89,27 +102,19 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj) * STATIC FUNCTIONS **********************/ -static void calc_explicit(lv_obj_t * obj, _lv_grid_calc_t * calc) -{ - calc_explicit_rows(obj, calc); - calc_explicit_cols(obj, calc); - -} - - -static void calc_flow_row(lv_obj_t * obj, _lv_grid_calc_t * calc) -{ - calc_explicit_cols(obj, calc); - calc_implicit_rows(obj, calc); -} - - static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc) { lv_grid_t * grid = cont->grid; uint32_t i; - lv_coord_t * cols_w = _lv_mem_buf_get(sizeof(lv_coord_t) * grid->col_dsc_len); + lv_coord_t * cols_w; + if(!col_dsc_buf_used && grid->col_dsc_len <= CALC_DSC_BUF_SIZE) { + cols_w = col_dsc_calc_buf; + col_dsc_buf_used = true; + } else { + cols_w = _lv_mem_buf_get(sizeof(lv_coord_t) * grid->col_dsc_len); + } + uint32_t col_fr_cnt = 0; lv_coord_t grid_w = 0; bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false; @@ -144,16 +149,24 @@ static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc) for(i = 0; i < grid->col_dsc_len; i++) { calc->col_dsc[i + 1] = calc->col_dsc[i] + cols_w[i]; } - _lv_mem_buf_release(cols_w); + + if(col_dsc_buf_used) col_dsc_buf_used = false ; + else _lv_mem_buf_release(cols_w); } static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc) { lv_grid_t * grid = cont->grid; uint32_t i; - calc_explicit_cols(cont, calc); - lv_coord_t * rows_h = _lv_mem_buf_get(sizeof(lv_coord_t) * grid->row_dsc_len); + lv_coord_t * rows_h; + if(!row_dsc_buf_used && grid->row_dsc_len <= CALC_DSC_BUF_SIZE) { + rows_h = row_dsc_calc_buf; + row_dsc_buf_used = true; + } else { + rows_h = _lv_mem_buf_get(sizeof(lv_coord_t) * grid->row_dsc_len); + } + uint32_t row_fr_cnt = 0; lv_coord_t grid_h = 0; @@ -192,7 +205,65 @@ static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc) calc->row_dsc[i + 1] = calc->row_dsc[i] + rows_h[i]; } - _lv_mem_buf_release(rows_h); + if(row_dsc_buf_used) row_dsc_buf_used = false; + else _lv_mem_buf_release(rows_h); +} + + +static void calc_implicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc) +{ + lv_grid_t * grid = cont->grid; + + uint32_t child_cnt = lv_obj_count_children(cont); + + uint32_t col_cnt = (child_cnt / grid->row_dsc_len) + 1; + /* If `col_dsc_buf_used`, nested a call of this func. will release `col_dsc_buf_used` because it think it taken it. + * So mark that if the buffer was taken in this call*/ + bool col_dsc_buf_mine = false; + /*At worst case all children is gird item prepare place for all of them*/ + lv_coord_t * cols_w; + if(!col_dsc_buf_used && col_cnt <= CALC_DSC_BUF_SIZE) { + cols_w = col_dsc_calc_buf; + col_dsc_buf_used = true; + col_dsc_buf_mine = true; + } else { + cols_w = _lv_mem_buf_get(sizeof(lv_coord_t) * col_cnt); + } + + uint32_t i; + + lv_obj_t * child = lv_obj_get_child_back(cont, NULL); + uint32_t row_i = 0; + uint32_t col_i = 0; + cols_w[0] = 0; + while(child) { + if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) { + lv_coord_t w; + if(_GRID_GET_CELL_FLAG(child->x_set) == LV_GRID_STRETCH) _lv_obj_calc_auto_size(child, &w, NULL); + else w = lv_obj_get_width(child); + cols_w[col_i] = LV_MATH_MAX(cols_w[col_i], w); + row_i++; + if(row_i == grid->row_dsc_len) { + row_i = 0; + col_i++; + cols_w[col_i] = 0; + } + } + child = lv_obj_get_child_back(cont, child); + } + + + calc->col_dsc_len = col_cnt + 1; + calc->col_dsc = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_dsc_len); + + calc->col_dsc[0] = 0; + + for(i = 0; i < col_cnt; i++) { + calc->col_dsc[i + 1] = calc->col_dsc[i] + cols_w[i]; + } + + if(col_dsc_buf_used && col_dsc_buf_mine) col_dsc_buf_used = false; + else _lv_mem_buf_release(cols_w); } @@ -200,26 +271,36 @@ static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc) { lv_grid_t * grid = cont->grid; - uint32_t child_cnt = lv_obj_count_children(cont); - uint32_t row_cnt = (child_cnt / grid->col_dsc_len) + 1; + bool row_dsc_buf_mine = false; /*At worst case all children is gird item prepare place for all of them*/ - lv_coord_t * rows_h = _lv_mem_buf_get(sizeof(lv_coord_t) * row_cnt); - _lv_memset_00(rows_h, sizeof(lv_coord_t) * row_cnt); + lv_coord_t * rows_h; + if(!row_dsc_buf_used && row_cnt <= CALC_DSC_BUF_SIZE) { + rows_h = row_dsc_calc_buf; + row_dsc_buf_used = true; + row_dsc_buf_mine = true; + } else { + rows_h = _lv_mem_buf_get(sizeof(lv_coord_t) * row_cnt); + } uint32_t i; lv_obj_t * child = lv_obj_get_child_back(cont, NULL); uint32_t col_i = 0; uint32_t row_i = 0; + rows_h[0] = 0; while(child) { if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) { - rows_h[row_i] = LV_MATH_MAX(rows_h[row_i], lv_obj_get_height(child)); + lv_coord_t h; + if(_GRID_GET_CELL_FLAG(child->y_set) == LV_GRID_STRETCH) _lv_obj_calc_auto_size(child, NULL, &h); + else h = lv_obj_get_height(child); + rows_h[row_i] = LV_MATH_MAX(rows_h[row_i], h); col_i++; if(col_i == grid->col_dsc_len) { col_i = 0; row_i++; + rows_h[row_i] = 0; } } child = lv_obj_get_child_back(cont, child); @@ -235,5 +316,6 @@ static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc) calc->row_dsc[i + 1] = calc->row_dsc[i] + rows_h[i]; } - _lv_mem_buf_release(rows_h); + if(row_dsc_buf_used && row_dsc_buf_mine) row_dsc_buf_used = false; + else _lv_mem_buf_release(rows_h); } diff --git a/src/lv_core/lv_align.h b/src/lv_core/lv_grid.h similarity index 98% rename from src/lv_core/lv_align.h rename to src/lv_core/lv_grid.h index ceb91b597..b64576072 100644 --- a/src/lv_core/lv_align.h +++ b/src/lv_core/lv_grid.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_ALIGN_H -#define LV_ALIGN_H +#ifndef LV_GRID_H +#define LV_GRID_H #ifdef __cplusplus extern "C" { @@ -128,4 +128,4 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj); } /* extern "C" */ #endif -#endif /*LV_ALIGN_H*/ +#endif /*LV_GRID_H*/ diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 7f450224b..193d977dd 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -49,6 +49,10 @@ #define LV_OBJ_DEF_WIDTH (LV_DPX(100)) #define LV_OBJ_DEF_HEIGHT (LV_DPX(50)) #define SCROLLBAR_MIN_SIZE (LV_DPX(10)) +#define SCROLL_ANIM_TIME_MIN 100 /*ms*/ +#define SCROLL_ANIM_TIME_MAX 300 /*ms*/ + +#define GRID_DEBUG 1 /*Draw rectangles on grid cells*/ /********************** * TYPEDEFS @@ -804,14 +808,14 @@ static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h) bool lv_obj_is_grid_item(lv_obj_t * obj); static void lv_grid_full_refr(lv_obj_t * cont); -static void _grid_item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc) +static void _grid_item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc, uint32_t * child_id_ext, lv_point_t * grid_abs) { if(lv_obj_is_grid_item(item) == false) return; - uint8_t col_pos; - uint8_t col_span; - uint8_t row_pos; - uint8_t row_span; + uint32_t col_pos; + uint32_t col_span; + uint32_t row_pos; + uint32_t row_span; if(cont->grid->row_dsc && cont->grid->col_dsc) { col_pos = _GRID_GET_CELL_POS(item->x_set); @@ -823,18 +827,26 @@ static void _grid_item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * row_span = 1; uint32_t child_id = 0; - lv_obj_t * child = lv_obj_get_child_back(cont, NULL); + if(child_id_ext) child_id = *child_id_ext; + else { + lv_obj_t * child = lv_obj_get_child_back(cont, NULL); - while(child) { - if(child == item) break; - if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) { - child_id++; + while(child) { + if(child == item) break; + if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) { + child_id++; + } + child = lv_obj_get_child_back(cont, child); } - child = lv_obj_get_child_back(cont, child); } - col_pos = child_id % cont->grid->col_dsc_len; - row_pos = child_id / cont->grid->col_dsc_len; + if(cont->grid->row_dsc == NULL) { + col_pos = child_id % cont->grid->col_dsc_len; + row_pos = child_id / cont->grid->col_dsc_len; + } else { + col_pos = child_id / cont->grid->row_dsc_len; + row_pos = child_id % cont->grid->row_dsc_len; + } } lv_coord_t col_w = calc->col_dsc[col_pos + col_span] - calc->col_dsc[col_pos]; @@ -902,19 +914,12 @@ static void _grid_item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * child = lv_obj_get_child(item, child); } } + bool moved = true; + if(grid_abs) { + if(grid_abs->x + x == item->coords.x1 && grid_abs->y + y == item->coords.y1) moved = false; + } - move_obj_to(item, x, y, false); -} - -bool lv_obj_is_content_sensitive(lv_obj_t * item) -{ - if(lv_obj_is_grid_item(item) == false) return false; - lv_obj_t * cont = lv_obj_get_parent(item); - - if(cont->grid->col_dsc == NULL && _GRID_GET_CELL_FLAG(item->x_set) == LV_GRID_STRETCH) return true; - if(cont->grid->row_dsc == NULL && _GRID_GET_CELL_FLAG(item->y_set) == LV_GRID_STRETCH) return true; - - return false; + if(moved) move_obj_to(item, x, y, false); } static void lv_grid_full_refr(lv_obj_t * cont) @@ -924,9 +929,21 @@ static void lv_grid_full_refr(lv_obj_t * cont) _lv_grid_calc_t calc; grid_calc(cont, &calc); + /* Calculate the grids absolute x and y coordinates. + * It will be used as helper during item repositioning to avoid calculating this value for every children*/ + lv_point_t grid_abs; + lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_OBJ_PART_MAIN); + lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_OBJ_PART_MAIN); + grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_left(cont); + grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_top(cont); + + uint32_t child_id = 0; lv_obj_t * item = lv_obj_get_child_back(cont, NULL); while(item) { - _grid_item_repos(cont, item, &calc); + if(_GRID_IS_CELL(item->x_set) && _GRID_IS_CELL(item->y_set)) { + _grid_item_repos(cont, item, &calc, &child_id, &grid_abs); + child_id++; + } item = lv_obj_get_child_back(cont, item); } grid_calc_free(&calc); @@ -944,7 +961,7 @@ static void lv_grid_item_refr_pos(lv_obj_t * item) _lv_grid_calc_t calc; grid_calc(cont, &calc); - _grid_item_repos(cont, item, &calc); + _grid_item_repos(cont, item, &calc, NULL, NULL); grid_calc_free(&calc); } @@ -993,10 +1010,18 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) /*If the object is on a grid item let the grid to position it. */ if(gi) { + lv_area_t old_area; + lv_area_copy(&old_area, &obj->coords); + lv_grid_item_refr_pos(obj); + lv_obj_t * cont = lv_obj_get_parent(obj); - /*If added to a grid with auto flow refresh the whole grid else just this item*/ - if(cont->grid->col_dsc == NULL || cont->grid->row_dsc == NULL) lv_grid_full_refr(cont); - else lv_grid_item_refr_pos(obj); + + /*If the item was moved and grid is implicit in the changed direction refresh the whole grid.*/ + if((cont->grid->col_dsc == NULL && (old_area.x1 != obj->coords.x1 || old_area.x2 != obj->coords.x2)) || + (cont->grid->row_dsc == NULL && (old_area.y1 != obj->coords.y1 || old_area.y2 != obj->coords.y2))) + { + lv_grid_full_refr(cont); + } } else { move_obj_to(obj, x, y, true); } @@ -1030,9 +1055,10 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w, lv_coord_t * h) { if(!w && !h) return; - static uint32_t cnt = 0; - printf("auto_size: %d\n", cnt); - cnt++; +// static uint32_t cnt = 0; +// printf("auto_size: %d\n", cnt); +// cnt++; + /*If no other effect the auto-size of zero by default*/ if(w) *w = 0; if(h) *h = 0; @@ -1043,8 +1069,8 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w, lv_coord_t * h) if(obj->grid) { _lv_grid_calc_t calc; grid_calc(obj, &calc); - grid_w = calc.col_dsc[calc.col_dsc_len - 1]; - grid_h = calc.row_dsc[calc.row_dsc_len - 1]; + grid_w = calc.col_dsc[calc.col_dsc_len - 1] + lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN) + + lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN); + grid_h = calc.row_dsc[calc.row_dsc_len - 1] + lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN) + lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);; grid_calc_free(&calc); } @@ -1058,9 +1084,6 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w, lv_coord_t * h) } if(h) { - static uint32_t cnt = 0; -// printf("auto_size_scrl: %d\n", cnt); - cnt++; lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF); lv_coord_t scroll_bottom = lv_obj_get_scroll_bottom(obj); children_h = lv_obj_get_height(obj) + scroll_bottom; @@ -1122,7 +1145,7 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h) h = auto_h; } - bool chg = refr_size(obj, w, h); + refr_size(obj, w, h); } /** @@ -1261,7 +1284,10 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable lv_anim_path_set_cb(&path, lv_anim_path_ease_out); if(x) { - lv_anim_set_time(&a, lv_anim_speed_to_time((lv_disp_get_hor_res(d) * 3) >> 2, 0, x)); + uint32_t t = lv_anim_speed_to_time((lv_disp_get_hor_res(d) * 3) >> 2, 0, x); + if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN; + if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX; + lv_anim_set_time(&a, t); lv_anim_set_values(&a, obj->scroll.x, obj->scroll.x + x); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) scroll_anim_x_cb); lv_anim_set_path(&a, &path); @@ -1269,7 +1295,10 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable } if(y) { - lv_anim_set_time(&a, lv_anim_speed_to_time((lv_disp_get_ver_res(d) * 3) >> 2, 0, y)); + uint32_t t = lv_anim_speed_to_time((lv_disp_get_ver_res(d) * 3) >> 2, 0, y); + if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN; + if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX; + lv_anim_set_time(&a, t); lv_anim_set_values(&a, obj->scroll.y, obj->scroll.y + y); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) scroll_anim_y_cb); lv_anim_set_path(&a, &path); @@ -2332,16 +2361,7 @@ lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_obj_t * result = NULL; - - if(child == NULL) { - result = _lv_ll_get_head(&obj->child_ll); - } - else { - result = _lv_ll_get_next(&obj->child_ll, child); - } - - return result; + return child ? _lv_ll_get_next(&obj->child_ll, child) : _lv_ll_get_head(&obj->child_ll); } /** @@ -2355,16 +2375,7 @@ lv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_obj_t * result = NULL; - - if(child == NULL) { - result = _lv_ll_get_tail(&obj->child_ll); - } - else { - result = _lv_ll_get_prev(&obj->child_ll, child); - } - - return result; + return child ? _lv_ll_get_prev(&obj->child_ll, child) : _lv_ll_get_tail(&obj->child_ll); } /** @@ -2818,6 +2829,12 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_PAD_RIGHT: if(list->pad_all_zero) def = true; break; + case LV_STYLE_MARGIN_TOP: + case LV_STYLE_MARGIN_BOTTOM: + case LV_STYLE_MARGIN_LEFT: + case LV_STYLE_MARGIN_RIGHT: + if(list->margin_all_zero) def = true; + break; case LV_STYLE_BG_BLEND_MODE: case LV_STYLE_BORDER_BLEND_MODE: case LV_STYLE_IMAGE_BLEND_MODE: @@ -4086,6 +4103,47 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area coords.y2 += h; lv_draw_rect(&coords, clip_area, &draw_dsc); } + +#if GRID_DEBUG + /*Draw the grid cells*/ + if(obj->grid) { + _lv_grid_calc_t calc; + grid_calc(obj, &calc); + + /*Create a color unique to this object. */ + lv_color_t c = lv_color_hex(((lv_uintptr_t) obj) & 0xFFFFFF); + + lv_draw_rect_dsc_t grid_rect_dsc; + lv_draw_rect_dsc_init(&grid_rect_dsc); + grid_rect_dsc.bg_color = c; + grid_rect_dsc.bg_opa = LV_OPA_20; + grid_rect_dsc.border_width = 2; + grid_rect_dsc.border_color = c; + grid_rect_dsc.border_opa = LV_OPA_70; + + lv_point_t grid_abs; + lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN); + lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN); + grid_abs.x = pad_left + obj->coords.x1 - lv_obj_get_scroll_left(obj); + grid_abs.y = pad_top + obj->coords.y1 - lv_obj_get_scroll_top(obj); + + uint32_t row; + uint32_t col; + for(row = 0; row < calc.row_dsc_len - 1; row ++) { + for(col = 0; col < calc.col_dsc_len - 1; col ++) { + lv_area_t a; + a.x1 = grid_abs.x + calc.col_dsc[col]; + a.x2 = grid_abs.x + calc.col_dsc[col + 1]; + a.y1 = grid_abs.y + calc.row_dsc[row]; + a.y2 = grid_abs.y + calc.row_dsc[row + 1]; + lv_draw_rect(&a, clip_area, &grid_rect_dsc); + } + } + + + grid_calc_free(&calc); + } +#endif } return LV_DESIGN_RES_OK; @@ -4194,6 +4252,17 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) obj->ext_draw_pad = LV_MATH_MAX(obj->ext_draw_pad, d); } else if(sign == LV_SIGNAL_STYLE_CHG) { + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + lv_obj_set_pos(child, child->x_set, child->y_set); + child = lv_obj_get_child(obj, child); + } + + + if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) { + lv_obj_set_size(obj, obj->w_set, obj->h_set); + } +// if(lv_obj_is_grid_item(obj)) lv_grid_full_refr(lv_obj_get_parent(obj)); lv_obj_refresh_ext_draw_pad(obj); } else if(sign == LV_SIGNAL_PRESSED) { @@ -4956,6 +5025,10 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) case LV_STYLE_PAD_BOTTOM: case LV_STYLE_PAD_LEFT: case LV_STYLE_PAD_RIGHT: + case LV_STYLE_MARGIN_TOP: + case LV_STYLE_MARGIN_BOTTOM: + case LV_STYLE_MARGIN_LEFT: + case LV_STYLE_MARGIN_RIGHT: case LV_STYLE_BG_BLEND_MODE: case LV_STYLE_BORDER_BLEND_MODE: case LV_STYLE_IMAGE_BLEND_MODE: @@ -5035,6 +5108,14 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->pad_all_zero = 0; } + list->margin_all_zero = 1; + if(lv_obj_get_style_margin_top(obj, part) != 0 || + lv_obj_get_style_margin_bottom(obj, part) != 0 || + lv_obj_get_style_margin_left(obj, part) != 0 || + lv_obj_get_style_margin_right(obj, part) != 0) { + list->margin_all_zero = 0; + } + list->blend_mode_all_normal = 1; #if LV_USE_BLEND_MODES if(lv_obj_get_style_bg_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index ffbfbbcff..cbfd9aef3 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -18,7 +18,7 @@ extern "C" { #include #include #include "lv_style.h" -#include "lv_align.h" +#include "lv_grid.h" #include "../lv_misc/lv_types.h" #include "../lv_misc/lv_area.h" #include "../lv_misc/lv_color.h" diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 0765fba27..cde758fa2 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -678,7 +678,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) draw_dsc.bg_color.full = debug_color.full; draw_dsc.bg_opa = LV_OPA_20; draw_dsc.border_width = 2; - draw_dsc.border_opa = LV_OPA_50; + draw_dsc.border_opa = LV_OPA_70; draw_dsc.border_color.full = (debug_color.full + 0x13) * 9; lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &draw_dsc); diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 3a2ad6d80..5fc116932 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1044,6 +1044,7 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) * STATIC FUNCTIONS **********************/ +static uint32_t stat[256]; /** * Get a property's index (byte index in `style->map`) from a style. * Return best matching property's index considering the state of `prop` @@ -1067,6 +1068,12 @@ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t size_t i = 0; + stat[prop & 0xFF]++; +// +// if((prop & 0xFF) == LV_STYLE_PAD_TOP) { +// printf("pad top\n"); +// } + uint8_t prop_id; while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSEING_PROP) { if(prop_id == id_to_find) { diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 420576dc5..c992388c0 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -231,7 +231,7 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint32_t style_cnt : 6; + uint32_t style_cnt : 5; uint32_t has_local : 1; uint32_t has_trans : 1; uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/ @@ -244,6 +244,7 @@ typedef struct { uint32_t clip_corner_off : 1; uint32_t transform_all_zero : 1; uint32_t pad_all_zero : 1; + uint32_t margin_all_zero : 1; uint32_t blend_mode_all_normal : 1; uint32_t bg_opa_transp : 1; uint32_t bg_opa_cover : 1; diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index ed3fd7929..3794593d5 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -260,7 +260,7 @@ lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_ else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time; - int32_t step = _lv_bezier3(t, 0, 1, 1, 1024); + int32_t step = _lv_bezier3(t, 0, 100, 200, 1024); int32_t new_value; new_value = (int32_t)step * (a->end - a->start); @@ -287,7 +287,7 @@ lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time; - int32_t step = _lv_bezier3(t, 0, 1023, 1023, 1024); + int32_t step = _lv_bezier3(t, 0, 800, 900, 1024); int32_t new_value; new_value = (int32_t)step * (a->end - a->start); diff --git a/src/lv_misc/lv_ll.c b/src/lv_misc/lv_ll.c index 9f25b8f7f..4d3e4dabc 100644 --- a/src/lv_misc/lv_ll.c +++ b/src/lv_misc/lv_ll.c @@ -249,37 +249,6 @@ void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool h } } -/** - * Return with head node of the linked list - * @param ll_p pointer to linked list - * @return pointer to the head of 'll_p' - */ -void * _lv_ll_get_head(const lv_ll_t * ll_p) -{ - void * head = NULL; - - if(ll_p != NULL) { - head = ll_p->head; - } - - return head; -} - -/** - * Return with tail node of the linked list - * @param ll_p pointer to linked list - * @return pointer to the head of 'll_p' - */ -void * _lv_ll_get_tail(const lv_ll_t * ll_p) -{ - void * tail = NULL; - - if(ll_p != NULL) { - tail = ll_p->tail; - } - - return tail; -} /** * Return with the pointer of the next node after 'n_act' @@ -289,8 +258,6 @@ void * _lv_ll_get_tail(const lv_ll_t * ll_p) */ void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act) { - if(ll_p == NULL) return NULL; - /* Pointer to the next node is stored in the end of this node. * Go there and return the address found there */ const lv_ll_node_t * n_act_d = n_act; @@ -306,8 +273,6 @@ void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act) */ void * _lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act) { - if(ll_p == NULL) return NULL; - /* Pointer to the prev. node is stored in the end of this node. * Go there and return the address found there */ const lv_ll_node_t * n_act_d = n_act; diff --git a/src/lv_misc/lv_ll.h b/src/lv_misc/lv_ll.h index 906414d16..0fac6a713 100644 --- a/src/lv_misc/lv_ll.h +++ b/src/lv_misc/lv_ll.h @@ -98,14 +98,20 @@ void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool h * @param ll_p pointer to linked list * @return pointer to the head of 'll_p' */ -void * _lv_ll_get_head(const lv_ll_t * ll_p); +static inline void * _lv_ll_get_head(const lv_ll_t * ll_p) +{ + return ll_p->head; +} /** * Return with tail node of the linked list * @param ll_p pointer to linked list * @return pointer to the head of 'll_p' */ -void * _lv_ll_get_tail(const lv_ll_t * ll_p); +static inline void * _lv_ll_get_tail(const lv_ll_t * ll_p) +{ + return ll_p->tail; +} /** * Return with the pointer of the next node after 'n_act' diff --git a/src/lv_misc/lv_mem.c b/src/lv_misc/lv_mem.c index 7fa3146f8..3ef1bd9ae 100644 --- a/src/lv_misc/lv_mem.c +++ b/src/lv_misc/lv_mem.c @@ -73,7 +73,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, size_t size); + static inline void * ent_alloc(lv_mem_ent_t * e, size_t size); static void ent_trunc(lv_mem_ent_t * e, size_t size); #endif @@ -84,9 +84,9 @@ typedef struct { static uint8_t * work_mem; #endif -static uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/ - +static uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/ #if LV_MEM_CUSTOM == 0 + static uint8_t * last_mem; /*Address of the last valid byte*/ static uint32_t mem_max_size; /*Tracks the maximum total size of memory ever used from the internal heap*/ #endif @@ -125,7 +125,7 @@ void _lv_mem_init(void) #else work_mem = (uint8_t *)LV_MEM_ADR; #endif - + last_mem = &work_mem[LV_MEM_SIZE - 1]; lv_mem_ent_t * full = (lv_mem_ent_t *)work_mem; full->header.s.used = 0; /*The total mem size id reduced by the first header and the close patterns */ @@ -176,13 +176,11 @@ void * lv_mem_alloc(size_t size) do { /* Get the next entry*/ e = ent_get_next(e); - + if( e == NULL) break; /*If there is next entry then try to allocate there*/ - if(e != NULL) { - alloc = ent_alloc(e, size); - } - /* End if there is not next entry OR the alloc. is successful*/ - } while(e != NULL && alloc == NULL); + if(!e->header.s.used && e->header.s.d_size >= size) alloc = ent_alloc(e, size); + /* End if the alloc. is successful*/ + } while(alloc == NULL); #else /*Use custom, user defined malloc function*/ @@ -817,19 +815,15 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_ff(void * dst, size_t len) */ static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e) { - lv_mem_ent_t * next_e = NULL; - - if(act_e == NULL) { /*NULL means: get the first entry*/ - next_e = (lv_mem_ent_t *)work_mem; - } - else { /*Get the next entry */ + /*NULL means: get the first entry; else get the next after `act_e`*/ + if(act_e == NULL) return (lv_mem_ent_t *)work_mem; + else { uint8_t * data = &act_e->first_data; - next_e = (lv_mem_ent_t *)&data[act_e->header.s.d_size]; + lv_mem_ent_t * next_e = (lv_mem_ent_t *)&data[act_e->header.s.d_size]; - if(&next_e->first_data >= &work_mem[LV_MEM_SIZE]) next_e = NULL; + if(&next_e->first_data > last_mem) return NULL; + else return next_e; } - - return next_e; } /** @@ -838,20 +832,23 @@ static lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e) * @param size size of the new memory in bytes * @return pointer to the allocated memory or NULL if not enough memory in the entry */ -static void * ent_alloc(lv_mem_ent_t * e, size_t size) +static inline void * ent_alloc(lv_mem_ent_t * e, size_t size) { - void * alloc = NULL; - /*If the memory is free and big enough then use it */ - if(e->header.s.used == 0 && e->header.s.d_size >= size) { +// static uint32_t cnt = 0; +// +//// if((cnt & 0xFFFF) == 0) +// printf("alloc: %d\n", cnt); +// cnt++; +// + + /*Truncate the entry to the desired size */ ent_trunc(e, size); e->header.s.used = 1; /*Save the allocated data*/ - alloc = &e->first_data; - } + return &e->first_data; - return alloc; } /**