[SDL] timing issue

David Olofson david.olofson at reologica.se
Tue Sep 17 02:55:00 PDT 2002

Ah, my favourite subject again! ;-)

On Tuesday 17 September 2002 06:04, Gijsbert Stoet wrote:
> Is there a way to precily tell when the screen shows what you want
> that you show?

No, not with any mainstream Linux drivers apart from svgalib, AFAIK. (And 
I would say you shouldn't rely too heavily on svgalib's retrace sync 
either... See below.)

> Now here is my question: Is there a way to find out when exactly
> something is presented on the screen with SDL?

No. In fact, no mainstream API I know of can tell you the exact display 
time for each frame. They can't even tell you how many video refreshes 
have elapsed, or whether you've missed any!

The closest you get is when using h/w double buffering
(SDL_HWSURFACE | SDL_DOUBLEBUF), which will cause SDL to retrace sync the 
flips, *provided* it's supported by the underlying API. On Linux, that 
basically means svgalib, or patched drivers.

> From the archives I
> understand there is no direct access to low level vsync information,
> but maybe you can suggest some other solution. Thanks!

Either hack your drivers (and make sure SDL makes use of your hack), or 
perform retrace sync on the application level.

Either way, it's a bit hairy to get right, since you can't rely on IRQs 
these days. All you've got is a single bit in a VGA legacy register 
(which may not work in non-VGA modes on some cards!), and this bit is 
active only during the actual retrace. If you miss it while polling, you 
drop a frame, and without looking at some timer (TSC, SDL_GetTicks() or 
something), you won't even know about it!

As if this isn't bad enough, polling for real time events (CPU hogging!) 
defeats the purpose in any multitasking OS. The scheduler will think that 
you're just doing some long winded internal calculations, and assumes 
that it doesn't matter much *when* you get to do it. Of course, that 
means that you'll lose the CPU for hundreds of ms - and miss several 
retraces - as soon as any other process has something to do.

My suggestion would be to do the retrace (or "vblank") polling in a 
background daemon (that effectively replaces the kernel idle thread), 
grab the current time before and after each "hit", and feed the data into 
a PLL.

You should measure or otherwise figure out the actual refresh rate during 
initialization. The PLL will basically just lock a synthetic "frame 
clock" to the actual refresh rate, and in my experience, you could get 
away with no more than one correctly timestamped "event" every few 
*minutes*. It's not like the polling thread needs to hog the system to 
extract useful data. :-)

Then, set up the Linux RTC device at a fixed rate - significantly higher 
than the video frame rate for accuracy - and hook a high priority 
SCHED_FIFO daemon up to it. The daemon should communicate with the 
retrace PLL, and stay in sync with the retrace that way.

Another, much simpler, but more drastic method would be to install 
RTLinux or RTAI, and set up one-shot thread that wakes up right before 
each retrace is expected (just a few tens of µs should do), polls until 
the retrace bit changes, writes something nices to an RT FIFO and then 
goes to sleep again, waiting for the next retrace. RTlinux and RTAI 
reprogram the PIT (or APIC if present) for accurate "dynamic" timing, so 
you're not restricted to 64, 128, 256,... Hz or anything like that, as 
you are with the RTC. And of course, RTlinux and RTAI provides the kind 
of scheduling latency guarantees need to pull this method off.

Regardless of sync method though, there's still one major issue: Page 
flipping. Without h/w page flipping, you're going to have a hard time 
doing smooth and tearing free animation.

"Half buffering" is a handy trick if you can't find a driver that 
supports h/w page flipping. Sync in the middle of the refresh, render the 
upper part of the screen, sync to the retrace and then render the lower 
part of the screen. Loop. This can work *very* well, but of course, you 
need fillrate to keep up with the refresh rate.

//David Olofson --- Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
|      Multimedia Application Integration Architecture      |
| A Free/Open Source Plugin API for Professional Multimedia |
`----------------------------> http://www.linuxdj.com/maia -'
.- David Olofson -------------------------------------------.
| Audio Hacker - Open Source Advocate - Singer - Songwriter |
`-------------------------------------> http://olofson.net -'

More information about the SDL mailing list