Double Buffering: Difference between revisions

m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (changed "he or she" to "they" because I spite god)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
Line 19:
For example, without double buffering consider a simple game rendering like the following:
 
<sourcesyntaxhighlight lang="c">
void run()
{
Line 35:
}
}
</syntaxhighlight>
</source>
 
Now imagine if each of those functions drew directly to the frame buffer. The video card and monitor may update just after you have drawn the background, or it may update just after you have cleared the screen. More likely, you're going to end up with a combination of effects with resulting in your screen flickering and seeing through objects.
Line 41:
Now imagine if each of these functions drew to a secondary buffer the size of the frame buffer. Each time you modify a pixel it won't be writing directly to the video card. Instead, after <code>draw_characters()</code> you would call:
 
<sourcesyntaxhighlight lang="c">
memcpy(framebuffer, backbuffer, width * height * bytesperpixel);
</syntaxhighlight>
</source>
 
so the final image in its entirety is sent to the frame buffer, not just parts of it.
Line 86:
An example of vertical synchronization is as follows:
 
<sourcesyntaxhighlight lang="c">
/* handle VBLANK, called by the interrupt handler */
void vga_handleVBlank()
Line 105:
while(vga_framerendered);
}
</syntaxhighlight>
</source>
 
There is no reason you HAVE to synchronize, another method could be you place a spinlock on the buffer, if you fail to acquire the lock simply skip that frame until you do. This may work fine in a video game where you redraw the frame over and over again so if you miss drawing something to the screen it will be redrawn on the following frame, but in a modern multitasking GUI environment, this is unacceptable.
Line 135:
==== Buffer creation ====
 
<sourcesyntaxhighlight lang="c">
/* Supposing the display is 800x600 with 32 bpp (meaning 32/8 = 4 bytes per pixel). */
uint8_t *BackBuffer = ((uint8_t *) (malloc(800 * 600 * 4)));
</syntaxhighlight>
</source>
 
This implementation absorbs the same amount of memory the real video memory does, in this case, 800 * 600 * 4 = 1920000 bytes = about 1,83 MB. While using single-buffering needs 1,83 MB of RAM with our video resolution (only the display itself), double-buffering would require 2 * 1,83 MB = about 3,66 MB. The higher the resolution, the more memory is required. There are of course implementations that can use up less than that with special techniques, but for some OS developers, high resolutions, and especially with double-buffering, are expensive features.
Line 145:
 
==== Double buffering ====
<sourcesyntaxhighlight lang="c">
uint8_t * VidMem;
uint8_t * BackBuffer;
Line 223:
}
}
</syntaxhighlight>
</source>
 
I believe this example is mostly clear. As there are too many different ways of changing video modes or putting pixels, I'm going to let you fill that in yourself. If you want more information, you can go to the [[GUI]] or the [[Drawing In Protected Mode]] pages.