After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 702196 - Unfinished frame being presented
Unfinished frame being presented
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: X11
3.8.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
: 708089 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2013-06-13 17:53 UTC by Lionel Landwerlin
Modified: 2013-09-26 21:20 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GdkWindowX11: Prevent non renderered window to be display by the compositor (2.21 KB, patch)
2013-06-13 18:01 UTC, Lionel Landwerlin
needs-work Details | Review
GdkWindowX11: Prevent non renderered window to be display by the compositor (1.88 KB, patch)
2013-09-26 12:58 UTC, Lionel Landwerlin
none Details | Review
GdkWindowX11: Prevent non renderered window to be display by the compositor (1.88 KB, patch)
2013-09-26 12:58 UTC, Lionel Landwerlin
committed Details | Review

Description Lionel Landwerlin 2013-06-13 17:53:14 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.
Comment 1 Lionel Landwerlin 2013-06-13 18:01:52 UTC
Created attachment 246762 [details] [review]
GdkWindowX11: Prevent non renderered window to be display by the compositor
Comment 2 Mantas Mikulėnas (grawity) 2013-09-24 12:42:11 UTC
*** Bug 708089 has been marked as a duplicate of this bug. ***
Comment 3 Owen Taylor 2013-09-26 00:08:36 UTC
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.
Comment 4 Lionel Landwerlin 2013-09-26 12:58:48 UTC
Created attachment 255830 [details] [review]
GdkWindowX11: Prevent non renderered window to be display by the compositor
Comment 5 Lionel Landwerlin 2013-09-26 12:58:49 UTC
Created attachment 255831 [details] [review]
GdkWindowX11: Prevent non renderered window to be display by the compositor
Comment 6 Owen Taylor 2013-09-26 18:53:54 UTC
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 7 Lionel Landwerlin 2013-09-26 21:19:42 UTC
Comment on attachment 255831 [details] [review]
GdkWindowX11: Prevent non renderered window to be display by the compositor

Pushed to master and 3.10.