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-screen.h"
|
||||||
#include "xwayland-shm.h"
|
#include "xwayland-shm.h"
|
||||||
#include "xwayland-window.h"
|
#include "xwayland-window.h"
|
||||||
|
#include "xwayland-window-buffers.h"
|
||||||
#include "xwayland-pixmap.h"
|
#include "xwayland-pixmap.h"
|
||||||
|
|
||||||
#include "tearing-control-v1-client-protocol.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);
|
wl_display_flush(xwl_window->xwl_screen->display);
|
||||||
xwl_window->present_flipped = TRUE;
|
|
||||||
return 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)) {
|
if (xwl_present_flip(vblank, damage)) {
|
||||||
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
|
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);
|
PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
|
||||||
|
|
||||||
/* Replace window pixmap with flip pixmap */
|
/* 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++;
|
vblank->pixmap->refcnt++;
|
||||||
dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
|
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);
|
DamageDamageRegion(&vblank->window->drawable, damage);
|
||||||
|
xwl_screen->ignore_damage = FALSE;
|
||||||
RegionDestroy(damage);
|
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 */
|
/* Put pending flip at the flip queue head */
|
||||||
xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
|
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 seat_list;
|
||||||
struct xorg_list damage_window_list;
|
struct xorg_list damage_window_list;
|
||||||
struct xorg_list window_list;
|
struct xorg_list window_list;
|
||||||
|
Bool ignore_damage;
|
||||||
|
|
||||||
int wayland_fd;
|
int wayland_fd;
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
|
|
|
@ -194,17 +194,8 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xwl_screen = xwl_window->xwl_screen;
|
xwl_screen = xwl_window->xwl_screen;
|
||||||
|
if (xwl_screen->ignore_damage)
|
||||||
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;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (xorg_list_is_empty(&xwl_window->link_damage))
|
if (xorg_list_is_empty(&xwl_window->link_damage))
|
||||||
xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
|
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;
|
||||||
struct wl_output *wl_output_fullscreen;
|
struct wl_output *wl_output_fullscreen;
|
||||||
struct xorg_list frame_callback_list;
|
struct xorg_list frame_callback_list;
|
||||||
Bool present_flipped;
|
|
||||||
#ifdef XWL_HAS_LIBDECOR
|
#ifdef XWL_HAS_LIBDECOR
|
||||||
struct libdecor_frame *libdecor_frame;
|
struct libdecor_frame *libdecor_frame;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue