1 /**
2  * @file lv_demo_benchmark.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_demo_benchmark.h"
10 
11 #if LV_USE_DEMO_BENCHMARK
12 
13 #if LV_FONT_MONTSERRAT_14 == 0
14     #error "LV_FONT_MONTSERRAT_14 is required for lv_demo_benchmark. Enable it in lv_conf.h."
15 #endif
16 
17 #if LV_FONT_MONTSERRAT_20 == 0
18     #error "LV_FONT_MONTSERRAT_20 is required for lv_demo_benchmark. Enable it in lv_conf.h."
19 #endif
20 
21 #if LV_FONT_MONTSERRAT_24 == 0
22     #error "LV_FONT_MONTSERRAT_24 is required for lv_demo_benchmark. Enable it in lv_conf.h."
23 #endif
24 
25 #if LV_FONT_MONTSERRAT_26 == 0
26     #error "LV_FONT_MONTSERRAT_26 is required for lv_demo_benchmark. Enable it in lv_conf.h."
27 #endif
28 
29 #if LV_USE_DEMO_WIDGETS == 0
30     #error "LV_USE_DEMO_WIDGETS needs to be enabled"
31 #endif
32 
33 #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN && LV_MEM_SIZE < 128 * 1024
34     #warning "It's recommended to have at least 128kB RAM for the benchmark"
35 #endif
36 
37 #include "../../lvgl_private.h"
38 
39 /**********************
40  *      DEFINES
41  **********************/
42 #define HEADER_HEIGHT   48
43 #define FALL_HEIGHT     80
44 #define PAD_BASIC       8
45 
46 /**********************
47  *      TYPEDEFS
48  **********************/
49 
50 typedef struct {
51     const char * name;
52     void (*create_cb)(void);
53     uint32_t scene_time;
54     uint32_t cpu_avg_usage;
55     uint32_t fps_avg;
56     uint32_t render_avg_time;
57     uint32_t flush_avg_time;
58     uint32_t measurement_cnt;
59 } scene_dsc_t;
60 
61 /**********************
62  *  STATIC PROTOTYPES
63  **********************/
64 
65 static void load_scene(uint32_t scene);
66 static void next_scene_timer_cb(lv_timer_t * timer);
67 
68 #if LV_USE_PERF_MONITOR
69     static void sysmon_perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
70 #endif
71 
72 static void summary_create(void);
73 
74 static void rnd_reset(void);
75 static int32_t rnd_next(int32_t min, int32_t max);
76 static lv_color_t rnd_color(void);
77 static void shake_anim_y_cb(void * var, int32_t v);
78 static void fall_anim(lv_obj_t * obj, int32_t y_max);
79 static void scroll_anim(lv_obj_t * obj, int32_t y_max);
80 static void scroll_anim_y_cb(void * var, int32_t v);
81 static void color_anim_cb(void * var, int32_t v);
82 static void color_anim(lv_obj_t * obj);
83 static void arc_anim(lv_obj_t * obj);
84 
85 static lv_obj_t * card_create(void);
86 
empty_screen_cb(void)87 static void empty_screen_cb(void)
88 {
89     color_anim(lv_screen_active());
90 }
91 
moving_wallpaper_cb(void)92 static void moving_wallpaper_cb(void)
93 {
94     lv_obj_set_style_pad_all(lv_screen_active(), 0, 0);
95     LV_IMAGE_DECLARE(img_benchmark_lvgl_logo_rgb);
96 
97     lv_obj_t * img = lv_image_create(lv_screen_active());
98     lv_obj_set_size(img, lv_pct(150), lv_pct(150));
99     lv_image_set_src(img, &img_benchmark_lvgl_logo_rgb);
100     lv_image_set_inner_align(img, LV_IMAGE_ALIGN_TILE);
101     fall_anim(img, - lv_display_get_vertical_resolution(NULL) / 3);
102 }
103 
single_rectangle_cb(void)104 static void single_rectangle_cb(void)
105 {
106     lv_obj_t * obj = lv_obj_create(lv_screen_active());
107     lv_obj_remove_style_all(obj);
108     lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0);
109     lv_obj_center(obj);
110     lv_obj_set_size(obj, lv_pct(30), lv_pct(30));
111 
112     color_anim(obj);
113 
114 }
115 
multiple_rectangles_cb(void)116 static void multiple_rectangles_cb(void)
117 {
118     lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_ROW_WRAP);
119     lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_EVENLY);
120 
121     uint32_t i;
122     for(i = 0; i < 9; i++) {
123         lv_obj_t * obj = lv_obj_create(lv_screen_active());
124         lv_obj_remove_style_all(obj);
125         lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0);
126         lv_obj_set_size(obj, lv_pct(25), lv_pct(25));
127 
128         color_anim(obj);
129     }
130 }
131 
multiple_rgb_images_cb(void)132 static void multiple_rgb_images_cb(void)
133 {
134     lv_obj_t * scr = lv_screen_active();
135     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
136     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
137     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
138 
139     LV_IMAGE_DECLARE(img_benchmark_lvgl_logo_rgb);
140     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 160;
141     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 160;
142 
143     if(hor_cnt < 1) hor_cnt = 1;
144     if(ver_cnt < 1) ver_cnt = 1;
145 
146     int32_t y;
147     for(y = 0; y < ver_cnt; y++) {
148         int32_t x;
149         for(x = 0; x < hor_cnt; x++) {
150             lv_obj_t * obj = lv_image_create(lv_screen_active());
151             lv_image_set_src(obj, &img_benchmark_lvgl_logo_rgb);
152             if(x == 0) lv_obj_add_flag(obj, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
153 
154             fall_anim(obj, 80);
155         }
156     }
157 }
158 
multiple_argb_images_cb(void)159 static void multiple_argb_images_cb(void)
160 {
161     lv_obj_t * scr = lv_screen_active();
162     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
163     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
164     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
165 
166     LV_IMAGE_DECLARE(img_benchmark_lvgl_logo_argb);
167     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 160;
168     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 160;
169 
170     if(hor_cnt < 1) hor_cnt = 1;
171     if(ver_cnt < 1) ver_cnt = 1;
172 
173     int32_t y;
174     for(y = 0; y < ver_cnt; y++) {
175         int32_t x;
176         for(x = 0; x < hor_cnt; x++) {
177             lv_obj_t * obj = lv_image_create(lv_screen_active());
178             lv_image_set_src(obj, &img_benchmark_lvgl_logo_argb);
179             if(x == 0) lv_obj_add_flag(obj, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
180 
181             fall_anim(obj, 80);
182         }
183     }
184 }
185 
rotated_argb_image_cb(void)186 static void rotated_argb_image_cb(void)
187 {
188     lv_obj_t * scr = lv_screen_active();
189     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
190     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
191     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
192 
193     LV_IMAGE_DECLARE(img_benchmark_lvgl_logo_argb);
194     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 240;   /*240 instead of 160 to have less rotated images*/
195     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 240;
196 
197     if(hor_cnt < 1) hor_cnt = 1;
198     if(ver_cnt < 1) ver_cnt = 1;
199 
200     int32_t y;
201     for(y = 0; y < ver_cnt; y++) {
202         int32_t x;
203         for(x = 0; x < hor_cnt; x++) {
204             lv_obj_t * obj = lv_image_create(lv_screen_active());
205             lv_image_set_src(obj, &img_benchmark_lvgl_logo_argb);
206             if(x == 0) lv_obj_add_flag(obj, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
207 
208             lv_image_set_rotation(obj, lv_rand(100, 3500));
209             fall_anim(obj, 80);
210         }
211     }
212 }
213 
multiple_labels_cb(void)214 static void multiple_labels_cb(void)
215 {
216     lv_obj_t * scr = lv_screen_active();
217     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
218     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
219 
220     int32_t hor_res = lv_display_get_horizontal_resolution(NULL);
221     int32_t ver_res = lv_display_get_vertical_resolution(NULL);
222     if(hor_res * ver_res > 800 * 480) lv_obj_set_style_text_font(scr, &lv_font_montserrat_26, 0);
223     else if(hor_res * ver_res > 320 * 240) lv_obj_set_style_text_font(scr, &lv_font_montserrat_20, 0);
224     else lv_obj_set_style_text_font(scr, &lv_font_montserrat_14, 0);
225 
226     lv_point_t s;
227     lv_text_get_size(&s, "Hello LVGL!", lv_obj_get_style_text_font(scr, 0), 0, 0, LV_COORD_MAX,
228                      LV_TEXT_FLAG_NONE);
229 
230     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / (s.x * 3 / 2);
231     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / (s.y  * 3);
232 
233     if(hor_cnt < 1) hor_cnt = 1;
234     if(ver_cnt < 1) ver_cnt = 1;
235 
236     int32_t y;
237     for(y = 0; y < ver_cnt; y++) {
238         int32_t x;
239         for(x = 0; x < hor_cnt; x++) {
240             lv_obj_t * obj = lv_label_create(lv_screen_active());
241             if(x == 0) lv_obj_add_flag(obj, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
242             lv_label_set_text_static(obj, "Hello LVGL!");
243             color_anim(obj);
244         }
245     }
246 }
247 
screen_sized_text_cb(void)248 static void screen_sized_text_cb(void)
249 {
250     const char * txt =
251         "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque fringilla, lorem dapibus fringilla feugiat, justo arcu volutpat magna, vitae ultricies metus tortor nec est. Fusce ut tellus arcu. Fusce eu rutrum metus, nec porta felis. Sed sed ligula laoreet, sodales lacus blandit, elementum justo. Sed posuere quam ut pellentesque ullamcorper. In quis consequat magna. Etiam quis turpis nec lorem dictum finibus. Donec mattis enim dolor, consequat lacinia nisi scelerisque id. Nulla euismod, purus sit amet accumsan tempus, lorem lectus euismod dolor, sit amet facilisis nisl quam elementum nisi. Curabitur et massa eget lorem lacinia scelerisque eget vitae felis. Nulla facilisi.\n\n"
252         "Vivamus auctor sit amet ante id rhoncus. Duis a dolor neque. Mauris eu ornare tortor. Vivamus consequat, ipsum a volutpat congue, sem libero laoreet nulla, malesuada efficitur leo orci a est. Donec tincidunt nulla nibh, quis pretium mi fermentum quis. Fusce a mattis libero. Curabitur in felis suscipit, ultrices diam imperdiet, vestibulum arcu. Praesent id faucibus turpis. Pellentesque sed massa tincidunt, interdum purus tempus, pellentesque risus. Fusce feugiat magna eget nisl eleifend efficitur. Mauris ut convallis justo. Integer malesuada rutrum orci non tincidunt.\n\n"
253         "Nullam aliquet leo sit amet volutpat tincidunt. Mauris ac accumsan nibh. Morbi accumsan commodo leo, at hendrerit massa hendrerit et. Aliquam nec sodales ex. Morbi at aliquet sem. Sed at magna ut felis mollis dictum ut ac orci. Nunc id lorem lacus. Vivamus id accumsan dolor, sed suscipit nulla. Pellentesque dictum erat non bibendum tempor. Fusce arcu risus, eleifend in lacus a, iaculis fermentum sapien. Praesent sodales libero vitae massa suscipit tincidunt. Aliquam quis arcu urna. Nunc sit amet mi leo.\n\n"
254         "Aliquam erat volutpat. Sed viverra pharetra ipsum, sed various arcu various nec. Curabitur rutrum odio et pretium fermentum. Maecenas vitae ligula nisi. Maecenas nec dapibus erat. Suspendisse vel accumsan erat. Proin congue diam at turpis accumsan eleifend.\n\n"
255         "Etiam suscipit metus magna, in vulputate magna cursus eget. Donec vel rhoncus turpis. Phasellus vitae enim quis sapien pharetra aliquam quis a quam. In mauris nulla, euismod quis orci et, interdum finibus lorem. Aenean quis dolor eget est ultricies consectetur eu nec metus. Nullam at pulvinar elit. Aenean blandit faucibus sodales. Vivamus vel porta enim, et pharetra libero. Donec aliquet pretium erat viverra fermentum. Fusce sit amet porta mi. Nullam non elit ex. In luctus, nunc id iaculis ullamcorper, eros quam eleifend elit, quis dictum sem justo eu eros. Nulla vitae faucibus lectus. Nunc blandit, mi eget suscipit scelerisque, lorem nunc tincidunt tellus, eget gravida libero metus sed nunc.\n\n"
256         "Morbi erat libero, commodo sit amet turpis eget, efficitur pulvinar dolor. Pellentesque vehicula, velit eget auctor scelerisque, sem risus aliquam lectus, sit amet dapibus massa ex non magna. Donec magna leo, laoreet quis erat vitae, consequat aliquet tellus. Etiam vitae lectus erat. Mauris interdum feugiat aliquet. Nunc justo augue, mattis id finibus eu, sagittis id enim. Vivamus malesuada mauris sed nibh luctus, porta bibendum quam ornare. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Vivamus malesuada magna nec diam tempus, laoreet imperdiet magna faucibus. Aliquam erat volutpat.\n\n"
257         "Aenean mattis lobortis quam in venenatis. Sed euismod convallis lectus vel euismod. Vestibulum consequat luctus neque. Quisque consequat bibendum neque eget mollis. Vivamus viverra vehicula eros vel dapibus. Nullam id lectus aliquam, sagittis mi efficitur, interdum mauris. Nunc at felis lobortis, lobortis erat a, euismod augue. In id purus malesuada, tempus magna at, porta mi. Sed tristique nunc eget placerat luctus. Pellentesque posuere non purus vitae malesuada. Curabitur hendrerit dolor metus, nec posuere orci placerat ac.\n\n";
258 
259     lv_obj_t * scr = lv_screen_active();
260     int32_t hor_res = lv_display_get_horizontal_resolution(NULL);
261     int32_t ver_res = lv_display_get_vertical_resolution(NULL);
262     if(hor_res * ver_res > 800 * 480) lv_obj_set_style_text_font(scr, &lv_font_montserrat_26, 0);
263     else if(hor_res * ver_res > 320 * 240) lv_obj_set_style_text_font(scr, &lv_font_montserrat_20, 0);
264     else lv_obj_set_style_text_font(scr, &lv_font_montserrat_14, 0);
265 
266     lv_obj_t * obj = lv_label_create(scr);
267     lv_obj_set_width(obj, lv_pct(100));
268     lv_label_set_text_static(obj, txt);
269 
270     lv_obj_update_layout(obj);
271 
272     scroll_anim(scr, lv_obj_get_scroll_bottom(scr));
273 }
274 
multiple_arcs_cb(void)275 static void multiple_arcs_cb(void)
276 {
277     lv_obj_t * scr = lv_screen_active();
278     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
279     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
280 
281     LV_IMAGE_DECLARE(img_benchmark_lvgl_logo_argb);
282 
283     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 160;
284     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 160;
285 
286     if(hor_cnt < 1) hor_cnt = 1;
287     if(ver_cnt < 1) ver_cnt = 1;
288 
289     int32_t y;
290     for(y = 0; y < ver_cnt; y++) {
291         int32_t x;
292         for(x = 0; x < hor_cnt; x++) {
293 
294             lv_obj_t * obj = lv_arc_create(lv_screen_active());
295             if(x == 0) lv_obj_add_flag(obj, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
296             lv_obj_set_size(obj, 100, 100);
297             lv_obj_center(obj);
298 
299             lv_arc_set_bg_angles(obj, 0, 360);
300 
301             lv_obj_set_style_arc_opa(obj, 0, LV_PART_MAIN);
302             lv_obj_set_style_bg_opa(obj, 0, LV_PART_KNOB);
303             lv_obj_set_style_arc_width(obj, 10, LV_PART_INDICATOR);
304             lv_obj_set_style_arc_rounded(obj, false, LV_PART_INDICATOR);
305             lv_obj_set_style_arc_color(obj, rnd_color(), LV_PART_INDICATOR);
306             arc_anim(obj);
307         }
308     }
309 }
310 
containers_cb(void)311 static void containers_cb(void)
312 {
313     lv_obj_t * scr = lv_screen_active();
314     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
315     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
316     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
317 
318     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 350;
319     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 170;
320 
321     if(hor_cnt < 1) hor_cnt = 1;
322     if(ver_cnt < 1) ver_cnt = 1;
323 
324     int32_t y;
325     for(y = 0; y < ver_cnt; y++) {
326         int32_t x;
327         for(x = 0; x < hor_cnt; x++) {
328             lv_obj_t * card = card_create();
329             if(x == 0) lv_obj_add_flag(card, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
330             fall_anim(card, 30);
331         }
332     }
333 }
334 
containers_with_overlay_cb(void)335 static void containers_with_overlay_cb(void)
336 {
337     lv_obj_t * scr = lv_screen_active();
338     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
339     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
340     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
341 
342     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 350;
343     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 170;
344 
345     if(hor_cnt < 1) hor_cnt = 1;
346     if(ver_cnt < 1) ver_cnt = 1;
347 
348     int32_t y;
349     for(y = 0; y < ver_cnt; y++) {
350         int32_t x;
351         for(x = 0; x < hor_cnt; x++) {
352             lv_obj_t * card = card_create();
353             if(x == 0) lv_obj_add_flag(card, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
354             fall_anim(card, 30);
355         }
356     }
357 
358     lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0);
359     color_anim(lv_layer_top());
360 }
361 
containers_with_opa_cb(void)362 static void containers_with_opa_cb(void)
363 {
364     lv_obj_t * scr = lv_screen_active();
365     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
366     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
367     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
368 
369     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 350;
370     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 170;
371 
372     if(hor_cnt < 1) hor_cnt = 1;
373     if(ver_cnt < 1) ver_cnt = 1;
374 
375     int32_t y;
376     for(y = 0; y < ver_cnt; y++) {
377         int32_t x;
378         for(x = 0; x < hor_cnt; x++) {
379             lv_obj_t * card = card_create();
380             if(x == 0) lv_obj_add_flag(card, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
381             lv_obj_set_style_opa(card, LV_OPA_50, 0);
382             fall_anim(card, 30);
383         }
384     }
385 }
386 
containers_with_opa_layer_cb(void)387 static void containers_with_opa_layer_cb(void)
388 {
389     lv_obj_t * scr = lv_screen_active();
390     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
391     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_EVENLY);
392     lv_obj_set_style_pad_bottom(scr, FALL_HEIGHT + PAD_BASIC, 0);
393 
394     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 350;
395     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / 170;
396 
397     if(hor_cnt < 1) hor_cnt = 1;
398     if(ver_cnt < 1) ver_cnt = 1;
399 
400     int32_t y;
401     for(y = 0; y < ver_cnt; y++) {
402         int32_t x;
403         for(x = 0; x < hor_cnt; x++) {
404             lv_obj_t * card = card_create();
405             lv_obj_set_style_opa_layered(card, LV_OPA_50, 0);
406             if(x == 0) lv_obj_add_flag(card, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
407             fall_anim(card, 30);
408         }
409     }
410 }
411 
containers_with_scrolling_cb(void)412 static void containers_with_scrolling_cb(void)
413 {
414     lv_obj_t * scr = lv_screen_active();
415     lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_ROW_WRAP);
416     lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
417     lv_obj_set_style_pad_row(scr, 32, 0);
418 
419     int32_t hor_cnt = ((int32_t)lv_obj_get_content_width(scr)) / 400;
420     int32_t ver_cnt = ((int32_t)lv_obj_get_content_height(scr)) / (120 + 32);
421 
422     if(hor_cnt < 1) hor_cnt = 1;
423     if(ver_cnt < 1) ver_cnt = 1;
424 
425     ver_cnt *= 2; /*To make it scroll*/
426     if(ver_cnt < 20) ver_cnt = 20; /*The test with many widgets*/
427 
428     int32_t y;
429     for(y = 0; y < ver_cnt; y++) {
430         int32_t x;
431         for(x = 0; x < hor_cnt; x++) {
432             lv_obj_t * card = card_create();
433             if(x == 0) lv_obj_add_flag(card, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
434         }
435     }
436 
437     lv_obj_update_layout(scr);
438     scroll_anim(scr, lv_obj_get_scroll_bottom(scr));
439 }
440 
widgets_demo_cb(void)441 static void widgets_demo_cb(void)
442 {
443     lv_obj_t * scr = lv_screen_active();
444     lv_obj_set_style_pad_hor(scr, 0, 0);
445     lv_obj_set_style_pad_bottom(scr, 0, 0);
446     lv_demo_widgets();
447     lv_demo_widgets_start_slideshow();
448 
449 }
450 
451 /**********************
452  *  STATIC VARIABLES
453  **********************/
454 
455 static scene_dsc_t scenes[] = {
456     {.name = "Empty screen",               .scene_time = 3000, .create_cb = empty_screen_cb},
457     {.name = "Moving wallpaper",           .scene_time = 3000, .create_cb = moving_wallpaper_cb},
458     {.name = "Single rectangle",           .scene_time = 3000, .create_cb = single_rectangle_cb},
459     {.name = "Multiple rectangles",        .scene_time = 3000, .create_cb = multiple_rectangles_cb},
460     {.name = "Multiple RGB images",        .scene_time = 3000, .create_cb = multiple_rgb_images_cb},
461     {.name = "Multiple ARGB images",       .scene_time = 3000, .create_cb = multiple_argb_images_cb},
462     {.name = "Rotated ARGB images",        .scene_time = 3000, .create_cb = rotated_argb_image_cb},
463     {.name = "Multiple labels",            .scene_time = 3000, .create_cb = multiple_labels_cb},
464     {.name = "Screen sized text",          .scene_time = 5000, .create_cb = screen_sized_text_cb},
465     {.name = "Multiple arcs",              .scene_time = 3000, .create_cb = multiple_arcs_cb},
466 
467     {.name = "Containers",                 .scene_time = 3000, .create_cb = containers_cb},
468     {.name = "Containers with overlay",    .scene_time = 3000, .create_cb = containers_with_overlay_cb},
469     {.name = "Containers with opa",        .scene_time = 3000, .create_cb = containers_with_opa_cb},
470     {.name = "Containers with opa_layer",  .scene_time = 3000, .create_cb = containers_with_opa_layer_cb},
471     {.name = "Containers with scrolling",  .scene_time = 5000, .create_cb = containers_with_scrolling_cb},
472 
473     {.name = "Widgets demo",               .scene_time = 20000,           .create_cb = widgets_demo_cb},
474 
475     {.name = "", .create_cb = NULL}
476 };
477 
478 static uint32_t scene_act;
479 static uint32_t rnd_act;
480 
481 /**********************
482  *      MACROS
483  **********************/
484 
485 /**********************
486  *   GLOBAL FUNCTIONS
487  **********************/
488 
lv_demo_benchmark(void)489 void lv_demo_benchmark(void)
490 {
491     scene_act = 0;
492 
493     lv_obj_t * scr = lv_screen_active();
494     lv_obj_remove_style_all(scr);
495     lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
496     lv_obj_set_style_text_color(scr, lv_color_black(), 0);
497     lv_obj_set_style_bg_color(scr, lv_palette_lighten(LV_PALETTE_GREY, 4), 0);
498     lv_obj_set_style_pad_all(lv_screen_active(), 8, 0);
499     lv_obj_set_style_pad_top(lv_screen_active(), HEADER_HEIGHT, 0);
500     lv_obj_set_style_pad_gap(lv_screen_active(), 8, 0);
501 
502     lv_obj_t * title = lv_label_create(lv_layer_top());
503     lv_obj_set_style_bg_opa(title, LV_OPA_COVER, 0);
504     lv_obj_set_style_bg_color(title, lv_color_white(), 0);
505     lv_obj_set_style_text_color(title, lv_color_black(), 0);
506     lv_obj_set_width(title, lv_pct(100));
507 
508     load_scene(scene_act);
509 
510     lv_timer_create(next_scene_timer_cb, scenes[0].scene_time, NULL);
511 
512 #if LV_USE_PERF_MONITOR
513     lv_display_t * disp = lv_display_get_default();
514     lv_subject_add_observer_obj(&disp->perf_sysmon_backend.subject, sysmon_perf_observer_cb, title, NULL);
515 #else
516     lv_label_set_text(title, "LV_USE_PERF_MONITOR is not enabled");
517 #endif
518 }
519 
520 /**********************
521  *   STATIC FUNCTIONS
522  **********************/
523 
load_scene(uint32_t scene)524 static void load_scene(uint32_t scene)
525 {
526     lv_obj_t * scr = lv_screen_active();
527     lv_obj_clean(scr);
528     lv_obj_set_style_bg_color(scr, lv_palette_lighten(LV_PALETTE_GREY, 4), 0);
529     lv_obj_set_style_text_color(scr, lv_color_black(), 0);
530     lv_obj_set_style_text_font(scr, LV_FONT_DEFAULT, 0);
531     lv_obj_set_style_pad_all(scr, PAD_BASIC, 0);
532     lv_obj_set_style_pad_gap(scr, PAD_BASIC, 0);
533     lv_obj_set_style_pad_top(scr, HEADER_HEIGHT, 0);
534     lv_obj_set_layout(scr, LV_LAYOUT_NONE);
535     lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
536 
537     lv_anim_delete(scr, scroll_anim_y_cb);
538     lv_anim_delete(scr, shake_anim_y_cb);
539     lv_anim_delete(scr, color_anim_cb);
540 
541     lv_anim_delete(lv_layer_top(), color_anim_cb);
542     lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0);
543 
544     rnd_reset();
545     if(scenes[scene].create_cb) scenes[scene].create_cb();
546 }
547 
next_scene_timer_cb(lv_timer_t * timer)548 static void next_scene_timer_cb(lv_timer_t * timer)
549 {
550     LV_UNUSED(timer);
551 
552     scene_act++;
553 
554     load_scene(scene_act);
555     if(scenes[scene_act].scene_time == 0) {
556         lv_timer_delete(timer);
557         summary_create();
558     }
559     else {
560         lv_timer_set_period(timer, scenes[scene_act].scene_time);
561     }
562 }
563 
564 #if LV_USE_PERF_MONITOR
sysmon_perf_observer_cb(lv_observer_t * observer,lv_subject_t * subject)565 static void sysmon_perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
566 {
567     const lv_sysmon_perf_info_t * info = lv_subject_get_pointer(subject);
568     lv_obj_t * label = lv_observer_get_target(observer);
569 
570     char scene_name[64];
571     if(scenes[scene_act].name[0] != '\0') {
572         lv_snprintf(scene_name, sizeof(scene_name), "%s: ", scenes[scene_act].name);
573     }
574     else {
575         scene_name[0] = '\0';
576     }
577 
578     lv_label_set_text_fmt(label,
579                           "%s"
580                           "%" LV_PRIu32" FPS, %" LV_PRIu32 "%% CPU\n"
581                           "refr. %" LV_PRIu32" ms = %" LV_PRIu32 "ms render + %" LV_PRIu32" ms flush",
582                           scene_name,
583                           info->calculated.fps, info->calculated.cpu,
584                           info->calculated.render_avg_time + info->calculated.flush_avg_time,
585                           info->calculated.render_avg_time, info->calculated.flush_avg_time);
586 
587     /*Ignore the first call as it contains data from the previous scene*/
588     if(scenes[scene_act].measurement_cnt != 0) {
589         scenes[scene_act].cpu_avg_usage += info->calculated.cpu;
590         scenes[scene_act].fps_avg += info->calculated.fps;
591         scenes[scene_act].render_avg_time += info->calculated.render_avg_time;
592         scenes[scene_act].flush_avg_time += info->calculated.flush_avg_time;
593     }
594     scenes[scene_act].measurement_cnt++;
595 
596 }
597 #endif
598 
table_draw_task_event_cb(lv_event_t * e)599 static void table_draw_task_event_cb(lv_event_t * e)
600 {
601     lv_draw_task_t * t = lv_event_get_draw_task(e);
602     lv_draw_dsc_base_t * draw_dsc_base = t->draw_dsc;
603     if(draw_dsc_base->part != LV_PART_ITEMS) return;
604 
605     int32_t row = draw_dsc_base->id1;
606     if(row == 0) {
607         lv_draw_fill_dsc_t * draw_dsc_fill = lv_draw_task_get_fill_dsc(t);
608         if(draw_dsc_fill) {
609             draw_dsc_fill->color = lv_palette_darken(LV_PALETTE_BLUE_GREY, 4);
610         }
611         lv_draw_label_dsc_t * draw_dsc_label = lv_draw_task_get_label_dsc(t);
612         if(draw_dsc_label) {
613             draw_dsc_label->color = lv_color_white();
614         }
615     }
616     else if(row == 1) {
617         lv_draw_border_dsc_t * draw_dsc_border = lv_draw_task_get_border_dsc(t);
618         if(draw_dsc_border) {
619             draw_dsc_border->color = lv_palette_darken(LV_PALETTE_BLUE_GREY, 4);
620             draw_dsc_border->width = 2;
621             draw_dsc_border->side = LV_BORDER_SIDE_BOTTOM;
622         }
623         lv_draw_label_dsc_t * draw_dsc_label = lv_draw_task_get_label_dsc(t);
624         if(draw_dsc_label) {
625             draw_dsc_label->color = lv_palette_darken(LV_PALETTE_BLUE_GREY, 4);
626         }
627     }
628 
629 }
630 
summary_create(void)631 static void summary_create(void)
632 {
633     lv_obj_clean(lv_screen_active());
634     lv_obj_set_style_pad_hor(lv_screen_active(), 0, 0);
635     lv_obj_t * table = lv_table_create(lv_screen_active());
636     lv_obj_set_width(table, lv_pct(100));
637     lv_obj_set_style_max_height(table, lv_pct(100), 0);
638     lv_obj_add_flag(table, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
639     lv_obj_set_style_text_color(table, lv_palette_darken(LV_PALETTE_BLUE_GREY, 2), LV_PART_ITEMS);
640     lv_obj_set_style_border_color(table, lv_palette_darken(LV_PALETTE_BLUE_GREY, 2), LV_PART_ITEMS);
641     lv_obj_add_event_cb(table, table_draw_task_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
642 
643     lv_table_set_cell_value(table, 0, 0, "Name");
644     lv_table_set_cell_value(table, 0, 1, "Avg. CPU");
645     lv_table_set_cell_value(table, 0, 2, "Avg. FPS");
646     lv_table_set_cell_value(table, 0, 3, "Avg. time (render + flush)");
647 
648     /* csv log */
649     LV_LOG("Benchmark Summary (%d.%d.%d %s)\r\n",
650            LVGL_VERSION_MAJOR,
651            LVGL_VERSION_MINOR,
652            LVGL_VERSION_PATCH,
653            LVGL_VERSION_INFO);
654     LV_LOG("Name, Avg. CPU, Avg. FPS, Avg. time, render time, flush time\r\n");
655 
656     lv_obj_update_layout(table);
657     int32_t col_w = lv_obj_get_content_width(table) / 4;
658 
659     lv_table_set_column_width(table, 0, col_w);
660     lv_table_set_column_width(table, 1, col_w);
661     lv_table_set_column_width(table, 2, col_w);
662     lv_table_set_column_width(table, 3, col_w);
663 
664     uint32_t i;
665     int32_t total_avg_fps = 0;
666     int32_t total_avg_cpu = 0;
667     int32_t total_avg_render_time = 0;
668     int32_t total_avg_flush_time = 0;
669     int32_t valid_scene_cnt = 0;
670     for(i = 0; scenes[i].create_cb; i++) {
671         lv_table_set_cell_value(table, i + 2, 0, scenes[i].name);
672 
673         /*the first measurement was ignored as it contains data from the previous scene*/
674         if(scenes[i].measurement_cnt <= 1) {
675             lv_table_set_cell_value(table, i + 2, 1, "N/A");
676             lv_table_set_cell_value(table, i + 2, 2, "N/A");
677             lv_table_set_cell_value(table, i + 2, 3, "N/A");
678         }
679         else {
680             int32_t cnt = scenes[i].measurement_cnt - 1;
681             lv_table_set_cell_value_fmt(table, i + 2, 1, "%"LV_PRIu32" %%", scenes[i].cpu_avg_usage / cnt);
682             lv_table_set_cell_value_fmt(table, i + 2, 2, "%"LV_PRIu32" FPS", scenes[i].fps_avg / cnt);
683 
684             uint32_t render_time = scenes[i].render_avg_time / cnt;
685             uint32_t flush_time = scenes[i].flush_avg_time / cnt;
686             lv_table_set_cell_value_fmt(table, i + 2, 3, "%"LV_PRIu32" ms (%"LV_PRIu32" + %"LV_PRIu32")",
687                                         render_time + flush_time, render_time, flush_time);
688 
689             /* csv log */
690             LV_LOG("%s, %"LV_PRIu32"%%, %"LV_PRIu32", %"LV_PRIu32", %"LV_PRIu32", %"LV_PRIu32"\r\n",
691                    scenes[i].name,
692                    scenes[i].cpu_avg_usage / cnt,
693                    scenes[i].fps_avg / cnt,
694                    render_time + flush_time,
695                    render_time,
696                    flush_time);
697 
698             valid_scene_cnt++;
699             total_avg_cpu += scenes[i].cpu_avg_usage / cnt;
700             total_avg_fps += scenes[i].fps_avg / cnt;
701             total_avg_render_time += scenes[i].render_avg_time / cnt;
702             total_avg_flush_time += scenes[i].flush_avg_time / cnt;
703         }
704     }
705 
706     /*Add the average*/
707     lv_table_set_cell_value(table, 1, 0, "All scenes avg.");
708     if(valid_scene_cnt < 1) {
709         lv_table_set_cell_value(table, 1, 1, "N/A");
710         lv_table_set_cell_value(table, 1, 2, "N/A");
711         lv_table_set_cell_value(table, 1, 3, "N/A");
712     }
713     else {
714         lv_table_set_cell_value_fmt(table, 1, 1, "%"LV_PRIu32" %%", total_avg_cpu / valid_scene_cnt);
715         lv_table_set_cell_value_fmt(table, 1, 2, "%"LV_PRIu32" FPS", total_avg_fps / valid_scene_cnt);
716 
717         uint32_t render_time = total_avg_render_time / valid_scene_cnt;
718         uint32_t flush_time = total_avg_flush_time / valid_scene_cnt;
719         lv_table_set_cell_value_fmt(table, 1, 3, "%"LV_PRIu32" ms (%"LV_PRIu32" + %"LV_PRIu32")",
720                                     render_time + flush_time, render_time, flush_time);
721         /* csv log */
722         LV_LOG("All scenes avg.,%"LV_PRIu32"%%, %"LV_PRIu32", %"LV_PRIu32", %"LV_PRIu32", %"LV_PRIu32"\r\n",
723                total_avg_cpu / valid_scene_cnt,
724                total_avg_fps / valid_scene_cnt,
725                render_time + flush_time,
726                render_time,
727                flush_time);
728     }
729 }
730 
731 /*----------------
732  * SCENE HELPERS
733  *----------------*/
734 
color_anim_cb(void * var,int32_t v)735 static void color_anim_cb(void * var, int32_t v)
736 {
737     LV_UNUSED(v);
738     lv_color_t c = rnd_color();
739     lv_obj_set_style_bg_color(var, c, 0);
740     lv_obj_set_style_text_color(var, rnd_color(), 0);
741 }
742 
color_anim(lv_obj_t * obj)743 static void color_anim(lv_obj_t * obj)
744 {
745     lv_anim_t a;
746     lv_anim_init(&a);
747     lv_anim_set_exec_cb(&a, color_anim_cb);
748     lv_anim_set_values(&a, 0, 100);
749     lv_anim_set_duration(&a, 100);      /*New value in each ms*/
750     lv_anim_set_var(&a, obj);
751     lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
752     lv_anim_start(&a);
753 }
754 
arc_anim_cb(void * var,int32_t v)755 static void arc_anim_cb(void * var, int32_t v)
756 {
757     lv_arc_set_value(var, v);
758 }
759 
arc_anim(lv_obj_t * obj)760 static void arc_anim(lv_obj_t * obj)
761 {
762     uint32_t t1 = rnd_next(1000, 3000);
763     uint32_t t2 = rnd_next(1000, 3000);
764     lv_anim_t a;
765     lv_anim_init(&a);
766     lv_anim_set_exec_cb(&a, arc_anim_cb);
767     lv_anim_set_values(&a, 0, 100);
768     lv_anim_set_duration(&a, t1);
769     lv_anim_set_reverse_duration(&a, t2);
770     lv_anim_set_var(&a, obj);
771     lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
772     lv_anim_start(&a);
773 }
774 
scroll_anim_y_cb(void * var,int32_t v)775 static void scroll_anim_y_cb(void * var, int32_t v)
776 {
777     lv_obj_scroll_to_y(var, v, LV_ANIM_OFF);
778 }
779 
scroll_anim(lv_obj_t * obj,int32_t y_max)780 static void scroll_anim(lv_obj_t * obj, int32_t y_max)
781 {
782     uint32_t t = lv_anim_speed(lv_display_get_dpi(NULL));
783 
784     lv_anim_t a;
785     lv_anim_init(&a);
786     lv_anim_set_var(&a, obj);
787     lv_anim_set_exec_cb(&a, scroll_anim_y_cb);
788     lv_anim_set_values(&a, 0, y_max);
789     lv_anim_set_duration(&a, t);
790     lv_anim_set_reverse_duration(&a, t);
791     lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
792     lv_anim_start(&a);
793 
794 }
shake_anim_y_cb(void * var,int32_t v)795 static void shake_anim_y_cb(void * var, int32_t v)
796 {
797     lv_obj_set_style_translate_y(var, v, 0);
798 }
799 
fall_anim(lv_obj_t * obj,int32_t y_max)800 static void fall_anim(lv_obj_t * obj, int32_t y_max)
801 {
802     uint32_t t1 = rnd_next(300, 3000);
803     uint32_t t2 = rnd_next(300, 3000);
804 
805     lv_anim_t a;
806     lv_anim_init(&a);
807     lv_anim_set_var(&a, obj);
808     lv_anim_set_exec_cb(&a, shake_anim_y_cb);
809     lv_anim_set_values(&a, 0, y_max);
810     lv_anim_set_duration(&a, t1);
811     lv_anim_set_reverse_duration(&a, t2);
812     lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
813     lv_anim_start(&a);
814 }
815 
card_create(void)816 static lv_obj_t * card_create(void)
817 {
818     lv_obj_t * panel = lv_obj_create(lv_screen_active());
819     lv_obj_set_size(panel, 270, 120);
820     lv_obj_set_style_pad_all(panel, 8, 0);
821 
822     LV_IMAGE_DECLARE(img_benchmark_avatar);
823     lv_obj_t * child = lv_image_create(panel);
824     lv_obj_align(child, LV_ALIGN_LEFT_MID, 0, 0);
825     lv_image_set_src(child, &img_benchmark_avatar);
826 
827     child = lv_label_create(panel);
828     lv_label_set_text_static(child, "John Smith");
829     lv_obj_set_style_text_font(child, &lv_font_montserrat_24, 0);
830     lv_obj_set_pos(child, 100, 0);
831 
832     child = lv_label_create(panel);
833     lv_label_set_text_static(child, "A DIY enthusiast");
834     lv_obj_set_style_text_font(child, &lv_font_montserrat_14, 0);
835     lv_obj_set_pos(child, 100, 30);
836 
837     child = lv_button_create(panel);
838     lv_obj_set_pos(child, 100, 50);
839 
840     child = lv_label_create(child);
841     lv_label_set_text_static(child, "Connect");
842 
843     return panel;
844 }
845 
rnd_reset(void)846 static void rnd_reset(void)
847 {
848     rnd_act = 0;
849 }
850 
rnd_next(int32_t min,int32_t max)851 static int32_t rnd_next(int32_t min, int32_t max)
852 {
853     static const uint32_t rnd_map[] = {
854         0xbd13204f, 0x67d8167f, 0x20211c99, 0xb0a7cc05,
855         0x06d5c703, 0xeafb01a7, 0xd0473b5c, 0xc999aaa2,
856         0x86f9d5d9, 0x294bdb29, 0x12a3c207, 0x78914d14,
857         0x10a30006, 0x6134c7db, 0x194443af, 0x142d1099,
858         0x376292d5, 0x20f433c5, 0x074d2a59, 0x4e74c293,
859         0x072a0810, 0xdd0f136d, 0x5cca6dbc, 0x623bfdd8,
860         0xb645eb2f, 0xbe50894a, 0xc9b56717, 0xe0f912c8,
861         0x4f6b5e24, 0xfe44b128, 0xe12d57a8, 0x9b15c9cc,
862         0xab2ae1d3, 0xb4dc5074, 0x67d457c8, 0x8e46b00c,
863         0xa29a1871, 0xcee40332, 0x80f93aa1, 0x85286096,
864         0x09bd6b49, 0x95072088, 0x2093924b, 0x6a27328f,
865         0xa796079b, 0xc3b488bc, 0xe29bcce0, 0x07048a4c,
866         0x7d81bd99, 0x27aacb30, 0x44fc7a0e, 0xa2382241,
867         0x8357a17d, 0x97e9c9cc, 0xad10ff52, 0x9923fc5c,
868         0x8f2c840a, 0x20356ba2, 0x7997a677, 0x9a7f1800,
869         0x35c7562b, 0xd901fe51, 0x8f4e053d, 0xa5b94923,
870         0xd2c5eedd, 0x24f0cc9b, 0x3aa7b571, 0xd289a1c9,
871         0x79c7dc3,  0x5bf68c86, 0xc9f55239, 0x42052cfb,
872         0x63dae9df, 0x75c9e11f, 0x407f9151, 0x104ebc63,
873         0xb4b52591, 0x53a46b7a, 0x9398d144, 0x9a7c6c3d,
874         0x76b35b78, 0xa028e33e, 0xbfe586e4, 0xf3f79731,
875         0x99591738, 0xd7b0a847, 0x1ffb1936, 0xfeeea2e4,
876         0xbc896279, 0xa8241a72, 0x871124fa, 0x27bb9866,
877         0x41794272, 0x92f5dc59, 0x98c9d185, 0x6fc5905b,
878         0xf0ba9f1a, 0x771cad1b, 0xf6285752, 0xb5ffcbc5,
879         0x6fd2b63c, 0x2c404190, 0x209469e6, 0x628531b1,
880         0x98a726bc, 0xcc6c0d97, 0x86c2e7b9, 0x7bc12e1f,
881         0xf9a67e10, 0xd5bf101f, 0xa1aaaf35, 0x69b078fc,
882         0x71d698b2, 0x9a954baa, 0xe7423a82, 0xdd9898e1,
883         0xf4980e5c, 0x4f3607b9, 0x9ce35d27, 0xb4b764e0,
884         0xa1fa3ad3, 0x220ad165, 0x282216b4, 0x7e583888,
885         0xf8315b2b, 0x81c27062, 0x8eb89a85,     /*Intentionally incomplete line to make the length of array more arbitrary*/
886 
887     };
888 
889     if(min == max) return min;
890 
891     if(min > max) {
892         int32_t t = min;
893         min = max;
894         max = t;
895     }
896 
897     int32_t d = max - min;
898     int32_t r = (rnd_map[rnd_act] % d) + min;
899 
900     rnd_act++;
901     if(rnd_act >= sizeof(rnd_map) / sizeof(rnd_map[0])) rnd_act = 0;
902 
903     return r;
904 }
905 
rnd_color(void)906 static lv_color_t rnd_color(void)
907 {
908     return lv_palette_main(rnd_next(0, LV_PALETTE_LAST - 1));
909 }
910 
911 #endif
912