So, my question is: How do I make SDL_Flip() not miss VBlanks? or,
Why does SDL_Flip() miss VBlank even when it has plenty of time to
wait for it?
This basically sounds like an OS, driver and/or hardware problem - and
I’m afraid there’s nothing much to do about it, short of taking
Linux/lowlatency, hacking the drivers and running your application and
the X server at real time priority.
We are still not focussing on his issue with this answer, though: How
does he make it work with the currently available solutions? No other
kernels/drivers/hacked-solutions will work, because people who download
his ‘game’ will not be able to run it the same way he does. Please
remember we are creating games for people to play, not for some
custom-hacked OS-specific solution…
Right, but at first, the problem seemed to be related to his system,
rather than his program - which doesn’t seem to be the case, though.
You may disregard the rest of that post as speculation based on
insufficient information.
First, kill off any background applications that might want to do
something every now and then. Because you’re basically hogging the CPU
100%, Windows will just stop your process and let the others run until
they block, whenever they wake up. Not even WinNT “real time” priority
will entirely protect you from that, and it seems like Windows is too
stupid to do the right thing regardless of whether retrace sync is
done by busy-waiting or proper (IRQ based) blocking.
It’s not Windows that is stupid here: It is assuming you are waisting
the OS time, and punishes you for that. Windows assumes all
applications should work together, with respect to each other. If you
want a real-time OS, don’t use Windows. Or do not expect that behaviour
from Windows, which would make more sense. Since a lot of people are
using Windows, let’s just keep it at Windows then. And after, that,
respect the shortcomings of the OS, don’t complain about it all the
time, instead try to find a way to live with it. No bashing about it’s
process/thread-priority- handling will help anyone to make smooth
games. A proper solution-suggestion would do better.
I have suggested “proper” solutions as well, but one isn’t supported by
SDL, and probably won’t be any time soon, and all other attempts seem to
be futile here. Neither the OS, nor the theory behind the solution is
wrong - the implementation is.
Another thing you might check is how much of the frame time is used
for rendering. (This includes any “fake” flipping with blits!)
Fake flipping with blits? How does this apply to Windows then… He is
just flipping hardware-wise, no fake or anything like that. This is
Windows… Not some X-bla-bla-Free86-version-6-point-9999 build not
supporting hardware-double-buffering.
So, how would you go about doing h/w pageflipping if the application
requests a bit depth not supported by the video card…?
Besides, AFAIK, XFree86 doesn’t support h/w pageflipping yet, regardless
of build, configuration or version. Nor does Windows in windowed mode.
Likewise for most other targets.
If you’re
using too much, that would explain why even the slightest “hickup”
that delays your game will result in a dropped frame - you simply
can’t render and flip in time, if you’re too late!
Ah, and that’s very true, indeed.
Triple buffering should help a lot, if this is the problem. As an
alternative to hacking a (currently) DirectX specific feature into
SDL, you could try using OpenGL (directly or through glSDL), as that
inherently adds a great deal of extra buffering (ie more “slack”) in
the form of the accelerator command buffer.
Triple buffering will still get you hooked up if you can’t manage to
finish the third buffer in time, although, mathematically seen, this
could only happen twice less times than with double buffering.
That’s not the whole thruth. Triple buffering means that you can actually
use the time you win during one fram, to make up for the extra time you
need for the next frame. This is not possible with less than three
buffers, unless you have significant amounts of non-rendering work to do.
Apart
from that, I would not suggest using OpenGL instead of DirectDraw all
the time: It involves a lot of work, even more than just finding a way
to work with DirectDraw/SDL properly. Also, you are almost suggesting
using OpenGL instead of DirectDraw wouldn’t be that much work, but it
really is.
This is about trying to figure out what’s going on. I’m not seriously
suffesting that anyone should write a 2D game using only OpenGL, unless
the game will make good use of the extra rendering power. Even then, a
software mode is nice, if possible to implement with a reasonable amount
of work.
There are a lot of libraries already written to do this
‘2D-in-OpenGL’-wrapping thing, which are far better than SDL, but they
are just not always better, let alone the same. Don’t underestimate
OpenGL, I would say!
Actually, I don’t think there is much point with 2D-on-OpenGL wrappers at
all. Note that glSDL as in implementation of the SDL API on top of
OpenGL, which is quite different. No new API to learn. Eventually, you
won’t even have to recompile SDL 2D code to use OpenGL. That’s the whole
point. If you want more than that, use OpenGL.
If nothing helps, I’m suspecting that your driver is straight polling
the retrace status, which will result in missed retraces if there’s
as much as a kernel driver IRQ in use. You could try to find another
driver and/or video card, that does retrace sync in a more reliable
way… (If the hardware somehow buffers the retrace “event”, it
shouldn’t matter if the driver is a few ms late - the “event” will
still be there for the driver to see. A card with retrace IRQ would
have been just fine - if there were any these days… heh)
Well, I wouldn’t say this is happening on a Windows system, since these
drivers always, currently, deliver rock-solid steady framerates,
without any artifact visible. And again: What is the use of having 1
card that fits your needs, when no one else has that card?
None whatsoever. (Unless you’re building arcade machines, or
something…) That wasn’t the point.
You can code
an application that behaves correctly with your graphics card, but
almost no one else will be able to use it. I do not think that the
original question was how to get smooth-running frames on one set of
hardware, but how to do it on any kind of hardware… So this IRQ
business is not of relevance here, then.
Again, this is just general rambling on what might have been going
wrong in this specific case.
All in all, I understand that some people are frustrated by the
incompatibilities between several hardware-drivers and OS’s, but let’s
please keep that seperate from this mailing list. What I mean is, if
someone asks how to get proper double-buffering work, don’t brag about
how current hardware is non-compliant to some VBlank-IRQ issue or
something like that, but let’s please help this person how to get this
working with the current solutions available. Letting people know you
know your business is fine, but please, let’s keep it short, and
especially, not repeated all the time: We know by now that some OS’s
are not meant for full-screen vsync’ed framerates, let’s focus on the
next big thing: How do we live with that fact? Instead of complaining
about it…
So, help each other out, don’t distract from the subject all the time?
Right, sorry about that.
//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 Sunday 24 March 2002 06:12, Martijn Melenhorst wrote: