elm perf tool - bring one back to efl

expedite is basically dead. because it's out of tree and because it
was ported to eo too early... but it's also not a great tool given it
requires manual addition of engines and can't test elm stuff (complex
widgets).

so this is an elm based performance tool. i've added some tests (taken
from expedite and modified a bit). to get the ball rolling. the idea
is to add all the important core tests (rects, images, text, video
etc.) and then add widget/smart object like tests that go beyond what
expedite did. the problem with these tests is they are dependent on
theme. there isn't really any way around that... but i might
categorize tests in the end.

@feature
This commit is contained in:
Carsten Haitzler 2018-11-22 16:48:56 +00:00 committed by Christopher Michael
parent 09f648ed81
commit 9315c220d5
13 changed files with 1676 additions and 2 deletions

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=Elementary Perf
Comment=Elementary Performance Test Application
Icon=elementary
Exec=elementary_perf
Terminal=false
Categories=Development;Utility;

View File

@ -1,4 +1,7 @@
desktop_files = files('elementary_config.desktop', 'elementary_test.desktop')
desktop_files = files(
'elementary_config.desktop',
'elementary_test.desktop',
'elementary_perf.desktop')
elementary_icon = files('elementary.png')
install_data(desktop_files,

View File

@ -210,7 +210,6 @@ elm_prefs_cc_src = [
'elm_prefs_cc_out.c',
'elm_prefs_cc_parse.c',
'elm_prefs_cc_handlers.c'
]
elm_prefs_cc = executable('elm_prefs_cc',
@ -232,3 +231,27 @@ elementary_run = executable('elementary_run',
c_args : package_c_args,
link_args: '-rdynamic'
)
elementary_perf_src = [
'perf.c',
'perf_rnd.c',
'perf_test_01.c',
'perf_test_02.c',
'perf_test_03.c',
'perf_test_04.c',
'perf_test_05.c',
'perf_test_06.c'
]
elementary_perf = executable('elementary_perf',
elementary_perf_src,
dependencies: [elementary] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args + [
'-Delementary_test_BIN_DIR="'+dir_bin+'"',
'-Delementary_test_LIB_DIR="'+dir_lib+'"',
'-Delementary_test_DATA_DIR="'+join_paths(dir_data,'elementary')+'"'
],
link_args: '-rdynamic'
)

301
src/bin/elementary/perf.c Normal file
View File

@ -0,0 +1,301 @@
#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()
///////////////////////////////////////////////////////////////////////////////

16
src/bin/elementary/perf.h Normal file
View File

@ -0,0 +1,16 @@
#include <Elementary.h>
#define NUM_MANY 1024
#define NUM 64
#define NUM_FEW 8
void srnd(void);
unsigned int rnd(void);
void cleanup_add(Evas_Object *o);
#define TST(x, y) \
void test_ ## x ## _ ## y
#define TPROT(x) \
TST(x, init)(Evas *e); \
TST(x, tick)(Evas *e, double f, Evas_Coord win_w, Evas_Coord win_h)

View File

@ -0,0 +1,6 @@
#include "perf_test_01.c"
#include "perf_test_02.c"
#include "perf_test_03.c"
#include "perf_test_04.c"
#include "perf_test_05.c"
#include "perf_test_06.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
#ifdef T2
TPROT(01);
#endif
#ifdef T1
{ TFUN(01), "Rectangles (Few)", 0.2 },
#endif
#if !defined(T1) && !defined(T2)
# include "perf.h"
static Evas_Object *objs[NUM_FEW];
TST(01, init) (Evas *e) {
Evas_Object *o;
int i;
srnd();
for (i = 0; i < NUM_FEW; i++)
{
objs[i] = o = evas_object_rectangle_add(e);
cleanup_add(o);
evas_object_color_set
(o, rnd() & 0x7f, rnd() & 0x7f, rnd() & 0x7f, 0x80);
evas_object_pass_events_set(o, EINA_TRUE);
evas_object_show(o);
}
}
TST(01, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h) {
int i;
Evas_Coord x, y, w, h, w0, h0;
for (i = 0; i < NUM_FEW; i++)
{
Evas_Object *o = objs[i];
w0 = 120;
h0 = 120;
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
y = (win_h / 2) - (h / 2);
y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
evas_object_geometry_set(o, x, y, w, h);
}
}
#endif

View File

@ -0,0 +1,45 @@
#ifdef T2
TPROT(02);
#endif
#ifdef T1
{ TFUN(02), "Rectangles (Few) - Solid", 0.4 },
#endif
#if !defined(T1) && !defined(T2)
# include "perf.h"
static Evas_Object *objs[NUM_FEW];
TST(02, init) (Evas *e) {
Evas_Object *o;
int i;
srnd();
for (i = 0; i < NUM_FEW; i++)
{
objs[i] = o = evas_object_rectangle_add(e);
cleanup_add(o);
evas_object_color_set
(o, rnd() & 0xff, rnd() & 0xff, rnd() & 0xff, 0xff);
evas_object_pass_events_set(o, EINA_TRUE);
evas_object_show(o);
}
}
TST(02, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h) {
int i;
Evas_Coord x, y, w, h, w0, h0;
for (i = 0; i < NUM_FEW; i++)
{
Evas_Object *o = objs[i];
w0 = 120;
h0 = 120;
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
y = (win_h / 2) - (h / 2);
y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
evas_object_geometry_set(o, x, y, w, h);
}
}
#endif

View File

@ -0,0 +1,45 @@
#ifdef T2
TPROT(03);
#endif
#ifdef T1
{ TFUN(03), "Rectangles", 1.0 },
#endif
#if !defined(T1) && !defined(T2)
# include "perf.h"
static Evas_Object *objs[NUM];
TST(03, init) (Evas *e) {
Evas_Object *o;
int i;
srnd();
for (i = 0; i < NUM; i++)
{
objs[i] = o = evas_object_rectangle_add(e);
cleanup_add(o);
evas_object_color_set
(o, rnd() & 0x7f, rnd() & 0x7f, rnd() & 0x7f, 0x80);
evas_object_pass_events_set(o, EINA_TRUE);
evas_object_show(o);
}
}
TST(03, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h) {
int i;
Evas_Coord x, y, w, h, w0, h0;
for (i = 0; i < NUM; i++)
{
Evas_Object *o = objs[i];
w0 = 120;
h0 = 120;
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
y = (win_h / 2) - (h / 2);
y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
evas_object_geometry_set(o, x, y, w, h);
}
}
#endif

View File

@ -0,0 +1,45 @@
#ifdef T2
TPROT(04);
#endif
#ifdef T1
{ TFUN(04), "Rectangles - Solid", 2.0 },
#endif
#if !defined(T1) && !defined(T2)
# include "perf.h"
static Evas_Object *objs[NUM];
TST(04, init) (Evas *e) {
Evas_Object *o;
int i;
srnd();
for (i = 0; i < NUM; i++)
{
objs[i] = o = evas_object_rectangle_add(e);
cleanup_add(o);
evas_object_color_set
(o, rnd() & 0xff, rnd() & 0xff, rnd() & 0xff, 0xff);
evas_object_pass_events_set(o, EINA_TRUE);
evas_object_show(o);
}
}
TST(04, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h) {
int i;
Evas_Coord x, y, w, h, w0, h0;
for (i = 0; i < NUM; i++)
{
Evas_Object *o = objs[i];
w0 = 120;
h0 = 120;
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
y = (win_h / 2) - (h / 2);
y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
evas_object_geometry_set(o, x, y, w, h);
}
}
#endif

View File

@ -0,0 +1,45 @@
#ifdef T2
TPROT(05);
#endif
#ifdef T1
{ TFUN(05), "Rectangles (Many)", 1.0 },
#endif
#if !defined(T1) && !defined(T2)
# include "perf.h"
static Evas_Object *objs[NUM_MANY];
TST(05, init) (Evas *e) {
Evas_Object *o;
int i;
srnd();
for (i = 0; i < NUM_MANY; i++)
{
objs[i] = o = evas_object_rectangle_add(e);
cleanup_add(o);
evas_object_color_set
(o, rnd() & 0x7f, rnd() & 0x7f, rnd() & 0x7f, 0x80);
evas_object_pass_events_set(o, EINA_TRUE);
evas_object_show(o);
}
}
TST(05, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h) {
int i;
Evas_Coord x, y, w, h, w0, h0;
for (i = 0; i < NUM_MANY; i++)
{
Evas_Object *o = objs[i];
w0 = 120;
h0 = 120;
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
y = (win_h / 2) - (h / 2);
y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
evas_object_geometry_set(o, x, y, w, h);
}
}
#endif

View File

@ -0,0 +1,45 @@
#ifdef T2
TPROT(06);
#endif
#ifdef T1
{ TFUN(06), "Rectangles (Many) - Solid", 2.0 },
#endif
#if !defined(T1) && !defined(T2)
# include "perf.h"
static Evas_Object *objs[NUM_MANY];
TST(06, init) (Evas *e) {
Evas_Object *o;
int i;
srnd();
for (i = 0; i < NUM_MANY; i++)
{
objs[i] = o = evas_object_rectangle_add(e);
cleanup_add(o);
evas_object_color_set
(o, rnd() & 0xff, rnd() & 0xff, rnd() & 0xff, 0xff);
evas_object_pass_events_set(o, EINA_TRUE);
evas_object_show(o);
}
}
TST(06, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h) {
int i;
Evas_Coord x, y, w, h, w0, h0;
for (i = 0; i < NUM_MANY; i++)
{
Evas_Object *o = objs[i];
w0 = 120;
h0 = 120;
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
y = (win_h / 2) - (h / 2);
y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
evas_object_geometry_set(o, x, y, w, h);
}
}
#endif