discomfitor pushed a commit to branch master.

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

commit df0173d24c8d93da6190ad8f90960322d235c0b4
Author: Mike Blumenkrantz <zm...@samsung.com>
Date:   Sat Jan 11 15:00:10 2014 -0500

    feature: support XPRESENT extension to reduce compositing overhead
    
    xorg 1.15 introduces this extension which has a magical event to notify 
when a pixmap's size changes, which means that the size never needs to be 
manually fetched
---
 src/bin/e_comp_object.c |  9 ++++++++-
 src/bin/e_comp_object.h |  1 +
 src/bin/e_comp_x.c      | 28 ++++++++++++++++++++++++++--
 src/bin/e_comp_x.h      |  1 +
 src/bin/e_pixmap.c      | 12 +++++++++++-
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c
index 87f076c..d6adfdf 100644
--- a/src/bin/e_comp_object.c
+++ b/src/bin/e_comp_object.c
@@ -1208,7 +1208,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw)
         return;
      }
    e_pixmap_size_get(cw->ec->pixmap, &pw, &ph);   
-   if ((!e_pixmap_refresh(cw->ec->pixmap)) || 
(!e_pixmap_size_get(cw->ec->pixmap, &w, &h)))
+   if (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))
      e_pixmap_clear(cw->ec->pixmap);
 
    if (cw->real_hid && w && h)
@@ -2756,6 +2756,13 @@ e_comp_object_damage(Evas_Object *obj, int x, int y, int 
w, int h)
    e_comp_object_render_update_add(obj);
 }
 
+EAPI Eina_Bool
+e_comp_object_damage_exists(Evas_Object *obj)
+{
+   API_ENTRY EINA_FALSE;
+   return cw->updates_exist;
+}
+
 EAPI void
 e_comp_object_render_update_add(Evas_Object *obj)
 {
diff --git a/src/bin/e_comp_object.h b/src/bin/e_comp_object.h
index 040a174..1fca825 100644
--- a/src/bin/e_comp_object.h
+++ b/src/bin/e_comp_object.h
@@ -60,6 +60,7 @@ EAPI void e_comp_object_signal_callback_del(Evas_Object *obj, 
const char *sig, c
 EAPI void e_comp_object_signal_callback_del_full(Evas_Object *obj, const char 
*sig, const char *src, Edje_Signal_Cb cb, const void *data);
 EAPI void e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, 
int h);
 EAPI void e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h);
+EAPI Eina_Bool e_comp_object_damage_exists(Evas_Object *obj);
 EAPI void e_comp_object_render_update_add(Evas_Object *obj);
 EAPI void e_comp_object_render_update_del(Evas_Object *obj);
 EAPI void e_comp_object_shape_apply(Evas_Object *obj);
diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index f3b8f53..c291305 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -199,6 +199,8 @@ _e_comp_x_client_new_helper(E_Client *ec)
    
 
    e_pixmap_visual_cmap_set(ec->pixmap, 
ec->comp_data->initial_attributes.visual, 
ec->comp_data->initial_attributes.colormap);
+   if (ec->override && (!ec->input_only))
+     ecore_x_present_select_events(win, 
ECORE_X_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY);
    if (ec->override && (!(ec->comp_data->initial_attributes.event_mask.mine & 
ECORE_X_EVENT_MASK_WINDOW_PROPERTY)))
      ecore_x_event_mask_set(win, ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
 
@@ -829,7 +831,8 @@ _e_comp_x_evas_resize_cb(void *data, Evas_Object *obj 
EINA_UNUSED, void *event_i
      }
 
    ec->post_resize = 1;
-   e_pixmap_dirty(ec->pixmap);
+   if (!ecore_x_present_exists())
+     e_pixmap_dirty(ec->pixmap);
    e_comp_object_render_update_del(ec->frame);
    _e_comp_x_post_client_idler_add(ec);
 }
@@ -1335,7 +1338,8 @@ _e_comp_x_configure(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_
      evas_object_move(ec->frame, ev->x, ev->y);
    if (resize)
      {
-        e_pixmap_dirty(ec->pixmap);
+        if (!ecore_x_present_exists())
+          e_pixmap_dirty(ec->pixmap);
         evas_object_resize(ec->frame, ev->w, ev->h);
      }
    return ECORE_CALLBACK_RENEW;
@@ -2458,6 +2462,24 @@ _e_comp_x_grab_replay(void *data EINA_UNUSED, int type, 
void *event)
                                         &ev2, NULL);
 }
 
+static Eina_Bool
+_e_comp_x_present_configure(void *data EINA_UNUSED, int t EINA_UNUSED, 
Ecore_X_Event_Present_Configure *ev)
+{
+   E_Client *ec;
+
+   ec = _e_comp_x_client_find_by_window(ev->win);
+   if (!ec) return ECORE_CALLBACK_RENEW;
+   if (e_pixmap_size_changed(ec->pixmap, ev->pixmap_width, ev->pixmap_height))
+     {
+        e_pixmap_dirty(ec->pixmap);
+        if (e_comp_object_damage_exists(ec->frame))
+          e_comp_object_render_update_add(ec->frame);
+        ec->comp_data->pw = ev->pixmap_width;
+        ec->comp_data->ph = ev->pixmap_height;
+     }
+   return ECORE_CALLBACK_RENEW;
+}
+
 static void
 _e_comp_x_hook_client_eval_end(void *d EINA_UNUSED, E_Client *ec)
 {
@@ -2582,6 +2604,7 @@ _e_comp_x_hook_client_pre_frame_assign(void *d 
EINA_UNUSED, E_Client *ec)
         pwin = ecore_x_window_override_new(ec->comp->man->root, ec->client.x, 
ec->client.y, ec->client.w, ec->client.h);
         ecore_x_window_shape_events_select(pwin, !ec->internal); //let's just 
agree never to do this with our own windows...
      }
+   ecore_x_present_select_events(pwin, 
ECORE_X_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY);
 
    if (ec->client.w && ec->client.h)
      /* force a resize here (no-op most of the time)
@@ -4974,6 +4997,7 @@ e_comp_x_init(void)
    E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_SYNC_ALARM,
                          _e_comp_x_sync_alarm, NULL);
 
+   E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_PRESENT_CONFIGURE, 
_e_comp_x_present_configure, NULL);
 
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN,
                          _e_comp_x_mouse_down, NULL);
diff --git a/src/bin/e_comp_x.h b/src/bin/e_comp_x.h
index 273931c..13d828c 100644
--- a/src/bin/e_comp_x.h
+++ b/src/bin/e_comp_x.h
@@ -19,6 +19,7 @@ struct _E_Comp_Client_Data
    Ecore_X_Damage       damage;  // damage region
    Ecore_X_Visual       vis;  // window visual
    Ecore_X_Colormap     cmap; // colormap of window
+   int pw, ph; //XPRESENT!
 
 #if 0 //NOT USED
    Ecore_X_Pixmap       cache_pixmap;  // the cached pixmap (1/nth the 
dimensions)
diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c
index 05c87ed..c8f9156 100644
--- a/src/bin/e_pixmap.c
+++ b/src/bin/e_pixmap.c
@@ -3,6 +3,9 @@
 #ifdef HAVE_WAYLAND_CLIENTS
 # include "e_comp_wl.h"
 #endif
+#ifndef WAYLAND_ONLY
+# include "e_comp_x.h"
+#endif
 
 static Eina_Hash *pixmaps[2] = {NULL};
 
@@ -329,7 +332,14 @@ e_pixmap_refresh(E_Pixmap *cp)
              e_comp_object_native_surface_set(cp->client->frame, 0);
            success = !!pixmap;
            if (!success) break;
-           ecore_x_pixmap_geometry_get(pixmap, NULL, NULL, &pw, &ph);
+           if (ecore_x_present_exists() && cp->client->comp_data->pw && 
cp->client->comp_data->ph &&
+               (!e_client_resizing_get(cp->client))) //PRESENT is unreliable 
during resizes
+             {
+                pw = cp->client->comp_data->pw;
+                ph = cp->client->comp_data->ph;
+             }
+           else
+             ecore_x_pixmap_geometry_get(pixmap, NULL, NULL, &pw, &ph);
            success = (pw > 0) && (ph > 0);
            if (success)
              {

-- 


Reply via email to