1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

optmize line drawing

This commit is contained in:
Gabor Kiss-Vamosi 2020-03-27 09:52:32 +01:00
parent 9f7365103b
commit afcb5c70bc
3 changed files with 52 additions and 33 deletions

View File

@ -395,8 +395,13 @@ static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2,
int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL);
int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL);
int16_t mask_top_id = lv_draw_mask_add(&mask_top_param, NULL);
int16_t mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL);
int16_t mask_top_id = LV_MASK_ID_INV;
int16_t mask_bottom_id = LV_MASK_ID_INV;
if(!dsc->raw_end) {
mask_top_id = lv_draw_mask_add(&mask_top_param, NULL);
mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL);
}
lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
@ -413,42 +418,54 @@ static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2,
* It's easy to calculate with steep lines, but the area can be very wide with very flat lines.
* So deal with it only with steep lines. */
int32_t draw_area_w = lv_area_get_width(&draw_area);
if(!flat) draw_area_w = LV_MATH_MIN(draw_area_w, dsc->width * 2 + 2);
/*Draw the background line by line*/
int32_t h;
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
size_t mask_buf_size = LV_MATH_MIN(lv_area_get_size(&draw_area), LV_HOR_RES_MAX);
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
lv_area_t fill_area;
fill_area.x1 = draw_area.x1 + disp_area->x1;
fill_area.x2 = draw_area.x2 + disp_area->x1;
fill_area.y1 = draw_area.y1 + disp_area->y1;
fill_area.y2 = fill_area.y1;
lv_point_t v;
v.x = p2.x - p1.x;
v.y = p2.y - p1.y;
int32_t x = vdb->area.x1 + draw_area.x1;
uint32_t mask_p = 0;
lv_memset_ff(mask_buf, mask_buf_size);
/*Fill the first row with 'color'*/
for(h = draw_area.y1 + disp_area->y1; h <= draw_area.y2 + disp_area->y1; h++) {
lv_memset_ff(mask_buf, draw_area_w);
if(!flat) {
/*Where is the current point?*/
x = (v.y * p1.x - v.x * p1.y + v.x * h) / v.y - dsc->width - 1;
if(x < draw_area.x1 + disp_area->x1) x = draw_area.x1 + disp_area->x1;
fill_area.x1 = x;
fill_area.x2 = fill_area.x1 + draw_area_w - 1;
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(&mask_buf[mask_p], x, h, draw_area_w);
if(mask_res == LV_DRAW_MASK_RES_FULL_TRANSP) {
lv_memset_00(&mask_buf[mask_p], draw_area_w);
}
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf, x, h, draw_area_w);
mask_p += draw_area_w;
if((uint32_t) mask_p + draw_area_w < mask_buf_size) {
fill_area.y2 ++;
}
else {
lv_blend_fill(&fill_area, clip,
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
dsc->blend_mode);
lv_blend_fill(clip, &fill_area,
dsc->color, mask_buf, mask_res, opa,
dsc->blend_mode);
fill_area.y1 = fill_area.y2 + 1;
fill_area.y2 = fill_area.y1;
mask_p = 0;
lv_memset_ff(mask_buf, mask_buf_size);
}
}
/*Flush the last part*/
if(fill_area.y1 != fill_area.y2) {
fill_area.y2--;
lv_blend_fill( &fill_area, clip,
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
dsc->blend_mode);
fill_area.y1++;
fill_area.y2++;
}
lv_mem_buf_release(mask_buf);

View File

@ -31,6 +31,7 @@ typedef struct {
lv_blend_mode_t blend_mode : 2;
uint8_t round_start : 1;
uint8_t round_end : 1;
uint8_t raw_end : 1; /*Do not bother with perpendicular line ending is it's not visible for any reason*/
} lv_draw_line_dsc_t;
/**********************

View File

@ -55,17 +55,17 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
LV_LOG_TRACE("line meter create started");
/*Create the ancestor of line meter*/
lv_obj_t * new_lmeter = lv_obj_create(par, copy);
LV_ASSERT_MEM(new_lmeter);
if(new_lmeter == NULL) return NULL;
lv_obj_t * linemeter = lv_obj_create(par, copy);
LV_ASSERT_MEM(linemeter);
if(linemeter == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_lmeter);
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(linemeter);
/*Allocate the line meter type specific extended data*/
lv_linemeter_ext_t * ext = lv_obj_allocate_ext_attr(new_lmeter, sizeof(lv_linemeter_ext_t));
lv_linemeter_ext_t * ext = lv_obj_allocate_ext_attr(linemeter, sizeof(lv_linemeter_ext_t));
LV_ASSERT_MEM(ext);
if(ext == NULL) {
lv_obj_del(new_lmeter);
lv_obj_del(linemeter);
return NULL;
}
@ -78,13 +78,13 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
ext->angle_ofs = 0;
/*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_cb(new_lmeter, lv_linemeter_signal);
lv_obj_set_design_cb(new_lmeter, lv_linemeter_design);
lv_obj_set_signal_cb(linemeter, lv_linemeter_signal);
lv_obj_set_design_cb(linemeter, lv_linemeter_design);
/*Init the new line meter line meter*/
if(copy == NULL) {
lv_obj_set_size(new_lmeter, LV_DPI, LV_DPI);
lv_theme_apply(new_lmeter, LV_THEME_LINEMETER);
lv_obj_set_size(linemeter, LV_DPI, LV_DPI);
lv_theme_apply(linemeter, LV_THEME_LINEMETER);
}
/*Copy an existing line meter*/
else {
@ -95,13 +95,13 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
ext->max_value = copy_ext->max_value;
ext->cur_value = copy_ext->cur_value;
// /*Refresh the style with new signal function*/
// lv_obj_refresh_style(new_lmeter);
/*Refresh the style with new signal function*/
lv_obj_refresh_style(linemeter, LV_STYLE_PROP_ALL);
}
LV_LOG_INFO("line meter created");
return new_lmeter;
return linemeter;
}
/*=====================
@ -293,6 +293,7 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin
lv_draw_line_dsc_t line_dsc;
lv_draw_line_dsc_init(&line_dsc);
lv_obj_init_draw_line_dsc(lmeter, part, &line_dsc);
line_dsc.raw_end = 1;
lv_style_int_t end_line_width = lv_obj_get_style_scale_end_line_width(lmeter, part);