e_hwc_windows: refactor updating the changes of hwc and hwc_window 18/306218/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Tue, 23 Jan 2024 05:36:52 +0000 (14:36 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 19 Feb 2024 04:12:42 +0000 (13:12 +0900)
Previously, the changes hwc and hwc_window was updated in every idle time
if wait_commit is false.
For reducing usage of cpu, this patch makes the changes of hwc and hwc_window
is updated when property, restriction, buffer, visible, geometry are changed.

Change-Id: I0833d3838e70b5a980e572e6bc63df7c024e08a6

src/bin/e_hwc.c
src/bin/e_hwc_window.c
src/bin/e_hwc_window_intern.h
src/bin/e_hwc_windows.c
src/bin/e_hwc_windows_intern.h
src/bin/video/iface/e_video_hwc_windows.c
src/include/e_hwc.h
src/include/e_hwc_window.h

index a622287..04709f4 100644 (file)
@@ -918,6 +918,8 @@ e_hwc_property_set(E_Hwc *hwc, unsigned int id, hwc_value value)
 
    hwc->property_changed = EINA_TRUE;
 
+   e_hwc_windows_changed_set(hwc, E_HWC_WINS_CHANGED_PROPERTY);
+
    ecore_event_add(E_EVENT_HWC_PROPERTY_CHANGED, NULL, NULL, NULL);
 
    EHINF("Set property id:%u value:%u", hwc, id, (unsigned int)value.u32);
index 09b1102..c418d05 100644 (file)
@@ -617,6 +617,82 @@ _e_hwc_window_free(E_Hwc_Window *hwc_window)
 }
 
 static void
+_e_hwc_window_obj_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (!(hwc_window = data)) return;
+
+   hwc_window->evas_visible = EINA_TRUE;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
+static void
+_e_hwc_window_obj_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (!(hwc_window = data)) return;
+
+   hwc_window->evas_visible = EINA_FALSE;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
+static void
+_e_hwc_window_obj_cb_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (!(hwc_window = data)) return;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_GEOMETRY);
+   
+   if (hwc_window->hwc_visible)
+     {
+        if (!e_hwc_window_client_geometry_visible_get(hwc_window))
+          e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+     }
+   else
+     {
+        if ((hwc_window->evas_visible) && (e_hwc_window_client_geometry_visible_get(hwc_window)))
+          e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+     }
+}
+
+static void
+_e_hwc_window_obj_cb_resize(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (!(hwc_window = data)) return;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_GEOMETRY);
+
+   if (hwc_window->hwc_visible)
+     {
+        if (!e_hwc_window_client_geometry_visible_get(hwc_window))
+          e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+     }
+   else
+     {
+        if ((hwc_window->evas_visible) && (e_hwc_window_client_geometry_visible_get(hwc_window)))
+          e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+     }
+}
+
+static void
+_e_hwc_window_obj_cb_restack(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (!(hwc_window = data)) return;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
+static void
 _e_hwc_window_del(E_Hwc_Window *hwc_window)
 {
    E_Client *ec;
@@ -628,6 +704,22 @@ _e_hwc_window_del(E_Hwc_Window *hwc_window)
    ec = hwc_window->ec;
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
+   evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_SHOW,
+                                       _e_hwc_window_obj_cb_show,
+                                       hwc_window);
+   evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_HIDE,
+                                       _e_hwc_window_obj_cb_hide,
+                                       hwc_window);
+   evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_MOVE,
+                                       _e_hwc_window_obj_cb_move,
+                                       hwc_window);
+   evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_RESIZE,
+                                       _e_hwc_window_obj_cb_resize,
+                                       hwc_window);
+   evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_RESTACK,
+                                       _e_hwc_window_obj_cb_restack,
+                                       hwc_window);
+
    ec->hwc_window = NULL;
    hwc_window->ec = NULL;
    hwc_window->is_deleted = EINA_TRUE;
@@ -665,9 +757,14 @@ _e_hwc_window_del(E_Hwc_Window *hwc_window)
    if (hwc_window->color_set_listener.notify)
      wl_list_remove(&hwc_window->color_set_listener.link);
 
+   if (hwc_window->color_visible_set_listener.notify)
+     wl_list_remove(&hwc_window->color_visible_set_listener.link);
+
    e_hwc_window_below_transparent_obj_set(hwc_window, EINA_FALSE);
    e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE, EINA_TRUE);
 
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+
    e_object_del(E_OBJECT(hwc_window));
 }
 
@@ -904,6 +1001,16 @@ _e_hwc_window_restriction_init(E_Hwc_Window *hwc_window)
    _e_hwc_window_commit_restriction_update(hwc_window);
 }
 
+static void
+_e_hwc_window_cb_color_visible_set(struct wl_listener *listener, void *data)
+{
+   E_Hwc_Window *hwc_window;
+
+   hwc_window = container_of(listener, E_Hwc_Window, color_visible_set_listener);
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
 static E_Hwc_Window *
 _e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
 {
@@ -964,6 +1071,28 @@ _e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
    hwc_window->color_set_listener.notify = _e_hwc_window_cb_color_set;
    e_comp_object_color_set_listener_add(ec->frame, &hwc_window->color_set_listener);
 
+   hwc_window->color_visible_set_listener.notify = _e_hwc_window_cb_color_visible_set;
+   e_comp_object_color_visible_set_listener_add(ec->frame, &hwc_window->color_visible_set_listener);
+
+   evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_SHOW,
+                                  _e_hwc_window_obj_cb_show,
+                                  hwc_window);
+   evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_HIDE,
+                                  _e_hwc_window_obj_cb_hide,
+                                  hwc_window);
+   evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_MOVE,
+                                  _e_hwc_window_obj_cb_move,
+                                  hwc_window);
+   evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_RESIZE,
+                                  _e_hwc_window_obj_cb_resize,
+                                  hwc_window);
+   evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_RESTACK,
+                                  _e_hwc_window_obj_cb_restack,
+                                  hwc_window);
+
+   if (evas_object_visible_get(ec->frame))
+     e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+
    EHWINF("is created on eout:%p, video:%d cursor:%d",
           hwc_window->ec, hwc_window->hwc, hwc_window, hwc->output,
           hwc_window->is_video, hwc_window->is_cursor);
@@ -1064,6 +1193,11 @@ _e_hwc_window_client_cb_transform_change(void *data EINA_UNUSED, E_Client *ec)
    else
      e_hwc_window_restriction_unset(hwc_window, E_HWC_WINDOW_RESTRICTION_TRANSFORM);
 
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_GEOMETRY);
+
+   if ((hwc_window->hwc_visible) && (!e_hwc_window_client_geometry_visible_get(hwc_window)))
+     e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+
    if (!e_comp_wl_video_subsurface_has(ec) && !e_comp_wl_normal_subsurface_has(ec))
      return;
 
@@ -1184,6 +1318,34 @@ _e_hwc_window_cb_surface_commit(void *data, E_Client *ec)
    _e_hwc_window_commit_restriction_update(ec->hwc_window);
 }
 
+static void
+_e_hwc_window_cb_buffer_change(void *data, E_Client *ec)
+{
+   E_Hwc_Window *hwc_window;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   hwc_window = ec->hwc_window;
+   if (!hwc_window) return;
+   
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_BUFFER);
+}
+
+static void
+_e_hwc_window_cb_alpha_change(void *data, E_Client *ec)
+{
+   E_Hwc_Window *hwc_window;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   hwc_window = ec->hwc_window;
+   if (!hwc_window) return;
+   
+   if (!hwc_window->hwc_visible) return;
+
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+}
+
 static Eina_Bool
 _e_hwc_window_cb_update_lock_set(void *data, E_Client *ec)
 {
@@ -1207,6 +1369,7 @@ _e_hwc_window_cb_update_lock_unset(void *data, E_Client *ec)
    if (!hwc_window) return EINA_TRUE;
 
    e_hwc_window_restriction_unset(hwc_window, E_HWC_WINDOW_RESTRICTION_RENDER_UPDATE_LOCK);
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_BUFFER | E_HWC_WINS_CHANGED_WIN_GEOMETRY);
 
    return EINA_TRUE;
 }
@@ -1220,6 +1383,7 @@ _e_hwc_window_cb_effect_start(void *data, E_Client *ec)
    if (!hwc_window) return EINA_TRUE;
 
    e_hwc_window_restriction_set(hwc_window, E_HWC_WINDOW_RESTRICTION_EFFECT);
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
 
    return EINA_TRUE;
 }
@@ -1233,6 +1397,7 @@ _e_hwc_window_cb_effect_end(void *data, E_Client *ec)
    if (!hwc_window) return EINA_TRUE;
 
    e_hwc_window_restriction_unset(hwc_window, E_HWC_WINDOW_RESTRICTION_EFFECT);
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
 
    return EINA_TRUE;
 }
@@ -1250,6 +1415,7 @@ _e_hwc_window_cb_pixmap_buffer_clear_done(void *data EINA_UNUSED, E_Pixmap *cp)
    if (!hwc_window) return;
    
    e_hwc_window_restriction_set(hwc_window, E_HWC_WINDOW_RESTRICTION_BUFFER);
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_BUFFER);
 }
 
 EINTERN Eina_Bool
@@ -1265,6 +1431,10 @@ e_hwc_window_init(void)
                          _e_hwc_window_cb_subsurface_synchronized_commit, NULL);
    E_COMP_WL_HOOK_APPEND(hwc_window_comp_wl_hooks, E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
                          _e_hwc_window_cb_surface_commit, NULL);
+   E_COMP_WL_HOOK_APPEND(hwc_window_comp_wl_hooks, E_COMP_WL_HOOK_BUFFER_CHANGE,
+                         _e_hwc_window_cb_buffer_change, NULL);
+   E_COMP_WL_HOOK_APPEND(hwc_window_comp_wl_hooks, E_COMP_WL_HOOK_CLIENT_ALPHA_CHANGE,
+                         _e_hwc_window_cb_alpha_change, NULL);
    E_PIXMAP_HOOK_APPEND(hwc_window_pixmap_hooks, E_PIXMAP_HOOK_BUFFER_CLEAR_DONE,
                         _e_hwc_window_cb_pixmap_buffer_clear_done, NULL);
    E_COMP_COMP_HOOK_APPEND(hwc_window_comp_object_hooks, E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET,
@@ -2358,6 +2528,8 @@ e_hwc_window_restriction_set(E_Hwc_Window *hwc_window, E_Hwc_Window_Restriction
 
    hwc_window->restriction |= restriction;
 
+   e_hwc_windows_changed_set(hwc_window->hwc, E_HWC_WINS_CHANGED_WIN_RESTRICTION);
+
    EHWTRACE("restriction set:0x%x", hwc_window->ec, hwc_window->hwc, hwc_window, restriction);
 }
 
@@ -2370,6 +2542,8 @@ e_hwc_window_restriction_unset(E_Hwc_Window *hwc_window, E_Hwc_Window_Restrictio
 
    hwc_window->restriction &= ~restriction;
 
+   e_hwc_windows_changed_set(hwc_window->hwc, E_HWC_WINS_CHANGED_WIN_RESTRICTION);
+
    EHWTRACE("restriction unset:0x%x", hwc_window->ec, hwc_window->hwc, hwc_window, restriction);
 }
 
@@ -2725,6 +2899,8 @@ e_hwc_window_set_property(E_Hwc_Window *hwc_window, unsigned int id, const char
                  hwc_window->ec, hwc_window->hwc, hwc_window,
                  prop->name, (unsigned int)value.u32,
                  e_hwc_window_name_get(hwc_window));
+
+        e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_PROPERTY);
      }
 
    return EINA_TRUE;
@@ -3372,5 +3548,87 @@ e_hwc_window_visible_skip_set(E_Hwc_Window *hwc_window, Eina_Bool set)
 
    hwc_window->visible_skip = set;
 
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_hwc_window_changed_set(E_Hwc_Window *hwc_window, E_Hwc_Wins_Changed changed)
+{
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window->hwc);
+
+   e_hwc_windows_changed_set(hwc_window->hwc, changed);
+
+   if (hwc_window->changed & changed) return;
+
+   if (!hwc_window->changed)
+     {
+        hwc_window->hwc->changed_windows = eina_list_append(hwc_window->hwc->changed_windows, hwc_window);
+        e_hwc_window_ref(hwc_window);
+     }
+
+   hwc_window->changed |= changed;
+
+   EHWTRACE("changed set:0x%x", hwc_window->ec, hwc_window->hwc, hwc_window, changed);
+}
+
+EINTERN Eina_Bool
+e_hwc_window_changed_get(E_Hwc_Window *hwc_window)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
+
+   return hwc_window->changed;
+}
+
+EINTERN void 
+e_hwc_window_changed_clear(E_Hwc_Window *hwc_window)
+{
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+   if (hwc_window->changed == E_HWC_WINS_CHANGED_NONE)
+     return;
+
+   hwc_window->changed = E_HWC_WINS_CHANGED_NONE;
+}
+
+EINTERN Eina_Bool
+e_hwc_window_client_geometry_visible_get(E_Hwc_Window *hwc_window)
+{
+   E_Client *ec;
+   int x, y, w, h;
+   int ee_w, ee_h;
+   int x1, x2, y1, y2;
+   E_Map *map;
+   
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
+
+   ec = hwc_window->ec;
+   if (!ec) return EINA_FALSE;
+
+   ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &ee_w, &ee_h);
+   evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
+
+   if ((ec->is_cursor) && (evas_object_map_enable_get(ec->frame)))
+     {
+        map = e_client_map_get(ec);
+        if (map)
+          {
+             e_map_point_coord_get(map, 0, &x1, &y1, NULL);
+             e_map_point_coord_get(map, 2, &x2, &y2, NULL);
+
+             x = MIN(x1, x2);
+             y = MIN(y1, y2);
+             w = MAX(x1, x2) - x;
+             h = MAX(y1, y2) - y;
+
+             e_map_free(map);
+          }
+     }
+
+   if (!E_INTERSECTS(0, 0, ee_w, ee_h, x, y, w, h))
+     return EINA_FALSE;
+
    return EINA_TRUE;
 }
index 3262237..e80c555 100644 (file)
@@ -15,6 +15,18 @@ typedef struct _E_Hwc_Window_Hook                 E_Hwc_Window_Hook;
 
 typedef void (*E_Hwc_Window_Hook_Cb) (void *data, E_Hwc_Window *hwc_window);
 
+typedef enum
+{
+   E_HWC_WINS_CHANGED_NONE = 0,
+   E_HWC_WINS_CHANGED_PROPERTY = (1 << 0),
+   E_HWC_WINS_CHANGED_RISTRICTION = (1 << 1),
+   E_HWC_WINS_CHANGED_WIN_VISIBLE = (1 << 2),
+   E_HWC_WINS_CHANGED_WIN_BUFFER = (1 << 3),
+   E_HWC_WINS_CHANGED_WIN_GEOMETRY = (1 << 4),
+   E_HWC_WINS_CHANGED_WIN_RESTRICTION = (1 << 5),
+   E_HWC_WINS_CHANGED_WIN_PROPERTY = (1 << 6),
+} E_Hwc_Wins_Changed;
+
 typedef enum _E_Hwc_Window_Restriction
 {
    E_HWC_WINDOW_RESTRICTION_NONE = 0,
@@ -129,4 +141,10 @@ EINTERN void                      e_hwc_window_restriction_set(E_Hwc_Window *hwc
 EINTERN void                      e_hwc_window_restriction_unset(E_Hwc_Window *hwc_window, E_Hwc_Window_Restriction restriction);
 EINTERN unsigned int              e_hwc_window_restriction_get(E_Hwc_Window *hwc_window);
 
+EINTERN void                      e_hwc_window_changed_set(E_Hwc_Window *hwc_window, E_Hwc_Wins_Changed cahnged);
+EINTERN Eina_Bool                 e_hwc_window_changed_get(E_Hwc_Window *hwc_window);
+EINTERN void                      e_hwc_window_changed_clear(E_Hwc_Window *hwc_window);
+
+EINTERN Eina_Bool                 e_hwc_window_client_geometry_visible_get(E_Hwc_Window *hwc_window);
+
 #endif
index 6d73859..2c6a866 100644 (file)
@@ -916,11 +916,10 @@ _e_hwc_windows_visible_windows_list_get(E_Hwc *hwc)
    E_Zone *zone;
    Evas_Object *o;
    int ee_w, ee_h;
-   int x, y, w, h, x1, x2, y1, y2;
+   int x, y, w, h;
    int ui_skip = EINA_FALSE;
    Eina_Bool effect_client;
    Evas_Render_Op render_op;
-   E_Map *map;
    Eina_Bool qps_visible;
 
    ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &ee_w, &ee_h);
@@ -972,23 +971,6 @@ _e_hwc_windows_visible_windows_list_get(E_Hwc *hwc)
 
         e_client_geometry_get(ec, &x, &y, &w, &h);
 
-        if ((ec->is_cursor) && (evas_object_map_enable_get(ec->frame)))
-          {
-             map = e_client_map_get(ec);
-             if (map)
-               {
-                  e_map_point_coord_get(map, 0, &x1, &y1, NULL);
-                  e_map_point_coord_get(map, 2, &x2, &y2, NULL);
-
-                  x = MIN(x1, x2);
-                  y = MIN(y1, y2);
-                  w = MAX(x1, x2) - x;
-                  h = MAX(y1, y2) - y;
-
-                  e_map_free(map);
-               }
-          }
-
         if ((!effect_client) && (!e_comp_object_color_visible_get(ec->frame)))
           {
              e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE, EINA_TRUE);
@@ -1006,7 +988,7 @@ _e_hwc_windows_visible_windows_list_get(E_Hwc *hwc)
           }
 
         // check geometry if located out of screen such as quick panel
-        if (!E_INTERSECTS(0, 0, ee_w, ee_h, x, y, w, h))
+        if (!e_hwc_window_client_geometry_visible_get(hwc_window))
           {
              e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE, EINA_TRUE);
              continue;
@@ -2210,7 +2192,10 @@ _e_hwc_windows_visible_windows_update(E_Hwc *hwc)
   if (eina_list_count(hwc->visible_windows))
     {
        EINA_LIST_FREE(hwc->visible_windows, hwc_window)
-         e_hwc_window_unref(hwc_window);
+         {
+            hwc_window->hwc_visible = EINA_FALSE;
+            e_hwc_window_unref(hwc_window);
+         }
     }
 
    /* store the current visible windows and the number of them */
@@ -2221,6 +2206,7 @@ _e_hwc_windows_visible_windows_update(E_Hwc *hwc)
    EINA_LIST_REVERSE_FOREACH(hwc->visible_windows, l, hwc_window)
      {
         /* assign zpos */
+        hwc_window->hwc_visible = EINA_TRUE;
         e_hwc_window_zpos_set(hwc_window, zpos++);
         e_hwc_window_ref(hwc_window);
      }
@@ -2280,42 +2266,41 @@ _e_hwc_windows_changes_update(E_Hwc *hwc)
 {
    E_Hwc_Window *hwc_window;
    Eina_Bool update_changes = EINA_FALSE;
-   const Eina_List *l, *ll;
+   unsigned int changed;
+
+   changed = e_hwc_windows_changed_get(hwc);
+   if (changed)
+     update_changes = EINA_TRUE;
 
-   if (hwc->property_changed)
+   if (changed & E_HWC_WINS_CHANGED_WIN_VISIBLE)
      {
-        hwc->property_changed = EINA_FALSE;
-        update_changes = EINA_TRUE;
+        if (_e_hwc_windows_visible_windows_update(hwc))
+          update_changes = EINA_TRUE;
      }
 
-   /* update the the visible windows */
-   if (_e_hwc_windows_visible_windows_update(hwc))
-     update_changes = EINA_TRUE;
-
-   EINA_LIST_FOREACH_SAFE(hwc->hwc_windows, l, ll, hwc_window)
+   EINA_LIST_FREE(hwc->changed_windows, hwc_window)
      {
-        if (e_hwc_window_is_target(hwc_window)) continue;
+        if (changed & E_HWC_WINS_CHANGED_WIN_BUFFER)
+          {
+             if (e_hwc_window_buffer_fetch(hwc_window))
+               update_changes = EINA_TRUE;
+          }
 
-        /* fetch the window buffer */
-        if (e_hwc_window_buffer_fetch(hwc_window))
-          update_changes = EINA_TRUE;
-        else
+        if ((changed & E_HWC_WINS_CHANGED_WIN_BUFFER) ||
+            (changed & E_HWC_WINS_CHANGED_WIN_GEOMETRY))
           {
-             /* sometimes client add frame cb without buffer attach */
-             if ((hwc_window->ec) &&
-                 (hwc_window->ec->pixmap) &&
-                 (e_pixmap_type_get(hwc_window->ec->pixmap) == E_PIXMAP_TYPE_WL) &&
-                 (hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE))
-               e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
+             if (e_hwc_window_info_update(hwc_window))
+               update_changes = EINA_TRUE;
           }
 
-        /* update the window's info */
-        if (e_hwc_window_info_update(hwc_window))
-          update_changes = EINA_TRUE;
+        if (changed & E_HWC_WINS_CHANGED_WIN_PROPERTY)
+          {
+             if (e_hwc_window_prop_update(hwc_window))
+               update_changes = EINA_TRUE;
+          }
 
-        /* update the window's props */
-        if (e_hwc_window_prop_update(hwc_window))
-          update_changes = EINA_TRUE;
+        e_hwc_window_changed_clear(hwc_window);
+        e_hwc_window_unref(hwc_window);
      }
 
    if (hwc->primary_output)
@@ -2338,6 +2323,8 @@ _e_hwc_windows_changes_update(E_Hwc *hwc)
         _e_hwc_windows_visible_windows_states_update(hwc);
      }
 
+   e_hwc_windows_changed_clear(hwc);
+
    return update_changes;
 }
 
@@ -4151,6 +4138,37 @@ e_hwc_windows_presentation_time_feedback_and_callback_take(E_Hwc *hwc, tbm_surfa
 }
 
 EINTERN void
+e_hwc_windows_changed_set(E_Hwc *hwc, E_Hwc_Wins_Changed changed)
+{
+   EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+   if (hwc->changed & changed) return;
+
+   hwc->changed |= changed;
+
+   EHWSTRACE("changed set:0x%x", NULL, hwc, changed);
+}
+
+EINTERN Eina_Bool
+e_hwc_windows_changed_get(E_Hwc *hwc)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+   return hwc->changed;
+}
+
+EINTERN void
+e_hwc_windows_changed_clear(E_Hwc *hwc)
+{
+   EINA_SAFETY_ON_NULL_RETURN(hwc);
+
+   if (hwc->changed == E_HWC_WINS_CHANGED_NONE)
+     return;
+
+   hwc->changed = E_HWC_WINS_CHANGED_NONE;
+}
+
+EINTERN void
 e_hwc_windows_comp_override_set(E_Hwc *hwc, Eina_Bool set)
 {
    EINA_SAFETY_ON_NULL_RETURN(hwc);
@@ -4174,6 +4192,8 @@ e_hwc_windows_restriction_set(E_Hwc *hwc, E_Hwc_Windows_Restriction restriction)
 
    hwc->restriction |= restriction;
 
+   e_hwc_windows_changed_set(hwc, E_HWC_WINS_CHANGED_RISTRICTION);
+
    EHWSTRACE("restriction set:0x%x", NULL, hwc, restriction);
 }
 
@@ -4186,6 +4206,8 @@ e_hwc_windows_restriction_unset(E_Hwc *hwc, E_Hwc_Windows_Restriction restrictio
 
    hwc->restriction &= ~restriction;
 
+   e_hwc_windows_changed_set(hwc, E_HWC_WINS_CHANGED_RISTRICTION);
+
    EHWSTRACE("restriction set:0x%x", NULL, hwc, restriction);
 }
 
index 72499d1..3993c69 100644 (file)
@@ -74,6 +74,10 @@ EINTERN Eina_Bool            e_hwc_windows_present_sync(E_Hwc *hwc);
 EINTERN void                 e_hwc_windows_trace_debug(Eina_Bool onoff);
 EINTERN void                 e_hwc_windows_debug_info_get(Eldbus_Message_Iter *iter, E_Hwc_Wins_Debug_Cmd cmd);
 
+EINTERN void                 e_hwc_windows_changed_set(E_Hwc *hwc, E_Hwc_Wins_Changed cahnged);
+EINTERN Eina_Bool            e_hwc_windows_changed_get(E_Hwc *hwc);
+EINTERN void                 e_hwc_windows_changed_clear(E_Hwc *hwc);
+
 EINTERN void                 e_hwc_windows_comp_override_set(E_Hwc *hwc, Eina_Bool set);
 
 EINTERN void                 e_hwc_windows_restriction_set(E_Hwc *hwc, E_Hwc_Windows_Restriction restriction);
index f2574aa..0646bfe 100644 (file)
@@ -76,6 +76,8 @@ end:
     * frame buffer. */
    evhw->commit_data.wait_release = EINA_TRUE;
 
+   e_hwc_window_changed_set(evhw->hwc_window, E_HWC_WINS_CHANGED_WIN_GEOMETRY|E_HWC_WINS_CHANGED_WIN_BUFFER);
+
    DBG("Client(%s):PID(%d), Buffer(%p, refcnt:%d) is shown."
        "Geometry details are : buffer size(%dx%d) src(%d,%d, %dx%d)"
        " dst(%d,%d, %dx%d), transform(%d)",
index 7adaf63..7adcd08 100644 (file)
@@ -178,6 +178,8 @@ struct _E_Hwc
    Eina_Bool            comp_override;
 
    unsigned int         restriction;
+   unsigned int         changed;
+   Eina_List           *changed_windows;
 };
 
 E_API extern int E_EVENT_HWC_ACTIVE;
index dcb47f3..2e7dd9c 100644 (file)
@@ -116,6 +116,12 @@ struct _E_Hwc_Window
    struct wl_listener             render_op_set_listener;
    struct wl_listener             content_type_set_listener;
    struct wl_listener             color_set_listener;
+   struct wl_listener             color_visible_set_listener;
+
+   Eina_Bool                      evas_visible;
+   Eina_Bool                      hwc_visible;
+
+   Eina_Bool                      changed;
 };
 
 struct _E_Hwc_Window_Target