GNOME Bugzilla – Bug 701224
Regression: Full screen video games are not unredirected
Last modified: 2013-08-11 09:04:03 UTC
I recently installed Fedora 19 Beta to try out the new fullscreen unredirect heuristics. It doesn't work at all. I'm trying Left 4 Dead 2 Beta on NVIDIA proprietary drivers. Even though I have disabled v-sync, the game is still synced (because the shell is actually still compositing the game). I get the same FPS in gnome 3.8 as in gnome 3.6 (with compositing enabled!). The problem is that I cannot turn off compositing in 3.8 since metacity is removed. It's kind of useless for game play. I get 20 FPS in 3.8 and I should get like 50 as in gnome 3.6 with metacity. As you know, I was involved in testing this new heuristics and it worked when I tested it. Now, it has somehow regressed totally. When I first installed Fedora 19 Beta, it seemed to work because the volume OSD did not appear when running fullscreen flash video, but then I did a full system update (which updated gnome-shell). After the update, OSD is displaying when I change volume in full screen games and flash. I don't know how to downgrade gnome-shell? It may be this last update that regressed the unredirect heuristics. Anyhow - it doesn't work at all now. Should the OSD appear when changing volume in a unredirected fullscreen app? Unredirected windows should not be able to display OSD because that needs a compositor. Is the window being composited for a short while and then unredirected again after the OSD disappears?
I have looked at this now. This is indeed a regression caused by the new tray icon code. We only unredirect windows when they are on top of the stack. Now tray icons are put on top of the stack which prevent windows from being detected as being on top of the stack. Steam uses a tray icon which causes steam games to be pretty much always hit by this.
Created attachment 245602 [details] [review] shell-gtk-embed: Lower tray icon windows to the bottom of the stack Otherwise they break the "top level window" detection used by the unredirect code in mutter, causes game windows not to be unredirected when tray icons are present.
Created attachment 245603 [details] [review] shell-gtk-embed: Lower tray icon windows to the bottom of the stack Otherwise they break the "top level window" detection used by the unredirect code in mutter, causes game windows not to be unredirected when tray icons are present.
Review of attachment 245602 [details] [review]: OK.
Attachment 245603 [details] pushed as 0509bb9 - shell-gtk-embed: Lower tray icon windows to the bottom of the stack
(In reply to comment #0) > I recently installed Fedora 19 Beta to try out the new fullscreen unredirect > heuristics. It doesn't work at all. Should be fixed in master and 3.8.3 once it gets released (should be soon (tm)), thanks for the report.
Great. But the question about OSD - will an unredirected window show volume OSD if I hit the volume media keys during fullscreen gameplay?
The window would have to be temporarily redirected again, as we need to blend the OSD against the window. For certain cases like Alt-Tab, we consider the additional performance drop not too bad during compositing, but we currently do not temporarily redirect for the OSD window. We may change this decision in the future.
(In reply to comment #8) > The window would have to be temporarily redirected again, as we need to blend > the OSD against the window. Yes in 3.6 this has been the case because the window would show on top of the stack, now the osd window is no longer a window so this wont happen but easy to fix.
Created attachment 245617 [details] [review] osdWindow: Disable unredirection while showing the OSD This allows OSDs to be visible even when displayed on top of unredirected windows. --- In 3.6 this worked because the OSDs where windows (and thus push the unredirected window of the top of the stack causing it to be unredirected while the window is shown). Now that we no longer use a window we have to do it by hand (like with that patch).
(In reply to comment #9) > (In reply to comment #8) > > The window would have to be temporarily redirected again, as we need to blend > > the OSD against the window. > > Yes in 3.6 this has been the case because the window would show on top of the > stack, now the osd window is no longer a window so this wont happen but easy > to fix. Sorry for the spam bugzilla didn't respond so I wasn't sure whether the comment went through.
Yeah, I'm wondering if it makes sense to disable unredirection when we have any chrome actors showing, that is, make it automatic as part of layout.js.
(In reply to comment #12) > Yeah, I'm wondering if it makes sense to disable unredirection when we have any > chrome actors showing, that is, make it automatic as part of layout.js. Wont work think of multimonitor. If you have the unredirected window on a non primary monitor the top panel (chrome) would always disable unredirection in that case.
Are you working on a fix or should I try attachment 245602 [details] [review] or 245603? They are marked obsolete and nothing has been committed to git. The bug was marked resolved but is now unconfirmed. I really want this feature to be part of Fedora 19.
Ah. Looked at the mutter git, not gnome-shell git :P
Review of attachment 245617 [details] [review]: Makes sense.
Attachment 245617 [details] pushed as 24703ff - osdWindow: Disable unredirection while showing the OSD
After this fix (I think is this) I tried to play fullscreen Heroes of Newearth with open source NVidia drivers. If I now press <Super> to switch workspace display stays on game without having any focus (ie I can't click anything). The only way to exit this screen is to jump to console (Alt+F2) and manually kill the game there.
(In reply to comment #18) This is in Fedora 19
I ran Fedora 19 with gnome-shell 3.8.2 when I first reported this bug. When 3.8.3-2 came, I updated to that version and tried L4D2 Beta. I noticed that the volume OSD made the game flicker black and I actually came up with the conclusion that unredirection was the opposite of what is supposed: when I ran the game I got 40 FPS and v-sync, but when I changed volume causing the OSD to appear I got 60+ fps and tearing during some seconds (the time OSD i showing). The game was set to not v-sync. I think you have mixed up the unredirection: you turn it On when OSD is Showing and you turn it Off when it's Not showing. I'm not 100% sure because I only updated gnome-shell and mutter to 3.8.3, all other packages was left at the old versions. After updating all packages, my system went into "Ooops mode" and I could no longer use that computer and I don't have the time to reinstall Fedora 19 and test once more. Could you please check this up? I'm 100% positive unredirection was messed up that time, but I don't know the reason - might be because I didn't update the whole system, might be a mix up in your patch. I'm not blaming anyone but the GNOME dev team might need to update the tests you run before releasing GNOME versions. New GNOME releases tend to fix some bugs and reintroduce some. You can easily test unredirection by running an OpenGL app in non-v-sync and see if it tears - that's how I determine unredirection. If the app is syncing then it must be composited by the shell. Peace.
Created attachment 246963 [details] [review] compositor: Track top_level window during stacking We have added a hack to gnome-shell to force tray icons to be always stacked at the bottom. This does not seem to work in all cases. So set the top window during stacking while excluding our own windows. This way we skip the tray icons and don't have to traverse the window list every time we want to query the top window.
(In reply to comment #20) > I ran Fedora 19 with gnome-shell 3.8.2 when I first reported this bug. When > 3.8.3-2 came, I updated to that version and tried L4D2 Beta. I noticed that the > volume OSD made the game flicker black and I actually came up with the > conclusion that unredirection was the opposite of what is supposed: when I ran > the game I got 40 FPS and v-sync, but when I changed volume causing the OSD to > appear I got 60+ fps and tearing during some seconds (the time OSD i showing). > The game was set to not v-sync. No that's not it. It seems that the "lower to the bottom of the stack hack" does not always work. I have attached a better patch that should always work.
Created attachment 246965 [details] [review] Revert "shell-gtk-embed: Lower tray icon windows to the bottom of the stack" This reverts commit 0509bb9bb4dd60558a4011ae18fc93a38d87fedf. Does not really fix the bug.
Jasper suggested on IRC to just revert the tray icon commit i.e https://git.gnome.org/browse/gnome-shell/commit/?id=5001bd881048103ae18a721b29f93ad9b9e06f5d
Created attachment 247208 [details] [review] compositor: Subtracting one from an usigned integer containing 0 is a bad idea I have no idea how this survived unnoticed for that long. This should never happen because it means there is an unmatched enable / disable pair somewhere. So in addition to fixing it add a warning when this case gets triggered.
Created attachment 247211 [details] [review] compositor: Prevent an error in application code from keeping unredirect on permanently We substract one from the unredirect counter when enable_unredirect_for_screen gets called. It is an unsigned integer so substracting one from zero (which means enable) would overflow and thus keep it peramently enabled. This should never happen because it means there is an unmatched enable / disable pair somewhere. So in addition to fixing it add a warning when this case gets triggered. ---- Fix commit message.
Attachment 247211 [details] pushed as 2a5b068 - compositor: Prevent an error in application code from keeping unredirect on permanently
Is that counter thread safe? Adding a mutex for enable / disable might be a good idea if you aren't sure where the mismatching enable/disable is. It might just be race condition?
mutter in general is not thread-safe. We never call that function from multiple threads. The answer is that somehow we're calling enable_unredirect_for_screen when we shouldn't have. That should have been a no-op, but it overflowed and the mutter thought that unredirection should be disabled. We're looking into why it's being called in a place that doesn't make sense right now.
(In reply to comment #28) > Is that counter thread safe? No and does not have to be as we only call it from a single thread (like pretty much everything in mutter, see Jasper's comment). > Adding a mutex for enable / disable might be a > good idea if you aren't sure where the mismatching enable/disable is. It might > just be race condition? Nope already tracked it down: https://git.gnome.org/browse/gnome-shell/commit/?id=9e44978aed39a5bade75fa17450438d87f4c3c8f https://git.gnome.org/browse/gnome-shell/commit/?id=580bd67278404cc64e5303678c8f807586e6e63e
Nice job finding this. Will there be a new release soon? 3.8.4?
(In reply to comment #31) > Nice job finding this. Will there be a new release soon? 3.8.4? There will be at some point. This is up to Florian ...
Could you please point what patch(es) net to be applied or removed to get unredirection working again? I'm little weird now :-) Base assumption: gnome-shell-3.8.3
(In reply to comment #33) > Could you please point what patch(es) net to be applied or removed to get > unredirection working again? I'm little weird now :-) > > Base assumption: gnome-shell-3.8.3 Either: https://git.gnome.org/browse/mutter/commit/?h=gnome-3-8&id=7b36dcf4a06bbb69231ab360356c269f9e7ccce8 (mutter) or https://git.gnome.org/browse/gnome-shell/commit/?h=gnome-3-8&id=4d785d249f149e2d90813df264c1833d53447714 (gnome-shell)
Thank you!
I've taken the patch for gnome-shell and it works for me! For subsequent readers: If you decide to use the patch for gnome-shell , it is necessary to add "})" and increment the modified-line counter. Otherwise you will cause a syntax-error and GDM won't be able to startup. See here: https://git.gnome.org/browse/gnome-shell/tree/js/ui/osdWindow.js#n173
(In reply to comment #36) > I've taken the patch for gnome-shell and it works for me! > > For subsequent readers: > If you decide to use the patch for gnome-shell , it is necessary to add "})" > and increment the modified-line counter. Otherwise you will cause a > syntax-error and GDM won't be able to startup. That's https://git.gnome.org/browse/gnome-shell/commit/?h=gnome-3-8&id=1aac5c43e41435e5ce7da0fa44935768558f6d5c
Thanks for pointing that out. I tried the gnome-shell patch but just got the "Ooops mode". Reinstalled and reapplied together with the syntax error fix. Now I have perfect unredirection. However, if I change volume during game play the game sort of gets all black and never returns to normal :( Have to force exit and restart. Testing Portal 1 on Bumblebee laptop. 3.8.3 + the two patches to gnome-shell.
Games just freeze up if you change volume (OSD). Tried Little Inferno also, rendering completely freezes forever until you force kill the game. OSD rendering is fine above the game but the game is frozen.
This is far from fixed. Still, in 3.8.4 games hang if you change volume during game play. 1. alt + f2, r, enter (restart gnome-shell) 2. open terminal, type glxgears -fullscreen 3. change volume using media keys 4. glxgears hangs (as do all OpenGL apps, some even crashes) Different behavior when doing this more than once without restarting gnome-shell. I'm using mutter 3.8.4 and gnome-shell 3.8.4 from Fedora 19 updates. In other news - 100 full damaged frames is too much for turning on unredirection. For v-synced apps that's 1/60 * 100 = 1.66 seconds aka almost 2 seconds of tearing before unredirection comes on. Starting a Valve game gives me tearing for 2 seconds before unredirection comes on. That means the starting video is tearing for 2 seconds. Make the frame count like 5 instead of 100 please.
* Remember to wait 2 seconds between steps 2 and 3, obviously. 100% reproducible.
(In reply to comment #40) > In other news - 100 full damaged frames is too much for turning on > unredirection. For v-synced apps that's 1/60 * 100 = 1.66 seconds aka almost 2 > seconds of tearing before unredirection comes on. > > Starting a Valve game gives me tearing for 2 seconds before unredirection comes > on. That means the starting video is tearing for 2 seconds. Make the frame > count like 5 instead of 100 please. You got this backwards. A redirected window should not tear unless the driver does not support the buffer_age extension and a fullscreen blit takes longer then the refresh interval. Unredirection is not supposed to fix tearing (in most cases it *causes* tearing). As for Valve games they use SDL2 which started to set the BYPASS_COMPOSITOR hint recently see http://bugzilla.libsdl.org/show_bug.cgi?id=1852 so it does not need any heuristic once an updated SDL2 is available. > Make the frame count like 5 instead of 100 please. No that catches way to many app. 5 frames do not tell us "this is a fullscreen opengl game".
Yeah I know about how it works. The fact is that games actually tear when being composited but not when being unredirected. Mesa drivers lack buffer age I guess. Great thing they are doing a flag nowadays. But you still need to fix the other issue where games hang if you change volume.
Should I open a new bug for the hang issue and close this one again?
(In reply to comment #44) > Should I open a new bug for the hang issue and close this one again? Yeah lets not mix two different issues in one bug.