efl/src/bin/elementary/perf.c

302 lines
8.4 KiB
C

#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#include "perf.h"
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static Evas *evas;
static Evas_Object *win, *bg;
static double total_time = 0.0;
static int total_frames = 0;
///////////////////////////////////////////////////////////////////////////////
typedef struct
{
void (*init) (Evas *e);
void (*tick) (Evas *e, double pos, Evas_Coord win_w, Evas_Coord win_h);
const char *desc;
double weight;
} Test;
static Eina_List *cleanup_list = NULL;
void
cleanup_add(Evas_Object *o)
{
cleanup_list = eina_list_append(cleanup_list, o);
}
#define T2
#include "perf_list.c"
#undef T2
#define T1
static Test tests[] = {
#define TFUN(x) test_ ## x ## _init, test_ ## x ## _tick
#include "perf_list.c"
{ NULL, NULL, NULL, 0.0 }
};
#undef T1
static unsigned int test_pos = 0;
static double time_start = 0.0;
static double anim_tick_delta_total = 0.0;
static int anim_tick_total = 0;
static Eina_Array *tests_to_do = NULL;
static double tests_fps = 0.0;
static double tests_weights = 0.0;
static double run_time = 5.0;
static double spin_up_delay = 2.0;
static void all_tests(Evas *e);
static Eina_Bool
next_test_delay(void *data EINA_UNUSED)
{
all_tests(data);
return EINA_FALSE;
}
#define ANIMATOR 1
#ifdef ANIMATOR
static Ecore_Animator *animator = NULL;
static Eina_Bool
anim_tick(void *data)
#else
static void
anim_tick(void *data, const Efl_Event *event EINA_UNUSED)
#endif
{
Evas_Coord win_w, win_h;
double f = ecore_time_get() - time_start;
static double pf = 0.0;
int p;
if (total_frames == 1) time_start = ecore_time_get();
if (anim_tick_total == 1)
{
anim_tick_delta_total = 0.0;
pf = f;
}
else
{
anim_tick_delta_total += (f - pf);
}
anim_tick_total++;
pf = f;
f = f / run_time; // time per test - 5sec.
p = (int)(uintptr_t)eina_array_data_get(tests_to_do, test_pos) - 1;
evas_output_viewport_get(data, NULL, NULL, &win_w, &win_h);
tests[p].tick(data, f, win_w, win_h);
if (f >= 1.0)
{
Evas_Object *o;
double time_spent = ecore_time_get() - time_start;
double load = total_time / time_spent;
// only got 1 frame rendered? eek. just assume we got one
if (total_frames < 2) total_frames = 2;
if (anim_tick_total < 2) anim_tick_total = 2;
if ((load <= 0.0) || (anim_tick_delta_total <= 0.0) ||
(run_time <= 0))
{
printf("?? | %s\n", tests[p].desc);
}
else
{
printf("%1.2f (fr=%i load=%1.5f tick=%i@%1.2fHz) | %1.2f %s\n",
(double)(total_frames - 2) / (load * run_time),
total_frames - 2,
load,
anim_tick_total - 2,
(double)(anim_tick_total - 2) / anim_tick_delta_total,
tests[p].weight,
tests[p].desc);
tests_fps += ((double)(total_frames - 2) / (load * run_time)) *
tests[p].weight;
tests_weights += tests[p].weight;
}
total_frames = 0.0;
total_time = 0.0;
EINA_LIST_FREE(cleanup_list, o) evas_object_del(o);
test_pos++;
#ifdef ANIMATOR
ecore_animator_del(animator);
animator = NULL;
#else
efl_event_callback_del(win, EFL_EVENT_ANIMATOR_TICK, anim_tick, data);
#endif
ecore_timer_add(0.5, next_test_delay, data);
}
#ifdef ANIMATOR
return EINA_TRUE;
#endif
}
static Eina_Bool
exit_delay(void *data EINA_UNUSED)
{
elm_exit();
return EINA_FALSE;
}
static void
all_tests(Evas *e)
{
Evas_Coord win_w, win_h;
int p;
evas_output_viewport_get(e, NULL, NULL, &win_w, &win_h);
if (test_pos >= eina_array_count_get(tests_to_do))
{
printf("--------------------------------------------------------------------------------\n");
printf("Average weighted FPS: %1.2f\n", tests_fps / tests_weights);
printf("--------------------------------------------------------------------------------\n");
ecore_timer_add(1.0, exit_delay, NULL);
return;
}
p = (int)(uintptr_t)eina_array_data_get(tests_to_do, test_pos) - 1;
tests[p].init(e);
tests[p].tick(e, 0.0, win_h, win_h);
time_start = ecore_time_get();
anim_tick_delta_total = 0.0;
anim_tick_total = 0;
#ifdef ANIMATOR
animator = ecore_animator_add(anim_tick, e);
#else
efl_event_callback_add(win, EFL_EVENT_ANIMATOR_TICK, anim_tick, e);
#endif
}
static Eina_Bool
all_tests_delay(void *data)
{
all_tests(data);
return EINA_FALSE;
}
static double rtime = 0.0;
static void
render_pre(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *info EINA_UNUSED)
{
rtime = ecore_time_get();
}
static void
render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *info EINA_UNUSED)
{
double spent = ecore_time_get() - rtime;
if (total_frames == 2) total_time = 0.0;
total_time += spent;
total_frames++;
}
static Eina_Bool
_spincpu_up_idler(void *data EINA_UNUSED)
{
return EINA_TRUE;
}
///////////////////////////////////////////////////////////////////////////////
EAPI int
elm_main(int argc, char **argv)
{
int i, j;
for (i = 1; i < argc; i++)
{
if ((!strcmp(argv[i], "--help")) ||
(!strcmp(argv[i], "-help")) ||
(!strcmp(argv[i], "-h")))
{
printf("Usage:\n"
" -h : This help\n"
" -l : List all tests\n"
" -t N : Run test number N\n"
" -r N : Run each test for N seconds\n"
" -d N : Initial spin-up delay\n"
"\n");
elm_exit();
return 1;
}
else if (!strcmp(argv[i], "-l"))
{
for (j = 0; tests[j].init; j++)
{
printf(" %3i | %s\n", j, tests[j].desc);
}
elm_exit();
return 1;
}
else if ((!strcmp(argv[i], "-t")) && (i < (argc - 1)))
{
i++;
if (!tests_to_do) tests_to_do = eina_array_new(32);
eina_array_push(tests_to_do, (void *)(uintptr_t)atoi(argv[i]));
}
else if ((!strcmp(argv[i], "-r")) && (i < (argc - 1)))
{
i++;
run_time = atof(argv[i]);
}
else if ((!strcmp(argv[i], "-d")) && (i < (argc - 1)))
{
i++;
spin_up_delay = atof(argv[i]);
}
}
if (!tests_to_do)
{
tests_to_do = eina_array_new(32);
for (j = 0; tests[j].init; j++)
{
eina_array_push(tests_to_do, (void *)(uintptr_t)(j + 1));
}
}
elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR);
elm_app_compile_lib_dir_set(PACKAGE_LIB_DIR);
elm_app_compile_data_dir_set(PACKAGE_DATA_DIR);
elm_app_info_set(elm_main, "elementary", "images/logo.png");
win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
if (!win)
{
elm_exit();
return 1;
}
evas = evas_object_evas_get(win);
elm_win_autodel_set(win, EINA_TRUE);
elm_win_title_set(win, "Elementary Performace Test");
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
bg = evas_object_rectangle_add(evas);
evas_object_color_set(bg, 128, 128, 128, 255);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bg);
evas_object_show(bg);
evas_event_callback_add(evas, EVAS_CALLBACK_RENDER_PRE, render_pre, NULL);
evas_event_callback_add(evas, EVAS_CALLBACK_RENDER_FLUSH_POST, render_post, NULL);
ecore_idler_add(_spincpu_up_idler, NULL);
printf("--------------------------------------------------------------------------------\n");
printf("Performance Test Engine: %s\n",
ecore_evas_engine_name_get(ecore_evas_ecore_evas_get(evas)));
printf("--------------------------------------------------------------------------------\n");
ecore_timer_add(spin_up_delay, all_tests_delay, evas);
evas_object_resize(win, 800, 800);
evas_object_show(win);
elm_run();
return 0;
}
ELM_MAIN()
///////////////////////////////////////////////////////////////////////////////