SDL: multiple wayland windows stuck at OpenGL rendering when occluded
When multiple Wayland windows are used with OpenGL and one of these windows is entirely occluded by another window, then all windows will not receive any further callbacks at will get stuck in their OpenGL rendering loop.
Reproduce:
- run
testgl2with 2 windows:SDL_VIDEODRIVER=wayland ./testgl2 --windows 2 - hide both windows behind another window, e.g. by maximising your browser over both windows
- select one of the window to appear in the foreground
The foreground window will now show a cube that is stuck at one point in the spinning animation. Only when the other window is at least partially visible, the cubes will rotate again. This also has implications for client-side decoration as it will prevent interaction (resize, close) with that window. Both windows will also continue their animation if they are visible on a thumbnail overview, e.g. in GNOME Shell when the Activity overview is activated by the top-left hot corner or the Meta / Windows key.
The reason for this is that Wayland compositors will inhibit frame callbacks for window that are not visible, so do not update the window when its content is not shown. When multiple windows are part of a render loop, these frame callbacks have to be handled manually.
See:
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 34 (2 by maintainers)
Commits related to this issue
- wayland: don't hang in SDL_GL_SwapBuffers if the compositor is ghosting us. If you hide a window on Mutter, for example, the compositor never requests new frames, which will cause Mesa to block forev... — committed to Cacodemon345/SDL by icculus 3 years ago
- wayland: don't hang in SDL_GL_SwapBuffers if the compositor is ghosting us. If you hide a window on Mutter, for example, the compositor never requests new frames, which will cause Mesa to block forev... — committed to RetroPie/SDL by icculus 3 years ago
FWIW we do have things in the works for this, but it’s tied in with the still-WIP Vulkan extension since we want to just do it right once.
(For extreme nitpick, ‘retrace’ isn’t relevant: what’s relevant is when the compositor decides which buffer to latch for a given frame, which may be significantly earlier than actual retrace if it needs to schedule GPU work for composition. And by ‘frame’ I mean ‘present cycle’ because hello VRR … anyway.)
My vote is for 10 frames’ worth of time, based on the display’s refresh_rate value.