From dc7ed56be8355794ef3a6d314ed2e2cda8e4c1f2 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Sat, 3 Aug 2013 18:00:16 -0300 Subject: [PATCH] Backport 1210067fbeb21bdce34ec710e66749de981a1617. ecore_evas/wayland_egl: Only render if last frame has been presented. This avoids blocking in eglSwapBuffers and has the side effect of avoiding doing unnecessary work - painting where a frame won't be presented. We do this by using the event that the wayland compositor will send us to tell us that the frame has been presented. Due to the fact that evas_render_updates() could do no work and not cause a eglSwapBuffers we must always have a frame callback listener setup. Original patch by: Rob Bradford (I just adjusted the patch to the single efl tree) --- src/lib/ecore_evas/ecore_evas_wayland_egl.c | 66 +++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 25aa6e0..01224ac 100644 --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c @@ -176,7 +176,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = NULL, NULL, NULL, - _ecore_evas_wl_render, + _ecore_evas_wl_render, _ecore_evas_wl_screen_geometry_get, _ecore_evas_wl_screen_dpi_get, NULL, // wm_rot_preferred_rotation_set @@ -830,6 +830,30 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) } } +static void +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time __UNUSED__); + +static const struct wl_callback_listener frame_listener = { + _ecore_evas_wl_frame_complete, +}; + +static void +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time __UNUSED__) +{ + Ecore_Evas *ee = data; + Ecore_Wl_Window *win = ee->engine.wl.win; + + win->frame_callback = NULL; + win->frame_pending = EINA_FALSE; + wl_callback_destroy(callback); + + win->frame_callback = + wl_surface_frame(win->surface); + + wl_callback_add_listener(win->frame_callback, + &frame_listener, ee); +} + static int _ecore_evas_wl_render(Ecore_Evas *ee) { @@ -842,6 +866,7 @@ _ecore_evas_wl_render(Ecore_Evas *ee) { Eina_List *ll = NULL, *updates = NULL; Ecore_Evas *ee2 = NULL; + Ecore_Wl_Window *win = NULL; if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); @@ -853,25 +878,40 @@ _ecore_evas_wl_render(Ecore_Evas *ee) if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); } - if ((updates = evas_render_updates(ee->evas))) + win = ee->engine.wl.win; + + if (!win->frame_pending) { - Eina_List *l = NULL; - Eina_Rectangle *r; + if (!win->frame_callback) + { + win->frame_callback = wl_surface_frame(win->surface); + wl_callback_add_listener(win->frame_callback, + &frame_listener, ee); + } + + if ((updates = evas_render_updates(ee->evas))) + { + Eina_List *l = NULL; + Eina_Rectangle *r; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); - LOGFN(__FILE__, __LINE__, __FUNCTION__); + EINA_LIST_FOREACH(updates, l, r) + ecore_wl_window_damage(win, + r->x, r->y, r->w, r->h); - EINA_LIST_FOREACH(updates, l, r) - ecore_wl_window_damage(ee->engine.wl.win, - r->x, r->y, r->w, r->h); + ecore_wl_flush(); - ecore_wl_flush(); + evas_render_updates_free(updates); + _ecore_evas_idle_timeout_update(ee); + rend = 1; + + win->frame_pending = EINA_TRUE; + } - evas_render_updates_free(updates); - _ecore_evas_idle_timeout_update(ee); - rend = 1; + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); } - if (ee->func.fn_post_render) ee->func.fn_post_render(ee); } return rend; } -- 2.7.4