tags:

views:

401

answers:

4

How does XNA maintain a consistent and precise 60 FPS frame rate? Additionally, how does it maintain such precise timing without pegging the CPU at 100%?

+2  A: 

I don't know specifically how XNA does it but when playing around with OpenGL a few years ago I accomplished the same thing using some very simple code.

at the core of it i assume XNA has some sort of rendering loop, it may or may not be integrated with a standard even processing loop but for the sake of example lets assume it isn't. in this case you could write it some thing like this.

TimeSpan FrameInterval =  TimeSpan.FromMillis(1000.0/60.0);
DateTime PrevFrameTime = DateTime.MinValue;
while(true)
{
    DateTime CurrentFrameTime = DateTime.Now;
    TimeSpan diff = DateTime.Now - PrevFrameTime;
    if(diff < FrameInterval)
    {
        DrawScene();
        PrevFrameTime = CurrentFrameTime;
    }
    else
    {
        Thread.Sleep(FrameInterval - diff);
    }
}

In reality you would probably use something like Environment.Ticks instead of DateTimes (it would be more accurate), but i think that this illustrates the point. This should only call drawScene about 60 times a second, and the rest of the time the thread will be sleeping so it will not incur any CPU time.

luke
But by using Thread.Sleep, isn't it dependent upon thread scheduling? That seems to be slightly predictable at best. That's what made me wonder how they are being so consistent.
oakskc
using thread sleep does leave you at the mercy of the scheduler, but in the long run it should average out pretty well, especially after 60 frames in a second. When it comes to high precision timing on a computer you are at the mercy of the scheduler anyway, because your thread could always be swapped out at any time.
luke
A: 

games should run at 60fps but that doesn't mean that they will. That's actually an upper limit for a released game.

If you run a game in debug mode you could get much higher frames per second - for example a blank starter template on my laptop in debug mode runs well over 1,000fps.

That being said the XNA framework in a released game will do its best to run at 60fps - but the code you included in your project has the chance of lowering that performance. For example having something constantly fire the garbage collection you normally would see a dip in the fps of the game, or throwing some complex math in the update or draw methods - thus having them fire every frame..which would usually be a bit excessive. There are a number of things to keep in mind to keep your game as streamlined as possible.

If you are asking how the XNA framework makes that ceiling happen - that I cant really explain - but I can say that depending on how you layout your code - and what you can do can definitely negatively impact this number, and it doesnt always have to be CPU related. In the instance of garbage Collection its just the cleaning up of a RAM which may not show a spike in CPU usage at all - but could impact your FPS, depending on the amount of garbage and interval it has to run.

David Larrabee
+1  A: 

While luke’s code above is theoretical right the used methods and properties are not the best choices:

The current XNA FX seems to hook into the Windows message loop and execute its internal pre-update each step and calling Game.Update only if it the elapsed time since the last update matches the specified framerate (e.g. each 16ms for the default settings). If you want to really know how the XNA FX does the job Reflector is your friend :)

Random tidbit: Back in the XNA GameStudio 1.0 Alpha/Beta time frame there were quite a few blog posts about the “perfect WinForms game loop”, albeit I fail to find them now…

Bjoern
A: 

You can read all about how the XNA timer was implemented here Game timing in XNA Game Studio but basicly it would try and wiat 1/60 of a second before continuing the loop again, also note that update can be called multiple times before a render if XNA needs to "catch up".

Lavinski