Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/ecore

Dir     : e17/libs/ecore/src/lib/ecore_x


Modified Files:
        Ecore_X.h ecore_x_dnd.c ecore_x_events.c ecore_x_private.h 
        ecore_x_window.c ecore_xcb_dnd.c 


Log Message:


improve xdnd performance by thousdands of times. it was HORRID. note the
comments in the code.

===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_x/Ecore_X.h,v
retrieving revision 1.191
retrieving revision 1.192
diff -u -3 -r1.191 -r1.192
--- Ecore_X.h   5 Nov 2007 20:47:29 -0000       1.191
+++ Ecore_X.h   15 Nov 2007 04:48:36 -0000      1.192
@@ -1090,6 +1090,7 @@
 EAPI void             ecore_x_window_defaults_set(Ecore_X_Window win);
 EAPI int              ecore_x_window_visible_get(Ecore_X_Window win);
 EAPI Ecore_X_Window   
ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int 
y, Ecore_X_Window *skip, int skip_num);
+EAPI Ecore_X_Window   ecore_x_window_shadow_parent_get(Ecore_X_Window root, 
Ecore_X_Window win);
 EAPI void             ecore_x_window_shadow_tree_flush(void);
 EAPI Ecore_X_Window   ecore_x_window_root_get(Ecore_X_Window win);
 EAPI Ecore_X_Window   ecore_x_window_at_xy_get(int x, int y);
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_x/ecore_x_dnd.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -3 -r1.32 -r1.33
--- ecore_x_dnd.c       5 Oct 2007 12:39:06 -0000       1.32
+++ ecore_x_dnd.c       15 Nov 2007 04:48:36 -0000      1.33
@@ -43,6 +43,14 @@
 static Ecore_X_DND_Target *_target = NULL;
 static int _ecore_x_dnd_init_count = 0;
 
+typedef struct _Version_Cache_Item
+{
+   Ecore_X_Window win;
+   int ver;
+} Version_Cache_Item;
+static Version_Cache_Item *_version_cache = NULL;
+static int _version_cache_num = 0, _version_cache_alloc = 0;
+
 void
 _ecore_x_dnd_init(void)
 {
@@ -163,15 +171,50 @@
    unsigned char *prop_data;
    int num;
 
+   // this looks hacky - and it is, but we need a way of caching info about
+   // a window while dragging, because we literally query this every mouse
+   // move and going to and from x multiple times per move is EXPENSIVE
+   // and slows things down, puts lots of load on x etc.
+   if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+     {
+       if (_version_cache)
+         {
+            int i;
+            
+            for (i = 0; i < _version_cache_num; i++)
+              {
+                 if (_version_cache[i].win == win)
+                   return _version_cache[i].ver;
+              }
+         }
+     }
+     
    if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE,
                                         XA_ATOM, 32, &prop_data, &num))
      {
        int version = (int) *prop_data;
        free(prop_data);
+       if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+         {
+            _version_cache_num++;
+            if (_version_cache_num > _version_cache_alloc)
+              _version_cache_alloc += 16;
+            _version_cache = realloc(_version_cache, _version_cache_alloc * 
sizeof(Version_Cache_Item));
+            _version_cache[_version_cache_num - 1].win = win;
+            _version_cache[_version_cache_num - 1].ver = version;
+         }
        return version;
      }
-   else
-     return 0;
+   if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+     {
+       _version_cache_num++;
+       if (_version_cache_num > _version_cache_alloc)
+         _version_cache_alloc += 16;
+       _version_cache = realloc(_version_cache, _version_cache_alloc * 
sizeof(Version_Cache_Item));
+       _version_cache[_version_cache_num - 1].win = win;
+       _version_cache[_version_cache_num - 1].ver = 0;
+     }
+   return 0;
 }
 
 EAPI int
@@ -331,6 +374,15 @@
    if (!ecore_x_selection_xdnd_set(source, data, size))
      return 0;
 
+   if (_version_cache)
+     {
+       free(_version_cache);
+       _version_cache = NULL;
+       _version_cache_num = 0;
+       _version_cache_alloc = 0;
+     }
+   ecore_x_window_shadow_tree_flush();
+   
    _source->win = source;
    ecore_x_window_ignore_set(_source->win, 1);
    _source->state = ECORE_X_DND_SOURCE_DRAGGING;
@@ -462,7 +514,7 @@
 }
 
 void
-_ecore_x_dnd_drag(int x, int y)
+_ecore_x_dnd_drag(Ecore_X_Window root, int x, int y)
 {
    XEvent          xev;
    Ecore_X_Window  win;
@@ -480,9 +532,17 @@
 
    /* Attempt to find a DND-capable window under the cursor */
    skip = ecore_x_window_ignore_list(&num);
-   win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
+// WARNING - this function is HEAVY. it goes to and from x a LOT walking the
+// window tree - use the SHADOW version - makes a 1-off tree copy, then uses
+// that instead.
+//   win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
+   win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
+
+// NOTE: This now uses the shadow version to find parent windows
+//   while ((win) && !(ecore_x_dnd_version_get(win)))
+//     win = ecore_x_window_parent_get(win);
    while ((win) && !(ecore_x_dnd_version_get(win)))
-     win = ecore_x_window_parent_get(win);
+     win = ecore_x_window_shadow_parent_get(root, win);
 
    /* Send XdndLeave to current destination window if we have left it */
    if ((_source->dest) && (win != _source->dest))
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_x/ecore_x_events.c,v
retrieving revision 1.98
retrieving revision 1.99
diff -u -3 -r1.98 -r1.99
--- ecore_x_events.c    27 Sep 2007 15:43:08 -0000      1.98
+++ ecore_x_events.c    15 Nov 2007 04:48:36 -0000      1.99
@@ -568,7 +568,7 @@
    _ecore_x_event_last_root_y = e->root.y;
 
    /* Xdnd handling */
-   _ecore_x_dnd_drag(e->root.x, e->root.y);
+   _ecore_x_dnd_drag(xevent->xmotion.root, e->root.x, e->root.y);
 
    ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
 }
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_x/ecore_x_private.h,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -3 -r1.62 -r1.63
--- ecore_x_private.h   6 Oct 2007 08:37:33 -0000       1.62
+++ ecore_x_private.h   15 Nov 2007 04:48:36 -0000      1.63
@@ -217,7 +217,7 @@
 void _ecore_x_dnd_init(void);
 Ecore_X_DND_Source *_ecore_x_dnd_source_get(void);
 Ecore_X_DND_Target *_ecore_x_dnd_target_get(void);
-void _ecore_x_dnd_drag(int x, int y);
+void _ecore_x_dnd_drag(Ecore_X_Window root, int x, int y);
 void _ecore_x_dnd_shutdown(void);
 
 /* from netwm */
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_x/ecore_x_window.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -3 -r1.56 -r1.57
--- ecore_x_window.c    10 Nov 2007 23:15:03 -0000      1.56
+++ ecore_x_window.c    15 Nov 2007 04:48:36 -0000      1.57
@@ -713,6 +713,7 @@
 typedef struct _Shadow Shadow;
 struct _Shadow
 {
+   Shadow         *parent;
    Shadow        **children;
    Window          win;
    int             children_num;
@@ -753,7 +754,10 @@
          {
             s->children_num = num;
             for (i = 0; i < num; i++)
-              s->children[i] = _ecore_x_window_tree_walk(list[i]);
+              {
+                 s->children[i] = _ecore_x_window_tree_walk(list[i]);
+                 if (s->children[i]) s->children[i]->parent = s;
+              }
             /* compress list down */
             j = 0;
             for (i = 0; i < num; i++)
@@ -935,8 +939,11 @@
 {
    Shadow *s;
    
-   if (!shadow_base) _ecore_x_window_tree_shadow_populate();
-   if (!shadow_base) return 0;
+   if (!shadow_base)
+     {
+       _ecore_x_window_tree_shadow_populate();
+       if (!shadow_base) return 0;
+     }
    s = _ecore_x_window_shadow_tree_find(base);
    if (!s) return 0;
    return _ecore_x_window_shadow_tree_at_xy_get_shadow(s, bx, by, x, y, skip, 
skip_num);
@@ -958,6 +965,38 @@
 ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int 
y, Ecore_X_Window *skip, int skip_num)
 {
    return _ecore_x_window_shadow_tree_at_xy_get(base, 0, 0, x, y, skip, 
skip_num);
+}
+
+/**
+ * Retrieves the parent window a given window has. This uses the shadow window
+ * tree.
+ * @param   root The root window of @p win - if 0, this will be automatically 
determined with extra processing overhead
+ * @param   win The window to get the parent window of
+ * @return  The parent window of @p win
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_parent_get(Ecore_X_Window root, Ecore_X_Window win)
+{
+   Shadow *s;
+   int i;
+   
+   if (!shadow_base)
+     {
+       _ecore_x_window_tree_shadow_populate();
+       if (!shadow_base) return 0;
+     }
+   for (i = 0; i < shadow_num; i++)
+     {
+       if (!shadow_base[i]) continue;
+       s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win);
+       if (s)
+         {
+            if (!s->parent) return 0;
+            return s->parent->win;
+         }
+     }
+   return 0;
 }
 
 /**
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_x/ecore_xcb_dnd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -3 -r1.1 -r1.2
--- ecore_xcb_dnd.c     13 Apr 2007 17:12:09 -0000      1.1
+++ ecore_xcb_dnd.c     15 Nov 2007 04:48:36 -0000      1.2
@@ -611,7 +611,8 @@
 }
 
 void
-_ecore_x_dnd_drag(int x,
+_ecore_x_dnd_drag(Ecore_X_Window root,
+                 int x,
                   int y)
 {
    xcb_client_message_event_t ev;
@@ -627,7 +628,8 @@
 
    /* Attempt to find a DND-capable window under the cursor */
    skip = ecore_x_window_ignore_list(&num);
-   win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
+//   win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
+   win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
    while (win)
      {
         xcb_query_tree_cookie_t cookie_tree;



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to