If a window is reparented and the new parent already has a child flipping, we need to cancel the flipping on the reparented window.
Install a new ReparentWindow handler in present screen with hooks in wnmd implementation to check if the new parent has flip pending or active in which case we cancel flip on the reparented window. Signed-off-by: Olivier Fourdan <ofour...@redhat.com> --- present/present_priv.h | 3 +++ present/present_scmd.c | 1 + present/present_screen.c | 16 ++++++++++++++++ present/present_wnmd.c | 17 +++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/present/present_priv.h b/present/present_priv.h index f62456755..668322416 100644 --- a/present/present_priv.h +++ b/present/present_priv.h @@ -106,6 +106,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_reparent_window_ptr)(WindowPtr pWin); typedef int (*present_priv_pixmap_ptr)(WindowPtr window, PixmapPtr pixmap, @@ -147,6 +148,7 @@ struct present_screen_priv { ConfigNotifyProcPtr ConfigNotify; DestroyWindowProcPtr DestroyWindow; ClipNotifyProcPtr ClipNotify; + ReparentWindowProcPtr ReparentWindow; present_vblank_ptr flip_pending; uint64_t unflip_event_id; @@ -171,6 +173,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_reparent_window_ptr reparent_window; present_priv_pixmap_ptr present_pixmap; present_priv_create_event_id_ptr create_event_id; diff --git a/present/present_scmd.c b/present/present_scmd.c index 0803a0c0b..a3ca16333 100644 --- a/present/present_scmd.c +++ b/present/present_scmd.c @@ -828,6 +828,7 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv) screen_priv->abort_vblank = &present_scmd_abort_vblank; screen_priv->flip_destroy = &present_scmd_flip_destroy; + screen_priv->reparent_window = NULL; } Bool diff --git a/present/present_screen.c b/present/present_screen.c index c7e37c5fd..f3f2ddef9 100644 --- a/present/present_screen.c +++ b/present/present_screen.c @@ -207,6 +207,21 @@ present_clip_notify(WindowPtr window, int dx, int dy) wrap(screen_priv, screen, ClipNotify, present_clip_notify); } +static void +present_reparent_window(WindowPtr pWin, WindowPtr pPriorParent) +{ + ScreenPtr screen = pWin->drawable.pScreen; + present_screen_priv_ptr screen_priv = present_screen_priv(screen); + + if (screen_priv->reparent_window) + screen_priv->reparent_window(pWin); + + unwrap(screen_priv, screen, ReparentWindow) + if (screen->ReparentWindow) + screen->ReparentWindow(pWin, pPriorParent); + wrap(screen_priv, screen, ReparentWindow, present_reparent_window); +} + static Bool present_screen_register_priv_keys(void) { @@ -232,6 +247,7 @@ present_screen_priv_init(ScreenPtr screen) wrap(screen_priv, screen, DestroyWindow, present_destroy_window); wrap(screen_priv, screen, ConfigNotify, present_config_notify); wrap(screen_priv, screen, ClipNotify, present_clip_notify); + wrap(screen_priv, screen, ReparentWindow, present_reparent_window); dixSetPrivate(&screen->devPrivates, &present_screen_private_key, screen_priv); diff --git a/present/present_wnmd.c b/present/present_wnmd.c index 8f3836440..0c49a3507 100644 --- a/present/present_wnmd.c +++ b/present/present_wnmd.c @@ -682,6 +682,22 @@ present_wnmd_flush(WindowPtr window) (*screen_priv->wnmd_info->flush) (window); } +static void +present_wnmd_reparent_window(WindowPtr pWin) +{ + present_window_priv_ptr parent_window_priv; + + parent_window_priv = present_window_priv(pWin->parent); + if (!parent_window_priv) + return; + + /* If the new parent window already has a child flipping, cancel the + * flip on the reparented window + */ + if (parent_window_priv->flip_pending || parent_window_priv->flip_active) + present_wnmd_cancel_flip(pWin); +} + void present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv) { @@ -700,4 +716,5 @@ present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv) screen_priv->abort_vblank = &present_wnmd_abort_vblank; screen_priv->flip_destroy = &present_wnmd_flip_destroy; + screen_priv->reparent_window = &present_wnmd_reparent_window; } -- 2.19.0 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel