VSync
aus Wikipedia, der freien Enzyklopädie
[Bearbeiten] Bedeutung von VSync bei "modernen" Grafikkarten
Bei der Darstellung von Grafiken auf einem Computer-Bildschirm kann es dazu kommen, dass die Grafik flimmert, weil während des Aufbaus der Grafik das Bild auf dem Monitor neu aufgebaut wird. Während der Elektronenstrahl von rechts unten nach links oben zurückspringt, wird ein Signal generiert, das zur vertikalen Synchronisation der Grafik genutzt werden kann. Dieses Signal wird als VSYNC bezeichnet.
Das Signal wird zur Synchronisierung des Bildaufbaus mit der Berechnung der Grafiken benutzt. Grafikkarten haben zwei hierbei wichtige Puffer (Zwischenspeicher) – die sogenannten Framebuffer (Bildspeicher). Aus dem einen, dem Primärpuffer (primary buffer), liest der Digital-analog-Konverter (DAC) bzw., bei einer DVI-Verbindung, der Monitor seine Daten aus – und zwar Pixel für Pixel. In den anderen Puffer, den Sekundärpuffer (secondary buffer), schreibt währenddessen der Grafikchip seine Berechnungen.
Zu einem bestimmten Zeitpunkt wechseln die beiden Puffer einfach ihre Rollen:
Ohne VSync: Sobald ein Bild fertig berechnet ist, erfolgt der Wechsel der Puffer. Dabei wird der (neue) Primärpuffer einfach dort weiter ausgelesen, wo vorher der alte stand. An dem einen Pixel wird noch das alte Bild ausgelesen, und am nächsten bereits das Neue. Dadurch kommt es zu Schlieren (glitches), d. h. die Geometrie auf zwei benachbarten Bildteilen passt nicht mehr aufeinander (Kanten gebrochen).
Mit VSync: Der Empfänger liest die Daten aus, bis das Bild fertig aufgebaut ist, erst dann wechseln die Framebuffer die Funktion. Das VSync-Signal zeigt das Ende des Bildaufbaus an. Der Grafikchip pausiert so lange mit der Bildberechnung, bis die Puffer vertauscht wurden. Ist der Grafikchip mit der Berechnung noch nicht fertig, wird nicht gewechselt und der Empfänger liest noch einmal das selbe Bild aus.
Daher:
- ohne VSync: immer die aktuellen Daten auf dem Monitor.
- mit VSync: keine glitches.
[Bearbeiten] Bedeutung von VSync bei VGA-Karten
Bei älteren VGA-Karten bezeichnete man den Rücklauf des Elektronenstrahls von rechts unten nach links oben als Vertical Retrace. Das Bild wird nämlich von oben nach unten Zeile für Zeile aufgebaut. Wenn nun der Elektronenstrahl fertig ist, also unten angekommen ist, dann muss er wieder zurück, um seine Arbeit wieder von vorne zu beginnen.
Die Zeit, die der Elektronenstahl braucht, um wieder nach oben zu kommen, kann man jetzt nutzen, um neue Daten in den Grafikspeicher zu kopieren. Der VGA-Chip kann nämlich nicht gleichzeitig das Bild darstellen und neue Daten in den Speicher lassen. Das Darstellen der Daten hat Vorrang vor dem Kopieren in den Speicher, deshalb ist es ungünstig, Berechnungen durchzuführen und die Ergebnisse sofort in den Speicher zu schreiben.
Dazu ein kleines Beispiel im Pseudocode:
repeat BerechneUndZeige(Welt); LeseBenutzerEingaben(); until BenutzerBeendet == true
Der obige Code berechnet also eine Welt (dies könnte z. B. die Umgebung in einem Computerspiel sein) und gibt diese sofort auf den Bildschirm aus. Danach liest man die Eingaben des Benutzers, welcher sich z. B. in der Welt bewegt. Falls der Benutzer das Programm nicht beendet, wird die Welt entsprechend den Eingaben des Benutzers neu berechnet und ausgegeben usw.
Hier würde ein Problem auftauchen, wenn der Programmierer nur mit dem Grafikspeicher arbeitet. Der schlimmste Fall tritt auf, falls die Berechnungen Pixel für Pixel erfolgen, wie es z. B. bei Raytracing gemacht wird. Wenn nämlich der VGA-Chip gerade Daten aus dem Speicher liest, um diese auf den Bildschirm zu schreiben, muss der Prozessor warten, bis der VGA-Chip fertig ist und den Grafikspeicher zum Schreiben freigibt. Dann erst kann der Prozessor den berechneten Pixel in den Grafikspeicher schreiben und mit dem nächsten weitermachen. Die Folgen davon sind ein flimmerndes Bild und Geschwindigkeitseinbußen.
Besser ist es die Berechnungen in einem Puffer zu machen, der außerhalb des Grafikspeichers liegt. Wenn man damit fertig ist und der Puffer zur Ausgabe bereit ist, dann wartet man noch einen kleinen Moment, bis der VGA-Chip meldet, dass der Kathodenstrahl gerade beim Rücklauf ist und schreibt die Daten des Puffers in den Grafikspeicher.
Hier wieder ein Beispiel:
repeat BerechneImPuffer(Welt); WarteAufVR(); SchreibePufferInGrafikspeicher(); LeseBenutzerEingaben(); until BenutzerBeendet == true
Man könnte das Warten auf den Vertical Retrace auch weglassen. Der VGA-Chip wird dem Prozessor schon selber mitteilen, wann dieser schreiben darf und wann nicht. Dazu kann auch die viel kürzere Zeitspanne eines Horizontal Retrace vom Prozessor benutzt werden. Wichtig ist eben, dass die Berechnungen in einem Puffer außerhalb des Grafikspeichers geschehen, um Geschwindigkeitsverluste zu vermeiden. Jedoch würde eventuell das Flimmern wieder auftreten.
Das Warten auf den Vertical Retrace kann aber auch eine ganz andere Aufgabe übernehmen. Nämlich die Synchronisation mit dem Bildschirm.
Der Bildschirm baut das Bild mit einer konstanten Frequenz auf (z. B. 60 Hz). Somit wird auch die Schleife des Programms mit der entsprechenden Frequenz abgespielt. Das menschliche Auge nimmt seine Umgebung mit einer Frequenz von 50 bis 60 Hz wahr, somit könnte man den Vertical Retrace verwenden, damit auch der Mensch sich auf die Veränderungen der virtuellen Umgebung rechtzeitig einstellen kann.
[Bearbeiten] Technische Details
Wenn der Elektronenstrahl sich gerade in einem Vertical Retrace befindet, schreibt der VGA-Chip den Wert 1 in das Bit Nr. 3 des "Input Status #1 Register" (port 0x03DA). Ansonsten wird das Bit auf den Wert 0 gesetzt.