e fps debug - have more details like wake+sleep, rend+rend flush etc.

more mini pixels to tell you a story of debug.
This commit is contained in:
Carsten Haitzler 2020-08-18 22:01:31 +01:00
parent 088b1b26c9
commit b1897a3667
3 changed files with 214 additions and 62 deletions

View File

@ -212,7 +212,7 @@ _e_comp_fps_update(void)
e_comp->canvas->fps_gr = evas_object_image_filled_add(e_comp->evas);
evas_object_image_smooth_scale_set(e_comp->canvas->fps_gr, EINA_FALSE);
evas_object_image_alpha_set(e_comp->canvas->fps_gr, EINA_TRUE);
evas_object_image_size_set(e_comp->canvas->fps_gr, 500, 3);
evas_object_image_size_set(e_comp->canvas->fps_gr, 1, 1);
evas_object_color_set(e_comp->canvas->fps_gr, 255, 255, 255, 255);
evas_object_layer_set(e_comp->canvas->fps_gr, E_LAYER_MAX);
evas_object_name_set(e_comp->canvas->fps_gr, "e_comp->canvas->fps_gr");
@ -380,33 +380,96 @@ _e_comp_nocomp_end(void)
}
static double
_e_comp_fps_calc(double *frametimes, int count)
_e_comp_frame_event_fps_calc(int info)
{
int i;
double t0 = frametimes[0], dt;
int i, count = 0, iind, start, end, end2;
Eina_Bool first = EINA_FALSE;
double t0 = 0.0, dt;
for (i = 1; i < count; i++)
start = e_comp->frame_event_now - 1 + E_COMP_FRAME_EVENT_COUNT;
end = e_comp->frame_event_now + E_COMP_FRAME_EVENT_COUNT ;
end2 = e_comp->frame_event_now + E_COMP_FRAME_EVENT_COUNT + 1;
for (i = start;;)
{
dt = t0 - frametimes[i];
if ((dt > 0.5) || (i >= (count - 1)))
iind = i % E_COMP_FRAME_EVENT_COUNT;
i--;
if (iind == (end % E_COMP_FRAME_EVENT_COUNT)) break;
if (e_comp->frame_events[iind].info[0] != info) continue;
count++;
if (!first)
{
if (dt > 0.0) return ((double)i) / dt;
t0 = e_comp->frame_events[iind].t;
first = EINA_TRUE;
}
else
{
dt = t0 - e_comp->frame_events[iind].t;
if ((dt > 0.5) || (iind == (end2 % E_COMP_FRAME_EVENT_COUNT)))
{
if (dt > 0.0) return ((double)(count - 1)) / dt;
}
}
}
return 0.0;
}
E_API void
e_comp_frame_event_add(int info[4], double t)
{
e_comp->frame_events[e_comp->frame_event_now].info[0] = info[0];
e_comp->frame_events[e_comp->frame_event_now].info[1] = info[1];
e_comp->frame_events[e_comp->frame_event_now].info[2] = info[2];
e_comp->frame_events[e_comp->frame_event_now].info[3] = info[3];
e_comp->frame_events[e_comp->frame_event_now].t = t;
e_comp->frame_event_now++;
if (e_comp->frame_event_now >= E_COMP_FRAME_EVENT_COUNT)
e_comp->frame_event_now = 0;
}
E_API void
e_comp_client_frame_add(Evas_Object *obj EINA_UNUSED)
{
int i;
int info[4] = { 0, 0, 0, 0 };
double t = ecore_time_get();
for (i = 121; i >= 1; i--)
e_comp->client_frametimes[i] = e_comp->client_frametimes[i - 1];
e_comp->client_frametimes[0] = t;
info[0] = E_COMP_FRAME_EVENT_CLIENT_DAMAGE;
e_comp_frame_event_add(info, t);
}
static inline void
_e_comp_fps_draw_point(unsigned int *pix, int stride, int w, int y, int col, int x)
{
unsigned int *pixrow = pix + (y * (stride / 4));
// out of bounds abort draw
if (x < 0) return;
if (x >= w) return;
pixrow[x] = col;
}
/* for future
static inline void
_e_comp_fps_draw_span(unsigned int *pix, int stride, int w, int y, int col, int x1, int x2)
{
unsigned int *pixrow = pix + (y * (stride / 4));
int x;
if (x2 < x1) // swap so x2 >= x1
{
x = x2;
x2 = x1;
x1 = x;
}
// out of bounds abort draw
if (x2 < 0) return;
if (x1 >= w) return;
// clip to span area
if (x1 < 0) x1 = 0;
if (x2 >= w) x2 = w - 1;
for (x = x1; x <= x2; x++)
pixrow[x] = col;
}
*/
E_API void
e_comp_fps_update(void)
{
@ -418,17 +481,20 @@ e_comp_fps_update(void)
E_Zone *z;
e_comp->frameskip++;
if (e_comp->frameskip >= 15)
if (e_comp->frameskip >= 20)
{
unsigned int *pix, *pixrow;
int pixw, pixh, pixstride, i, px, pixscale;
unsigned int *pix;
int i, pixw, pixh, pixsz, pixstride, px, pixscale, info0, start, end, iind;
double t;
t = ecore_time_get();
e_comp->frameskip = 0;
fps = _e_comp_fps_calc(e_comp->frametimes, 122);
comp_fps = _e_comp_fps_calc(e_comp->comp_frametimes, 122);
pixh = 8;
pixsz = 2;
fps = _e_comp_frame_event_fps_calc(E_COMP_FRAME_EVENT_HANDLE_DAMAGE);
comp_fps = _e_comp_frame_event_fps_calc(E_COMP_FRAME_EVENT_RENDER_END);
snprintf(buf, sizeof(buf), "FPS: (in) %1.1f (out) %1.1f", fps, comp_fps);
evas_object_text_text_set(e_comp->canvas->fps_fg, buf);
@ -446,40 +512,40 @@ e_comp_fps_update(void)
y = z->y + z->h - h;
gw = 500;
gh = 3 * 5;
gh = pixh * pixsz;
gx = x + w - gw;
gy = y - gh - 8;
bw = (gw > bw) ? gw : bw;
bh = h + gh + 8;
bh = h + gh + 16;
bx = (x > gx) ? gx: x;
by = gy;
by = gy - 8;
break;
case 2: // bottom-left
x = z->x;
y = z->y + z->h - h;
gw = 500;
gh = 3 * 5;
gh = pixh * pixsz;
gx = x;
gy = y - gh - 8;
bw = (gw > bw) ? gw : bw;
bh = h + gh + 8;
bh = h + gh + 16;
bx = x;
by = gy;
by = gy - 8;
break;
case 1: // top-right
x = z->x + z->w - w;
y = z->y;
gw = 500;
gh = 3 * 5;
gh = pixh * pixsz;
gx = x + w - gw;
gy = y + h;
bw = (gw > bw) ? gw : bw;
bh = h + gh + 8;
bh = h + gh + 16;
bx = (x > gx) ? gx: x;
by = y;
break;
@ -489,12 +555,12 @@ e_comp_fps_update(void)
y = z->y;
gw = 500;
gh = 3 * 5;
gh = pixh * pixsz;
gx = x;
gy = y + h;
bw = (gw > bw) ? gw : bw;
bh = h + gh + 8;
bh = h + gh + 16;
bx = x;
by = y;
break;
@ -502,7 +568,6 @@ e_comp_fps_update(void)
}
pixscale = 1000;
pixw = 500;
pixh = 3;
evas_object_image_size_set(e_comp->canvas->fps_gr, pixw, pixh);
evas_object_image_alpha_set(e_comp->canvas->fps_gr, EINA_TRUE);
pixstride = evas_object_image_stride_get(e_comp->canvas->fps_gr);
@ -510,29 +575,35 @@ e_comp_fps_update(void)
memset(pix, 0, pixstride * pixh);
// comp render done...
pixrow = pix + (0 * (pixstride / 4));
for (i = 0; i < 122; i++)
// go backwards from newest to oldest
start = e_comp->frame_event_now + E_COMP_FRAME_EVENT_COUNT - 1;
end = e_comp->frame_event_now + E_COMP_FRAME_EVENT_COUNT ;
for (i = start;;)
{
px = (t - e_comp->comp_frametimes[i]) * pixscale;
if (px >= pixw) break;
pixrow[pixw - 1 - px] = 0xffff5533;
}
// client update jobs done...
pixrow = pix + (1 * (pixstride / 4));
for (i = 0; i < 122; i++)
{
px = (t - e_comp->frametimes[i]) * pixscale;
if (px >= pixw) break;
pixrow[pixw - 1 - px] = 0xff55ff33;
}
// client updates
pixrow = pix + (2 * (pixstride / 4));
for (i = 0; i < 122; i++)
{
px = (t - e_comp->client_frametimes[i]) * pixscale;
if (px >= pixw) break;
pixrow[pixw - 1 - px] = 0xff3355ff;
iind = i % E_COMP_FRAME_EVENT_COUNT;
i--;
if (iind == (end % E_COMP_FRAME_EVENT_COUNT)) break;
info0 = e_comp->frame_events[iind].info[0];
px = (t - e_comp->frame_events[iind].t) * pixscale;
px = pixw - px - 1;
if (px < 0) break;
if (info0 == E_COMP_FRAME_EVENT_RENDER2_END)
_e_comp_fps_draw_point(pix, pixstride, pixw, 0, 0xffffffff, px);
else if (info0 == E_COMP_FRAME_EVENT_RENDER2_BEGIN)
_e_comp_fps_draw_point(pix, pixstride, pixw, 1, 0xffffee88, px);
else if (info0 == E_COMP_FRAME_EVENT_RENDER_END)
_e_comp_fps_draw_point(pix, pixstride, pixw, 2, 0xffff9944, px);
else if (info0 == E_COMP_FRAME_EVENT_RENDER_BEGIN)
_e_comp_fps_draw_point(pix, pixstride, pixw, 3, 0xffff4433, px);
else if (info0 == E_COMP_FRAME_EVENT_IDLE_ENTER)
_e_comp_fps_draw_point(pix, pixstride, pixw, 4, 0xff994499, px);
else if (info0 == E_COMP_FRAME_EVENT_IDLE_EXIT)
_e_comp_fps_draw_point(pix, pixstride, pixw, 5, 0xffff88ff, px);
else if (info0 == E_COMP_FRAME_EVENT_HANDLE_DAMAGE)
_e_comp_fps_draw_point(pix, pixstride, pixw, 6, 0xff44ff22, px);
else if (info0 == E_COMP_FRAME_EVENT_CLIENT_DAMAGE)
_e_comp_fps_draw_point(pix, pixstride, pixw, 7, 0xff4466ff, px);
}
evas_object_image_data_set(e_comp->canvas->fps_gr, pix);
@ -573,12 +644,11 @@ _e_comp_cb_update(void)
_e_comp_fps_update();
if (conf->fps_show)
{
int i;
double t = ecore_loop_time_get();
int info[4] = { 0, 0, 0, 0 };
for (i = 121; i >= 1; i--)
e_comp->frametimes[i] = e_comp->frametimes[i - 1];
e_comp->frametimes[0] = t;
info[0] = E_COMP_FRAME_EVENT_HANDLE_DAMAGE;
e_comp_frame_event_add(info, t);
e_comp_fps_update();
}
/*

View File

@ -91,6 +91,23 @@ typedef struct E_Comp_Canvas
Evas_Object *gadget_site; //desktop gadget site
} E_Comp_Canvas;
#define E_COMP_FRAME_EVENT_COUNT 1024
#define E_COMP_FRAME_EVENT_RENDER_BEGIN 1
#define E_COMP_FRAME_EVENT_RENDER_END 2
#define E_COMP_FRAME_EVENT_RENDER2_BEGIN 3
#define E_COMP_FRAME_EVENT_RENDER2_END 4
#define E_COMP_FRAME_EVENT_CLIENT_DAMAGE 5
#define E_COMP_FRAME_EVENT_HANDLE_DAMAGE 6
#define E_COMP_FRAME_EVENT_IDLE_EXIT 7
#define E_COMP_FRAME_EVENT_IDLE_ENTER 8
typedef struct E_Comp_Frame_Event
{
int info[4];
double t;
} E_Comp_Event;
struct _E_Comp
{
E_Object e_obj_inherit;
@ -146,9 +163,8 @@ struct _E_Comp
Ecore_Timer *nocomp_delay_timer; //delay before activating nocomp in x11
Ecore_Timer *nocomp_override_timer; //delay before overriding nocomp in x11
int animating; //number of animating comp objects
double frametimes[122]; //used for calculating fps
double comp_frametimes[122]; //used for calculating fps
double client_frametimes[122]; //used for calculating fps
E_Comp_Event frame_events[E_COMP_FRAME_EVENT_COUNT]; // history of frame events for debug
int frame_event_now;
int frameskip;
int nocomp_override; //number of times nocomp override has been requested
@ -225,6 +241,7 @@ E_API Eina_Bool e_comp_grab_input(Eina_Bool mouse, Eina_Bool kbd);
E_API void e_comp_ungrab_input(Eina_Bool mouse, Eina_Bool kbd);
E_API void e_comp_gl_set(Eina_Bool set);
E_API Eina_Bool e_comp_gl_get(void);
E_API void e_comp_frame_event_add(int info[4], double t);
E_API void e_comp_client_frame_add(Evas_Object *obj);
E_API void e_comp_button_bindings_grab_all(void);

View File

@ -69,17 +69,48 @@ _e_comp_canvas_render_post_job(void *data EINA_UNUSED)
}
}
static void
_e_comp_canvas_render_track_pre(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
info[0] = E_COMP_FRAME_EVENT_RENDER_BEGIN;
e_comp_frame_event_add(info, ecore_time_get());
}
static void
_e_comp_canvas_render_track_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
info[0] = E_COMP_FRAME_EVENT_RENDER_END;
e_comp_frame_event_add(info, ecore_time_get());
}
static void
_e_comp_canvas_render_track_flush_pre(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
info[0] = E_COMP_FRAME_EVENT_RENDER2_BEGIN;
e_comp_frame_event_add(info, ecore_time_get());
}
static void
_e_comp_canvas_render_track_flush_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
info[0] = E_COMP_FRAME_EVENT_RENDER2_END;
e_comp_frame_event_add(info, ecore_time_get());
}
static void
_e_comp_canvas_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
E_Comp_Config *conf = e_comp_config_get();
double t = ecore_time_get();
int i;
// NOTE: don't modify objects here as we may lose updates - defer...
for (i = 121; i >= 1; i--)
e_comp->comp_frametimes[i] = e_comp->comp_frametimes[i - 1];
e_comp->comp_frametimes[0] = t;
if (conf->fps_show)
{
if (_e_comp_update_job) ecore_job_del(_e_comp_update_job);
@ -425,10 +456,15 @@ _e_comp_canvas_cb_zone_sort(const void *data1, const void *data2)
static void
_e_comp_canvas_prerender(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
double t = ecore_time_get();
E_Comp_Cb cb;
Eina_List *l;
E_Comp_Config *conf = e_comp_config_get();
info[0] = E_COMP_FRAME_EVENT_RENDER_BEGIN;
e_comp_frame_event_add(info, t);
e_comp->rendering = EINA_TRUE;
if (conf->grab && (!e_comp->grabbed))
@ -441,6 +477,24 @@ _e_comp_canvas_prerender(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *even
cb();
}
static Eina_Bool
_e_comp_canvas_cb_idle_enterer(void *data EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
info[0] = E_COMP_FRAME_EVENT_IDLE_ENTER;
e_comp_frame_event_add(info, ecore_time_get());
return EINA_TRUE;
}
static Eina_Bool
_e_comp_canvas_cb_idle_exiter(void *data EINA_UNUSED)
{
int info[4] = { 0, 0, 0, 0 };
info[0] = E_COMP_FRAME_EVENT_IDLE_EXIT;
e_comp_frame_event_add(info, ecore_time_get());
return EINA_TRUE;
}
E_API Eina_Bool
e_comp_canvas_init(int w, int h)
{
@ -464,6 +518,17 @@ e_comp_canvas_init(int w, int h)
e_comp->evas = ecore_evas_get(e_comp->ee);
static int inited = 0;
if (!inited)
{
inited = 1;
ecore_idle_enterer_add(_e_comp_canvas_cb_idle_enterer, NULL);
ecore_idle_exiter_add(_e_comp_canvas_cb_idle_exiter, NULL);
}
evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_PRE, _e_comp_canvas_render_track_pre, NULL);
evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_render_track_post, NULL);
evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _e_comp_canvas_render_track_flush_pre, NULL);
evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _e_comp_canvas_render_track_flush_post, NULL);
if (e_first_frame)
evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_cb_first_frame, NULL);
o = evas_object_rectangle_add(e_comp->evas);