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