2013-03-02 10 views
5

Also, wenn Sie OpenGL-Funktionen wie glDraw oder gLBufferData aufrufen, führt dies dazu, dass der Thread des Programms stoppt und darauf wartet, dass GL die Aufrufe beendet?Führen OpenGL-Funktionen zum Einfrieren des Hauptthreads?

Wenn nicht, wie behandelt der GL dann wichtige Funktionen wie glDraw und ändert dann sofort eine Einstellung, die sich auf die Zeichenaufrufe auswirkt?

+0

Ja, sie würden im Allgemeinen blockierende Funktionen, ich bin nicht sicher, wie ich es vorher nicht getan habe, aber ich nehme an, dass es auf einer Schleife ausgeführt würde und nur aktualisiert, wenn nötig, um die Framerate hoch zu halten. – PsyKzz

+0

@MattPsyK: OpenGL-Funktionen, die keinen Synchronisationspunkt einführen, werden nicht blockiert. – datenwolf

+0

Meine schlechten Annahmen wurden getroffen. – PsyKzz

Antwort

6

Nein, sie (meistens) nicht. Die meisten GL-Funktionen werden gepuffert, wenn sie verwendet und später tatsächlich ausgeführt werden. Das heißt, Sie können sich die CPU und die GPU nicht als zwei Prozessoren vorstellen, die gleichzeitig zusammenarbeiten. Normalerweise führt die CPU eine Reihe von GL-Funktionen aus, die gepuffert werden und sobald sie an die GPU geliefert werden, führt sie diese aus. Dies bedeutet, dass Sie nicht zuverlässig steuern können, wie viel Zeit für die Ausführung einer bestimmten GL-Funktion benötigt wurde, indem Sie einfach die Zeit vor und nach der Ausführung vergleichen.

Wenn Sie dies tun möchten, müssen Sie zuerst eine glFinish() ausführen, damit es tatsächlich auf alle zuvor gepufferten GL-Aufrufe warten muss, und dann können Sie mit dem Zählen beginnen, die Aufrufe ausführen, die Sie benchmarken möchten. Rufen Sie glFinish erneut auf, um sicherzustellen, dass diese Aufrufe ebenfalls ausgeführt werden, und beenden Sie dann den Benchmark.

Auf der anderen Seite sagte ich "meistens". Dies liegt daran, dass Lesefunktionen tatsächlich mit der GPU synchronisiert werden müssen, um echte Ergebnisse zu zeigen. In diesem Fall warten sie also und frieren den Hauptthread ein.

edit: Ich denke, die Erklärung selbst beantwortet die Frage, die Sie gefragt zweitens, aber nur für den Fall: die Tatsache, dass alle Anrufe gepuffert sind machen es möglich, eine Verlosung zuerst abzuschließen, und ändern Sie anschließend eine Einstellung für aufeinanderfolgende Anrufe

+0

also lesen Funktionen implizit glFinish() aufrufen? –

+0

@DanWebster: [\ * hust \ *] (http://www.opengl.org/wiki/Synchronization) –

1

Es hängt ausschließlich von dem OpenGL-Aufruf und dem OpenGL-Status ab. Wenn Sie OpenGL-Aufrufe ausführen, reiht die Implementierung sie zunächst intern in die Warteschlange ein und führt sie dann asynchron zur Ausführung des aufrufenden Programms aus. Ein wichtiges Konzept von OpenGL sind Synchronisationspunkte. Dies sind Vorgänge in der Arbeitswarteschlange, bei denen der OpenGL-Aufruf blockiert werden muss, bis bestimmte Bedingungen erfüllt sind.

OpenGL-Objekte (Texturen, Pufferobjekte, etc.) sind rein abstrakt und per Spezifikation das Handle eines Objekts im Client-Programm immer auf die Daten, das Objekt hat zum Aufrufzeitpunkt von OpenGL-Funktionen, die auf dieses Objekt verweisen. So nehmen beispielsweise diese Sequenz:

glBindTexture(GL_TEXTURE_2D, texID); 

glTexImage2D(..., image_1); 
draw_textured_quad(); 

glTexImage2D(..., image_2); 
draw_textured_quad(); 

Die erste draw_textured_quad zurückkehren kann sogar lange bevor irgendetwas gezogen wurde. Durch die Aufrufe erzeugt OpenGL jedoch einen internen Verweis auf die Daten, die derzeit von der Textur gehalten werden. Wenn also glTexImage2D ein zweites Mal aufgerufen wird, was vor dem Zeichnen des ersten Quads passieren kann, muss OpenGL intern ein sekundäres Texturobjekt erstellen, das zur Textur texID wird und von den zweiten Aufrufen von draw_textured_quad verwendet wird. Wenn glTexSubImage2D aufgerufen wurde, müsste es sogar eine modifizierte Kopie davon machen.

OpenGL-Aufrufe werden nur blockiert, wenn das Ergebnis des Aufrufs den clientseitigen Speicher ändert und von Daten abhängt, die von früheren OpenGL-Aufrufen generiert wurden. Mit anderen Worten, wenn OpenGL-Aufrufe ausgeführt werden, generiert die OpenGL-Implementierung intern eine Abhängigkeitsstruktur, um zu verfolgen, was von was abhängt. Und wenn ein Synchronisationspunkt blockiert werden muss, blockiert er mindestens, bis alle Abhängigkeiten erfüllt sind.

Verwandte Themen