Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
perf(draw) ignore masks if they don't affect the current draw area
  • Loading branch information
kisvegabor committed Aug 5, 2021
1 parent 4f9a037 commit a842791
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 38 deletions.
18 changes: 11 additions & 7 deletions src/core/lv_obj.c
Expand Up @@ -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
}
Expand All @@ -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

Expand All @@ -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;
Expand Down
16 changes: 8 additions & 8 deletions src/draw/lv_draw_img.c
Expand Up @@ -353,25 +353,25 @@ 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);
}

#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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/draw/lv_draw_label.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
20 changes: 10 additions & 10 deletions src/draw/lv_draw_line.c
Expand Up @@ -127,18 +127,19 @@ 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);
draw_area.x2 = LV_MAX(point1->x, point2->x) - 1;
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,
Expand Down Expand Up @@ -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,
Expand Down
24 changes: 22 additions & 2 deletions src/draw/lv_draw_mask.c
Expand Up @@ -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;

}

/**
Expand Down
10 changes: 7 additions & 3 deletions src/draw/lv_draw_mask.h
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions src/draw/lv_draw_rect.c
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit a842791

Please sign in to comment.