Someone walk me thru the vertical blank refresh ?

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

The Forum Archive is locked. These are the original blitzbasic.com forums, kept so their posts can still be read and searched. No new topics, replies or edits can be made here. To join the conversation, head over to the Blitz3D+ forums.

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.