Correct handling of Alt-Enter / Alt-Tab Screen resolution in full screen mode

The DXGI MSDN page provides instructions on how to handle full-screen resolutions other than desktop resolutions. It says to call IDXGISwapChain::ResizeTargets() before calling IDXGISwapChain::SetFullscreenState() to prevent flickering, by the way.

It does not say how to handle Alt-Enter, which calls IDXGISwapChain::SetFullscreenState() before the program is given the chance to make its own call IDXGISwapChain::ResizeTargets() . If the last method is called with the WM_SIZE message, another WM_SIZE message will be sent, which can cause an infinite loop. How can I guarantee that the latter will be called before the first when alt-enter or alt-tab is pressed, and that the mode switching is painless at all?

+5
source share
2 answers

It will be very difficult ... correctly, as it should be handled, IDXGIFactory::MakeWindowAssociation , which, as far as I know, no one was able to use successfully. In any case, you can try.

The "correct" answer is to manually control Alt + Enter. So, disable Alt + Enter with MakeWindowAssociation and get your hands dirty. Firstly, there is no need to capture WM_SIZE . Instead, listen to WM_ENTERSIZEMOVE , WM_CAPTURECHANGED , WM_WINDOWPOSCHANGED and WM_EXITSIZEMOVE . This will not allow you to deal with WM_SIZE and still receive all the relevant window resizing events. (At the same time, also read this question: WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE - when using the menu, not always paired )

So, assuming everything went fine, for Alt + Enter you need to do the following: you set your swap chain to full screen using IDXGISwapChain::SetFullscreenState , and then resize your swap chain ( IDXGISwapChain::ResizeBuffers ). By default, you get a swap chain that will be as close as possible to the current resolution of your window before resizing. The way you do this is to first list the permissions in full screen, and then switch to full screen mode, calling up the required resolution. It sounds ugly, but it seems to be the most reliable way to solve the problem.

In general, a real exclusive full-screen mode is not worth the trouble, since you will always flicker when someone goes over Alt + Tab (you cannot avoid this if the mode switches, as the screen itself will have to be reconfigured.) A much better solution is Use a full-screen borderless window. You simply create a class of windows without any decoration, make it full-screen, place it so that it covers the entire screen and becomes with it. Then you do not need to worry about Alt + Enter and Alt + Tab. It also allows people to continue to work on the second screen without flickering. Performance wise, that's pretty good (most new games support this as "unlimited full screen mode.")

There may be a silver bullet that solves all this correctly, but I have not seen it yet. If there is a cleaner / more pleasant solution, I would be very interested to hear that. "Unlimited full-screen mode" appears to be the current standard, although, IIRC, Unity 5 allows "unlimited full-screen mode" for Direct3D 11.

+4
source

I just want to add an update on this problem - I wrote a small window library that I think works fine with DXGI - there are no debugging messages, error messages, and everything behaves as intended, at least in my Windows environment, The complete solution to this problem is too difficult to explain in one answer, since it requires a lot of precisely placed method calls (DXGI is really, really hard, as it turns out), but I have some code on github if someone wants to take a look at it. In particular, this file and this file are the ones you want to see - the latter is the cumulative object of the former.

Note that I disabled ALT + ENTER in favor of F11 , but the functionality is exactly the same.

If you want to use this library, by the way, I will release it as free software and will soon provide documentation.

+1
source

Source: https://habr.com/ru/post/1200614/


All Articles