discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=5e3fb38f8602f61546b25553912042716446a989

commit 5e3fb38f8602f61546b25553912042716446a989
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Wed Mar 23 15:43:34 2016 -0400

    optimize compositor canvas updating when zone geometry is marked dirty
    
    in many cases where a zone's useful geometry is marked dirty, the resulting
    recalc ends up having the same useful geometry as before: this is the case
    for things like tasks gadgets, which continually expand and contract along
    a single axis and thus will never affect useful geometry while still forcing
    a recalc
    
    by ignoring these cases, a huge amount of compositor thrashing is avoided 
and
    a number of related bugs can also be fixed
---
 src/bin/e_comp_canvas.c |  6 ++++-
 src/bin/e_zone.c        | 59 +++++++++++++++++++++++++------------------------
 src/bin/e_zone.h        | 12 +++++-----
 3 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/src/bin/e_comp_canvas.c b/src/bin/e_comp_canvas.c
index 45385a9..5bfe21c 100644
--- a/src/bin/e_comp_canvas.c
+++ b/src/bin/e_comp_canvas.c
@@ -187,8 +187,12 @@ _e_comp_cb_mouse_wheel(void *d EINA_UNUSED, int t 
EINA_UNUSED, Ecore_Event_Mouse
 ////////////////////////////////////
 
 static Eina_Bool
-_e_comp_cb_zone_change()
+_e_comp_cb_zone_change(void *d EINA_UNUSED, int t, E_Event_Zone_Move_Resize 
*ev)
 {
+   if (ev->zone->useful_geometry_dirty && (t == E_EVENT_ZONE_MOVE_RESIZE))
+     {
+        if (!e_zone_useful_geometry_get(ev->zone, NULL, NULL, NULL, NULL)) 
return ECORE_CALLBACK_RENEW;
+     }
    e_comp_canvas_update();
    return ECORE_CALLBACK_PASS_ON;
 }
diff --git a/src/bin/e_zone.c b/src/bin/e_zone.c
index ad16140..701f94d 100644
--- a/src/bin/e_zone.c
+++ b/src/bin/e_zone.c
@@ -198,11 +198,11 @@ e_zone_new(int num, int id, int x, int y, int w, int h)
    zone->num = num;
    zone->id = id;
 
-   zone->useful_geometry.dirty = 1;
-   zone->useful_geometry.x = -1;
-   zone->useful_geometry.y = -1;
-   zone->useful_geometry.w = -1;
-   zone->useful_geometry.h = -1;
+   zone->useful_geometry_dirty = 1;
+   zone->useful_geometry[0].x = zone->useful_geometry[0].y =
+     zone->useful_geometry[0].w = zone->useful_geometry[0].h = -1;
+   zone->useful_geometry[1].x = zone->useful_geometry[1].y =
+     zone->useful_geometry[1].w = zone->useful_geometry[1].h = -1;
 
    //printf("@@@@@@@@@@ e_zone_new: %i %i | %i %i %ix%i = %p\n", num, id, x, 
y, w, h, zone);
 
@@ -1275,7 +1275,7 @@ _e_zone_useful_geometry_calc(const E_Zone *zone, int dx, 
int dy, int *x, int *y,
 /**
  * Get (or calculate) the useful (or free, without any shelves) area.
  */
-E_API void
+E_API Eina_Bool
 e_zone_useful_geometry_get(E_Zone *zone,
                            int *x,
                            int *y,
@@ -1284,23 +1284,28 @@ e_zone_useful_geometry_get(E_Zone *zone,
 {
    int zx, zy, zw, zh;
 
-   E_OBJECT_CHECK(zone);
-   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+   E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
+   E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
 
-   if (zone->useful_geometry.dirty)
+   if (zone->useful_geometry_dirty)
      {
         _e_zone_useful_geometry_calc(zone, zone->desk_x_current, 
zone->desk_y_current, &zx, &zy, &zw, &zh);
-        zone->useful_geometry.x = zx;
-        zone->useful_geometry.y = zy;
-        zone->useful_geometry.w = zw;
-        zone->useful_geometry.h = zh;
+        memcpy(&zone->useful_geometry[0], &zone->useful_geometry[1], 
sizeof(Eina_Rectangle));
+        zone->useful_geometry[1].x = zx;
+        zone->useful_geometry[1].y = zy;
+        zone->useful_geometry[1].w = zw;
+        zone->useful_geometry[1].h = zh;
+        zone->useful_geometry_changed =
+          !!memcmp(&zone->useful_geometry[0], &zone->useful_geometry[1], 
sizeof(Eina_Rectangle));
+        
      }
-   zone->useful_geometry.dirty = 0;
+   zone->useful_geometry_dirty = 0;
 
-   if (x) *x = zone->useful_geometry.x;
-   if (y) *y = zone->useful_geometry.y;
-   if (w) *w = zone->useful_geometry.w;
-   if (h) *h = zone->useful_geometry.h;
+   if (x) *x = zone->useful_geometry[1].x;
+   if (y) *y = zone->useful_geometry[1].y;
+   if (w) *w = zone->useful_geometry[1].w;
+   if (h) *h = zone->useful_geometry[1].h;
+   return zone->useful_geometry_changed;
 }
 
 E_API void
@@ -1332,11 +1337,7 @@ e_zone_useful_geometry_dirty(E_Zone *zone)
    e_object_ref(E_OBJECT(ev->zone));
    ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev, _e_zone_event_generic_free, 
NULL);
 
-   zone->useful_geometry.dirty = 1;
-   zone->useful_geometry.x = -1;
-   zone->useful_geometry.y = -1;
-   zone->useful_geometry.w = -1;
-   zone->useful_geometry.h = -1;
+   zone->useful_geometry_dirty = 1;
 }
 
 E_API E_Zone_Obstacle *
@@ -1365,12 +1366,12 @@ e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, 
Eina_Rectangle *geom, Eina_Bool
      {
         desk->obstacles = eina_inlist_append(desk->obstacles, 
EINA_INLIST_GET(obs));
         if (desk->visible)
-          desk->zone->useful_geometry.dirty = 1;
+          desk->zone->useful_geometry_dirty = 1;
      }
    else
      {
         zone->obstacles = eina_inlist_append(zone->obstacles, 
EINA_INLIST_GET(obs));
-        zone->useful_geometry.dirty = 1;
+        zone->useful_geometry_dirty = 1;
      }
    return obs;
 }
@@ -1394,12 +1395,12 @@ e_zone_obstacle_modify(E_Zone_Obstacle *obs, 
Eina_Rectangle *geom, Eina_Bool ver
      {
         desk = (E_Desk*)obs->owner;
         if (desk->visible)
-          desk->zone->useful_geometry.dirty = 1;
+          desk->zone->useful_geometry_dirty = 1;
      }
    else
      {
         zone = (E_Zone*)obs->owner;
-        zone->useful_geometry.dirty = 1;
+        zone->useful_geometry_dirty = 1;
      }
 }
 
@@ -1693,13 +1694,13 @@ _e_zone_obstacle_free(E_Zone_Obstacle *obs)
         desk = (E_Desk*)obs->owner;
         desk->obstacles = eina_inlist_remove(desk->obstacles, 
EINA_INLIST_GET(obs));
         if (desk->visible)
-          desk->zone->useful_geometry.dirty = 1;
+          desk->zone->useful_geometry_dirty = 1;
      }
    else
      {
         zone = (E_Zone*)obs->owner;
         zone->obstacles = eina_inlist_remove(zone->obstacles, 
EINA_INLIST_GET(obs));
-        zone->useful_geometry.dirty = 1;
+        zone->useful_geometry_dirty = 1;
      }
    free(obs);
 }
diff --git a/src/bin/e_zone.h b/src/bin/e_zone.h
index e069a67..371ead1 100644
--- a/src/bin/e_zone.h
+++ b/src/bin/e_zone.h
@@ -87,13 +87,11 @@ struct _E_Zone
 
    int            id;
 
-   struct
-   {
-      int       x, y, w, h;
-      Eina_Bool dirty : 1;
-   } useful_geometry;
-   Eina_Bool      stowed : 1;
+   Eina_Rectangle useful_geometry[2];
    char *randr2_id; // same id we get from randr2 so look it up there
+   Eina_Bool useful_geometry_changed : 1;
+   Eina_Bool useful_geometry_dirty : 1;
+   Eina_Bool      stowed : 1;
 };
 
 struct _E_Event_Zone_Generic
@@ -158,7 +156,7 @@ E_API Eina_Bool e_zone_exists_direction(E_Zone *zone, 
E_Zone_Edge edge);
 E_API void      e_zone_edge_win_layer_set(E_Zone *zone, E_Layer layer);
 
 E_API void      e_zone_useful_geometry_dirty(E_Zone *zone);
-E_API void      e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int 
*w, int *h);
+E_API Eina_Bool e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int 
*w, int *h);
 E_API void      e_zone_desk_useful_geometry_get(const E_Zone *zone, const 
E_Desk *desk, int *x, int *y, int *w, int *h);
 E_API void      e_zone_stow(E_Zone *zone);
 E_API void      e_zone_unstow(E_Zone *zone);

-- 


Reply via email to