diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index 783b04ff4..3c27333b7 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -35,6 +35,7 @@ #include "xwayland-screen.h" #include "xwayland-shm.h" #include "xwayland-window.h" +#include "xwayland-window-buffers.h" #include "xwayland-pixmap.h" #include "tearing-control-v1-client-protocol.h" @@ -833,7 +834,6 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage) } wl_display_flush(xwl_window->xwl_screen->display); - xwl_window->present_flipped = TRUE; return TRUE; } @@ -890,6 +890,8 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (xwl_present_flip(vblank, damage)) { WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window); + struct xwl_window *xwl_window = xwl_window_from_window(window); + struct xwl_screen *xwl_screen = xwl_window->xwl_screen; PixmapPtr old_pixmap = screen->GetWindowPixmap(window); /* Replace window pixmap with flip pixmap */ @@ -906,10 +908,19 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) vblank->pixmap->refcnt++; dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id); - /* Report damage */ + /* Report damage, let damage_report ignore it though */ + xwl_screen->ignore_damage = TRUE; DamageDamageRegion(&vblank->window->drawable, damage); + xwl_screen->ignore_damage = FALSE; RegionDestroy(damage); + /* Clear damage region, to ensure damage_report is called before + * any drawing to the window + */ + xwl_window_buffer_add_damage_region(xwl_window); + RegionEmpty(xwl_window_get_damage_region(xwl_window)); + xorg_list_del(&xwl_window->link_damage); + /* Put pending flip at the flip queue head */ xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue); diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index a53d18bad..993b3cb12 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -90,6 +90,7 @@ struct xwl_screen { struct xorg_list seat_list; struct xorg_list damage_window_list; struct xorg_list window_list; + Bool ignore_damage; int wayland_fd; struct wl_display *display; diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index d19b383d0..c8b62db6e 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -194,17 +194,8 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) return; xwl_screen = xwl_window->xwl_screen; - - if (xwl_window->present_flipped) { - /* This damage is from a Present flip, which already committed a new - * buffer for the surface, so we don't need to do anything in response - */ - xwl_window_buffer_add_damage_region(xwl_window); - RegionEmpty(DamageRegion(pDamage)); - xorg_list_del(&xwl_window->link_damage); - xwl_window->present_flipped = FALSE; + if (xwl_screen->ignore_damage) return; - } if (xorg_list_is_empty(&xwl_window->link_damage)) xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list); diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h index 827a0fd53..03d3fed14 100644 --- a/hw/xwayland/xwayland-window.h +++ b/hw/xwayland/xwayland-window.h @@ -111,7 +111,6 @@ struct xwl_window { struct wl_output *wl_output; struct wl_output *wl_output_fullscreen; struct xorg_list frame_callback_list; - Bool present_flipped; #ifdef XWL_HAS_LIBDECOR struct libdecor_frame *libdecor_frame; #endif