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) { --