mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-23 07:46:36 +08:00
perf(draw) ignore masks if they don't affect the current draw area
This commit is contained in:
+11
-7
@@ -518,11 +518,14 @@ static void lv_obj_draw(lv_event_t * e)
|
||||
|
||||
#if LV_DRAW_COMPLEX
|
||||
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
||||
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
|
||||
/*If the radius is 0 the parent's coordinates will clip anyway*/
|
||||
lv_coord_t r = lv_obj_get_style_radius(obj, LV_PART_MAIN);
|
||||
lv_draw_mask_radius_init(mp, &obj->coords, r, false);
|
||||
/*Add the mask and use `obj+8` as custom id. Don't use `obj` directly because it might be used by the user*/
|
||||
lv_draw_mask_add(mp, obj + 8);
|
||||
if(r != 0) {
|
||||
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
|
||||
lv_draw_mask_radius_init(mp, &obj->coords, r, false);
|
||||
/*Add the mask and use `obj+8` as custom id. Don't use `obj` directly because it might be used by the user*/
|
||||
lv_draw_mask_add(mp, obj + 8);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -533,8 +536,10 @@ static void lv_obj_draw(lv_event_t * e)
|
||||
#if LV_DRAW_COMPLEX
|
||||
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
||||
lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8);
|
||||
lv_draw_mask_free_param(param);
|
||||
lv_mem_buf_release(param);
|
||||
if(param) {
|
||||
lv_draw_mask_free_param(param);
|
||||
lv_mem_buf_release(param);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -556,7 +561,6 @@ static void lv_obj_draw(lv_event_t * e)
|
||||
coords.y1 -= h;
|
||||
coords.y2 += h;
|
||||
|
||||
|
||||
lv_obj_draw_part_dsc_t part_dsc;
|
||||
lv_obj_draw_dsc_init(&part_dsc, clip_area);
|
||||
part_dsc.class_p = MY_CLASS;
|
||||
|
||||
@@ -353,10 +353,10 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
draw_area.x2 -= disp_area->x1;
|
||||
draw_area.y2 -= disp_area->y1;
|
||||
|
||||
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
|
||||
bool mask_any = lv_draw_mask_is_any(map_area);
|
||||
|
||||
/*The simplest case just copy the pixels into the draw_buf*/
|
||||
if(other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE &&
|
||||
if(!mask_any && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE &&
|
||||
chroma_key == false && alpha_byte == false && draw_dsc->recolor_opa == LV_OPA_TRANSP) {
|
||||
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
|
||||
draw_dsc->blend_mode);
|
||||
@@ -364,14 +364,14 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
/*Simple case without masking and transformations*/
|
||||
else if(other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false &&
|
||||
else if(!mask_any && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false &&
|
||||
chroma_key == true && draw_dsc->recolor_opa == LV_OPA_TRANSP) { /*copy with color keying (+ alpha)*/
|
||||
lv_gpu_nxp_pxp_enable_color_key();
|
||||
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
|
||||
draw_dsc->blend_mode);
|
||||
lv_gpu_nxp_pxp_disable_color_key();
|
||||
}
|
||||
else if(other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false &&
|
||||
else if(!mask_any && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false &&
|
||||
chroma_key == false && draw_dsc->recolor_opa != LV_OPA_TRANSP) { /*copy with recolor (+ alpha)*/
|
||||
lv_gpu_nxp_pxp_enable_recolor(draw_dsc->recolor, draw_dsc->recolor_opa);
|
||||
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
|
||||
@@ -408,7 +408,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
|
||||
bool transform = draw_dsc->angle != 0 || draw_dsc->zoom != LV_IMG_ZOOM_NONE ? true : false;
|
||||
/*Simple ARGB image. Handle it as special case because it's very common*/
|
||||
if(other_mask_cnt == 0 && !transform && !chroma_key && draw_dsc->recolor_opa == LV_OPA_TRANSP && alpha_byte) {
|
||||
if(!mask_any && !transform && !chroma_key && draw_dsc->recolor_opa == LV_OPA_TRANSP && alpha_byte) {
|
||||
#if LV_USE_GPU_STM32_DMA2D && LV_COLOR_DEPTH == 32
|
||||
/*Blend ARGB images directly*/
|
||||
if(lv_area_get_size(&draw_area) > 240) {
|
||||
@@ -509,7 +509,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
draw_dsc->zoom != LV_IMG_ZOOM_NONE) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
|
||||
/*Prepare the `mask_buf`if there are other masks*/
|
||||
if(other_mask_cnt) {
|
||||
if(mask_any) {
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
}
|
||||
|
||||
@@ -589,7 +589,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
}
|
||||
#if LV_DRAW_COMPLEX
|
||||
/*Apply the masks if any*/
|
||||
if(other_mask_cnt) {
|
||||
if(mask_any) {
|
||||
lv_draw_mask_res_t mask_res_sub;
|
||||
mask_res_sub = lv_draw_mask_apply(mask_buf + px_i_start, draw_area.x1 + draw_buf->area.x1, y + draw_area.y1 + draw_buf->area.y1,
|
||||
lv_area_get_width(&draw_area));
|
||||
@@ -619,7 +619,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
|
||||
draw_dsc->zoom != LV_IMG_ZOOM_NONE) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
|
||||
/*Prepare the `mask_buf`if there are other masks*/
|
||||
if(other_mask_cnt) {
|
||||
if(mask_any) {
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_
|
||||
fill_area.y1 = row_start + pos_y;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
#if LV_DRAW_COMPLEX
|
||||
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
|
||||
bool mask_any = lv_draw_mask_is_any(&fill_area);
|
||||
#endif
|
||||
|
||||
uint32_t col_bit_max = 8 - bpp;
|
||||
@@ -577,7 +577,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_
|
||||
|
||||
#if LV_DRAW_COMPLEX
|
||||
/*Apply masks if any*/
|
||||
if(other_mask_cnt) {
|
||||
if(mask_any) {
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, fill_area.x1, fill_area.y2,
|
||||
lv_area_get_width(&fill_area));
|
||||
if(mask_res == LV_DRAW_MASK_RES_TRANSP) {
|
||||
@@ -695,8 +695,7 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
/*If the letter is partially out of mask the move there on draw_buf*/
|
||||
disp_buf_buf_tmp += (row_start * disp_buf_width) + col_start / 3;
|
||||
|
||||
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
|
||||
|
||||
bool mask_any = lv_draw_mask_is_any(&map_area);
|
||||
uint8_t font_rgb[3];
|
||||
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
@@ -784,7 +783,7 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
|
||||
}
|
||||
|
||||
/*Apply masks if any*/
|
||||
if(other_mask_cnt) {
|
||||
if(mask_any) {
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, map_area.x1, map_area.y2,
|
||||
lv_area_get_width(&map_area));
|
||||
if(mask_res == LV_DRAW_MASK_RES_TRANSP) {
|
||||
|
||||
+10
-10
@@ -127,11 +127,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const
|
||||
int32_t w_half0 = w >> 1;
|
||||
int32_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
|
||||
|
||||
bool dashed = dsc->dash_gap && dsc->dash_width ? true : false;
|
||||
|
||||
bool simple_mode = true;
|
||||
if(lv_draw_mask_get_cnt()) simple_mode = false;
|
||||
else if(dashed) simple_mode = false;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = LV_MIN(point1->x, point2->x);
|
||||
@@ -139,6 +135,11 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const
|
||||
draw_area.y1 = point1->y - w_half1;
|
||||
draw_area.y2 = point1->y + w_half0;
|
||||
|
||||
bool dashed = dsc->dash_gap && dsc->dash_width ? true : false;
|
||||
bool simple_mode = true;
|
||||
if(lv_draw_mask_is_any(&draw_area)) simple_mode = false;
|
||||
else if(dashed) simple_mode = false;
|
||||
|
||||
/*If there is no mask then simply draw a rectangle*/
|
||||
if(simple_mode) {
|
||||
_lv_blend_fill(clip, &draw_area,
|
||||
@@ -227,18 +228,17 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const
|
||||
int32_t w_half0 = w >> 1;
|
||||
int32_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
|
||||
|
||||
bool dashed = dsc->dash_gap && dsc->dash_width ? true : false;
|
||||
|
||||
bool simple_mode = true;
|
||||
if(lv_draw_mask_get_cnt()) simple_mode = false;
|
||||
else if(dashed) simple_mode = false;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = point1->x - w_half1;
|
||||
draw_area.x2 = point1->x + w_half0;
|
||||
draw_area.y1 = LV_MIN(point1->y, point2->y);
|
||||
draw_area.y2 = LV_MAX(point1->y, point2->y) - 1;
|
||||
|
||||
bool dashed = dsc->dash_gap && dsc->dash_width ? true : false;
|
||||
bool simple_mode = true;
|
||||
if(lv_draw_mask_is_any(&draw_area)) simple_mode = false;
|
||||
else if(dashed) simple_mode = false;
|
||||
|
||||
/*If there is no mask then simply draw a rectangle*/
|
||||
if(simple_mode) {
|
||||
_lv_blend_fill(clip, &draw_area,
|
||||
|
||||
+22
-2
@@ -211,9 +211,29 @@ LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void)
|
||||
return cnt;
|
||||
}
|
||||
|
||||
bool lv_draw_mask_is_any(void)
|
||||
bool lv_draw_mask_is_any(const lv_area_t * a)
|
||||
{
|
||||
return LV_GC_ROOT(_lv_draw_mask_list[0]).param ? true : false;
|
||||
if(a == NULL) return LV_GC_ROOT(_lv_draw_mask_list[0]).param ? true : false;
|
||||
|
||||
uint8_t i;
|
||||
for(i = 0; i < _LV_MASK_MAX_NUM; i++) {
|
||||
_lv_draw_mask_common_dsc_t * comm_param = LV_GC_ROOT(_lv_draw_mask_list[i]).param;
|
||||
if(comm_param == NULL) continue;
|
||||
if(comm_param->type == LV_DRAW_MASK_TYPE_RADIUS) {
|
||||
lv_draw_mask_radius_param_t * radius_param = LV_GC_ROOT(_lv_draw_mask_list[i]).param;
|
||||
if(radius_param->cfg.outer) {
|
||||
if(!_lv_area_is_out(a, &radius_param->cfg.rect, radius_param->cfg.radius)) return true;
|
||||
}
|
||||
else {
|
||||
if(!_lv_area_is_in(a, &radius_param->cfg.rect, radius_param->cfg.radius)) return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,11 +55,14 @@ typedef _lv_draw_mask_saved_t _lv_draw_mask_saved_arr_t[_LV_MASK_MAX_NUM];
|
||||
|
||||
|
||||
#if LV_DRAW_COMPLEX == 0
|
||||
static inline uint8_t lv_draw_mask_get_cnt(void) {
|
||||
static inline uint8_t lv_draw_mask_get_cnt(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool lv_draw_mask_is_any(void) {
|
||||
static inline bool lv_draw_mask_is_any(const lv_area_t * a)
|
||||
{
|
||||
LV_UNUSED(a);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -277,9 +280,10 @@ LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void);
|
||||
|
||||
/**
|
||||
* Check is there is any added draw mask
|
||||
* @param a an area to test for affecting masks.
|
||||
* @return true: there is t least 1 draw mask; false: there are no draw masks
|
||||
*/
|
||||
bool lv_draw_mask_is_any(void);
|
||||
bool lv_draw_mask_is_any(const lv_area_t * a);
|
||||
|
||||
//! @endcond
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_are
|
||||
lv_grad_dir_t grad_dir = dsc->bg_grad_dir;
|
||||
if(dsc->bg_color.full == dsc->bg_grad_color.full) grad_dir = LV_GRAD_DIR_NONE;
|
||||
|
||||
bool mask_any = lv_draw_mask_is_any();
|
||||
bool mask_any = lv_draw_mask_is_any(&coords_bg);
|
||||
|
||||
/*Most simple case: just a plain rectangle*/
|
||||
if(!mask_any && dsc->radius == 0 && (grad_dir == LV_GRAD_DIR_NONE)) {
|
||||
@@ -497,7 +497,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv
|
||||
|
||||
|
||||
/*Skip a lot of masking if the background will cover the shadow that would be masked out*/
|
||||
bool mask_any = lv_draw_mask_is_any();
|
||||
bool mask_any = lv_draw_mask_is_any(&shadow_area);
|
||||
bool simple = true;
|
||||
if(mask_any || dsc->bg_opa < LV_OPA_COVER) simple = false;
|
||||
|
||||
@@ -1083,7 +1083,7 @@ void draw_border_generic(const lv_area_t * clip_area, const lv_area_t * outer_ar
|
||||
if(!_lv_area_intersect(&draw_area, outer_area, clip_area)) return;
|
||||
int32_t draw_area_w = lv_area_get_width(&draw_area);
|
||||
|
||||
bool mask_any = lv_draw_mask_is_any();
|
||||
bool mask_any = lv_draw_mask_is_any(outer_area);
|
||||
|
||||
/*Create a mask if there is a radius*/
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
|
||||
|
||||
Reference in New Issue
Block a user