present: Dispatch clear_window_flip via present_screen_priv hook

Eliminates special cases in present_destroy_window.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
This commit is contained in:
Michel Dänzer 2021-04-21 17:01:36 +02:00 committed by Michel Dänzer
parent 93666ebe37
commit b6d54b0f5d
4 changed files with 52 additions and 48 deletions

View File

@ -108,6 +108,7 @@ typedef Bool (*present_priv_check_flip_ptr)(RRCrtcPtr crtc,
PresentFlipReason *reason);
typedef void (*present_priv_check_flip_window_ptr)(WindowPtr window);
typedef Bool (*present_priv_can_window_flip_ptr)(WindowPtr window);
typedef void (*present_priv_clear_window_flip_ptr)(WindowPtr window);
typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
PixmapPtr pixmap,
@ -170,6 +171,7 @@ struct present_screen_priv {
present_priv_check_flip_ptr check_flip;
present_priv_check_flip_window_ptr check_flip_window;
present_priv_can_window_flip_ptr can_window_flip;
present_priv_clear_window_flip_ptr clear_window_flip;
present_priv_pixmap_ptr present_pixmap;

View File

@ -495,6 +495,26 @@ present_scmd_can_window_flip(WindowPtr window)
return TRUE;
}
/*
* Clean up any pending or current flips for this window
*/
static void
present_scmd_clear_window_flip(WindowPtr window)
{
ScreenPtr screen = window->drawable.pScreen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
present_vblank_ptr flip_pending = screen_priv->flip_pending;
if (flip_pending && flip_pending->window == window) {
present_set_abort_flip(screen);
flip_pending->window = NULL;
}
if (screen_priv->flip_window == window) {
present_restore_screen_pixmap(screen);
screen_priv->flip_window = NULL;
}
}
/*
* Once the required MSC has been reached, execute the pending request.
*
@ -812,6 +832,7 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
screen_priv->check_flip = &present_check_flip;
screen_priv->check_flip_window = &present_check_flip_window;
screen_priv->can_window_flip = &present_scmd_can_window_flip;
screen_priv->clear_window_flip = &present_scmd_clear_window_flip;
screen_priv->present_pixmap = &present_scmd_pixmap;

View File

@ -86,50 +86,6 @@ present_free_window_vblank(WindowPtr window)
}
}
/*
* Clean up any pending or current flips for this window
*/
static void
present_clear_window_flip(WindowPtr window)
{
ScreenPtr screen = window->drawable.pScreen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
present_vblank_ptr flip_pending = screen_priv->flip_pending;
if (flip_pending && flip_pending->window == window) {
present_set_abort_flip(screen);
flip_pending->window = NULL;
}
if (screen_priv->flip_window == window) {
present_restore_screen_pixmap(screen);
screen_priv->flip_window = NULL;
}
}
static void
present_wnmd_clear_window_flip(WindowPtr window)
{
present_window_priv_ptr window_priv = present_window_priv(window);
present_vblank_ptr vblank, tmp;
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
vblank = window_priv->flip_active;
if (vblank) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
window_priv->flip_active = NULL;
}
/*
* Hook the close window function to clean up our window private
*/
@ -146,10 +102,7 @@ present_destroy_window(WindowPtr window)
present_free_events(window);
present_free_window_vblank(window);
if (screen_priv->wnmd_info)
present_wnmd_clear_window_flip(window);
else
present_clear_window_flip(window);
screen_priv->clear_window_flip(window);
free(window_priv);
}

View File

@ -373,6 +373,33 @@ present_wnmd_check_flip_window (WindowPtr window)
}
}
/*
* Clean up any pending or current flips for this window
*/
static void
present_wnmd_clear_window_flip(WindowPtr window)
{
present_window_priv_ptr window_priv = present_window_priv(window);
present_vblank_ptr vblank, tmp;
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
vblank = window_priv->flip_active;
if (vblank) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
window_priv->flip_active = NULL;
}
static Bool
present_wnmd_flip(WindowPtr window,
RRCrtcPtr crtc,
@ -689,6 +716,7 @@ present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
screen_priv->check_flip = &present_wnmd_check_flip;
screen_priv->check_flip_window = &present_wnmd_check_flip_window;
screen_priv->clear_window_flip = &present_wnmd_clear_window_flip;
screen_priv->present_pixmap = &present_wnmd_pixmap;
screen_priv->queue_vblank = &present_wnmd_queue_vblank;