xwayland/present: Handle clearing damage after flip in xwl_present_execute
Due to DamageReportNonEmpty, damage_report doesn't get called if the damage region was already non-empty before the flip. In which case it didn't get called before the first draw after the flip either. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1627 Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>
This commit is contained in:
parent
6b290fa5d9
commit
64341c479c
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue