From 96d2fcef302617d6cbfb451a19a403e6f68a631a Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Wed, 11 Jan 2017 09:31:01 +0100 Subject: [PATCH] compositor: check errors after XPresentPixmap() Bug: 13257 If for some reason XPresentPixmap() fails, we might end up waiting forever for a present complete notification that will never arrive. Check for possible errors after XPresentPixmap() and do not set the pending state if an error occured. Signed-off-by: Olivier Fourdan --- src/compositor.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 015030f..79fd16f 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1615,20 +1615,33 @@ redraw_glx_texture (ScreenInfo *screen_info) #endif /* HAVE_EPOXY */ #ifdef HAVE_PRESENT_EXTENSION -static void +static gboolean present_flip (ScreenInfo *screen_info, XserverRegion region, Pixmap pixmap) { static guint32 present_serial; + gint error; - g_return_if_fail (screen_info != NULL); - g_return_if_fail (region != None); - g_return_if_fail (pixmap != None); + g_return_val_if_fail (screen_info != NULL, FALSE); + g_return_val_if_fail (region != None, FALSE); + g_return_val_if_fail (pixmap != None, FALSE); TRACE ("entering present_flip (serial %d)", present_serial); + gdk_error_trap_push (); XPresentPixmap (myScreenGetXDisplay (screen_info), screen_info->output, - pixmap, present_serial++, None, region, 0, 0, None, None, None, + pixmap, present_serial, None, region, 0, 0, None, None, None, PresentOptionNone, 0, 1, 0, NULL, 0); + error = gdk_error_trap_pop(); + if (error) + { + DBG ("XPresentPixmap() window %p pixmap %p: Error %i", + screen_info->output, pixmap, error); + return FALSE; + } + + present_serial++; + + return TRUE; } #endif /* HAVE_PRESENT_EXTENSION */ @@ -2217,9 +2230,16 @@ paint_all (ScreenInfo *screen_info, XserverRegion region, gushort buffer) None, screen_info->rootBuffer[buffer], 0, 0, 0, 0, 0, 0, screen_width, screen_height); } - present_flip (screen_info, region, screen_info->rootPixmap[buffer]); - screen_info->present_pending = TRUE; - DBG ("present flip requested, present pending..."); + if (present_flip (screen_info, region, screen_info->rootPixmap[buffer])) + { + screen_info->present_pending = TRUE; + DBG ("present flip requested, present pending..."); + } + else + { + screen_info->present_pending = FALSE; + DBG ("Warning, present flip failed!"); + } } else #endif /* HAVE_PRESENT_EXTENSION */ -- 2.9.3