GNOME Bugzilla – Bug 702196
Unfinished frame being presented
Last modified: 2013-09-26 21:20:15 UTC
This might a bit of a mutter/gtk+ interaction bug with the frame synchronization stuff Owen has been working on. So basically I get this unfinished frame of gnome-screenshot being presented by mutter : https://www.youtube.com/watch?v=bWiao9WEelk . You can notice that for a short time the window is even presented without decoration. Sometimes (but this is harder to reproduce), the window will actually remain completely non rendered (including window decorations), until it is resized (which means a new buffer will be attached to the mutter's ClutterActor). I believe there might be a race condition in Mutter, but I also believe GTK+ is not doing the right thing. Also I think I might be able to see this problem only because I have a slow enough laptop and I might be using a much heavier theme that delays the very first rendering of the window. Here is what I think happens : On the application side : 1. gnome-screenshot starts and creates a window 2. the windows is mapped (XMapWindow call, at this point the sync_request_counter is at 0) 3. cairo starts some drawing 4. the sync_request_counter is set to 1 5. the window content is drawn 6. the sync_request_counter is set to 2 On the compositor side : 1. mutter receives a CreateNotify event 2. several window property are changed, including the one reporting that the window supports synchronous rendering 3. mutter receives a MapNotify event and creates the actor associated with the window 4. mutter calls the plugin to start the animation to display the window 5. gnome-shell do not display animation for dialog windows (which is the type of the screenshot window), mutter is notified of the end if the animation 6. a pixmap is attached to the mutter actor 7. the sync_request_counter passes from 0 to 1 8. the sync_request_counter passes from 1 to 2 and a redraw cycle is triggered I believe the time it takes to the application to set sync_request_counter to 1 is taking too long for some reason. Most applications seem to be able to set the sync_request_counter to 1 before the mutter creates the ClutterActor associated with the window. Therefore the window isn't presented to the user until its content is painted at least once. I remain convinced that there is a race condition somewhere in the compositor, that sometimes least the window completely blank with no decoration painted, but lately I can't reproduce this. Anyway, removing the delay between setting sync_request_counter to 1 and the first XMapWindow call seems to completely prevent the race to happen and it really makes sense to me not display anyway until we've painted at least a frame. Attached a GTK+ patch to remove the latency.
Created attachment 246762 [details] [review] GdkWindowX11: Prevent non renderered window to be display by the compositor
*** Bug 708089 has been marked as a duplicate of this bug. ***
Review of attachment 246762 [details] [review]: ::: gdk/x11/gdkwindow-x11.c @@ +328,2 @@ static void +gdk_x11_window_begin_frame (GdkWindow *window, gboolean first_frame) I'd call the boolean force_frame rather than first_frame. @@ +349,3 @@ + } + else if (impl->toplevel->configure_counter_value != 0 && + impl->toplevel->configure_counter_value_is_extended) This needs to be *before* the check for force_frame @@ +949,2 @@ /* Start off in a frozen state - we'll finish this when we first paint */ + gdk_x11_window_begin_frame (window, TRUE); This brings up the fact that this is in the wrong place. We want to begin the frame before we *map* a window, rather than when we create it - because it should apply every time we map a window, not just the first time. So I think this belongs before the call to XMapWindow() in gdk_window_x11_show(). But that should be a separate patch from this - so I think if the above is fixed, this should be good to go.
Created attachment 255830 [details] [review] GdkWindowX11: Prevent non renderered window to be display by the compositor
Created attachment 255831 [details] [review] GdkWindowX11: Prevent non renderered window to be display by the compositor
Review of attachment 255831 [details] [review]: Looks good other than one style thing ::: gdk/x11/gdkwindow-x11.c @@ +327,2 @@ static void +gdk_x11_window_begin_frame (GdkWindow *window, gboolean force_frame) in GTK+, parameters on separate lines, aligned
Comment on attachment 255831 [details] [review] GdkWindowX11: Prevent non renderered window to be display by the compositor Pushed to master and 3.10.