xwayland: Implement throttling for surfaces based on the frame event

This implements simple throttling that keeps us to one attach per
frame. There isn't really an active performance benefit, since the
buffers will be redrawn only once per frame anyway, but it does cut down
on the chatty network traffic. Since the Wayland sockets might fill
up as well, the cut down on the volume of data we send out also provides
us with a big stability benefit.

Namely, mutter is a lot more stable running gtkperf, a fairly intensive
X11 application, after this change.

Reviewed-by: Daniel Stone <daniel@fooishbar.org>
Signed-off-by: Jasper St. Pierre <jstpierre@mecheye.net>
This commit is contained in:
Jasper St. Pierre 2014-06-30 13:53:50 -04:00
parent 6c442fc4f7
commit 5ecc0315a2
2 changed files with 31 additions and 5 deletions

View File

@ -308,6 +308,9 @@ xwl_unrealize_window(WindowPtr window)
xorg_list_del(&xwl_window->link_damage);
DamageUnregister(xwl_window->damage);
DamageDestroy(xwl_window->damage);
if (xwl_window->frame_callback)
wl_callback_destroy(xwl_window->frame_callback);
free(xwl_window);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
@ -320,18 +323,36 @@ xwl_save_screen(ScreenPtr pScreen, int on)
return TRUE;
}
static void
frame_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
struct xwl_window *xwl_window = data;
xwl_window->frame_callback = NULL;
}
static const struct wl_callback_listener frame_listener = {
frame_callback
};
static void
xwl_screen_post_damage(struct xwl_screen *xwl_screen)
{
struct xwl_window *xwl_window;
struct xwl_window *xwl_window, *next_xwl_window;
RegionPtr region;
BoxPtr box;
int count, i;
struct wl_buffer *buffer;
PixmapPtr pixmap;
xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
link_damage) {
xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
&xwl_screen->damage_window_list, link_damage) {
/* If we're waiting on a frame callback from the server,
* don't attach a new buffer. */
if (xwl_window->frame_callback)
continue;
region = DamageRegion(xwl_window->damage);
count = RegionNumRects(region);
@ -351,11 +372,15 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
box->x1, box->y1,
box->x2 - box->x1, box->y2 - box->y1);
}
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
wl_surface_commit(xwl_window->surface);
DamageEmpty(xwl_window->damage);
}
xorg_list_init(&xwl_screen->damage_window_list);
xorg_list_del(&xwl_window->link_damage);
}
}
static void

View File

@ -102,6 +102,7 @@ struct xwl_window {
WindowPtr window;
DamagePtr damage;
struct xorg_list link_damage;
struct wl_callback *frame_callback;
};
#define MODIFIER_META 0x01