Frame rate issues (early handmade hero-related)

Hey everyone,

I am currently using the early HH streams to help me build a platform layer so that I could build a simple game on top of it. Currently what it does is it just displays the weird gradient.

What I noticed was that:

1. The time that it needed to sleep every frame in order to enforce 60fps may vary significantly for no obvious reason (Like, normally it requires 4ms to finish off the drawing and then it sleeps for 12ms, but sometimes it can take 10ms to draw).

2. The movement of the gradient was smooth most of the time but occasionally it jerked (can it be related to the blit not being synced to the monitor refresh rate?)

3. Usually it took exactly 16.67ms per frame but sometimes it was 16.69 or 17+.

I'm out of ideas why those things are happening. If anyone could please give me a hint I would appreciate it very much. Attached is the full code - it is based on HH early code, but different. If you run it, there are logging calls that demonstrate the timing issues.

I've had a look at the HH code from the day 19 (after the frame rate was fixed) and looks like there's a similar problem there too, but it's doing much more than just drawing weird gradient.

Thanks.

Edited by Ivan Ivanov on Reason: Added build.bat
This is not something I would really worry about right now, because the preliminary platform layer is using a very antiquated method of blitting the results to the screen which is not going to be a very stable way of ensuring 60fps. When we update to going through a 3D API (even for our hand-written rasterizer) to update the display, that would be the more appropriate time to start tracking down display hiccups of this format, because then we will be actually calling through to a system that can use the vertical blank to time the video presentation.

- Casey
Thanks Casey, I've definitely stopped worrying about it already.

But I would really like to know the reasons why this way of blitting is not supposed to be stable enough. I mean, it's just a bunch of memory writes, every time exactly onto the same block of memory (maybe it's unrelated, but probably you'll get fewer cache misses due to that?)

Is it because of Windows interrupting the process by its own things intermittently? I'm talking about the difference in time it takes to blit and stretchdibits frame to frame, not about the jerking on the screen, though they seem to correlate in time.

I would really appreciate if you or anyone could tell me more about that.

Thanks!
Well, there's two reasons really.

One is that Sleep() is not a soft-real-time capable call, so really, the operating system is under no obligation to _actually_ wake you up in any approximation of the time you pass. It's purely a hint to the scheduler. So, in a high-performance scenario, you never really want to sleep this way, you want to sleep on the GPU, and have it wait on the monitor refresh, so that you only actually yield time to the system when you are far enough ahead of the monitor to be sure you don't need any time, and where the OS knows you are not "sleeping" idly.

The other is that we are going through Windows' compositor to show our graphics, and we don't really know if we are synchronized with it or not. So, depending on where we "hit" its processing when we try to upload our bitmap, we may be ahead of its work for the next frame, and we'll get shown, or behind it, and we will get pushed to the frame after. So you really don't want to be going through something like StretchDiBits these days, because it's simply not something suitable for consistent frame output. We're only using it right now because it is very simple and easy to understand, so I could show people how the pixels that we write go directly out to the OS and I don't have to explain a huge 3D API pipeline until later on in the process when everyone is more comfortable and has been programming Handmade Hero for many hours.

Hope that makes sense...

- Casey
That makes a lot of sense, thanks so much.

So we're kind of back to the 80s but not really