Description
For previous lvgl dev7.0 can run shadow well, but when update to the lastest dev7.0.
It occurs some run-time error. How to use the newest lv_style_t with shadow?
Is there any simple example?
What MCU/Processor/Board and compiler are you using?
ESP32 with the lastest dev7.0
What do you want to achieve?
Set shadow attribute fot the object.
What have you tried so far?
Code to reproduce
void obj_with_shadow() {
lv_obj_t* my_obj = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_size(my_obj, 200,160);
lv_obj_align(my_obj, NULL, LV_ALIGN_CENTER,0,0);
static lv_style_t style;
lv_style_copy(&style, &lv_style_pretty_color);
style.body.radius = LV_RADIUS_CIRCLE;
style.body.main_color = LV_COLOR_RED;
style.body.grad_color = LV_COLOR_ORANGE;
style.body.border.color = LV_COLOR_BLUE;
style.body.border.width = 3;
style.body.border.opa = LV_OPA_30;
style.body.shadow.color = LV_COLOR_GREEN;
style.body.shadow.width = 5;
lv_obj_set_style(my_obj, &style);
}
Screenshot and/or video
Runtime error occurs at shadow_blur_corner(..)
Anda
January 18, 2020, 7:25am
2
Hi, you can achieve it like this
lv_obj_t *OBJ = lv_obj_create(lv_scr_act(), NULL);
static lv_style_t obj_style;
lv_style_copy(&obj_style, lv_obj_get_style(OBJ));
obj_style.body.radius = 20;
obj_style.body.main_color = LV_COLOR_MAGENTA;
obj_style.body.grad_color = LV_COLOR_MAGENTA;
obj_style.body.shadow.width = 2;
obj_style.body.shadow.color = LV_COLOR_PURPLE;
obj_style.body.shadow.opa = LV_OPA_90;
obj_style.body.shadow.offset = (lv_point_t){ 5, 5 };
obj_style.body.shadow.spread = 2;
lv_obj_set_style(OBJ, &obj_style);
lv_obj_set_size(OBJ, 100, 100);
lv_obj_align(OBJ, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_drag(OBJ, true);
1 Like
I have just tried by the rounded-rect, it’s ok.
However when make to a circle style
lv_obj_t *OBJ = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_size(OBJ, 100, 100);
lv_style_copy(&obj_style, lv_obj_get_style(OBJ));
obj_style.body.radius = LV_RADIUS_CIRCLE;
obj_style.body.main_color = LV_COLOR_MAGENTA;
obj_style.body.grad_color = LV_COLOR_MAGENTA;
obj_style.body.shadow.width = 10;
obj_style.body.shadow.color = LV_COLOR_PURPLE;
obj_style.body.shadow.opa = LV_OPA_90;
obj_style.body.shadow.offset = (lv_point_t){ 0, 0 };
obj_style.body.shadow.spread = 10;
lv_obj_set_style(OBJ, &obj_style);
lv_obj_align(OBJ, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_drag(OBJ, true);
This code is ok. But when change to
lv_obj_set_size(OBJ, 160, 160);
It occurs runtime-error. Maybe it is a bug?.
I’ve temporarily unmarked the solution so that @kisvegabor will know the problem hasn’t been completely solved.
1 Like
It works for me with both 160 and 200.
Do you use the latest version?
If you still see the error please report the line of the crash with the updated version.
I have just updated again to the lastest 3 days ago commit c8027aa
and have tested by the following code on ESP32.
OBJ = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_size(OBJ, 160, 160);
lv_style_copy(&obj_style, &lv_style_plain);//lv_obj_get_style(OBJ));
obj_style.body.radius = LV_RADIUS_CIRCLE;
obj_style.body.main_color = LV_COLOR_MAGENTA;
obj_style.body.grad_color = LV_COLOR_MAGENTA;
obj_style.body.shadow.width = 10;
obj_style.body.shadow.color = LV_COLOR_PURPLE;
obj_style.body.shadow.opa = LV_OPA_90;
obj_style.body.shadow.offset = (lv_point_t){ 0, 0 };
obj_style.body.shadow.spread = 10;
lv_obj_set_style(OBJ, &obj_style);
lv_obj_align(OBJ, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_drag(OBJ, true);
The runtime-error is founded at
shadow_blur_corner(..)
at lv_draw_rect.c line 973
I’ve just found what could be the issue.
dev-7.0
uses some temporal buffers during shadow drawing which are allocated n lv_mem
. The require size is (radius + shadow_width + shadow_spread)^2 * 5 = (80 + 10 + 10)^2 * 5 = 50k
. So I suppose you are out of memory.
With a small radius it should a more acceptable number. E.g. (5 + 5 + 2)^2 * 5 = 720 bytes
.
I’ll take look how to reduce the memory usage here.
1 Like
I’ve just added an update which reduces the memory usage by 30-40%. The new formula is:
size = radius + shadow_width + shadow_spread
mem = 3 * size^2 + 2 * size
Examples:
size = 12
mem = 456
size = 100
mem = 30k
1 Like
Can we bail out of drawing in that case instead of segfaulting? It would be cleaner, in my opinion.
OK, it’s worked now.
My ESP32 has PSRAM4 MB
I set lv_mem to PSRAM instead.
1 Like
Great!
I further reduced the memory usage to about 40% of the original.
size: 5 old: 125 new: 65 (52%)
size: 10 old: 500 new: 230 (46%)
size: 15 old: 1125 new: 495 (44%)
size: 20 old: 2000 new: 860 (43%)
size: 25 old: 3125 new: 1325 (42%)
size: 30 old: 4500 new: 1890 (42%)
size: 50 old: 12500 new: 5150 (41%)
size: 100 old: 50000 new: 20300 (40%)
size: 200 old: 200000 new: 80600 (40%)
1 Like
Thank you very much for updating shadow-drawing new version.
1 Like