[How to] How to use shadow in lvgl-dev7.0 lastest?

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(..)

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);

image

1 Like

Thank you : D

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.

capture_00249

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

Sure! I’ll add it!

1 Like

Thank you very much for updating shadow-drawing new version.

1 Like