summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2014-07-16 11:42:51 -0400
committerAdam Jackson <ajax@redhat.com>2014-07-16 11:50:04 -0400
commitbf2df5db0bfb5a8fea2a8a8561e38d44009d7095 (patch)
tree38e2f8e426951bb241bc0a9d4c490f5c5e7a3bdc
parent02e2cf0cec3a05a718ed70f2273f72b7ad8ef72e (diff)
xwayland: Defer surface realization to block handlerwayland-netwm-etc
In addition to batching requests better, this also optimizes out the case of a window destroyed before we flush the realization to wayland. This does come at a cost, in that we're no longer allocating everything we need for the surface at RealizeWindow time, so it's possible to end up with an X window with no corresponding wayland surface; hence the surface validity check in the damage blockhandler. But we do retry surface creation every time we block until it succeeds, so if it's just a transient allocation problem we should eventually push through. Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--hw/xwayland/xwayland.c29
-rw-r--r--hw/xwayland/xwayland.h2
2 files changed, 28 insertions, 3 deletions
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 031c8f18b..9190f6536 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -329,7 +329,9 @@ xwl_realize_window(WindowPtr window)
xwl_window = calloc(sizeof *xwl_window, 1);
xwl_window->xwl_screen = xwl_screen;
xwl_window->window = window;
- xwl_window->surface = xwl_create_surface(xwl_screen, xwl_window);
+ xorg_list_init(&xwl_window->link_realize);
+ xorg_list_append(&xwl_window->link_realize,
+ &xwl_screen->realize_window_list);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
@@ -372,7 +374,10 @@ xwl_unrealize_window(WindowPtr window)
if (!xwl_window)
return ret;
- wl_surface_destroy(xwl_window->surface);
+ if (!xorg_list_is_empty(&xwl_window->link_realize))
+ xorg_list_del(&xwl_window->link_realize);
+ if (xwl_window->surface)
+ wl_surface_destroy(xwl_window->surface);
if (RegionNotEmpty(DamageRegion(xwl_window->damage)))
xorg_list_del(&xwl_window->link_damage);
DamageUnregister(xwl_window->damage);
@@ -390,6 +395,20 @@ xwl_save_screen(ScreenPtr pScreen, int on)
}
static void
+xwl_screen_realize_windows(struct xwl_screen *xwl_screen)
+{
+ struct xwl_window *xwl_window, *cur;
+
+ xorg_list_for_each_entry_safe(xwl_window, cur,
+ &xwl_screen->realize_window_list,
+ link_realize) {
+ xwl_window->surface = xwl_create_surface(xwl_screen, xwl_window);
+ if (xwl_window->surface)
+ xorg_list_del(&xwl_window->link_realize);
+ }
+}
+
+static void
xwl_screen_post_damage(struct xwl_screen *xwl_screen)
{
struct xwl_window *xwl_window;
@@ -401,7 +420,6 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
link_damage) {
region = DamageRegion(xwl_window->damage);
-
pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
#if GLAMOR_HAS_GBM
@@ -411,6 +429,9 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
if (!xwl_screen->glamor)
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
+ if (!xwl_window->surface)
+ continue;
+
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
box = RegionExtents(DamageRegion(xwl_window->damage);
wl_surface_damage(xwl_window->surface, box->x1, box->y1,
@@ -491,6 +512,7 @@ block_handler(void *data, struct timeval **tv, void *read_mask)
struct xwl_screen *xwl_screen = data;
int ret;
+ xwl_screen_realize_windows(xwl_screen);
xwl_screen_post_damage(xwl_screen);
while (xwl_screen->prepare_read == 0 &&
@@ -609,6 +631,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
xorg_list_init(&xwl_screen->output_list);
xorg_list_init(&xwl_screen->seat_list);
xorg_list_init(&xwl_screen->damage_window_list);
+ xorg_list_init(&xwl_screen->realize_window_list);
xwl_screen->depth = 24;
xwl_screen->display = wl_display_connect(NULL);
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index d82e77e5c..ecbf75efa 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -68,6 +68,7 @@ struct xwl_screen {
struct xorg_list output_list;
struct xorg_list seat_list;
struct xorg_list damage_window_list;
+ struct xorg_list realize_window_list;
int wayland_fd;
struct wl_display *display;
@@ -103,6 +104,7 @@ struct xwl_window {
WindowPtr window;
DamagePtr damage;
struct xorg_list link_damage;
+ struct xorg_list link_realize;
Bool supports_wm_sync_request;
XID wm_sync_counter;
};