views:

1608

answers:

4

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.

+29  A: 

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

John JJ Curtis
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.)
chaos
Nice vertical reputation graph. You're quite the bounty hunter. :)
chaos
Yea, surprised they don't have a badge for that!
John JJ Curtis
http://stackoverflow.uservoice.com/pages/1722-general/suggestions/110435-bounty-hunter-badges :)
chaos
So are you developing a game on your own or are you part of a team creating a game?
John JJ Curtis
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.
chaos
+1  A: 

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 :-)

20th Century Boy
+1  A: 

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)

chris166
+2  A: 

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.

Captain Lepton
The best 'lost device', is the one caused by a driver upgrade ;-)
Steve Lacey
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.
Captain Lepton