Vertical Retrace

Is there a function incuded with SDL that will wait for the verticle
retrace to start so I can draw my screen and things won’t look so jumpy?
There was a similar function in Allegro called vsync(). And if there is
not one, where might I find out how to make one?

  • Mik Mifflin

On hardware that supports double-buffering, SDL_Flip does:
http://sdldoc.csn.ul.ie/sdlflip.php

Other than that, I think you just need to come up with something on your own
(or use one of the many add-on libraries that include functions like this).

One very quick and dirty way of doing it is by using SDL_GetTicks after each
screen update, and comparing it to the value it returns after you have
performed whatever you need to between refreshes, and SDL_Delay’ing the
difference. Or something like this:

void waitframe(void) {
static Uint32 next_tick = 0;
Uint32 this_tick;

this_tick = SDL_GetTicks();
if (this_tick < next_tick) {
    SDL_Delay(next_tick - this_tick);
}
next_tick = this_tick + (1000 / FRAMES_PER_SEC);

}

(Bear in mind this is Quick’N’Dirty, and there are much more sophisticated
ways to do it. This also doesn’t garantee a very consistant frame-rate, but
for many purposes, it’s “Good Enough”.)On Friday 13 July 2001 10:43pm, Mik Mifflin wrote:

Is there a function incuded with SDL that will wait for the verticle
retrace to start so I can draw my screen and things won’t look so jumpy?
There was a similar function in Allegro called vsync(). And if there is
not one, where might I find out how to make one?


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

Here we go again… :slight_smile:

No, you can’t get SDL to explicitly sync with the retrace (seems
that most targets cannot support that anyway), but SDL_FlipSurface()
does it when possible. (Someone will have to fill in the details here

  • I’m not sure when SDL is supposed to sync; I’m just aware that it
    never does on any Linux targets but svgalib, because these targets
    don’t support it…)

On Windows you can get retrace sync when using DirectX. (Possibly
even in windowed mode - not sure.) On Linux, you have to use the
svgalib target, OpenGL on X, using a driver with retrace sync, or you
own retrace sync code.

I have some retrace sync code lying around, with TSC timing to deal
with the fact that you miss lots of retraces (due to the stupid way
the VGA retrace bit works), but 1) you need to be root to get access
to the VGA port, 2) you need to take additional measures to produce a
tearing free display (“flipping” is done by blitting the back buffer
to screen on X), and 3) my timing code could use some more tweaking.
(I’m working some on the game I wrote it for, so there’s hope! :slight_smile:

Anyway, the proper way to do smooth animation on modern computers (ie
with multitasking and other crap :wink: is not to have the entire engine
sync with the retrace, but to have the driver sync the flip! This,
in combination with triplebuffering (or more), makes it possible to
produce rock solid animation even at near 100% CPU load, as long as
the driver (or the video hardware) does it’s job properly. No need
for hard real time scheduling for the rendering engine.

Of course, this increases latency a bit, but fortunately, the eye is
a lot slower than the ear, so video programming is rather forgiving
compared to audio in this respect. (Meanwhile, it’s possible to do
rock solid audio processing with <3 ms latency on slightly modified
Linux kernels these days, so there’s no theoretical excuse for video
lagging behind like this. We’re dealing with driver and architecture
limitations.)

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Saturday 14 July 2001 00:43, Mik Mifflin wrote:

Is there a function incuded with SDL that will wait for the
verticle retrace to start so I can draw my screen and things won’t
look so jumpy? There was a similar function in Allegro called
vsync(). And if there is not one, where might I find out how to
make one?

On Windows you can get retrace sync when using DirectX. (Possibly
even in windowed mode - not sure.) On Linux, you have to use the
svgalib target

Actually SDL supports waiting for sync on flip with almost every driver
that does hardware double-buffering. Including accelerated framebuffer
console, DGA 2.0, etc.

See ya,
-Sam Lantinga, Lead Programmer, Loki Software, Inc.

Speaking of this, is there a way to determine in your app if it is being run
on a system with hardware double-buffering? (I may have asked this before,
and I may have even discovered the answer, but if I did, I’ve forgotten it :wink:

I.e., is there some return value for SDL_VideoDriverName or a param in the
return value of SDL_GetVideoInfo (or something else) that will tell us this,
so we can then choose dynamically which sync method would be best to use?On Sunday 15 July 2001 10:38am, Sam Lantinga wrote:

On Windows you can get retrace sync when using DirectX. (Possibly
even in windowed mode - not sure.) On Linux, you have to use the
svgalib target

Actually SDL supports waiting for sync on flip with almost every driver
that does hardware double-buffering. Including accelerated framebuffer
console, DGA 2.0, etc.


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

I know this has been talked about before, but SDL really needs a
WaitForVerticalRetrace routine. If the sub system doesn’t support this
feature then it can just return without waiting. In the documentation you
can keep a matrix of which systems support the function and which don’t.
You can even have it return a value saying saying everything is ok, an error
occurred or we don’t support this. This could even be a part of the
video_info structure.

In my current application I could really use this. I was sliding an image
horizontally across the screen and experienced tearing. I turned on double
buffering and went from 38 to 14 fps because I am using some alpha blitting.
I don’t want to lose the alpha blits. Eventually I plan to make it all use
OpenGL for hardware acceleration, but I would like a software version to
fall back on that doesn’t tear if possible.

Or is there something that I am missing in all of this that will solve my
problems?

Mike

I know this has been talked about before, but SDL really needs a
WaitForVerticalRetrace routine. If the sub system doesn’t support this
feature then it can just return without waiting. In the documentation
you can keep a matrix of which systems support the function and which
don’t. You can even have it return a value saying saying everything is
ok, an error occurred or we don’t support this. This could even be a
part of the video_info structure.

Well, could solve some problems, but there are three major problems:

1. Most general purpose operating systems are incapable of
   running a proper implementation of a retrace sync call.
   You need a Soft/Firm Real Time OS to get sufficient
   retrace -> wake up latency (*might* work most of the time
   on standard OSs), and you need a Hard RTOS (like RTL or
   RTAI) to emulate retrace IRQs for all the cards that don't
   have it in hardware. It's doable on Linux/lowlatency with
   RTAI or RTL, but takes some hacking.

2. Many targets don't support explicit retrace sync as a
   stand-alone call, part becaues of the above hardware
   problems, part because...

3. ..."hard" retrace sync in applications is not the way to
   do it on multitasking platforms. The right way is to set
   up at least two buffers, and have the video card or driver
   manage flipping timing. After rendering a frame, send the
   buffer off to the video card, but *don't* sync! Instead,
   try to lock the "new" buffer for rendering. This will in
   fact block your application until the new buffer is
   released by the driver - or not at all, if the buffer is
   already free.

   This way, you get one frame period of scheduling jitter
   "margin", to relax the timing requirements a bit. If you
   look carefully at DirectX, SDL and most other "modern"
   APIs, you'll notice that this is the way they're designed
   to operate.

In my current application I could really use this. I was sliding an
image horizontally across the screen and experienced tearing. I turned
on double buffering and went from 38 to 14 fps because I am using some
alpha blitting.

Then you’re doing something wrong…

Note that reading from VRAM is very, VERY slow, so never perform alpha
blending directly to the screen!

If you need alpha blending, use a software shadow buffer for the
rendering, and then blit that to the VRAM buffer - just as SDL does when
it can’t give you hardware double buffering. (This is what I call
"SemiTriple" buffering in Kobo Deluxe.)

//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 -'On Wednesday 28 November 2001 02:05, Mike Jarosch wrote: