2013-08-07 5 views
5

Ich entwickle eine OpenGL ES 2.0-Anwendung (mit Winkelprojekt unter Windows für die Entwicklung), die aus mehreren "Frames" besteht.EGL/OpenGL ES/Switching Context ist langsam

Jeder Rahmen ist eine isolierte Anwendung, die die umgebenden Rahmen nicht stören sollte. Die Frames werden mit OpenGL ES 2.0 gezeichnet, indem der Code in diesem Frame ausgeführt wird.

Mein erster Versuch war, jedem Rahmen einen Bildspeicher zuzuordnen. Aber es gab ein Problem - OpenGLs interne Zustände werden geändert, während ein Rahmen gezeichnet wird, und wenn der nächste Rahmen nicht jeden bekannten OpenGL-Zustand vollständig zurücksetzt, könnte es mögliche Nebenwirkungen geben. Dies vereitelt meine Anforderung, dass jeder Rahmen isoliert sein sollte und sich nicht gegenseitig beeinflussen sollte.

Mein nächster Versuch war es, einen Kontext pro Frame zu verwenden. Ich habe für jeden Frame einen eindeutigen Kontext erstellt. Ich benutze Sharing-Ressourcen, so dass ich eglMakeCurrent zu jedem Frame machen kann, rendere jedes zu ihrem eigenen Frame-Puffer/Textur, dann eglMakeCurrent zurück zu global, um jede Textur auf dem endgültigen Bildschirm zu verfassen.

Dies ist ein großer Job bei der Isolierung der Instanzen, aber .. eglMakeCurrent ist sehr langsam. So wenig wie 4 von ihnen können es eine Sekunde oder mehr dauern, um den Bildschirm zu rendern.

Welchen Ansatz kann ich verwenden? Gibt es eine Möglichkeit, den Kontextwechsel zu beschleunigen oder Kontextwechsel zu vermeiden, indem ich den OpenGL-Status pro Frame irgendwie speichere?

Antwort

-1

Das Problem hier ist zu versuchen, dies in einer allgemeinen Plattform und OS unabhängig zu tun. Wenn Sie eine bestimmte Plattform wählen, gibt es gute Lösungen. Unter Windows gibt es die Bibliotheken wgl und glut, die Ihnen mehrere Fenster mit vollständig unabhängigen OpenGL-Kontexten gleichzeitig zur Verfügung stellen. Sie heißen Windows, keine Frames. Sie könnten auch DirectX anstelle von OpenGL verwenden. Angle verwendet DirectX. Unter Linux ist die Lösung X11 für OpenGL. In jedem Fall ist es wichtig, hochwertige OpenGL-Treiber zu haben. Keine Intel Extreme Chipsatz Treiber. Wenn Sie dies auf Android oder iOS tun möchten, erfordern diese unterschiedliche Lösungen. Es gab einen kürzlichen Thread im Khronos.org OpenGL ES Forum über den Android Fall.

+0

Das Problem mit eglMakeCurrent existiert auf vielen Plattformen, selbst wenn die von der Plattform bereitgestellten EGL- und OpenGL ES-Bibliotheken unter Umgehung von ANGLE direkt verwendet werden. Das grundlegende Problem ist, dass eglMakeCurrent oft ein teurer Aufruf ist, da die EGL-Spezifikation effektiv erfordert, dass der Treiber glFlush intern aufruft, bevor eglMakeCurrent zurückgibt. glFlush kann viel CPU verbrauchen. Der EGLContext-Tausch trifft auch auf die Bestätigung des internen GL-Zustandsautomaten durch den Fahrer. – Chadversary

0

Ich habe einen Vorschlag, der den Overhead von eglMakeCurrent beseitigen kann, während Sie Ihren aktuellen Ansatz verwenden können.

Das Konzept des aktuellen EGLContext ist Thread-lokal. Ich schlage vor, alle Kontexte im Master-Thread des Prozesses zu erstellen, dann einen Thread pro Kontext zu erstellen und jedem Thread einen Kontext zu übergeben. Während der Initialisierung jedes Threads ruft er eglMakeCurrent für den zugehörigen Kontext auf und ruft nie wieder eglMakeCurrent auf. Bei der Implementierung von ANGLE wird der Thread-lokale Speicher für Kontexte hoffentlich effizient implementiert und hat keinen unnötigen Synchronisationsaufwand.