expedite/src/bin/ui.c

799 lines
19 KiB
C

#include "main.h"
#include <Eo.h>
#define PROTO
#include "tests.h"
#undef PROTO
static double wfps = 0.0;
static double t_start = 0.0;
static double t_loop = 0.0;
static int f_start = 0;
static int f_loop = 0;
static char data_dir[4096];
int async_render = 0;
Eina_List *menu = NULL;
static Evas_Object *o_bg = NULL;
static Evas_Object *o_wallpaper = NULL;
static Evas_Object *o_title = NULL;
static Evas_Object *o_byline = NULL;
static Evas_Object *o_menu_logo = NULL;
static Evas_Object *o_menu_icon = NULL;
static Evas_Object *o_menu_icon_sel = NULL;
static Evas_Object *o_menu_icon_sel2 = NULL;
static Evas_Object *o_menu_text_sel = NULL;
static Evas_Object *o_menu_title = NULL;
static int menu_sel = 0;
static int menu_active = 0;
static double menu_anim = 0.0;
static double menu_anim_sel = 0.0;
static double p_fps = 0.0;
static void (*key_func) (const char *key) = NULL;
static void (*loop_func) (double t, int f) = NULL;
double weights[] =
{
0.0, // no test 0
0.0, // all tests 0
50.4851, // test 1
97.3703, // test 2
10.0000, // test 3
87.3703, // ...
10.0000,
150.0000, // test 6
10.0000,
150.0000,
10.0000,
150.0000,
10.0000, // test 11
150.0000,
10.0000,
10.6493,
38.4818,
40.7314, // test 16
32.0866,
21.3337,
21.2167,
71.6141,
64.8893, // test 21
95.0880,
121.0438,
41.2646,
162.7149,
89.1650, // test 26
105.3571,
40.9657,
98.4671,
28.4322,
60.000, // test 31
75.5507,
51.6601,
135.4753,
38.2705,
35.9915, // test 36
31.9500,
22.6752,
38.2702,
37.4459,
37.2009, // test 41
34.5459,
38.5043,
50.0000,
37.0282,
55.8886, // test 46
17.2535,
23.1457,
36.9874,
37.9336,
17.1830, // test 51
20.7521,
29.0141,
131.6784,
13.6851,
23.4462, // test 56
14.7573,
36.5261,
5.0000,
5.0000,
24.3482, // test 61
10.4611,
86.0290,
82.0735,
18.6459,
37.4608, // test 66
32.4417,
11.5449,
5.0000,
11.4172,
13.3682, // test 71
10.0324,
10.0584,
10.0170,
5.4029,
10.6349, // test 76
21.7728,
12.7933,
19.4177,
34.4192,
23.9110, // test 81
22.8287,
41.2399,
30.1383,
22.0342,
38.2952, // test 86
5.5560,
0.5000,
1.000,
10.000,
5.000, // test 91
1.000, // test 92 (line)
10.000, // test 93 Image Blend Many Smooth Down Scaled
20.000, // MASK
20.000, // MASK 2
20.000, // MASK 3
20.000, // MASK 4
20.000, // test 96
20.000, // MASK 6
20.000, // MASK 7
20.000, // MASK 8
20.000, // MASK 9
20.000, // test 101
20.000, // MASK 11
20.000, // MASK 12
20.000, // MASK 13
20.000, // MASK 14
20.000, // test 106 MASK 15
1.000,
2.000,
1.000,
2.000,
1.000, // test 111
2.000,
1.000,
2.000,
1.000,
2.000, // test 116
10.000,
10.000,
0.0, // Exit
0.0, // no final test - add a 0 at the end anyway to pad
0.0,
0.0,
0.0,
0.0,
0.0
};
static void
_ui_exit(void)
{
Menu_Item *mi;
EINA_LIST_FREE(menu, mi)
{
free(mi->icon);
free(mi->text);
free(mi);
}
ecore_main_loop_quit();
}
extern const char *profile;
extern int win_w, win_h;
extern int loops;
static int test_item = -1;
static void
_ui_menu_show(Eina_Bool visibility)
{
efl_gfx_visible_set(o_menu_logo, visibility);
efl_gfx_visible_set(o_menu_title, visibility);
efl_gfx_visible_set(o_menu_icon, visibility);
efl_gfx_visible_set(o_menu_icon_sel, visibility);
/* FIXME: ask if it's ok o_menu_icon_sel2 == NULL */
efl_gfx_visible_set(o_menu_icon_sel2, visibility);
efl_gfx_visible_set(o_menu_text_sel, visibility);
efl_gfx_visible_set(o_title, visibility);
efl_gfx_visible_set(o_byline, visibility);
}
static void
_ui_select(void)
{
Eina_List *l;
int i;
void (*func) (void) = NULL;
_ui_menu_show(EINA_FALSE);
for (i = 0, l = menu; l; l = l->next, i++)
{
Menu_Item *mi;
mi = l->data;
efl_gfx_visible_set(mi->o_icon, EINA_FALSE);
if (i == menu_sel)
func = mi->func;
}
efl_gfx_visible_set(o_title, EINA_FALSE);
efl_gfx_visible_set(o_byline, EINA_FALSE);
menu_active = 0;
if (func) func();
}
static void
_ui_key(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Input_Key *ev = event->info;
const char *keyname = efl_input_key_name_get(ev);
if (!keyname) return;
if (key_func)
{
key_func(keyname);
return;
}
if ((!strcmp(keyname, "Escape")) ||
(!strcmp(keyname, "q")) ||
(!strcmp(keyname, "Q")))
{
_ui_exit();
return;
}
if (menu_active)
{
if (!strcmp(keyname, "Left")) menu_sel++;
else if (!strcmp(keyname, "Right")) menu_sel--;
else if (!strcmp(keyname, "Up")) menu_sel++;
else if (!strcmp(keyname, "Down")) menu_sel--;
else if (!strcmp(keyname, "Home")) menu_sel = eina_list_count(menu) - 1;
else if (!strcmp(keyname, "End")) menu_sel = 0;
else if (!strcmp(keyname, "Next")) menu_sel -= 10;
else if (!strcmp(keyname, "Prior")) menu_sel += 10;
if (menu_sel < 0) menu_sel = 0;
else if ((unsigned int)menu_sel >= eina_list_count(menu)) menu_sel = eina_list_count(menu) - 1;
menu_anim_sel = menu_sel;
if (!strcmp(keyname, "Return")) _ui_select();
}
}
static Evas_Coord down_x, down_y;
static int down_menu_sel = 0;
static void
_ui_mouse_down(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Input_Pointer *ev = event->info;
if (efl_input_pointer_button_get(ev) != 1) return;
if (menu_active)
{
efl_input_pointer_position_get(ev, &down_x, &down_y);
down_menu_sel = menu_sel;
}
}
static void
_ui_mouse_up(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Input_Pointer *ev = event->info;
if (efl_input_pointer_button_get(ev) != 1) return;
if (menu_active)
{
Evas_Coord dx, dy, x, y;
efl_input_pointer_position_get(ev, &x, &y);
dx = x - down_x;
dy = y - down_y;
if ((((dx * dx) + (dy * dy)) < (20 * 20)) &&
(menu_sel == down_menu_sel))
_ui_select();
}
else
{
evas_event_feed_key_down(evas, "Escape", "Escape", NULL, NULL, 0, NULL);
evas_event_feed_key_up(evas, "Escape", "Escape", NULL, NULL, 0, NULL);
}
}
static void
_ui_mouse_move(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Input_Pointer *ev = event->info;
if (efl_input_pointer_button_get(ev) != 1) return;
if (menu_active)
{
Evas_Coord x;
efl_input_pointer_position_get(ev, &x, NULL);
menu_sel = down_menu_sel + ((x - down_x) / 25);
/* scroll */
if (menu_sel < 0) menu_sel = 0;
else if ((unsigned int)menu_sel >= eina_list_count(menu))
menu_sel = eina_list_count(menu) - 1;
menu_anim_sel = menu_sel;
}
}
static void
_ui_menu_item_full_add(Eina_Bool test,
char *icon, char *text,
void (*func) (void))
{
Menu_Item *mi;
mi = malloc(sizeof(Menu_Item));
mi->o_icon = efl_add(EFL_CANVAS_IMAGE_CLASS, evas);
efl_file_set(mi->o_icon, build_path(icon), NULL);
efl_gfx_size_set(mi->o_icon, 32, 32);
efl_gfx_fill_set(mi->o_icon, 0, 0, 32, 32);
mi->test = test;
mi->icon = strdup(icon);
mi->text = strdup(text);
mi->func = func;
menu = eina_list_append(menu, mi);
efl_gfx_stack_raise(o_menu_icon_sel2);
}
#define _ui_menu_item_add(Icon, Text, Func) _ui_menu_item_full_add(EINA_TRUE, Icon, Text, Func)
EFL_CALLBACKS_ARRAY_DEFINE(ui_callbacks,
{ EFL_EVENT_KEY_DOWN, _ui_key },
{ EFL_EVENT_POINTER_DOWN, _ui_mouse_down },
{ EFL_EVENT_POINTER_UP, _ui_mouse_up },
{ EFL_EVENT_POINTER_MOVE, _ui_mouse_move });
void
ui_setup(unsigned int ui_w, unsigned int ui_h)
{
Evas_Object *o;
Evas_Coord x, y, w, h;
win_w = ui_w;
win_h = ui_h;
o = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas);
efl_gfx_position_set(o, 0, 0);
efl_gfx_size_set(o, win_w, win_h);
efl_gfx_color_set(o, 0, 0, 0, 0);
efl_gfx_stack_layer_set(o, 1000);
evas_object_focus_set(o, 1);
efl_gfx_visible_set(o, EINA_TRUE);
efl_event_callback_array_add(o, ui_callbacks(), NULL);
o_bg = o;
o = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas);
efl_gfx_position_set(o, 0, 0);
efl_gfx_size_set(o, win_w, win_h);
efl_gfx_color_set(o, 255, 255, 255, 255);
efl_gfx_stack_layer_set(o, -99);
efl_gfx_visible_set(o, EINA_TRUE);
o_wallpaper = o;
o = evas_object_text_add(evas);
efl_text_properties_font_set(o, "Vera-Bold", 10);
efl_text_set(o, "EXPEDITE");
efl_gfx_stack_layer_set(o, 100);
efl_gfx_color_set(o, 0, 0, 0, 100);
evas_object_pass_events_set(o, 1);
efl_gfx_size_get(o, &w, &h);
x = (win_w - w) / 2;
y = 0;
efl_gfx_position_set(o, x, y);
efl_gfx_visible_set(o, EINA_TRUE);
o_title = o;
o = evas_object_text_add(evas);
efl_text_properties_font_set(o, "Vera", 9);
efl_text_set(o, "LEFT/RIGHT - select, ENTER - select, ESCAPE - exit.");
efl_gfx_stack_layer_set(o, 100);
efl_gfx_color_set(o, 0, 0, 0, 60);
evas_object_pass_events_set(o, 1);
efl_gfx_size_get(o, &w, NULL);
x = (win_w - w) / 2;
y = h + 2;
efl_gfx_position_set(o, x, y);
efl_gfx_visible_set(o, EINA_TRUE);
o_byline = o;
o = efl_add(EFL_CANVAS_IMAGE_CLASS, evas);
efl_gfx_position_set(o, (win_w - 120) / 2, ((win_h - 160) / 2));
efl_file_set(o, build_path("e-logo.png"), NULL);
efl_gfx_fill_set(o, 0, 0, 120, 160);
efl_gfx_size_set(o, 120, 160);
efl_gfx_stack_layer_set(o, -98);
efl_gfx_color_set(o, 255, 255, 255, 255);
efl_gfx_visible_set(o, EINA_TRUE);
o_menu_logo = o;
o = efl_add(EFL_CANVAS_IMAGE_CLASS, evas);
efl_gfx_position_set(o, win_w - 128, - 128);
efl_gfx_fill_set(o, 0, 0, 256, 256);
efl_gfx_size_set(o, 256, 256);
efl_gfx_visible_set(o, EINA_TRUE);
o_menu_icon = o;
o = efl_add(EFL_CANVAS_IMAGE_CLASS, evas);
efl_gfx_position_set(o, 0, 0);
efl_file_set(o, build_path("icon_sel.png"), NULL);
efl_gfx_size_set(o, 48, 48);
efl_gfx_fill_set(o, 0, 0, 48, 48);
o_menu_icon_sel = o;
o = efl_add(EFL_CANVAS_IMAGE_CLASS, evas);
efl_gfx_position_set(o, 0, 0);
efl_file_set(o, build_path("text_sel.png"), NULL);
efl_gfx_size_set(o, 96, 32);
efl_gfx_fill_set(o, 0, 0, 96, 32);
efl_image_border_set(o, 7, 7, 7, 7);
o_menu_text_sel = o;
o = evas_object_text_add(evas);
efl_text_properties_font_set(o, "Vera", 10);
efl_text_set(o, "");
efl_gfx_color_set(o, 0, 0, 0, 100);
evas_object_pass_events_set(o, 1);
efl_gfx_size_get(o, &w, &h);
x = (win_w - w) / 2;
y = (win_h - h) / 2;
efl_gfx_position_set(o, x, y);
o_menu_title = o;
_ui_menu_item_full_add(EINA_FALSE, "e.png", "About", about_start);
_ui_menu_item_full_add(EINA_FALSE, "e.png", "All Tests", ui_all);
#define UI
#include "tests.h"
#undef UI
_ui_menu_item_full_add(EINA_FALSE, "exit.png", "Exit", _ui_exit);
#ifdef HAVE_SYNC
/* make sure disk io isn't going to turn up unexpectedly */
sync();
sync();
sync();
#endif
menu_active = 1;
}
void
ui_num(int n)
{
Menu_Item *mi;
mi = eina_list_nth(menu, n);
if (mi)
{
if (!mi->test)
return;
menu_sel = n;
if (one_test) test_item = menu_sel;
_ui_select();
}
}
Eina_Bool
ui_loop(void *data EINA_UNUSED)
{
static int first = 1;
static double pt = 0.0;
double t, t2;
efl_gfx_size_set(o_bg, win_w, win_h);
efl_gfx_size_set(o_wallpaper, win_w, win_h);
if (loop_func)
{
t = get_time();
f_loop++;
f_start++;
if ((t - t_loop) >= 1.0)
{
// ui_fps((double)f_loop / (t - t_loop));
t_loop = t;
f_loop = 0;
}
loop_func(t - t_start, f_start);
return EINA_TRUE;
}
t2 = get_time();
if (first)
{
t = 0.1;
pt = t2;
}
else
{
t = t2 - pt;
pt = t2;
}
first = 0;
/* menu layout */
if (menu_active)
{
Eina_List *l;
Menu_Item *mi;
int i = 0;
static double tr = 0.0;
double tt;
tt = t;
tt += tr;
while (tt > 0.001)
{
menu_anim = (menu_anim * 0.995) + (menu_anim_sel * 0.005);
tt -= 0.001;
}
tr = tt;
EINA_LIST_FOREACH(menu, l, mi)
{
char buf[4096];
Evas_Coord x, y, w, h, tw, th;
Evas_Coord len;
double a;
Evas_Object *o;
o = mi->o_icon;
efl_gfx_size_get(o_menu_logo, &w, &h);
len = ((w * 3) + 10) / 4;
efl_gfx_size_get(o, &w, &h);
x = (win_w / 2)
+ (sin((menu_anim - (double)i) * 0.33) * len)
- (w / 2);
y = (win_h / 2)
+ (cos((menu_anim - (double)i) * 0.33) * len)
- (h / 2);
efl_gfx_position_set(o, x, y);
a = menu_anim - (double)i;
if (a < 0) a = -a;
a = 255 - (30 * a);
if (a < 0) a = 0;
if (a > 255) a = 255;
efl_gfx_color_set(o, a, a, a, a);
efl_gfx_visible_set(o, EINA_TRUE);
if (i == menu_sel)
{
a = menu_anim - (double)i;
if (a < 0) a = -a;
a = 255 - (255 * a);
if (a < 0) a = 0;
if (a > 255) a = 255;
o = o_menu_icon_sel;
efl_gfx_position_set(o, x - ((48 - w) / 2), y - ((48 - h) / 2));
efl_gfx_color_set(o, a, a, a, a);
o = o_menu_title;
efl_gfx_color_set(o, a, a, a, a);
efl_text_set(o, mi->text);
efl_gfx_size_get(o, &tw, &th);
x = (win_w - tw) / 2;
y = (win_h / 2) + len + 48;
efl_gfx_position_set(o, x, y);
o = o_menu_text_sel;
w = tw + 24;
h = 28;
x = x - 12;
y = y + ((th - h) / 2);
efl_gfx_position_set(o, x, y);
efl_gfx_size_set(o, w, h);
efl_gfx_fill_set(o, 0, 0, w, h);
efl_gfx_color_set(o, a, a, a, a);
o = o_menu_icon;
snprintf(buf, 4096, "%s%s", data_dir, mi->icon);
efl_file_set(o, buf, NULL);
efl_gfx_color_set(o, a / 2, a / 2, a / 2, a / 2);
}
i++;
}
efl_gfx_position_set(o_menu_logo, (win_w - 120) / 2, ((win_h - 160) / 2));
efl_gfx_visible_set(o_menu_logo, EINA_TRUE);
_ui_menu_show(EINA_TRUE);
}
else
{
}
return EINA_TRUE;
}
void
ui_menu(void)
{
efl_gfx_visible_set(o_title, EINA_TRUE);
efl_gfx_visible_set(o_byline, EINA_TRUE);
efl_text_set
(o_byline, "LEFT/RIGHT - select, ENTER - select, ESCAPE - exit.");
menu_active = 1;
key_func = NULL;
loop_func = NULL;
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
}
void
ui_func_set(void (*kfunc) (const char *key), void (*lfunc) (double t, int f))
{
key_func = kfunc;
loop_func = lfunc;
t_loop = t_start = get_time();
f_loop = f_start = 0;
ui_fps(0.0);
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
ecore_animator_custom_tick();
}
void
ui_all(void)
{
Eina_List *l;
Menu_Item *mi;
int i = 0;
double t, t0;
_ui_menu_show(EINA_FALSE);
/* warm up the cpu with some spinning */
t0 = time(NULL);
for (;;)
{
t = time(NULL);
if (t - t0 > 2) break;
}
wfps = 0;
EINA_LIST_FOREACH(menu, l, mi)
{
i++;
if (!mi->test)
continue;
menu_sel = i - 1;
test_item = menu_sel;
_ui_select();
break;
}
}
void
ui_fps(double fps)
{
p_fps = fps;
if (fps > 0.0 && test_item > 0)
{
Menu_Item *mi;
key_func("Escape");
/* This does not give time to delete the objects of the previous test
and make the result of next test less accurate. Benefit we do not
loose track of any of the cost anymore (Would be better to force
an empty render and account that to the previous test). */
wfps += (fps * weights[test_item]);
test_item++;
mi = eina_list_nth(menu, test_item);
if (one_test || !mi->test)
{
char datestr[1024];
struct tm *tim;
time_t now;
double avgw = 0.0;
unsigned int i;
unsigned int t_count;
t_count = EINA_C_ARRAY_LENGTH(weights) - 3;
for (i = 2; i < EINA_C_ARRAY_LENGTH(weights) - 1; i++)
avgw += weights[i];
avgw /= t_count;
now = time(NULL);
tim = localtime(&now);
if (tim) strftime(datestr, sizeof(datestr), "%Y-%m-%d %H:%M:%S", tim);
else snprintf(datestr, sizeof(datestr), "unknown");
if (cmp_report)
printf("%5.2f , EVAS SPEED (WEIGHTED), "
"tn, %i , "
"t, %s , "
"ev , %i.%i.%i.%i , "
"p , %s , "
"sz , %i , %i , "
"c , %i , "
"e , %s , "
"fs , %i\n",
wfps / (t_count * avgw),
// fps / t_count,
t_count,
datestr,
evas_version->major,
evas_version->minor,
evas_version->micro,
evas_version->revision,
profile,
win_w, win_h,
loops,
choosen_engine,
fullscreen);
else
printf("\n#####Test Result#####\n"
"evas fps speed: %5.2f\n"
"evas fps speed(weighted): %5.2f\n"
"testcase count: %i\n"
"date: %s\n"
"evas version: %i.%i.%i.%i\n"
"profile: %s\n"
"window size: %i, %i\n"
"loop count: %i\n"
"engine: %s\n"
"full screen: %i\n",
(fps / t_count),
(wfps / avgw) / t_count,
t_count,
datestr,
evas_version->major, evas_version->minor, evas_version->micro,
evas_version->revision,
profile,
win_w, win_h,
loops,
choosen_engine,
fullscreen);
ecore_main_loop_quit();
}
else
{
menu_sel = test_item;
_ui_select();
}
}
}