diff options
author | Adam Jackson <ajax@redhat.com> | 2014-07-16 11:42:51 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2014-07-16 11:50:04 -0400 |
commit | bf2df5db0bfb5a8fea2a8a8561e38d44009d7095 (patch) | |
tree | 38e2f8e426951bb241bc0a9d4c490f5c5e7a3bdc | |
parent | 02e2cf0cec3a05a718ed70f2273f72b7ad8ef72e (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.c | 29 | ||||
-rw-r--r-- | hw/xwayland/xwayland.h | 2 |
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; }; |