Was ist der Inhalt des Puffers * nach * einem Aufruf von glSwapBuffers ()?

8

( SDL_GL_SwapBuffers()insbesondere)

Wenn Sie eine Szene gezeichnet haben und Swap-Puffer aufrufen, ist es Routine, glClear()die Szene dann zu zeichnen, bevor Sie etwas zeichnen. Wenn Sie nicht löschen, wie lautet der Inhalt des Puffers? Ist dies durch eine Spezifikation definiert oder variiert es je nach Fahrer?

Wille
quelle
Das ist eine sehr interessante Frage.
Notabene

Antworten:

13

Die Details zum Austauschen des vorderen und hinteren Puffers variieren von Plattform zu Plattform. Daher ist die Antwort plattformabhängig.

Gemäß der Referenzdokumentation zu GLX glXSwapBuffers :

Der Inhalt des Backpuffers wird nach einem Swap undefiniert. Beachten Sie, dass dies sowohl für Pixelpuffer als auch für Fenster gilt.

Es gibt jedoch die Erweiterung GLX_EXT_buffer_age :

Ziel dieser Erweiterung ist es, Anwendungen genügend Informationen darüber zur Verfügung zu stellen, wie der Treiber den Satz von vorderen und hinteren Puffern verwaltet, die einer bestimmten Oberfläche zugeordnet sind, damit Anwendungen den Inhalt alter Frames wiederverwenden und minimieren können, wie viel für die neu gezeichnet werden muss nächster Frame.

Aber Win32 SwapBuffers sagt nur:

Wenn das aktuelle Pixelformat für das Fenster, auf das dieser Gerätekontext verweist, einen Rückpuffer enthält, tauscht die Funktion den vorderen und den hinteren Puffer aus. Wenn das aktuelle Pixelformat für das Fenster, auf das der Gerätekontext verweist, keinen Rückpuffer enthält, ist dies der Fall Aufruf hat keine Auswirkung und der Inhalt des Rückpuffers ist undefiniert, wenn die Funktion zurückkehrt.

Und CGLFlushDrawable für OS X Core Graphics sagt:

Wenn das Attribut für den Sicherungsspeicher auf false festgelegt ist, können die Puffer ausgetauscht und nicht kopiert werden. Dies ist im Vollbildmodus häufig der Fall. Wenn der Empfänger kein doppelt gepufferter Kontext ist, führt dieser Aufruf nichts aus.

Schließlich in der OpenGL ES-Standard-Pufferaustauschfunktion eglSwapBuffers :

Der Farbpuffer der Oberfläche bleibt nach dem Aufruf von eglSwapBuffers undefiniert.

Was bedeutet das alles?

  • Um wirklich plattformübergreifend zu sein, können Sie nach einem Swap nichts über den Backpuffer annehmen. Der Inhalt ist undefiniert, und Sie sollten ihn wahrscheinlich glClear oder auf andere Weise reparieren, bevor Sie ihn verwenden.
  • Wenn Sie Linux verwenden, können Sie nach der Erweiterung des Pufferalters suchen. Da ein System möglicherweise dreifach gepuffert ist, müssen Sie möglicherweise den Schaden mehrerer Frames im Auge behalten und damit umgehen.
  • Wenn Sie OS X verwenden, werden Sie möglicherweise kopiert und erhalten einen Austausch. Sie können also davon ausgehen, dass der Inhalt des Backbuffers kein Müll ist, aber Sie steuern nicht, ob es sich um den gerade gesendeten oder den zuvor gesendeten Frame handelt.
  • Wenn Sie nur auf Win32 abzielen und sicher sind, dass Sie einen Backpuffer haben, können Sie vermutlich davon ausgehen, dass der Inhalt jetzt der Inhalt des Frontpuffers ist. (Obwohl dies eher eine Annahme der Auslassung als eine explizite Angabe ist; ich wäre nicht überrascht, wenn es bei vielen / keiner Konfiguration nicht funktioniert.)

Angesichts der Einschränkungen von GLX und CGL und des Wunsches, Änderungen zwischen OpenGL und OpenGL ES zu minimieren, können Sie genauso gut davon ausgehen, dass es sich bei dem Inhalt um Müll handelt.

Sunny Sachanandani
quelle
1

Nach dem, was ich gelesen habe, ist das einzige Verhalten UNDEFINIERT. Ich würde also davon ausgehen, dass es keine Garantie für den Inhalt des Puffers gibt. Ganz zu schweigen davon, dass einige Bibliotheken tatsächlich einen eindeutigen Aufruf in den Aufruf der Swap-Puffer einbinden.

David Yenglin
quelle
-1 mangels Beschaffung; Die OpenGL-Dokumentation ist reichlich vorhanden und leicht zu verknüpfen.
+1, weil er tatsächlich geantwortet hat und die Antwort richtig war. Quellen helfen auf jeden Fall, sind aber keinesfalls erforderlich!
o0 '.
@ Lo'oris: Außer, er ist nicht richtig. Er ist für einige Plattformen korrekt, aber nicht für alle, wie meine Antwort erklärt.
@ Joe: Die einzige Antwort, die unabhängig von der "Umgebung" richtig ist, ist diese, wie Ihre Antwort erklärt. Zu wissen, dass dies "irgendwo" kaputt geht, wäre in erster Linie falsch.
o0 '.
1
@ Lo'oris: Der gesamte Code, insbesondere das Rendern von Code, wird wahrscheinlich irgendwo kaputt gehen . Eine gute Antwort sagt das nicht nur, sondern erklärt, wo das irgendwo ist.
0

Das Verhalten ist UNDEFINED. Wenn Sie also trotzdem den gesamten Bildschirm ausfüllen möchten, können Sie das Löschen löschen. Außer in einigen Umgebungen (zumindest bei bestimmten Kachelarchitekturen) wird die Leistung dadurch tatsächlich beeinträchtigt. Das Löschen des Vollbilds zu Beginn des Renderns ist so häufig, dass ich mich wundern würde, wenn es nicht auf allen Zielplattformen gut optimiert wäre.

Der Grund, warum es UNDEFINED ist, ist, dass für viele Architekturen das Definieren des Inhaltsstatus einen zusätzlichen Aufwand darstellt, unabhängig davon, wie Sie den Standard definieren würden.

Was Sie dort finden, kann ich aufgrund von Erfahrungen erraten.

Auf doppelt (oder mehrfach) gepufferten Architekturen, wie bei den meisten Desktop-PC-Videohardware, finden Sie wahrscheinlich die "anderen" Pufferdaten. Dies ist jedoch nicht garantiert, da es nicht in der Spezifikation enthalten ist. Wenn eine seltsame Optimierung davon profitiert, werden die Daten verstümmelt.

Auf gekachelten Architekturen finden Sie möglicherweise dieselben Daten wie im letzten Frame, einige seltsam verstümmelte Daten basierend auf der Kachelgröße oder fast alles andere.

Dann haben Sie einige seltsame Architekturen (wie das NDS), die Ihnen fast alles bieten könnten, da ihre Definition des Puffers nicht genau das ist, was Sie erwarten würden.

Jari Komppa
quelle
Wow, negative Stimmen. Ich meine es ernst mit dem, worüber ich geschrieben habe - besonders wenn Sie für mobile Hardware schreiben, stellen Sie sicher, dass Sie dies klar angeben.
Jari Komppa
Ich habe abgelehnt, weil Ihre Antwort fast identisch mit der von David ist, immer noch keine Referenzen hat und wie die von David weder richtig noch die ganze Geschichte ist.
OK. Der einzige Hinweis, den ich geben kann, ist jedoch meine eigene Erfahrung. Ich werde vorsichtiger sein.
Jari Komppa
Ich habe abgelehnt, weil diese Antwort streng schlecht war als die beiden anderen (die ich beide positiv bewertet habe): Sie fügte nichts hinzu und war viel weniger klar.
o0 '.