Open AnyOldName3 opened 1 month ago
Would it be possible to have a dedicate background thread associated with Win32_Window.cpp that polls the events?
The messages arrive in the thread that created the window. I don't know if we could move loads of stuff to a helper thread so that everything was dealt with by a background thread - that seems complicated and potentially fragile. I did have a look at what glfw does in case it's got a brilliant system to make the problem go away, but at least with how VulkanTutorial uses it, it's got the same problem as we do where new frames aren't drawn during the resize.
I've had a look at the typical approaches for getting rid of this problem with GLFW, and they are:
As discussed a few days ago, resizing the window on Windows is supposed to continue drawing frames during the resize, but doesn't, and instead, the last frame just gets bilinearly scaled to fit the window until the mouse is released.
I've done some investigation, and the reason for the current behaviour is that the default window message handlers aren't leaving the stack until the resize has finished. That means that the resize events just get queued up in a buffer and then all happen in quick succession between frames. That's particularly bad as each of the buffered resize events triggers regeneration of all pipelines, and those new pipelines will go unused except for the final resize, although with #1268 or equivalent, that would stop happening.
If we were to do things by the book, then instead of having the current
main loop, we'd have something more like
Win32_Window.cpp
'sand all the calls to the viewer would be done in response to a
WM_PAINT
message.Windows is sending a
WM_PAINT
message several times during a resize to tell us to draw a new frame, but because theviewer->handleEvents()
call hasn't returned, we can't.For comparison, I checked what the OSG did, and its behaviour was arguably worse - it didn't do the bilinear scaling, but did still stop rendering frames, so you'd end up with this ugly mess:
vsgQt's
vsgqtviewer
avoids the problem because it basically doesn't use a typical VSG main loop, instead letting Qt have control over the main loop. Qt internally has something relatively similar to a by-the-book Win32 window event pump as its main loop, and fits its own work within it, e.g. interleaving the timer event that triggers a redraw into its event queue.I'll look into ways to solve this and hope there'll be something that doesn't require the message pump to become the main loop.