sqrt speed up tests

This commit is contained in:
Gabor Kiss-Vamosi
2020-04-06 09:02:24 +02:00
parent 06484394ce
commit 922cc6fc52
4 changed files with 59 additions and 9 deletions

View File

@@ -1,3 +1,7 @@
/** /**
* @file lv_mask.c * @file lv_mask.c
* *
@@ -372,6 +376,9 @@ void lv_draw_mask_radius_init(lv_draw_mask_radius_param_t * param, const lv_area
param->cfg.outer = inv ? 1 : 0; param->cfg.outer = inv ? 1 : 0;
param->dsc.cb = (lv_draw_mask_cb_t)lv_draw_mask_radius; param->dsc.cb = (lv_draw_mask_cb_t)lv_draw_mask_radius;
param->dsc.type = LV_DRAW_MASK_TYPE_RADIUS; param->dsc.type = LV_DRAW_MASK_TYPE_RADIUS;
param->y_prev = INT32_MIN;
param->y_prev_x.f = 0;
param->y_prev_x.i = 0;
} }
@@ -939,18 +946,43 @@ static lv_draw_mask_res_t lv_draw_mask_radius(lv_opa_t * mask_buf, lv_coord_t ab
if(radius <= 256) sqrt_mask = 0x800; if(radius <= 256) sqrt_mask = 0x800;
else sqrt_mask = 0x8000; else sqrt_mask = 0x8000;
lv_sqrt_res_t x0;
lv_sqrt_res_t x1;
/* y = 0 should mean the top of the circle */ /* y = 0 should mean the top of the circle */
int32_t y; int32_t y;
if(abs_y < radius) y = radius - abs_y; if(abs_y < radius) {
else y = radius - (h - abs_y) + 1; y = radius - abs_y;
/* Get the x intersection points for `abs_y` and `abs_y+1` /* Get the x intersection points for `abs_y` and `abs_y+1`
* Use the circle's equation x = sqrt(r^2 - y^2) */ * Use the circle's equation x = sqrt(r^2 - y^2) */
lv_sqrt_res_t x0; if(y == p->y_prev) {
lv_sqrt(r2 - (y * y), &x0, sqrt_mask); x0.f = p->y_prev_x.f;
x0.i = p->y_prev_x.i;
} else {
lv_sqrt(r2 - (y * y), &x0, sqrt_mask);
}
lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
p->y_prev = y-1;
p->y_prev_x.f = x1.f;
p->y_prev_x.i = x1.i;
}
else {
y = radius - (h - abs_y) + 1;
if((y-1) == p->y_prev) {
x1.f = p->y_prev_x.f;
x1.i = p->y_prev_x.i;
} else {
lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
}
lv_sqrt(r2 - (y * y), &x0, sqrt_mask);
p->y_prev = y;
p->y_prev_x.f = x0.f;
p->y_prev_x.i = x0.i;
}
printf("x0.i:%d, x0.f:%d, x1.i:%d, x1.f:%d\n", x0.i, x0.f, x1.i, x1.f);
lv_sqrt_res_t x1;
lv_sqrt(r2 - ((y - 1) * (y - 1)), &x1, sqrt_mask);
/* If x1 is on the next round coordinate (e.g. x0: 3.5, x1:4.0) /* If x1 is on the next round coordinate (e.g. x0: 3.5, x1:4.0)
* then treat x1 as x1: 3.99 to handle them as they were on the same pixel*/ * then treat x1 as x1: 3.99 to handle them as they were on the same pixel*/
@@ -1180,3 +1212,15 @@ static inline lv_opa_t mask_mix(lv_opa_t mask_act, lv_opa_t mask_new)
return (int32_t)((int32_t)(mask_act * mask_new) >> 8); return (int32_t)((int32_t)(mask_act * mask_new) >> 8);
} }
static inline sqrt_approx(lv_sqrt_res_t * q, lv_sqrt_res_t * ref, uint32_t x)
{
uint32_t raw = (ref->i << 4) + (ref->f >> 4);
}

View File

@@ -127,6 +127,8 @@ typedef struct {
/* Invert the mask. 0: Keep the pixels inside.*/ /* Invert the mask. 0: Keep the pixels inside.*/
uint8_t outer: 1; uint8_t outer: 1;
} cfg; } cfg;
int32_t y_prev;
lv_sqrt_res_t y_prev_x;
} lv_draw_mask_radius_param_t; } lv_draw_mask_radius_param_t;

View File

@@ -113,6 +113,8 @@ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3)
*/ */
void lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask) void lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask)
{ {
static volatile cnt = 0;
cnt++;
x = x << 8; /*To get 4 bit precision. (sqrt(256) = 16 = 4 bit)*/ x = x << 8; /*To get 4 bit precision. (sqrt(256) = 16 = 4 bit)*/
uint32_t root = 0; uint32_t root = 0;

View File

@@ -488,7 +488,9 @@ void lv_theme_mono_apply(lv_obj_t * obj, lv_theme_style_t name)
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN); lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN); list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
lv_style_list_add_style(list, &style_bg); lv_style_list_add_style(list, &style_bg);
lv_style_list_add_style(list, &style_pad_none); lv_style_list_add_style(list, &style_border_none);
lv_style_list_add_style(list, &style_no_radius);
// lv_style_list_add_style(list, &style_pad_none);
break; break;
case LV_THEME_OBJ: case LV_THEME_OBJ:
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN); lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);