devilhorns pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=757f530af96562eac570b0ac75541e6972b5c422

commit 757f530af96562eac570b0ac75541e6972b5c422
Author: Chris Michael <cp.mich...@samsung.com>
Date:   Fri Dec 11 11:26:24 2015 -0500

    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.mich...@samsung.com>
---
 .../engines/wayland/ecore_evas_wayland_common.c    |   1 +
 .../engines/wayland/ecore_evas_wayland_egl.c       | 126 +++++++++++++++++---
 .../engines/wayland/ecore_evas_wayland_private.h   |   3 +
 .../engines/wayland/ecore_evas_wayland_shm.c       | 129 ++++++++++++++++++---
 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 c43414d..75ac428 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 6514968..b9fa475 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 6d6b695..ecbaede 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 0592feb..c815f79 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);
 

-- 


Reply via email to