summaryrefslogtreecommitdiff
path: root/src/modules/ecore_evas/engines/wayland
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-12-11 11:26:24 -0500
committerChris Michael <cp.michael@samsung.com>2015-12-11 11:26:24 -0500
commit757f530af96562eac570b0ac75541e6972b5c422 (patch)
tree074880e1c874c0038d7f6018c1f105592507c436 /src/modules/ecore_evas/engines/wayland
parent8c85a89303db1eb878655a91f90021b32d04b76a (diff)
downloadefl-757f530af96562eac570b0ac75541e6972b5c422.tar.gz
ecore-evas-wl: Defer creating surfaces for wayland canvas
This code adds support for deferring of surface creation and showing inside Ecore_Evas Wayland. This is needed for Enlightenment so that it does not try to create or show surfaces until the compositor has had a chance to sync globals. This fixes an issue where early surface creation would cause a crash in the compositor due to globals not being syncd. @fix Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src/modules/ecore_evas/engines/wayland')
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c1
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c126
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h3
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c129
4 files changed, 228 insertions, 31 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 c43414d096..75ac4288d4 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
@@ -1362,6 +1362,7 @@ _ecore_evas_wl_common_render(Ecore_Evas *ee)
if (!ee) return 0;
if (!(wdata = ee->engine.data)) return 0;
+ if (!wdata->sync_done) return 0;
/* TODO: handle comp no sync */
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 651496898f..b9fa475529 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
@@ -114,6 +114,87 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
/* external variables */
+static Eina_Bool
+_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
+{
+ Ecore_Evas *ee;
+ Evas_Engine_Info_Wayland_Shm *einfo;
+ Ecore_Evas_Engine_Wl_Data *wdata;
+
+ ee = data;
+ wdata = ee->engine.data;
+ if (wdata->sync_done) return ECORE_CALLBACK_PASS_ON;
+ wdata->sync_done = EINA_TRUE;
+
+ if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
+ {
+ einfo->info.wl_disp = ecore_wl2_display_get(wdata->display);
+ einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display);
+ einfo->info.destination_alpha = EINA_TRUE;
+ einfo->info.rotation = ee->rotation;
+ einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win);
+
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
+ }
+ }
+ else
+ {
+ ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
+ }
+
+ if (wdata->defer_show)
+ {
+ int fw, fh;
+
+ wdata->defer_show = EINA_FALSE;
+
+ ecore_wl2_window_show(wdata->win);
+ ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
+ ecore_wl2_window_transparent_set(wdata->win, ee->transparent);
+
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
+
+ if (wdata->win)
+ {
+
+ einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ struct wl_surface *surf;
+
+ surf = ecore_wl2_window_surface_get(wdata->win);
+ if ((!einfo->info.wl_surface) || (einfo->info.wl_surface != surf))
+ {
+ einfo->info.wl_surface = surf;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
+ }
+ }
+ }
+
+ if (wdata->frame)
+ {
+ evas_object_show(wdata->frame);
+ evas_object_resize(wdata->frame, ee->w + fw, ee->h + fh);
+ }
+
+ ee->prop.withdrawn = EINA_FALSE;
+ if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
+
+ if (!ee->visible)
+ {
+ ee->visible = 1;
+ ee->should_be_visible = 1;
+ ee->draw_ok = EINA_TRUE;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+ }
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
/* external functions */
EAPI Ecore_Evas *
ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
@@ -218,6 +299,7 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
ee->alpha = ecore_wl2_window_alpha_get(p);
}
+ wdata->sync_done = EINA_FALSE;
wdata->parent = p;
wdata->display = ewd;
wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
@@ -243,24 +325,28 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
if (ee->prop.draw_frame)
evas_output_framespace_set(ee->evas, fx, fy, fw, fh);
- if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
+ if (ewd->sync_done)
{
- einfo->info.display = ecore_wl2_display_get(ewd);
- einfo->info.destination_alpha = EINA_TRUE;
- einfo->info.rotation = ee->rotation;
- einfo->info.depth = 32;
- einfo->info.surface = ecore_wl2_window_surface_get(wdata->win);
- if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ wdata->sync_done = EINA_TRUE;
+ if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
{
- ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
+ einfo->info.display = ecore_wl2_display_get(ewd);
+ einfo->info.destination_alpha = EINA_TRUE;
+ einfo->info.rotation = ee->rotation;
+ einfo->info.depth = 32;
+ einfo->info.surface = ecore_wl2_window_surface_get(wdata->win);
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
+ goto err;
+ }
+ }
+ else
+ {
+ ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
goto err;
}
}
- else
- {
- ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
- goto err;
- }
/* ecore_wl2_display_animator_source_set(ewd, ECORE_ANIMATOR_SOURCE_CUSTOM); */
@@ -285,6 +371,8 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
(Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
+ ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONER, _ee_cb_sync_done, ee);
+
return ee;
err:
@@ -339,14 +427,19 @@ _ecore_evas_wl_show(Ecore_Evas *ee)
if ((!ee) || (ee->visible)) return;
+ wdata = ee->engine.data;
+ if (!wdata->sync_done)
+ {
+ wdata->defer_show = EINA_TRUE;
+ return;
+ }
+
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
- wdata = ee->engine.data;
if (wdata->win)
{
ecore_wl2_window_show(wdata->win);
ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
- /* ecore_wl_window_update_size(wdata->win, ee->w + fw, ee->h + fh); */
einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
if (einfo)
@@ -429,6 +522,7 @@ _ecore_evas_wayland_egl_alpha_do(Ecore_Evas *ee, int alpha)
if (ee->alpha == alpha) return;
ee->alpha = alpha;
wdata = ee->engine.data;
+ if (!wdata->sync_done) return;
if (wdata->win) ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
@@ -470,6 +564,8 @@ _ecore_evas_wayland_egl_transparent_do(Ecore_Evas *ee, int transparent)
ee->transparent = transparent;
wdata = ee->engine.data;
+ if (!wdata->sync_done) return;
+
if (wdata->win)
ecore_wl2_window_transparent_set(wdata->win, ee->transparent);
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 6d6b69510f..ecbaede7d8 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
@@ -39,6 +39,9 @@ struct _Ecore_Evas_Engine_Wl_Data
struct wl_egl_window *egl_win;
#endif
struct wl_callback *anim_callback;
+
+ Eina_Bool sync_done : 1;
+ Eina_Bool defer_show : 1;
};
Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void);
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 0592febd47..c815f79945 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
@@ -114,6 +114,87 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
/* external variables */
+static Eina_Bool
+_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
+{
+ Ecore_Evas *ee;
+ Evas_Engine_Info_Wayland_Shm *einfo;
+ Ecore_Evas_Engine_Wl_Data *wdata;
+
+ ee = data;
+ wdata = ee->engine.data;
+ if (wdata->sync_done) return ECORE_CALLBACK_PASS_ON;
+ wdata->sync_done = EINA_TRUE;
+
+ if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
+ {
+ einfo->info.wl_disp = ecore_wl2_display_get(wdata->display);
+ einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display);
+ einfo->info.destination_alpha = EINA_TRUE;
+ einfo->info.rotation = ee->rotation;
+ einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win);
+
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
+ }
+ }
+ else
+ {
+ ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
+ }
+
+ if (wdata->defer_show)
+ {
+ int fw, fh;
+
+ wdata->defer_show = EINA_FALSE;
+
+ ecore_wl2_window_show(wdata->win);
+ ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
+ ecore_wl2_window_transparent_set(wdata->win, ee->transparent);
+
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
+
+ if (wdata->win)
+ {
+
+ einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ struct wl_surface *surf;
+
+ surf = ecore_wl2_window_surface_get(wdata->win);
+ if ((!einfo->info.wl_surface) || (einfo->info.wl_surface != surf))
+ {
+ einfo->info.wl_surface = surf;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
+ }
+ }
+ }
+
+ if (wdata->frame)
+ {
+ evas_object_show(wdata->frame);
+ evas_object_resize(wdata->frame, ee->w + fw, ee->h + fh);
+ }
+
+ ee->prop.withdrawn = EINA_FALSE;
+ if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
+
+ if (!ee->visible)
+ {
+ ee->visible = 1;
+ ee->should_be_visible = 1;
+ ee->draw_ok = EINA_TRUE;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+ }
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
/* external functions */
EAPI Ecore_Evas *
ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
@@ -153,6 +234,7 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
ERR("Failed to allocate Ecore_Evas");
goto ee_err;
}
+
if (!(wdata = calloc(1, sizeof(Ecore_Evas_Engine_Wl_Data))))
{
ERR("Failed to allocate Ecore_Evas_Engine_Wl_Data");
@@ -214,6 +296,7 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
ee->alpha = ecore_wl2_window_alpha_get(p);
}
+ wdata->sync_done = EINA_FALSE;
wdata->parent = p;
wdata->display = ewd;
wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
@@ -239,24 +322,29 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
if (ee->prop.draw_frame)
evas_output_framespace_set(ee->evas, fx, fy, fw, fh);
- if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
+ if (ewd->sync_done)
{
- einfo->info.wl_disp = ecore_wl2_display_get(ewd);
- einfo->info.wl_shm = ecore_wl2_display_shm_get(ewd);
- einfo->info.destination_alpha = EINA_TRUE;
- einfo->info.rotation = ee->rotation;
- einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win);
- if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ wdata->sync_done = EINA_TRUE;
+ if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
{
- ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
+ einfo->info.wl_disp = ecore_wl2_display_get(ewd);
+ einfo->info.wl_shm = ecore_wl2_display_shm_get(ewd);
+ einfo->info.destination_alpha = EINA_TRUE;
+ einfo->info.rotation = ee->rotation;
+ einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win);
+
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
+ goto err;
+ }
+ }
+ else
+ {
+ ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
goto err;
}
}
- else
- {
- ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
- goto err;
- }
/* ecore_wl2_display_animator_source_set(ewd, ECORE_ANIMATOR_SOURCE_CUSTOM); */
@@ -281,6 +369,8 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
(Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
+ ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
+
return ee;
err:
@@ -335,15 +425,19 @@ _ecore_evas_wl_show(Ecore_Evas *ee)
if ((!ee) || (ee->visible)) return;
- evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
wdata = ee->engine.data;
+ if (!wdata->sync_done)
+ {
+ wdata->defer_show = EINA_TRUE;
+ return;
+ }
+
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (wdata->win)
{
ecore_wl2_window_show(wdata->win);
ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
- /* TODO: Needed ?? */
- /* ecore_wl_window_update_size(wdata->win, ee->w + fw, ee->h + fh); */
einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
if (einfo)
@@ -426,6 +520,7 @@ _ecore_evas_wayland_shm_alpha_do(Ecore_Evas *ee, int alpha)
if (ee->alpha == alpha) return;
ee->alpha = alpha;
wdata = ee->engine.data;
+ if (!wdata->sync_done) return;
if (wdata->win) ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
@@ -466,6 +561,8 @@ _ecore_evas_wayland_shm_transparent_do(Ecore_Evas *ee, int transparent)
ee->transparent = transparent;
wdata = ee->engine.data;
+ if (!wdata->sync_done) return;
+
if (wdata->win)
ecore_wl2_window_transparent_set(wdata->win, ee->transparent);