From 5966a730cd802f1e70bdbbd0138f43a8254ec890 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Sat, 30 Nov 2013 10:09:38 -0200 Subject: [PATCH 1/4] evas/wayland_shm: Don't use a global var to store the sent buffer. When an Ecore_Evas is hidden, it will destroy the buffer swapper. When it's shown again, it will try to attach a new buffer, that can be same buffer. If that global var is still pointing to the old buffer, it can match to it again and avoid sending a new buffer. So, just put this sent buffer var in the buffer swapper, and it will get set to NULL when the swapper is destroyed and created again. This should fix an intermitent problem of ecore_evas_show() not always working after an ecore_evas_hide() on the wayland_shm engine. --- src/modules/evas/engines/wayland_shm/evas_swapper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/evas/engines/wayland_shm/evas_swapper.c b/src/modules/evas/engines/wayland_shm/evas_swapper.c index f9f5b3de21..1a879faece 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapper.c +++ b/src/modules/evas/engines/wayland_shm/evas_swapper.c @@ -29,6 +29,7 @@ struct _Wl_Buffer struct _Wl_Swapper { Wl_Buffer buff[3]; + Wl_Buffer *buffer_sent; int in_use; int dx, dy, w, h, depth; int buff_cur, buff_num; @@ -448,7 +449,6 @@ static void _evas_swapper_buffer_put(Wl_Swapper *ws, Wl_Buffer *wb, Eina_Rectangle *rects, unsigned int count) { Eina_Rectangle *rect; - static Wl_Buffer *sent = NULL; LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -488,12 +488,12 @@ _evas_swapper_buffer_put(Wl_Swapper *ws, Wl_Buffer *wb, Eina_Rectangle *rects, u } /* surface attach */ - if (sent != wb) + if (ws->buffer_sent != wb) { wl_surface_attach(ws->surface, wb->buffer, ws->dx, ws->dy); ws->dx = 0; ws->dy = 0; - sent = wb; + ws->buffer_sent = wb; } wl_surface_damage(ws->surface, rect->x, rect->y, rect->w, rect->h); From ff5533b4e17241e5bf7b56b3629e4097d55991e6 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Sat, 30 Nov 2013 10:14:05 -0200 Subject: [PATCH 2/4] ecore_evas/wayland: Implement ecore_evas_withdrawn_set. Just call ecore_evas_show/hide inside the function. --- .../engines/wayland/ecore_evas_wayland_common.c | 11 +++++++++++ .../engines/wayland/ecore_evas_wayland_egl.c | 2 +- .../engines/wayland/ecore_evas_wayland_private.h | 1 + .../engines/wayland/ecore_evas_wayland_shm.c | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index efdea8397f..189f382c91 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -1285,6 +1285,17 @@ _ecore_evas_wl_common_render(Ecore_Evas *ee) return rend; } +void +_ecore_evas_wl_common_withdrawn_set(Ecore_Evas *ee, int val) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (val) + ecore_evas_hide(ee); + else + ecore_evas_show(ee); +} + void _ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) { diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c index c150d6aa03..ff4a6012c9 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c @@ -59,7 +59,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = _ecore_evas_wl_common_maximized_set, _ecore_evas_wl_common_fullscreen_set, NULL, // func avoid_damage set - NULL, // func withdrawn set + _ecore_evas_wl_common_withdrawn_set, NULL, // func sticky set _ecore_evas_wl_common_ignore_events_set, _ecore_evas_wl_alpha_set, diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h index 11c405eb1b..edf7be27cc 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h @@ -76,6 +76,7 @@ void _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int * void _ecore_evas_wl_common_render_updates(void *data, Evas *evas, void *event); void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize); void _ecore_evas_wl_common_borderless_set(Ecore_Evas *ee, int borderless); +void _ecore_evas_wl_common_withdrawn_set(Ecore_Evas *ee, int val); Evas_Object * _ecore_evas_wl_common_frame_add(Evas *evas); void _ecore_evas_wl_common_frame_border_size_set(Evas_Object *obj, int fx, int fy, int fw, int fh); diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c index b4539470c7..c4b7fbcefd 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c @@ -59,7 +59,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = _ecore_evas_wl_common_maximized_set, _ecore_evas_wl_common_fullscreen_set, NULL, // func avoid_damage set - NULL, // func withdrawn set + _ecore_evas_wl_common_withdrawn_set, NULL, // func sticky set _ecore_evas_wl_common_ignore_events_set, _ecore_evas_wl_alpha_set, From 77a4654470aa48edc1dae69f928fa3291ce6e130 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Mon, 2 Dec 2013 17:42:37 -0200 Subject: [PATCH 3/4] ecore_evas/wayland_egl: Unset the surface on window hide. We must unset it, so the Evas engine knows that it has to do all the setup to destroy the EGL surfaces associated with it. And in the case of an ecore_evas_show, recreate everything again. --- .../engines/wayland/ecore_evas_wayland_egl.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c index ff4a6012c9..335111c949 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c @@ -285,7 +285,7 @@ _ecore_evas_wl_rotation_set(Ecore_Evas *ee, int rotation, int resize) static void _ecore_evas_wl_show(Ecore_Evas *ee) { - /* Evas_Engine_Info_Wayland_Egl *einfo; */ + Evas_Engine_Info_Wayland_Egl *einfo; Ecore_Evas_Engine_Wl_Data *wdata; int fw, fh; @@ -300,14 +300,13 @@ _ecore_evas_wl_show(Ecore_Evas *ee) { ecore_wl_window_show(wdata->win); ecore_wl_window_update_size(wdata->win, ee->w + fw, ee->h + fh); -// ecore_wl_window_buffer_attach(wdata->win, NULL, 0, 0); - /* einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); */ - /* if (einfo) */ - /* { */ - /* einfo->info.surface = ecore_wl_window_surface_get(wdata->win); */ - /* evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); */ - /* } */ + einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.surface = ecore_wl_window_surface_get(wdata->win); + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } } if (wdata->frame) From 615d5ab634df5e8e74ff9de51073e3cfdae54e4b Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Mon, 2 Dec 2013 17:39:24 -0200 Subject: [PATCH 4/4] ecore_evas/wayland: Add a function to cleanup the frame callback. This callback must be manually destroyed and removed on ecore_evas_hide(), because it won't be delivered anymore after the surface is destroyed. If the callback still exists, the engine will find it and avoid doing a new redraw until it is finally called. Maybe the correct thing to do is to keep this callback in the Ecore_Wl_Window struct, and have some functions to set/unset it, so it gets destroyed when the window is hidden. Or when the surface is destroyed. --- .../wayland/ecore_evas_wayland_common.c | 23 +++++++++++++++---- .../engines/wayland/ecore_evas_wayland_egl.c | 1 + .../wayland/ecore_evas_wayland_private.h | 2 ++ .../engines/wayland/ecore_evas_wayland_shm.c | 1 + 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index 189f382c91..2fcad77197 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -1200,21 +1200,34 @@ _ecore_evas_wl_common_post_render(Ecore_Evas *ee) if (ee->func.fn_post_render) ee->func.fn_post_render(ee); } +void +_ecore_evas_wl_common_frame_callback_clean(Ecore_Evas *ee) +{ + Ecore_Evas_Engine_Wl_Data *wdata; + + wdata = ee->engine.data; + + if (!wdata->frame_pending) + return; + wl_callback_destroy(wdata->frame_callback); + wdata->frame_callback = NULL; + wdata->frame_pending = EINA_FALSE; +} + static void -_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm EINA_UNUSED) +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback EINA_UNUSED, uint32_t tm EINA_UNUSED) { Ecore_Evas *ee = data; Ecore_Wl_Window *win = NULL; Ecore_Evas_Engine_Wl_Data *wdata; if (!ee) return; + + _ecore_evas_wl_common_frame_callback_clean(ee); + wdata = ee->engine.data; if (!(win = wdata->win)) return; - wdata->frame_callback = NULL; - wdata->frame_pending = EINA_FALSE; - wl_callback_destroy(callback); - if (ecore_wl_window_surface_get(win)) { wdata->frame_callback = diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c index 335111c949..a9a17763a3 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c @@ -344,6 +344,7 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) ee->visible = 0; ee->should_be_visible = 0; + _ecore_evas_wl_common_frame_callback_clean(ee); if (ee->func.fn_hide) ee->func.fn_hide(ee); } diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h index edf7be27cc..a48bdb27c8 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h @@ -78,6 +78,8 @@ void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize void _ecore_evas_wl_common_borderless_set(Ecore_Evas *ee, int borderless); void _ecore_evas_wl_common_withdrawn_set(Ecore_Evas *ee, int val); +void _ecore_evas_wl_common_frame_callback_clean(Ecore_Evas *ee); + Evas_Object * _ecore_evas_wl_common_frame_add(Evas *evas); void _ecore_evas_wl_common_frame_border_size_set(Evas_Object *obj, int fx, int fy, int fw, int fh); diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c index c4b7fbcefd..e091830040 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c @@ -343,6 +343,7 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) ee->visible = 0; ee->should_be_visible = 0; + _ecore_evas_wl_common_frame_callback_clean(ee); if (ee->func.fn_hide) ee->func.fn_hide(ee); }