Smooth resize on X11 using _NET_WM_SYNC_REQUEST
On X11, smooth resize requires the application to implement the _NET_WM_SYNC_REQUEST WM protocol. This PR adds such support to SDL, with exception of Vulkan windows.
Description
See the protocol description. In a nutshell:
- When a WM wants to resize a window, it sends it a
_NET_WM_SYNC_REQUESTmessage with resize ID and only then requests resize. - After the window handles the resize (updated its contents), it needs to put the resize ID into a specific “counter”.
Because resize ID and actual resize info arrive in separate messages, this PR adds two functions to handle them: X11_HandleSyncRequest and X11_HandleConfigure. After both messages arrive, resize_id will contain resize ID and resize_in_progress will be true. Now the application is expected to redraw the window and swap buffers. The latter calls X11_HandlePresent to notify the WM that the resize is handled, if one was in progress.
All other functions are supplementary.
Existing Issue(s)
Fixes #7638
Questions
- Is this implementation okay, generally?
- Didn’t I miss a way the application can redraw the window? (I’ve updated
X11_UpdateWindowFramebuffer,X11_GL_SwapWindow, andX11_GLES_SwapWindow)- Singlebuffer windows? (IIUC singlebuffer is not guaranteed so
SDL_GL_SwapWindowis still necessary in this case, so should work) - Vulkan? (IIUC SDL isn’t notified here at all, so no chance to work without an API update)
- Singlebuffer windows? (IIUC singlebuffer is not guaranteed so
- Should there be a hint for this WM protocol like there is for
_NET_WM_PING?
Thanks! Can you squash this to a single commit for review?
Thanks! Can you squash this to a single commit for review?
Done
This seems reasonable to me, @icculus?
Is the expectation that the application will have already resized the backbuffer before the next swap buffers?
Now the application is expected to redraw the window and swap buffers.
What happens if it doesn't? Like, there's a resize event while it's loading a level and it doesn't draw to the screen for 60 seconds?
Now the application is expected to redraw the window and swap buffers.
What happens if it doesn't? Like, there's a resize event while it's loading a level and it doesn't draw to the screen for 60 seconds?
Depends on the WM. E.g. KWin won’t actually resize it until it responds. But, blocking the UI thread for 60 seconds? I guess Windows™ would show “not responding” far earlier. If it processes events but doesn’t paint though... I dunno what the correct behavior would be then.
What bothers me more is if it does draw but in a way that avoids SDL and as such, X11_HandlePresent. That would be a problem too (e.g. KWin will only resize the window after a delay in this case). That’s why I disabled this for Vulkan as apparently, the way to swap buffers on it is to call Vulkan directly.
Hello, any updates on this ? For now, I implemented it my self, and it works great with vulkan, but it would be great if this was built-in
This PR looks reasonable to me. Are there any performance penalties for this PR when resizing is not active?
This PR looks reasonable to me. Are there any performance penalties for this PR when resizing is not active?
Not really, except if you consider the time it takes to check for the _NET_WM_SYNC_REQUEST a penalty (this is in micro seconds on my machine)
@numberZero, would you mind updating this PR so we can merge it for SDL 3.0?