weight expedite benchmarks based on closer to real-life usage. evas_speed at
[framework/uifw/expedite.git] / src / bin / ui.c
1 #include "main.h"
2
3 #define PROTO
4 #include "tests.h"
5 #undef PROTO
6
7 static double start = 0.0;
8
9 static double t_start = 0.0;
10 static double t_loop = 0.0;
11 static int    f_start = 0;
12 static int    f_loop = 0;
13 static char   data_dir[4096];
14
15 typedef struct _Menu_Item Menu_Item;
16
17 struct _Menu_Item
18 {
19    Evas_Object *o_icon;
20    char *icon;
21    char *text;
22    void (*func) (void);
23 };
24
25 static Evas_Object *o_bg = NULL;
26 static Evas_Object *o_wallpaper = NULL;
27 static Evas_Object *o_title = NULL;
28 static Evas_Object *o_byline = NULL;
29 static Evas_Object *o_menu_logo = NULL;
30 static Evas_Object *o_menu_icon = NULL;
31 static Evas_Object *o_menu_icon_sel = NULL;
32 static Evas_Object *o_menu_icon_sel2 = NULL;
33 static Evas_Object *o_menu_text_sel = NULL;
34 static Evas_Object *o_menu_title = NULL;
35 static Eina_List   *menu = NULL;
36 static int          menu_sel = 0;
37 static int          menu_active = 0;
38 static double       menu_anim = 0.0;
39 static double       menu_anim_sel = 0.0;
40
41 static double       p_fps = 0.0;
42
43 static void (*key_func) (char *key) = NULL;
44 static void (*loop_func) (double t, int f) = NULL;
45
46 static int run_all = 0;
47 static int run_test = 0;
48 static int list_test = 0;
49 static int exit_after_test = 0;
50
51 static double weights[] =
52 {
53    0.0, // no test 0
54      
55      50.4851, // test 1
56      37.3703, // test 2
57      10.6493, // ...
58      38.4818,
59      40.7314,
60      32.0866,
61      21.3337,
62      21.2167,
63      71.6141,
64      64.8893,
65      95.0880,
66      121.0438,
67      41.2646,
68      162.7149,
69      89.1650,
70      105.3571,
71      40.9657,
72      98.4671,
73      28.4322,
74      60.000,
75      75.5507,
76      51.6601,
77      135.4753,
78      38.2705,
79      35.9915,
80      31.9500,
81      22.6752,
82      38.2702,
83      37.4459,
84      37.2009,
85      34.5459,
86      38.5043,
87      50.0000,
88      37.0282,
89      55.8886,
90      17.2535,
91      23.1457,
92      36.9874,
93      37.9336,
94      17.1830,
95      20.7521,
96      29.0141,
97      131.6784,
98      13.6851,
99      23.4462,
100      14.7573,
101      36.5261,
102      24.3482,
103      10.4611,
104      86.0290,
105      82.0735,
106      18.6459,
107      37.4608,
108      32.4417,
109      11.5449,
110      11.4172,
111      13.3682,
112      10.0324,
113      10.0584,
114      10.0170,
115      5.4029,
116      10.6349,
117      21.7728,
118      12.7933,
119      19.4177,
120      34.4192,
121      23.9110,
122      22.8287,
123      41.2399,
124      30.1383,
125      22.0342,
126      38.2952,
127      5.5560,
128      
129      0.0 // no final test - add a 0 at the end anyway to pad
130 };
131
132 static void
133 _ui_exit(void)
134 {
135    Menu_Item *mi;
136
137    EINA_LIST_FREE(menu, mi)
138      {
139         free(mi->icon);
140         free(mi->text);
141         free(mi);
142      }
143    engine_abort();
144 }
145
146 static void
147 _ui_all(void)
148 {
149    Eina_List *l;
150    double fps = 0.0;
151    double wfps = 0.0;
152    int t_count = 0;
153    int i;
154    double avgw = 0.0;
155
156    evas_object_hide(o_menu_logo);
157    evas_object_hide(o_menu_title);
158    evas_object_hide(o_menu_icon);
159    evas_object_hide(o_menu_icon_sel);
160    evas_object_hide(o_menu_icon_sel2);
161    evas_object_hide(o_menu_text_sel);
162    evas_object_hide(o_title);
163    evas_object_hide(o_byline);
164    for (l = menu; l; l = l->next)
165      {
166         Menu_Item *mi;
167
168         mi = l->data;
169         if ((mi->func == about_start) ||
170             (mi->func == _ui_exit) ||
171             (mi->func == _ui_all))
172           continue;
173         if (mi->func) mi->func();
174         while (p_fps == 0.0)
175           {
176              engine_loop();
177              ui_loop();
178              evas_render(evas);
179           }
180         /* This give time to delete the objects of the previous test and make
181            the result of next test more accurate. Draw back, some time is not
182            counted at all. */
183         evas_render(evas);
184         t_count++;
185         fps += p_fps;
186         wfps += (p_fps * weights[t_count]);
187         key_func("Escape");
188      }
189    for (i = 1; i < ((sizeof(weights) / sizeof(double)) - 1); i++)
190      avgw += weights[i];
191    avgw /= (i - 1);   
192    if (t_count > 0)
193      {
194 //        printf("%4.2f , EVAS SPEED\n", fps / t_count);
195         printf("%4.2f , EVAS SPEED (WEIGHTED)\n", wfps / (t_count * avgw));
196      }
197 }
198
199
200 static void
201 _ui_num(int n)
202 {
203    Eina_List *l;
204    double fps = 0.0;
205    double wfps = 0.0;
206    int t_count = 0;
207    Menu_Item *mi;
208    int i;
209    double avgw = 0.0;
210
211    evas_object_hide(o_menu_logo);
212    evas_object_hide(o_menu_title);
213    evas_object_hide(o_menu_icon);
214    evas_object_hide(o_menu_icon_sel);
215    evas_object_hide(o_menu_icon_sel2);
216    evas_object_hide(o_menu_text_sel);
217    mi = eina_list_nth(menu, n);
218    if (mi)
219      {
220         if ((mi->func == about_start) ||
221             (mi->func == _ui_exit) ||
222             (mi->func == _ui_all))
223           goto done;
224         if (mi->func) mi->func();
225         while (p_fps == 0.0)
226           {
227              ui_loop();
228              engine_loop();
229              evas_render(evas);
230           }
231         /* This give time to delete the objects of the previous test and make
232            the result of next test more accurate. Draw back, some time is not
233            counted at all. */
234         evas_render(evas);
235         t_count++;
236         fps += p_fps;
237         wfps += (p_fps * weights[n]);
238         key_func("Escape");
239      }
240    done:
241    for (i = 1; i < ((sizeof(weights) / sizeof(double)) - 1); i++)
242      avgw += weights[i];
243    avgw /= (i - 1);   
244    if (t_count > 0)
245      {
246 //        printf("%4.2f , EVAS SPEED\n", fps / t_count);
247         printf("%4.2f , EVAS SPEED (WEIGHTED)\n", wfps / (t_count * avgw));
248      }
249 }
250
251 static void
252 _ui_select(void)
253 {
254    Eina_List *l;
255    int i;
256    void (*func) (void) = NULL;
257
258    evas_object_hide(o_menu_logo);
259    evas_object_hide(o_menu_title);
260    evas_object_hide(o_menu_icon);
261    evas_object_hide(o_menu_icon_sel);
262    evas_object_hide(o_menu_icon_sel2);
263    evas_object_hide(o_menu_text_sel);
264    evas_object_hide(o_title);
265    evas_object_hide(o_byline);
266    for (i = 0, l = menu; l; l = l->next, i++)
267      {
268         Menu_Item *mi;
269
270         mi = l->data;
271         evas_object_hide(mi->o_icon);
272         if (i == menu_sel)
273           func = mi->func;
274      }
275    menu_active = 0;
276    if (func) func();
277 }
278
279 static void
280 _ui_key(void *data, Evas *e, Evas_Object *obj, void *event_info)
281 {
282    Evas_Event_Key_Down *ev;
283
284    ev = event_info;
285    if (key_func)
286      {
287         key_func(ev->keyname);
288         return;
289      }
290    if ((!strcmp(ev->keyname, "Escape")) ||
291        (!strcmp(ev->keyname, "q")) ||
292        (!strcmp(ev->keyname, "Q")))
293      {
294         _ui_exit();
295      }
296    if (menu_active)
297      {
298         if (!strcmp(ev->keyname, "Left")) menu_sel++;
299         if (!strcmp(ev->keyname, "Right")) menu_sel--;
300         if (menu_sel < 0) menu_sel = 0;
301         else if (menu_sel >= eina_list_count(menu)) menu_sel = eina_list_count(menu) - 1;
302         menu_anim_sel = menu_sel;
303         if (!strcmp(ev->keyname, "Return")) _ui_select();
304      }
305 }
306
307 static Evas_Coord down_x, down_y;
308 static int down = 0;
309 static int down_menu_sel = 0;
310
311 static void
312 _ui_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
313 {
314    Evas_Event_Mouse_Down *ev;
315
316    ev = event_info;
317    if (ev->button != 1) return;
318    if (menu_active)
319      {
320         down_x = ev->canvas.x;
321         down_y = ev->canvas.y;
322         down++;
323         down_menu_sel = menu_sel;
324      }
325    else
326      {
327      }
328 }
329
330 static void
331 _ui_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
332 {
333    Evas_Event_Mouse_Up *ev;
334
335    ev = event_info;
336    if (ev->button != 1) return;
337    if (menu_active)
338      {
339         Evas_Coord dx, dy;
340
341         dx = ev->canvas.x - down_x;
342         dy = ev->canvas.y - down_y;
343         if ((((dx * dx) + (dy * dy)) < (20 * 20)) &&
344             (menu_sel == down_menu_sel))
345           _ui_select();
346         down--;
347      }
348    else
349      {
350         evas_event_feed_key_down(evas, "Escape", "Escape", NULL, NULL, 0, NULL);
351         evas_event_feed_key_up(evas, "Escape", "Escape", NULL, NULL, 0, NULL);
352      }
353 }
354
355 static void
356 _ui_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
357 {
358    Evas_Event_Mouse_Move *ev;
359
360    ev = event_info;
361    if (!down) return;
362    if (menu_active)
363      {
364         menu_sel = down_menu_sel + ((ev->cur.canvas.x - down_x) / 25);
365         /* scroll */
366         if (menu_sel < 0) menu_sel = 0;
367         else if (menu_sel >= eina_list_count(menu)) menu_sel = eina_list_count(menu) - 1;
368         menu_anim_sel = menu_sel;
369      }
370    else
371      {
372      }
373 }
374
375 static void
376 _ui_menu_item_add(char *icon, char *text, void (*func) (void))
377 {
378    Menu_Item *mi;
379
380    mi = malloc(sizeof(Menu_Item));
381    mi->o_icon = evas_object_image_add(evas);
382    evas_object_image_file_set(mi->o_icon, build_path(icon), NULL);
383    evas_object_resize(mi->o_icon, 32, 32);
384    evas_object_image_fill_set(mi->o_icon, 0, 0, 32, 32);
385    mi->icon = strdup(icon);
386    mi->text = strdup(text);
387    mi->func = func;
388    menu = eina_list_append(menu, mi);
389    evas_object_raise(o_menu_icon_sel2);
390 }
391
392 static void
393 _ui_setup(void)
394 {
395    Evas_Object *o;
396    Evas_Coord x, y, w, h;
397
398    o = evas_object_rectangle_add(evas);
399    evas_object_move(o, 0, 0);
400    evas_object_resize(o, win_w, win_h);
401    evas_object_color_set(o, 0, 0, 0, 0);
402    evas_object_layer_set(o, 1000);
403    evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, _ui_key, NULL);
404    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _ui_mouse_down, NULL);
405    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _ui_mouse_up, NULL);
406    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _ui_mouse_move, NULL);
407    evas_object_focus_set(o, 1);
408    evas_object_show(o);
409    o_bg = o;
410
411    o = evas_object_rectangle_add(evas);
412    evas_object_move(o, 0, 0);
413    evas_object_resize(o, win_w, win_h);
414    evas_object_color_set(o, 255, 255, 255, 255);
415    evas_object_layer_set(o, -99);
416    evas_object_show(o);
417    o_wallpaper = o;
418
419    o = evas_object_text_add(evas);
420    evas_object_text_font_set(o, "Vera-Bold", 10);
421    evas_object_text_text_set(o, "EXPEDITE");
422    evas_object_layer_set(o, 100);
423    evas_object_color_set(o, 0, 0, 0, 100);
424    evas_object_pass_events_set(o, 1);
425    evas_object_geometry_get(o, NULL, NULL, &w, &h);
426    x = (win_w - w) / 2;
427    y = 0;
428    evas_object_move(o, x, y);
429    evas_object_show(o);
430    o_title = o;
431
432    o = evas_object_text_add(evas);
433    evas_object_text_font_set(o, "Vera", 9);
434    evas_object_text_text_set(o, "LEFT/RIGHT - select, ENTER - select, ESCAPE - exit.");
435    evas_object_layer_set(o, 100);
436    evas_object_color_set(o, 0, 0, 0, 60);
437    evas_object_pass_events_set(o, 1);
438    evas_object_geometry_get(o, NULL, NULL, &w, NULL);
439    x = (win_w - w) / 2;
440    y = h + 2;
441    evas_object_move(o, x, y);
442    evas_object_show(o);
443    o_byline = o;
444
445    o = evas_object_image_add(evas);
446    evas_object_move(o, (win_w - 120) / 2, ((win_h - 160) / 2));
447    evas_object_image_file_set(o, build_path("e-logo.png"), NULL);
448    evas_object_image_fill_set(o, 0, 0, 120, 160);
449    evas_object_resize(o, 120, 160);
450    evas_object_layer_set(o, -98);
451    evas_object_color_set(o, 255, 255, 255, 255);
452    evas_object_show(o);
453    o_menu_logo = o;
454
455    o = evas_object_image_add(evas);
456    evas_object_move(o, win_w - 128, - 128);
457    evas_object_image_fill_set(o, 0, 0, 256, 256);
458    evas_object_resize(o, 256, 256);
459    evas_object_show(o);
460    o_menu_icon = o;
461
462    o = evas_object_image_add(evas);
463    evas_object_move(o, 0, 0);
464    evas_object_image_file_set(o, build_path("icon_sel.png"), NULL);
465    evas_object_resize(o, 48, 48);
466    evas_object_image_fill_set(o, 0, 0, 48, 48);
467    o_menu_icon_sel = o;
468
469    o = evas_object_image_add(evas);
470    evas_object_move(o, 0, 0);
471    evas_object_image_file_set(o, build_path("text_sel.png"), NULL);
472    evas_object_resize(o, 96, 32);
473    evas_object_image_fill_set(o, 0, 0, 96, 32);
474    evas_object_image_border_set(o, 7, 7, 7, 7);
475    o_menu_text_sel = o;
476
477    o = evas_object_text_add(evas);
478    evas_object_text_font_set(o, "Vera", 10);
479    evas_object_text_text_set(o, "");
480    evas_object_color_set(o, 0, 0, 0, 100);
481    evas_object_pass_events_set(o, 1);
482    evas_object_geometry_get(o, NULL, NULL, &w, &h);
483    x = (win_w - w) / 2;
484    y = (win_h - h) / 2;
485    evas_object_move(o, x, y);
486    o_menu_title = o;
487
488    _ui_menu_item_add("e.png", "About Enlightenment", about_start);
489    _ui_menu_item_add("e.png", "All Tests", _ui_all);
490 #define UI
491 #include "tests.h"
492 #undef UI
493    _ui_menu_item_add("exit.png", "Exit", _ui_exit);
494
495    if (run_all)
496      {
497         _ui_all();
498      }
499    else if (run_test > 0)
500      {
501         _ui_num(run_test);
502      }
503    else if (list_test > 0)
504      {
505         Eina_List *l;
506         int i;
507
508         for (l = menu, i = -1; l; l = l->next, i++)
509           {
510              Menu_Item *mi;
511
512              mi = l->data;
513              if (i > 0)
514                printf("%3i - %s\n", i, mi->text);
515           }
516      }
517    else
518      {
519         menu_active = 1;
520      }
521
522    if (exit_after_test)
523     _ui_exit();
524
525 }
526
527 void
528 ui_args(int argc, char **argv)
529 {
530    int i;
531
532    for (i = 1; i < argc; i++)
533      {
534         if (!strcmp(argv[i], "-a"))
535           {
536              run_all = 1;
537              exit_after_test = 1;
538           }
539         else if ((!strcmp(argv[i], "-t")) && (i < (argc - 1)))
540           {
541              run_test = atoi(argv[i + 1]) + 1;
542              exit_after_test = 1;
543              if (run_test < 2) run_test = 2;
544           }
545         else if (!strcmp(argv[i], "-l"))
546           {
547              list_test = 1;
548           }
549      }
550    _ui_setup();
551    start = get_time();
552 }
553
554 void
555 ui_loop(void)
556 {
557    static int first = 1;
558    static double pt = 0.0;
559    double t, t2;
560
561    evas_object_resize(o_bg, win_w, win_h);
562    evas_object_resize(o_wallpaper, win_w, win_h);
563    if (loop_func)
564      {
565         t = get_time();
566         f_loop++;
567         f_start++;
568         if ((t - t_loop) >= 1.0)
569           {
570 //           ui_fps((double)f_loop / (t - t_loop));
571              t_loop = t;
572              f_loop = 0;
573           }
574         loop_func(t - t_start, f_start);
575         return;
576      }
577    t2 = get_time();
578    if (first)
579      {
580         t = 0.1;
581         pt = t2;
582      }
583    else
584      {
585         t = t2 - pt;
586         pt = t2;
587      }
588    first = 0;
589
590    /* menu layout */
591    if (menu_active)
592      {
593         Eina_List *l;
594         int i;
595         static double tr = 0.0;
596         double tt;
597
598         tt = t;
599         tt += tr;
600         while (tt > 0.001)
601           {
602              menu_anim = (menu_anim * 0.995) + (menu_anim_sel * 0.005);
603              tt -= 0.001;
604           }
605         tr = tt;
606         for (i = 0, l = menu; l; l = l->next, i++)
607           {
608              char buf[4096];
609              Menu_Item *mi;
610              Evas_Coord x, y, w, h, tw, th;
611              Evas_Coord len;
612              double a;
613              Evas_Object *o;
614
615              mi = l->data;
616              o = mi->o_icon;
617              evas_object_geometry_get(o_menu_logo, NULL, NULL, &w, &h);
618              len = ((w * 3) + 10) / 4;
619              evas_object_geometry_get(o, NULL, NULL, &w, &h);
620              x = (win_w / 2)
621                + (sin((menu_anim - (double)i) * 0.33) * len)
622                  - (w / 2);
623              y = (win_h / 2)
624                + (cos((menu_anim - (double)i) * 0.33) * len)
625                  - (h / 2);
626              evas_object_move(o, x, y);
627              a = menu_anim - (double)i;
628              if (a < 0) a = -a;
629              a = 255 - (30 * a);
630              evas_object_color_set(o, a, a, a, a);
631              evas_object_show(o);
632
633              if (i == menu_sel)
634                {
635                   a = menu_anim - (double)i;
636                   if (a < 0) a = -a;
637                   a = 255 - (255 * a);
638
639                   o = o_menu_icon_sel;
640                   evas_object_move(o, x - ((48 - w) / 2), y - ((48 - h) / 2));
641                   evas_object_color_set(o, a, a, a, a);
642
643                   o = o_menu_title;
644                   evas_object_color_set(o, a, a, a, a);
645                   evas_object_text_text_set(o, mi->text);
646                   evas_object_geometry_get(o, NULL, NULL, &tw, &th);
647                   x = (win_w - tw) / 2;
648                   y = (win_h / 2) + len + 48;
649                   evas_object_move(o, x, y);
650
651                                  
652                   o = o_menu_text_sel;
653                   w = tw + 24;
654                   h = 28;
655                   x = x - 12;
656                   y = y + ((th - h) / 2);
657                   evas_object_move(o, x, y);
658                   evas_object_resize(o, w, h);
659                   evas_object_image_fill_set(o, 0, 0, w, h);
660                   evas_object_color_set(o, a, a, a, a);
661
662                   o = o_menu_icon;
663                   snprintf(buf, 4096, "%s%s", data_dir, mi->icon);
664                   evas_object_image_file_set(o, buf, NULL);
665                   evas_object_color_set(o, a / 2, a / 2, a / 2, a / 2);
666                }
667           }
668         evas_object_move(o_menu_logo, (win_w - 120) / 2, ((win_h - 160) / 2));
669         evas_object_show(o_menu_logo);
670         evas_object_show(o_menu_title);
671         evas_object_show(o_menu_icon);
672         evas_object_show(o_menu_icon_sel);
673         evas_object_show(o_menu_icon_sel2);
674         evas_object_show(o_menu_text_sel);
675      }
676    else
677      {
678      }
679 }
680
681 void
682 ui_menu(void)
683 {
684    evas_object_show(o_title);
685    evas_object_show(o_byline);
686    evas_object_text_text_set
687      (o_byline, "LEFT/RIGHT - select, ENTER - select, ESCAPE - exit.");
688    menu_active = 1;
689    key_func = NULL;
690    loop_func = NULL;
691 }
692
693 void
694 ui_func_set(void (*kfunc) (char *key), void (*lfunc) (double t, int f))
695 {
696    key_func = kfunc;
697    loop_func = lfunc;
698    t_loop = t_start = get_time();
699    f_loop = f_start = 0;
700    ui_fps(0.0);
701 }
702
703
704 void
705 ui_fps(double fps)
706 {
707    /*
708    char buf[256];
709
710    snprintf(buf, sizeof(buf), "ESCAPE - exit, FPS: %4.3f", fps);
711    evas_object_text_text_set(o_byline, buf);
712     */
713    p_fps = fps;
714 }