From e0af09061f9e8397ca564ec3bbedea51974455d4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 7 Jan 2019 15:20:05 +0100 Subject: [PATCH xserver 13/15] xwayland: Separate DamagePtr into separate window data This will be dissociated in future commits to handle the cases where windows are being realized before there is a compositor handling redirection. In that case, we still want the DamagePtr to be registered upfront on RealizeWindowProc before a corresponding xwl_window might be created. Most notably, it cannot be lazily created on SetWindowPixmapProc as damage accounting gets broken. Signed-off-by: Carlos Garnacho (cherry picked from commit 4e50440ae20c537d6a4edf356cda67dd33d4e5a8) --- hw/xwayland/xwayland.c | 74 +++++++++++++++++++++++++++++++++--------- hw/xwayland/xwayland.h | 1 - 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 7e6e0ab25..1efebd061 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -125,6 +125,7 @@ ddxProcessArgument(int argc, char *argv[], int i) static DevPrivateKeyRec xwl_window_private_key; static DevPrivateKeyRec xwl_screen_private_key; static DevPrivateKeyRec xwl_pixmap_private_key; +static DevPrivateKeyRec xwl_damage_private_key; static struct xwl_window * xwl_window_get(WindowPtr window) @@ -367,8 +368,14 @@ xwl_cursor_confined_to(DeviceIntPtr device, static void damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) { - struct xwl_window *xwl_window = data; - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + WindowPtr window = data; + struct xwl_window *xwl_window = xwl_window_get(window); + struct xwl_screen *xwl_screen; + + if (!xwl_window) + return; + + xwl_screen = xwl_window->xwl_screen; #ifdef GLAMOR_HAS_GBM if (xwl_window->present_flipped) { @@ -390,6 +397,47 @@ damage_destroy(DamagePtr pDamage, void *data) { } +static Bool +register_damage(WindowPtr window) +{ + DamagePtr damage; + + damage = DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, + FALSE, window->drawable.pScreen, window); + if (damage == NULL) { + ErrorF("Failed creating damage\n"); + return FALSE; + } + + DamageRegister(&window->drawable, damage); + DamageSetReportAfterOp(damage, TRUE); + + dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, damage); + + return TRUE; +} + +static void +unregister_damage(WindowPtr window) +{ + DamagePtr damage; + + damage = dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key); + if (!damage) + return; + + DamageUnregister(damage); + DamageDestroy(damage); + + dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, NULL); +} + +static DamagePtr +window_get_damage(WindowPtr window) +{ + return dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key); +} + static void shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) @@ -545,18 +593,10 @@ xwl_realize_window(WindowPtr window) wl_surface_set_user_data(xwl_window->surface, xwl_window); - xwl_window->damage = - DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, - FALSE, screen, xwl_window); - if (xwl_window->damage == NULL) { - ErrorF("Failed creating damage\n"); - goto err_surf; - } - compRedirectWindow(serverClient, window, CompositeRedirectManual); - DamageRegister(&window->drawable, xwl_window->damage); - DamageSetReportAfterOp(xwl_window->damage, TRUE); + if (!register_damage(window)) + goto err_surf; dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window); xorg_list_init(&xwl_window->link_damage); @@ -620,8 +660,8 @@ xwl_unrealize_window(WindowPtr window) wl_surface_destroy(xwl_window->surface); xorg_list_del(&xwl_window->link_damage); - DamageUnregister(xwl_window->damage); - DamageDestroy(xwl_window->damage); + unregister_damage(window); + if (xwl_window->frame_callback) wl_callback_destroy(xwl_window->frame_callback); @@ -689,7 +729,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window) assert(!xwl_window->frame_callback); - region = DamageRegion(xwl_window->damage); + region = DamageRegion(window_get_damage(xwl_window->window)); pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window); #ifdef XWL_HAS_GLAMOR @@ -726,7 +766,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window) wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window); wl_surface_commit(xwl_window->surface); - DamageEmpty(xwl_window->damage); + DamageEmpty(window_get_damage(xwl_window->window)); xorg_list_del(&xwl_window->link_damage); } @@ -962,6 +1002,8 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) return FALSE; if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0)) return FALSE; + if (!dixRegisterPrivateKey(&xwl_damage_private_key, PRIVATE_WINDOW, 0)) + return FALSE; dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen); xwl_screen->screen = pScreen; diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 463622669..dfa3b37c3 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -178,7 +178,6 @@ struct xwl_window { struct wl_surface *surface; struct wl_shell_surface *shell_surface; WindowPtr window; - DamagePtr damage; struct xorg_list link_damage; struct wl_callback *frame_callback; Bool allow_commits; -- 2.21.0