|
There are definitely some gotchas to this simple approach to vertical sync'ing. I believe that native call I make simply spins in a tight loop, polling the facility that does the vertical retrace until it's ready; not the usual approach to robust multi-threaded code.
Unfortunately, you definitely have to do this on your rendering loop because you want that sync call to happen as close as possible to the time when the bits are copied to the screen. Tossing it onto a different thread would defeat the purpose entirely.
Trying to sync up your repaint time and the vertical refresh rate is a good goal, but it's not sufficient; without knowing exactly when that beam will be moving down the screen, you cannot know when is a good time to touch the onscreen pixels.
One approach is to do your heavy (non-rendering) lifting on other threads so that that stuff could theoretically happen in parallel. Another thing to consider is calling any available API to check where the vertical retrace is, and to go do some other work until an appropriate time. An example is the GetScanLine() function in that same IDirectDraw7 object that the demo code uses to call WaitForVerticalBlank(). GetScanLine will return the current line being scanned, and your code could decide to go do something else, or to sleep and let other threads do their thing, before you synchronize on the vertical blank.
There are other things about the vertical retrace sync that are far from perfect. Did anyone notice that the frame rate was radically reduced? If you crank down the resolution (up-arrow key) and get the animation really kicking, you should be well over 100 fps, or as fast as the Thread.sleep(0) can noop and the rendering loop can draw things. But when you enable vertical retrace, you're pegged at the frame rate of the monitor. Or even worse, you sometimes get less than that rate because of the timing mis-match between when you ask for the sync and when it occurs; if you happen to ask for it right after it occurred, you'll wait for nearly an entire frame before your request succeeds. The result is a much smoother animation because of the flicker reduction, but a much less fine-grained animation because the frame rate went down.
So I don't think this approach is for everyone. It's just another tool in the box to consider. The other techniques outlined here are potentially eaiser to implement and may provide bigger bang for the buck; smoothing out the edges, motion blur, and non-linear movement can go a long way toward making vertical refresh flicker irrelevant.
|