e_hwc_window: free e_hwc_window when e_client is freed 10/219510/4
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 5 Dec 2019 11:20:02 +0000 (20:20 +0900)
committerJunkyeong Kim <jk0430.kim@samsung.com>
Thu, 12 Dec 2019 11:44:34 +0000 (11:44 +0000)
it is possible that client is visible even if wl_surface is deleted
becase effect module want to show hide effect with deleted e_client.
so e_hwc_window is needed untill e_client is freed for preventing
transition flicker.

Change-Id: I7a8c065967fad91a401a7989464a48b6842a79d5

src/bin/e_hwc_window.c
src/bin/e_hwc_window.h

index 07d456ae89ee2778aaeeea167bb1b160bc3cc45c..0d7986ccb456821adf2366cd5e35608482a985e3 100644 (file)
@@ -403,8 +403,6 @@ _e_hwc_window_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
    if (e_hwc_window_is_video(ec->hwc_window)) return;
 
    e_hwc_window_constraints_reset(ec->hwc_window);
-
-   e_hwc_window_free(ec->hwc_window);
 }
 
 static Eina_Bool
@@ -776,6 +774,14 @@ e_hwc_window_free(E_Hwc_Window *hwc_window)
    hwc_window->ec = NULL;
    hwc_window->is_deleted = EINA_TRUE;
 
+   /* if delfn is called, ec_delfn should be set null
+    * before we get here */
+   if (hwc_window->ec_delfn)
+     {
+        e_object_delfn_del(E_OBJECT(ec), hwc_window->ec_delfn);
+        hwc_window->ec_delfn = NULL;
+     }
+
    if (hwc_window->queue)
      {
         e_hwc_window_queue_user_unset(hwc_window->queue, hwc_window);
@@ -794,6 +800,21 @@ e_hwc_window_free(E_Hwc_Window *hwc_window)
    e_object_del(E_OBJECT(hwc_window));
 }
 
+static void
+_e_hwc_window_cb_ec_free(void *data, void *obj)
+{
+   E_Client *ec = (E_Client *)obj;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   if (ec->hwc_window)
+     {
+        /* if delfn is called, ec_delfn should be set null */
+        ec->hwc_window->ec_delfn = NULL;
+        e_hwc_window_free(ec->hwc_window);
+     }
+}
+
 EINTERN E_Hwc_Window *
 e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
 {
@@ -814,7 +835,6 @@ e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, NULL);
 
    hwc_window->hwc = hwc;
-   hwc_window->ec = ec;
    hwc_window->zpos = E_HWC_WINDOW_ZPOS_NONE;
    hwc_window->render_target = EINA_TRUE;
    hwc_window->device_state_available = EINA_TRUE;
@@ -832,6 +852,10 @@ e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
      hwc_window->is_cursor = EINA_TRUE;
 
    /* set the hwc window to the e client */
+   hwc_window->ec = ec;
+   hwc_window->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
+                                             _e_hwc_window_cb_ec_free,
+                                             NULL);
    ec->hwc_window = hwc_window;
 
    hwc->hwc_windows = eina_list_append(hwc->hwc_windows, hwc_window);
@@ -938,6 +962,7 @@ _e_hwc_window_cursor_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc
 
    ec = hwc_window->ec;
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
 
    pointer = e_pointer_get(ec);
    if (!pointer) return EINA_TRUE;
@@ -1012,6 +1037,7 @@ _e_hwc_window_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_win_in
 
    ec = hwc_window->ec;
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
 
    hwc = hwc_window->hwc;
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
@@ -1109,6 +1135,7 @@ _e_hwc_window_video_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_
 
    ec = hwc_window->ec;
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
 
    if (!e_client_video_info_get(ec, &vinfo))
      {
@@ -1127,45 +1154,54 @@ EINTERN Eina_Bool
 e_hwc_window_info_update(E_Hwc_Window *hwc_window)
 {
    tdm_hwc_window_info hwc_win_info = {0};
+   E_Client *ec;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
 
    if (hwc_window->is_deleted) return EINA_FALSE;
 
-   if (e_hwc_window_is_cursor(hwc_window))
+   if (hwc_window->is_target)
      {
-        if (!_e_hwc_window_cursor_info_get(hwc_window, &hwc_win_info))
+        if (!_e_hwc_window_target_info_get(hwc_window, &hwc_win_info))
           {
-             EHWERR("fail to _e_hwc_window_cursor_info_get",
+             EHWERR("fail to _e_hwc_window_target_info_get",
                     hwc_window->ec, hwc_window->hwc, hwc_window);
              return EINA_FALSE;
           }
      }
-   else if (e_hwc_window_is_video(hwc_window))
+   else
      {
-        if (!_e_hwc_window_video_info_get(hwc_window, &hwc_win_info))
+        ec = hwc_window->ec;
+        if (!ec) return EINA_FALSE;
+
+        if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+
+        if (e_hwc_window_is_cursor(hwc_window))
           {
-             EHWERR("fail to _e_hwc_window_video_info_get",
-                    hwc_window->ec, hwc_window->hwc, hwc_window);
-             return EINA_FALSE;
+             if (!_e_hwc_window_cursor_info_get(hwc_window, &hwc_win_info))
+               {
+                  EHWERR("fail to _e_hwc_window_cursor_info_get",
+                         hwc_window->ec, hwc_window->hwc, hwc_window);
+                  return EINA_FALSE;
+               }
           }
-     }
-   else if (hwc_window->is_target)
-     {
-        if (!_e_hwc_window_target_info_get(hwc_window, &hwc_win_info))
+        else if (e_hwc_window_is_video(hwc_window))
           {
-             EHWERR("fail to _e_hwc_window_target_info_get",
-                    hwc_window->ec, hwc_window->hwc, hwc_window);
-             return EINA_FALSE;
+             if (!_e_hwc_window_video_info_get(hwc_window, &hwc_win_info))
+               {
+                  EHWERR("fail to _e_hwc_window_video_info_get",
+                         hwc_window->ec, hwc_window->hwc, hwc_window);
+                  return EINA_FALSE;
+               }
           }
-     }
-   else
-     {
-        if (!_e_hwc_window_info_get(hwc_window, &hwc_win_info))
+        else
           {
-             EHWERR("fail to _e_hwc_window_info_get",
-                    hwc_window->ec, hwc_window->hwc, hwc_window);
-             return EINA_FALSE;
+             if (!_e_hwc_window_info_get(hwc_window, &hwc_win_info))
+               {
+                  EHWERR("fail to _e_hwc_window_info_get",
+                         hwc_window->ec, hwc_window->hwc, hwc_window);
+                  return EINA_FALSE;
+               }
           }
      }
 
@@ -1204,6 +1240,7 @@ e_hwc_window_buffer_fetch(E_Hwc_Window *hwc_window)
    tdm_hwc_window *thwc_window = NULL;
    tdm_error error = TDM_ERROR_NONE;
    E_Hwc_Window_Queue_Buffer *queue_buffer = NULL, *queue_buffer2 = NULL;
+   E_Client *ec = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
 
@@ -1224,7 +1261,9 @@ e_hwc_window_buffer_fetch(E_Hwc_Window *hwc_window)
         return EINA_TRUE;
      }
 
-   if (hwc_window->is_deleted)
+   ec = hwc_window->ec;
+
+   if ((hwc_window->is_deleted) || (!ec) || e_object_is_del(E_OBJECT(ec)))
      {
         tsurface = NULL;
         if (!hwc_window->buffer.tsurface) return EINA_FALSE;
@@ -1626,16 +1665,15 @@ e_hwc_window_device_state_available_update(E_Hwc_Window *hwc_window)
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
 
-   if (hwc_window->is_deleted)
+   ec = hwc_window->ec;
+
+   if ((hwc_window->is_deleted) || (!ec) || e_object_is_del(E_OBJECT(ec)))
      {
         restriction = E_HWC_WINDOW_RESTRICTION_DELETED;
         available = EINA_FALSE;
         goto finish;
      }
 
-   ec = hwc_window->ec;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
-
    if (ec->comp_override > 0)
      {
         restriction = E_HWC_WINDOW_RESTRICTION_OVERRIDE;
@@ -1866,8 +1904,12 @@ _e_hwc_window_client_recover(E_Hwc_Window *hwc_window)
    tbm_surface_h tsurface =NULL;
    E_Client *ec = NULL;
 
+   if (hwc_window->is_deleted) return;
+
    ec = hwc_window->ec;
-   EINA_SAFETY_ON_NULL_RETURN(ec);
+   if (!ec) return;
+
+   if (e_object_is_del(E_OBJECT(ec))) return;
 
    recover_buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
    if (!recover_buffer)
@@ -1896,8 +1938,12 @@ _e_hwc_window_rendered_window_set(E_Hwc_Window *hwc_window, Eina_Bool set)
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
 
+   if (hwc_window->is_deleted) return EINA_FALSE;
+
    ec = hwc_window->ec;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   if (!ec) return EINA_FALSE;
+
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
 
    if (hwc_window->render_target == set) return EINA_TRUE;
 
@@ -1946,7 +1992,9 @@ e_hwc_window_rendered_window_update(E_Hwc_Window *hwc_window)
    if (hwc_window->is_deleted) return EINA_TRUE;
 
    ec = hwc_window->ec;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   if (!ec) return EINA_TRUE;
+
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_TRUE;
 
    if (hwc_window->is_cursor)
      pointer = e_pointer_get(hwc_window->ec);
@@ -2162,6 +2210,7 @@ e_hwc_window_set_property(E_Hwc_Window *hwc_window, unsigned int id, const char
 
    ec = hwc_window->ec;
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
 
    if (force)
      {
@@ -2309,7 +2358,9 @@ e_hwc_window_pp_rendered_window_update(E_Hwc_Window *hwc_window)
    if (hwc_window->is_deleted) return EINA_TRUE;
 
    ec = hwc_window->ec;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   if (!ec) return EINA_TRUE;
+
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_TRUE;
 
    if (hwc_window->is_cursor)
      pointer = e_pointer_get(hwc_window->ec);
index 62954c5d28b39c072765de04d99e1ece02015782..8f0609d9cbcab230abd3c3291a3cc4afd0aaa1d6 100644 (file)
@@ -78,6 +78,7 @@ struct _E_Hwc_Window
    E_Object                       e_obj_inherit;
 
    E_Client                      *ec;
+   E_Object_Delfn                *ec_delfn;
    E_Hwc                         *hwc;
    tdm_hwc_window                *thwc_window;
    int                            zpos;