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
This commit is contained in:
parent
2ee8262ea5
commit
df0173d24c
|
@ -1208,7 +1208,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e_pixmap_size_get(cw->ec->pixmap, &pw, &ph);
|
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);
|
e_pixmap_clear(cw->ec->pixmap);
|
||||||
|
|
||||||
if (cw->real_hid && w && h)
|
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);
|
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
|
EAPI void
|
||||||
e_comp_object_render_update_add(Evas_Object *obj)
|
e_comp_object_render_update_add(Evas_Object *obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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_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_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 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_add(Evas_Object *obj);
|
||||||
EAPI void e_comp_object_render_update_del(Evas_Object *obj);
|
EAPI void e_comp_object_render_update_del(Evas_Object *obj);
|
||||||
EAPI void e_comp_object_shape_apply(Evas_Object *obj);
|
EAPI void e_comp_object_shape_apply(Evas_Object *obj);
|
||||||
|
|
|
@ -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);
|
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)))
|
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);
|
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;
|
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_object_render_update_del(ec->frame);
|
||||||
_e_comp_x_post_client_idler_add(ec);
|
_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);
|
evas_object_move(ec->frame, ev->x, ev->y);
|
||||||
if (resize)
|
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);
|
evas_object_resize(ec->frame, ev->w, ev->h);
|
||||||
}
|
}
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
@ -2458,6 +2462,24 @@ _e_comp_x_grab_replay(void *data EINA_UNUSED, int type, void *event)
|
||||||
&ev2, NULL);
|
&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
|
static void
|
||||||
_e_comp_x_hook_client_eval_end(void *d EINA_UNUSED, E_Client *ec)
|
_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);
|
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_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)
|
if (ec->client.w && ec->client.h)
|
||||||
/* force a resize here (no-op most of the time)
|
/* 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_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_SYNC_ALARM,
|
||||||
_e_comp_x_sync_alarm, NULL);
|
_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_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN,
|
||||||
_e_comp_x_mouse_down, NULL);
|
_e_comp_x_mouse_down, NULL);
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct _E_Comp_Client_Data
|
||||||
Ecore_X_Damage damage; // damage region
|
Ecore_X_Damage damage; // damage region
|
||||||
Ecore_X_Visual vis; // window visual
|
Ecore_X_Visual vis; // window visual
|
||||||
Ecore_X_Colormap cmap; // colormap of window
|
Ecore_X_Colormap cmap; // colormap of window
|
||||||
|
int pw, ph; //XPRESENT!
|
||||||
|
|
||||||
#if 0 //NOT USED
|
#if 0 //NOT USED
|
||||||
Ecore_X_Pixmap cache_pixmap; // the cached pixmap (1/nth the dimensions)
|
Ecore_X_Pixmap cache_pixmap; // the cached pixmap (1/nth the dimensions)
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#ifdef HAVE_WAYLAND_CLIENTS
|
#ifdef HAVE_WAYLAND_CLIENTS
|
||||||
# include "e_comp_wl.h"
|
# include "e_comp_wl.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WAYLAND_ONLY
|
||||||
|
# include "e_comp_x.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static Eina_Hash *pixmaps[2] = {NULL};
|
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);
|
e_comp_object_native_surface_set(cp->client->frame, 0);
|
||||||
success = !!pixmap;
|
success = !!pixmap;
|
||||||
if (!success) break;
|
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);
|
success = (pw > 0) && (ph > 0);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue