Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » vsync

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
vsync
23yrold3yrold
Member #1,134
March 2001
avatar

Tearing is when you do a screen update between screen refreshes. So the bottom of the screen looks like the current frame and the top of the screen looks like the last frame. They don't quite match up in the middle (or whereever), so it looks like the screen is "torn". vsync() is the standard way to avoid that. Page Flipping and Triple Buffering work too.

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

gillius
Member #119
April 2000

Yep, that's right. If you really want to see it, I'll bet you might be able to exaggerate the effect by blitting two opposite colors every other frame, without vsync on, and turning your refresh to its highest rate (something I've noticed, maybe wrong, is that the faster your computer and the lower the refresh, the less tearing is visible.)

Gillius
Gillius's Programming -- https://gillius.org/

Richard Phipps
Member #1,632
November 2001
avatar

It's not so bad with a static display, but any kind of scrolling shows the effect up badly.

Thomas Harte
Member #33
April 2000
avatar

Quote:

But "how fast the game runs when not restricted (...)" ? If your screen has a rate of 75Hz, displaying more than 75 frames per second is NOT faster, it's only more CPU/memcopy stress...

Don't get started on this, you'll be surprised how many allegro.cc people completely disagree without any logical reason whatsoever.

On the topic of vsync, Allegro implements this on win32 via:

/* gfx_directx_sync:
 *  wait for vertical sync
 */
void gfx_directx_sync(void)
{
   IDirectDraw2_WaitForVerticalBlank(directdraw, DDWAITVB_BLOCKBEGIN, NULL);
}

It completely ignores the return result, which may be DDERR_UNSUPPORTED (i.e. your video driver does not support vertical sync) or, assuming Allegro overlaps drawing when possible, DDERR_WASSTILLDRAWING.

Just from DDERR_UNSUPPORTED, it is perfectly possible that vsync() is doing absolutely nothing. In this case, Allegro simply wouldn't tell you. So, if a user writes asking why your game features completely torn up graphics and runs at a stupid rate, vsync may well be to blame.

If Allegro overlaps drawing, then vsync() may do absolutely nothing on any card without Allegro telling you, depending on the timing of the last blit to the primary surface and the timing characteristics of that card.

If Allegro does not overlap drawing then it is probably a substantially slower library than it needs to be.

Moral of the story: don't use vsync. Use 'page flipping' (to stick with the Allegro community orthodoxy for naming) instead!

Derezo
Member #1,666
April 2001
avatar

Quote:

you'll be surprised how many allegro.cc people completely disagree without any logical reason whatsoever.

Well, they're just plain wrong. :P
I have a friend who is the same way. Has his monitor set to 60hz, and whines when he doesn't get 100+ FPS in games. ::)

Page flipping is nice, but can be much slower.
It's not suitable for transparency effects under 16 or 32 bit modes, for example.

"He who controls the stuffing controls the Universe"

Thomas Harte
Member #33
April 2000
avatar

Quote:

Page flipping is nice, but can be much slower.
It's not suitable for transparency effects under 16 or 32 bit modes, for example.

Well, as the page flip is all but free, I don't see any performance difference between preparing everything on a memory buffer and blitting it to an unseen video surface, then making that video surface the front at next vertical sync through one function call and preparing everything on a memory buffer, waiting for vsync through one function call then blitting to the seen video surface.

Certainly using two buffers in video memory is much more likely to include a working vertical synchronisation under Allegro.

Richard Phipps
Member #1,632
November 2001
avatar

We all know Triple Buffering is the best. ;)

Yves Rizoud
Member #909
January 2001
avatar

:( On a DOS machine with VGA card, vsync() works but page flipping is impossible if your card has not enough memory for 2 screens.
And now you say that in DirectX, vsync() may not work, so use page flipping instead...
So in short, if you want a simple VGA game to be portable, you need to code both engines, and use #ifdefs or a check at runtime to select the suitable one ? ugh

Anyway, the Allegro function for "page flipping" (edit: show_video_bitmap() ) is supposed to wait for a VBL to prevent tearing. If it calls the same IDirectDraw2_WaitForVerticalBlank() function, synchronization will not work either?

edit: and for triple buffering, request_scroll() "is only possible on certain hardware", alas :'(

Oscar Giner
Member #2,207
April 2002
avatar

Quote:

On a DOS machine with VGA card, vsync() works but page flipping is impossible if your card has not enough memory for 2 screens.
And now you say that in DirectX, vsync() may not work, so use page flipping instead...
So in short, if you want a simple VGA game to be portable, you need to code both engines, and use #ifdefs or a check at runtime to select the suitable one ? ugh

If there's not enough vram for a second page, create_video_bitmap will fail and in such case you can use double buffer.

The best you can do is write a wrapper that handles the update method for you.

Yves Rizoud
Member #909
January 2001
avatar

Yes, you can detect if you have enough video ram while grabbing it.
There's even an Allegro example somewhere testing all the drawing methods (double buffer, dirty rect etc.) so that's a starting frame for an engine handling all methods.
What annoys me in grabbing more than one screen of video memory, is that when calling set_gfx_mode() you'll hog a "screen" bitmap much larger than what you asked for (this is true in DOS/DJGPP, never tested since). Only through experimenting can you know how much mem you can take from a given video card.

Now what really annoys me there is a lack of GFX_CAN_VSYNC in gfx_capabilities ...
I can't boast my code can compile and run on any platform, but still, I don't like having functions failing without a way to detect it within the Allegro API.

gillius
Member #119
April 2000

You know, I'm starting to think that Allegro should provide an API that allows you to choose (or if it can, choose itself), the best update method. The main interaction with that API would be two methods. One method to grab BITMAP* you draw to. And another method would be to tell the API that you are done drawing that BITMAP. Direct3D does something similar so it is easy to do buffering. Allegro could allocate memory for triple buf if there is enough VRAM, or it might try to double otherwise. It would handle the vsync for you.

Gillius
Gillius's Programming -- https://gillius.org/

Thomas Harte
Member #33
April 2000
avatar

Quote:

Anyway, the Allegro function for "page flipping" (edit: show_video_bitmap() ) is supposed to wait for a VBL to prevent tearing. If it calls the same IDirectDraw2_WaitForVerticalBlank() function, synchronization will not work either?

No, it won't use WaitForVerticalBlank for that purpose - DirectDraw has a thing called a flipping chain. You connect a bunch of video surfaces in a chain, then move from one to the next using the Flip method. To that you can pass a parameter stating that you don't want the change to occur until the next vertical sync. How do I know this? I've consulted an aged and wise sage, who remembers back to the deep dark ages and beyond - to the age of the DirectDraw interface Allegro continues to use!

That is the normal way to do 'page flipping' in DirectDraw. Thinking about it, I'm not sure how Allegro does it, using its theoretical ability to use any old video bitmap in any old order as the new front buffer. I guess I'll go and have a look at the code again, unless someone can refresh my memory? It being an Allegro thing, I expect it goes through some hideously complicated mess of stodge code.

Oscar Giner
Member #2,207
April 2002
avatar

Quote:

using its theoretical ability to use any old video bitmap in any old order as the new front buffer.

maybe theoretical, but not real in the practice, if you mean that you can use any video bitmap for page flipping. If you create any video bitmap before the page flipping video pages, page flipping doesnt work propertly. That is, video pages must be the first two video bitmaps you create.

Richard Phipps
Member #1,632
November 2001
avatar

Have a look Thomas. Maybe you can improve the code. :)

Evert
Member #794
November 2000
avatar

Quote:

Just from DDERR_UNSUPPORTED, it is perfectly possible that vsync() is doing absolutely nothing. In this case, Allegro simply wouldn't tell you.

vsync is unreliable on some hardware. I thought this was in the docs somewhere, but I can't seem to find where, so maybe it's not there.

Quote:

Now what really annoys me there is a lack of GFX_CAN_VSYNC in gfx_capabilities ...

Yes, this would be a sensible thing to add. I'm not sure how to test for this on all hardware, but it's something that should be looked into.

Quote:

You know, I'm starting to think that Allegro should provide an API that allows you to choose (or if it can, choose itself), the best update method.

Yes, this was discussed (and I think more or less agreed on) on AD. The set_color_depth()/set_gfx_mode() combom is in need of deprecation anyway. What form such an API will take hasn't been finalized though.

Quote:

I've consulted an aged and wise sage, who remembers back to the deep dark ages and beyond - to the age of the DirectDraw interface Allegro continues to use!

As you may or may not have picked up, a minority of Allegro developers uses Windows at the moment. So if you care to assist in that area...

Quote:

It being an Allegro thing, I expect it goes through some hideously complicated mess of stodge code.

Again, feel free to help out.

Rosen Iliev
Member #4,911
August 2004

What is page flipping ? And what is the advantage of 3ple buffering?
I see tearing with double buffering with vsync, using blit(screen,dblbuff,SCREEN_W,SCREEN_H,0,0,0)
If i calculate exactly when the frame is drawn i blit to screen at that moment,will that problem dissapear?

Tobias Dammers
Member #2,604
August 2002
avatar

Double buffering:
Draw a complete frame to a memory or system bitmap.
Optionally wait for retrace (vsync()).
Blit the memory bitmap to screen.
Page flipping:
Allocate 2 pages of vram (2 video bitmaps).
Select one page to display, one for drawing.
Draw a complete frame to the drawing page.
Flip the pages so that the drawing page becomes the visible page and vv. Unfortunately, flipping always waits for a retrace, so you probably lose valuable cpu time here.
Triple buffering:
Works the same as page flipping, but you allocate 3 pages, not 1. You have now one visible page, one queued page and one drawing page. Each time you finish drawing a frame, you flip queued and drawing page, thereby queueing the drawing page. Allegro (or the graphics driver or that tiny little dwarf inside your computer case) flips queued and visible frame on each retrace, except when no page has been queued.

Now, each method has its advantages.
Double buffering is very easy to implement, and it can live with minimum vram requirements (1 page). On modern machines, the memory transfer through the bus is not very expensive, so it can run at high frame rates. All video cards and platforms support this. It does, however, produce the "tearing" issue.
Page flipping is "cleaner", and, on some machines and depending on what you are doing, can be faster than double buffer. But: Not all video cards / platforms support page flipping, and you need enough vram to hold 2 pages. A big disadvantage is that flipping can only happen while retracing, so you lose time here.
Triple buffering is usually the fastest and smoothest solution, but it requires 3 pages of vram, and, of course, video card and platform must support it.

And finally:

Quote:

If i calculate exactly when the frame is drawn i blit to screen at that moment,will that problem dissapear?

This is exactly what vsync() tries to do, so I'm afraid this will not solve your problem.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Rosen Iliev
Member #4,911
August 2004

Thanks for nfo.
So if I use triple buffer my program can do usefull job or free cpu time for other windows jobs, right?
And can you tell me the names or prototypes of the functs i need for triple buffering?

Richard Phipps
Member #1,632
November 2001
avatar

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

So if I use triple buffer my program can do usefull job or free cpu time for other windows jobs, right?

Sort of. The biggest advantage is that you stay in sync with the screen, without waiting for the retrace.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

gillius
Member #119
April 2000

If you render more than one frame ahead, a good implementation of triple buffering (I mean at the API level) will block the CPU until vsync. That requires hardware and OS support. For Direct3D, I know it is possible, at least on my video card.

Gillius
Gillius's Programming -- https://gillius.org/

Thomas Harte
Member #33
April 2000
avatar

Evert said:

feel free to help out.

The whole thing is already too much of a mess for someone of my limited resources (time and ability for comprehension of other people's code - especially very large projects) to help!

Anyway, when the problem is that the API simply isn't up to the job (in this case - what could a win32 implementation ever do on DDERR_WASSTILLDRAWING? How could the innate 'goodness' of flipping chains ever be realised by Allegro?), what help could a new programmer possibly be?

Personally I'm looking forward to AllegroPro. I've not really been looking too hard at the specification, but Korval seems focussed and knowledgable. In the meantime my SDL conversion remains all but complete.

Yves Rizoud
Member #909
January 2001
avatar

with MSVC6, Win98, a GeForce card, allegro 4.1.15 freshly installed, Triple buffer on the demo program does:
GDI: unsupported
DirectX windowed: unsupported
DirectX fullscreen : works flawlessly

And little grey men invaded my computer.

Also, Page flipping now works ok in ModeX, DirectX (all supported modes) but in VESA (compiled with DJGPP) the top of the screen flickers black like crazy..

Never mind, with Doom3 out I'll get a new computer anyway..

X-G
Member #856
December 2000
avatar

Quote:

GDI: unsupported
DirectX windowed: unsupported

Expected. You can never do triple buffering in windowed mode, as far as I know.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Richard Phipps
Member #1,632
November 2001
avatar

 1   2   3 


Go to: