Someone walk me thru the vertical blank refresh ?

BlitzMax Forums/BlitzMax Beginners Area/Someone walk me thru the vertical blank refresh ?

Dax Trajero(Posted 2005) [#1]
I would really like to know how to get a rock solid 60fps in perfect sync with my (and everyone's) monitors for my 2D platform game. Some people suggest delta time, some vwait flip some vwait flip false and I'm getting confused ;-)

To satisy myself I'd really like to know the chain of events that happen leading up to and after the vertical blank refresh on everyone's PC.

eg. is the cpu interrupted ?
eg. what is and why do people turn off "vsync" on their graphics cards ?
eg. how can a make sure my sprites are drawn in sync with everyone's monitors

Thanks in advance,
Dax


Matt McFarland(Posted 2005) [#2]
V-SYNC (from the wikipedia)
Vertical synchronization (abbreviated as vertical sync or V-sync) is a method used in computer games to only allow the game to draw to the screen starting at the beginning of a video scan. This limits the frame rate of the game to the monitor's refresh frequency and also prevents page tearing.

V-sync is often found in applications where frames forming a motion sequence are rendered in real time at a variable rate, including 2D/3D games and audio/data visualizations, but does not apply to video playback.



PAGE TEARING (from the wikipedia)

Page tearing is when a previously rendered frame is shown with a newly rendered frame in a computer/video game. It creates a 'torn' look as two parts of an object, most likely a wall, don't line up.

Vertical synchronization waits for the previous frame to be rendered before rendering the next frame. The faster the monitor's response time, the less page tearing, the higher the monitor's refresh rate, the higher the frames per second.

A Note from me
Since it limits the frame rate of a game to the monitors refresh rate, this is all you need to do to get the rock solid 60 fps. Set the V-sync to the ON position and set the monitor refresh rate to 60mhz and whammo your game will not go higher than 60 fps.

It may go UNDER 60 fps but that would be related to the game itself. If you have a memory leak it can turn into a cpu nightmare. There are lots of reasons why a game runs slower than it should, but I dont think it has anything to do with vsync or a refresh rate.

I never turn off V-Sync because it causes page tearing. If I want the fps to be higher, I'd much rather just increase the frequency on the monitor refresh rate in video options rather than turning V-Sync off.

Playing a game like Battlefield 2 at 60mhz with v-sync on means the game wont go higher than 60fps. Considering that sometimes the fps could even be lower than 60, I dont see any reason on picking a higher refresh rate unless I had an uber computer that would run smoothly at say 80mhz.

I hope that I helped..


Dax Trajero(Posted 2005) [#3]
Thanks Matthew,

What can cause a memory leak and how will it manifest itself?

I'm currently using VWAIT FLIP FALSE, but not currently utilising double buffering. Can I still achive 60fps with double-buffering ?


Matt McFarland(Posted 2005) [#4]
Ok first let me tell you I had severe memory leak problems when I was developing my first game (which is still currently under development) - I found out that my problem was that I was reloading a sound effect over and over and over again with every loop. If you fire any command with the prefix "load" in your loop you will cause a memory leak. because it will just apply a file to new memory block and end up using more memory. My memory leak was huuge within minutes I had used up a gig of ram. haha it was terrible! Ok I want to point you to a very useful page. This HELPED ME tremendously!

http://www.blitzwiki.org/index.php/Memory_management


Maybe have it display the memory used in the game in the main loop, if you see it increasing steadily then you have a memory leak and the game will get slower and slower.I do not know how to achieve the best vsync technique in bmax. I know that Darkbasic had a simple command like (sync = 60) lol. But with bmax I dont know! I hope that someone tells us because I'm sure it is very important!

I also wanted to point out something about Delta Timing. I was reading this over at http://forums.indiegamer.com/showthread.php?t=4832

The following is a copy paste excerpt:

The idea is to create a new effect every X frames, having a max you never get overloaded of effects. When you have less than Y fps you must freeze the game.

ie:
//This code was written in C++ as an example to show
//the math behind delta timing.  I hope this helps, I am
//currently too lazy to translate to bmax. lol
deltatime()
  {
  double delta_time = Get_Delta();
  if(delta_time > 0.05)
    {
    delta_time=0.05; // 20 fps min static
    int fxcount = 0; 
    fxcount ++; 
    if(fxcount > 5 ) 
       {
        New_Efect();
        fxcount=0;
       }
    }
  }


what else can drop the frame rate? (also from http://forums.indiegamer.com/showthread.php?t=4832)
Things to look out for...

Too many texture changes
Poor batching
Too many vertices (this almost never happens)
Expensive per-pixel operations (additive blending is pretty slow on old cards)
Incorrect vertex buffer usage

Hope this helps somewhat.


tonyg(Posted 2005) [#5]
There was a lot of discussion on this...
Framerates
more framerates
timing
more timing


Sledge(Posted 2005) [#6]

Playing a game like Battlefield 2 at 60mhz with v-sync on means the game wont go higher than 60fps. Considering that sometimes the fps could even be lower than 60, I dont see any reason on picking a higher refresh rate unless I had an uber computer that would run smoothly at say 80mhz.



One reason (that you would go higher than 60fps) might be screen res - running a high res display at 60Hz makes the flicker more obvious. I'm all for speed capping, especially via a v-sync, but it does restrict the resolutions that you can use in comfort.


ImaginaryHuman(Posted 2005) [#7]
My understanding of it is basically the same, worded as follows

The vertical sync is based on the vertical refresh rate of the display, that is, the speed at which the video `beam` of light or whatever makes it way from left to right accross `scanlines` and down the screen in rows. A display at 60Hz for example, 60 cycles per second, redraws the contents of the screen 60 times every second due to the rate at which the beam moves (although this is a bit different for LCD screens).

What you're mainly doing when you synchronize with the vertical refresh, is using the fact that the display updates fairly constantly to synchronize what goes on in your game, so that your game operates at a set pace. In the old days this would be achieved with a vertical blank interrupt which would be set up to actually interrupt everything the CPU is doing, in hardware, and trigger off a small piece of code called an interrupt handler (similar to exceptions). A display might produce an `interrupt` each time it gets to the end of drawing the screen, or when it gets back up to the top. This interrupt could then be used to set the pace or timing of your game or whatever, and some people would put a lot of code into the interrupt handler program itself so that it would just get called every `cycle` - although this required the program to be able to `finish running` within 1 full cycle otherwise it'd run into problems.

I don't know exactly whether the same system is used now. I think BlitzMax attempts to use a hardware interrupt to handle the synchronization, otherwise if not available it uses a software based timer system.

So what happens with the vertical retrace, which happens on a monitor but not so sure how it works on an LCD/flatpanel, is that the contents of the display in `video memory` are read off and turned into colors and sent to the physical screen to produce light in that color. Then the beam moves a little bit and does the next pixel, reading more data from video memory. So the video display doesn't actually refresh `all at once`, it is constantly being updated, scanned from left to right for each row, and from the top row downwards. It's as if there is a constant `line` moving down the screen and then jumping back to the top again.

So, what tearing is, as said by others, is where the video beam has begun to draw the contents of video ram using the data from the `previous frame`, because your program wasn't fast enough or synchronized enough to make a new frame before the beam started reading memory. So while the image on the screen might've been there the last time the beam went along, if your program was too slow at making a new image it will just be reading from the old data.

Now, tearing only happens when, usually, you have a single-buffered display, or when you are copying from a double/triple buffer into the front visible buffer. This occurs in combination with the previously mentioned `program was too slow to make a new image so the old one got used` concept, but is also caused by the creation of that new image, in visible video memory, being faster than the speed of the beam. So, while the beam started out reading old pixels from the previous `frame` of animation, the CPU or GFX card suddenly zips along at a high speed putting new pixels into that memory buffer, and all of a sudden the beam is reading new pixels. The `tear` is the contrast between the parts of the screen that `so far` show old pixels, and the parts of the screen that are now starting to show `new` pixels. The position of the tear is the exact postion that the video beam was at when new pixel data suddenly started to be noticed, ahead of where the beam had got to so far. So everything after that point is usually `new pixels` and everything before it was old pixels.

You most definitely will likely see some tearing going on if you have both a single-buffered display that you draw directly to the visible buffer, and the drawing is not in any way synchronized with the vertical refresh rate (the vertical blank interrupt). The cpu or gfx card will be drawing pixels at a totally different rate, to that visible buffer, than the rate that the beam is transforming the data into visible pixels, and that point where the two `meet` and cross over is what you see as a tear. And it fluctuates, of course, so the tear tends to move all over the place depending on how much time difference there is between the two.

Another related issue is where, if you are drawing to the front buffer, the drawing process can be seen, and can become `torn` looking, because you might be drawing an area that crosses over where the video beam has got to - thus maybe the beam only gets the chance to draw the lower portion of the area and you might never even see the upper portion. This can make objects seem to disappear and flicker a lot, in addition to being partially torn. This is where a double buffered system comes in, which is the default setup in BlitzMax. With a double buffer you eradicate the flickering and tearing of objects that are being drawn, even if the update is not synchronized with the speed of the beam. You only then have to worry about moving the hidden `backbuffer` to the visible `front buffer` (or to tell the hardware where to get its data from when it makes the picture), because if that involves copying data from one buffer to another it might also be unsynchronized and cause a tear. On systems like the Amiga there wasn't a copy of data from back to front buffers, you could just tell the hardware to look in a different place to get the data - which was faster, but it still had to only be told to start looking there when the `frame` was fully drawn. Some people had issue with this which is why they resorted to triple buffering, which allowed you to `get ahead of yourself` in drawing frames and be working on the next frame before the current and previous one were done with.

If your program is synchronized with the refresh rate, and it is able to always draw the frame from top to bottom fast enough to always be ahead of the video beam, you should not get any tearing and you should only need a single buffered system. But usually this is not practical or completely reliable.

So generally overall it's a good idea to have all your objects drawn to the hidden backbuffer with double buffering, to have the hidden buffer switch into view at a time which is not going to cross paths with the video beam (ie vertically synchronized), and usually that will mean pausing the game to make it slow down to wait for that moment. So when you synchronize you are basically saying `slow down and wait for the next whole cycle to begin` (or this one to end). You hope, then, that either the hardware can look at the backbuffer for its data (and swap references), or move the backbuffer data to the front buffer fast enough that you don't see it tearing.

If there is too much work to do within the amount of time you have in 1 full screen refresh, by the video beam, then being synchronized to that rate means you have to wait till the end of the whole next frame. This is where you lose a lot of processing time. It's something that a lot of people have to juggle. It's also where delta timing and trying to `decouple` the animation rate from the refresh rate comes into play. Ie, in games like Elite, it would know where the objects should be after a given amount of real time, and tried to draw them at that position as soon as it could, so if things were really slowing down, the objects were still in the right locations when you saw them but you just didn't get to see them `getting there` so smoothly. Vice versa you have tweening, filling in the blanks to make more frames and steps in the animation, when you have more time on your hands than you need.

Synchronizing to the vertical blank is usually a good thing. It looks smooth, and if your game isn't too demanding it can run at 60 or 30 or 25fps smoothly which looks nice. You do lose out on some potential processing time, which is where a triple buffered system would make it up by doing `as much as possible` of the next frame in the extra time. But for most purposes it's pretty useful and pretty well implemented in BlitzMax.


WolRon(Posted 2005) [#8]
60mhz
I wasn't aware that monitors could refresh at 60 megahurtz yet...
Computers really are advancing quickly.


Matt McFarland(Posted 2005) [#9]
oops :/


ImaginaryHuman(Posted 2005) [#10]
lol, Hz! Hz!