Best practices for Alt-Tab support in a DirectX app?
Asked Answered
B

4

40

When writing DirectX applications, obviously it's desirable to support the user suspending the application via Alt-Tab in a way that's fast and error-free. What is the best set of practices for ensuring this? Things that need to be addressed include:

  1. The best methods of detecting when your application has been alt-tabbed out of and when it has been returned to.
  2. What DirectX resources are lost when the user alt-tabs, and the best ways to cope with this.
  3. Major things to do and things to avoid in application architecture for purposes of alt-tab support.
  4. Any significant differences between major DirectX versions as they apply to the above.

Interesting tricks and gotchas are also good to hear about.

Broughton answered 9/6, 2009 at 20:22 Comment(6)
The code sampler link posted below looks adequate to begin with, so I'll just add this: we've found that an easy way to test this situation is to run the app in windowed mode and lock the Windows desktop. This way you can easily test the lost device situation while running under the debugger locally.Fannyfanon
not sure why you're picking on Valve. Half-life was one of the first games I had that did alt-tab without issues. If there are issues it's probably because of DirectX itself (HL used OpenGL on my setup)Bloodthirsty
SpliFF, it was the first game that had Alt Tab issues for me, at least that I can remember. :)Conditioned
SpliFF: TF2 is notorious for alt-tab problems. I'm not sure if they've been fixed, but a common one was for a player to disappear when you alt-tabbed back into the game (which took ages - another problem). As in, you couldn't see them but they could see and kill you. I don't know if it was due to an image buffer getting cleared and not reloaded when it should have, but it made for some interesting encounters.Simon
Huh, I didn't even realize this was a problem. The only game I play nowadays (which I'm now developing also) has never had an issue with alt-tab.Bjork
I used to have TF2 Alt+Tab problems, but setting "-window -noborder" as the startup arguments solved it completely. While I wait to respawn, I'm browsing or doing something else, and I've never had a problem with graphic corruption.Simile
E
44

I will assume you are using C++ for the purposes of my answers, but if you can afford to use C#, XNA (http://creators.xna.com/) is an excellent game platform that handles all of these issues for you.

1]

This article is helpful for windows events in the window procedure to detect when a window loses or gains focus, you could handle this on your main window: http://www.functionx.com/win32/Lesson05.htm. Also, check out the WM_ACTIVATEAPP message here: http://msdn.microsoft.com/en-us/library/ms632614(VS.85).aspx

2]

3]

I would make sure to never disable Alt-Tab. You probably want minimal CPU load while the application is not active because the user probably Alt-Tabbed because they want to do something else, so you could completely pause the application, or reduce the frames rendered per second. If the application is minimzed, you of course don't need to render anything either. After thinking about a network game, my best solution is that you should still reduce the frames rendered per second as well as the amount of network packets handled, possibly even throwing away many of the packets that come in until the game is re-activated.

4]

Honestly I would just stick to DirectX 9.0c (or DirectX 10 if you want to limit your target operating system to Vista and newer) if at all possible :)

Finally, the DirectX sdk has numerous tutorials and samples: http://www.microsoft.com/downloads/details.aspx?FamilyID=24a541d6-0486-4453-8641-1eee9e21b282&displaylang=en

Eniwetok answered 9/6, 2009 at 20:22 Comment(3)
Your answer looks very solid; thanks! I believe I'm going to put this question up for bounty when the waiting period is up, since I believe it's an important topic that's lacking for coherent resources. If you're inclined to do any further edits to your answer, I'd suggest summarizing high points from the various links; it'd be nice if someone looking for this topic could get as much relevant information as feasible right in the answer. (And links are, of course, vulnerable to linkrot.)Broughton
So are you developing a game on your own or are you part of a team creating a game?Enlightenment
Reading "DirectX game" for "game", neither at the moment. A long time ago I did enough work, solo as far as code went, to know some of the issues involved. (Oh hey guys, you can use DX surfaces to do lots of your work on. Just, y'know, if the user alt-tabs they mysteriously vanish. Oops!) There might be some more of that in my future, and I was somewhat dreading trial-and-error on the issue for current DX versions, then it occurred to me: hey, that's kinda what SO is for innit.Broughton
H
2

We solved it by not using a fullscreen DirectX device at all - instead we used a full-screen window with the top-most flag to make it hide the task bar. If you Alt-Tab out of that, you can remove the flag and minimize the window. The texture resources are kept alive by the window.

However, this approach doesn't handle the device lost event happening due to 'lock screen', Ctrl+Alt+Delete, remote desktop connections, user switching or similar. But those don't need to be handled extremely fast or efficiently (at least that was the case in our application)

Helluva answered 16/6, 2009 at 20:26 Comment(0)
V
2

All serious D3D apps should be able to handle lost devices as this is something that can happen for a variety of reasons.

In DX10 under Vista there is a new "Timeout Detection and Recovery" feature that makes it common in my experience for graphics devices to be reset which would cause a lost device for your app. This seems to be improving as drivers mature but you need to handle it anyway.

Villeneuve answered 17/6, 2009 at 13:46 Comment(2)
The best 'lost device', is the one caused by a driver upgrade ;-)Gillead
Chortle chortle but seriously. Being able to handle context switching and being able to reset state is an important part of building a robust application in a multitasking environment.Villeneuve
M
1

In DX8 and 9 (and 10?) if you create your resources (vertex and index buffers and textures mainly) using D3DPOOL_MANAGED they will persist across lost devices and will not need reloading. This is because they are stored in system memory and the DX runtime copies to video memory automatically. However there is a performance cost due to the copying and this is not recommended for rapidly changing vertex data. Of course you would profile first to determine if there is a speed issue :-)

Modla answered 16/6, 2009 at 2:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.