Double Buffering

Freitag, 12. März 2004
 / von aths
 

Das beste wäre in diesem Fall, wenn die Grafik-Engine mit genau 100 fps liefe. Das ist natürlich fast nie der Fall. Hier kommt nun VSync ins Spiel. Meistens arbeiten die Grafikkarten mit Double Buffering. Dann gibt es einen Front- und einen Backbuffer. Während der Frontbuffer angezeigt wird, rendert die Karte das neue Bild in den Backbuffer. Ist das Bild fertig, sendet die Engine ein Signal zum "Swap". Die Grafikhardware vertauscht nun die Adressen von Front- und Backbuffer. Der RAMDAC liest dann aus dem ehemaligen Backbuffer, der dank Adressentausch jetzt Frontbuffer ist.

Dabei interessiert den RAMDAC jedoch nicht, wann der Swap erfolgte, er macht ungerührt weiter. Das heißt, ist der Bildaufbau gerade in der Mitte, wird ab dort das neue Frame angezeigt – das letztlich auf dem Monitor angezeigte Bild stammt also eigentlich aus zwei unterschiedlichen Frames. Vor allem bei links-rechts-Bewegung resultiert das in "Tearing", da man an dieser Stelle einen "Riss" erkennt: Obere und untere Hälfte sind (an der Bruchstelle der beiden Frames) zueinander versetzt.

Aktiviertes VSync verhindert nun dieses Tearing. Wenn die Engine den "Swap"-Befehl gibt, verzögert die Grafikkarte die Ausführung des Befehls solange, bis der RAMDAC die letzte Zeile des Bildes gelesen und in das Monitorsignal umgewandelt hat. Dann sendet er nämlich ein Signal, welches abgefragt werden kann. Bei "VSync on" wird nun in der Zeit, während der Kathodenstrahl nach links oben positioniert wird, geswappt. Man sieht auf dem Monitor immer nur ganze Frames, ohne Risse. Doch dieses Verfahren hat auch Nachteile.

Liefe das Spiel ansonsten mit 110 fps, sehen wir jetzt nur noch 100 Bilder pro Sekunde. Das ist natürlich kein echtes Problem. Aber wenn die Grundgeschwindigkeit unter 100 fps sinkt, bekommen wir nur noch 50 fps auf dem Monitor zu sehen. Warum das?

Sagen wir, die Grundgeschwindigkeit wäre 80 fps und wir haben den Monitor auf 100 Hz gestellt und VSync aktiviert. Das heißt, alle 12,5 Millisekunden würde ein neues Bild fertig, und alle 10 Millisekunden könnte ein neues Bild angezeigt werden. 12,5 Millisekunden Rechnenzeit und 10 Millisekunden Anzeige heißt, ein Bild wird jetzt zwei Zyklen lang angezeigt. Denn wenn schon geswappt werden könnte, ist das neue Bild noch nicht fertig. Also wird der Swap verzögert.

Jedesmal gehen 7,5 Millisekunden verloren, in denen die Grafikkarte wartet, um vertikal zu synchronisieren. Die vertikale Richtung ist die von unten nach oben (oder anders herum). Der Kathodenstrahl wird am Ende des Scanouts von unten nach oben positioniert, hiermit wird nun synchronisiert. Horizontale Sychronisation (HSync) fragt ab, wann der Kathodenstrahl auf eine neue Zeile springt, doch das soll unser Thema heute nicht sein.

Pro Bild haben wir jetzt 12,5 Millisekunden Rechen- und 7,5 Millisekunden Wartezeit, was 20 Millisekunden pro Frame ergibt. Das heißt, 50 fps. Sinkt die Grundgeschwindigkeit unter 50 fps, resultiert die tatsächliche Geschwindigkeit in 33,3 fps: Jedes Bild wird drei Zyklen lang anzeigt. Es läuft also auf ganzzahlige Vielfache hinaus.

Tatsächlich ereichbare Geschwindigkeiten mit VSync und Double Buffering
Bildwiederholrate [Hz] entsprechend mögliche Frameraten [fps]
60 60, 30, 20, 15, 12, ...
75 75, 38, 25, 19, 15, ...
85 85, 42, 28, 21, 17, ...
100 100, 50, 33, 25, 20, ...
120 120, 60, 40, 30, 24, ...