2013-08-07 189 views
5

我正在開發一個由多個「幀」組成的OpenGL ES 2.0應用程序(在Windows上使用angularproject進行開發)。EGL/OpenGL ES /切換上下文很慢

每個框架是一個獨立的應用程序,不應該干擾周圍的框架。框架使用OpenGL ES 2.0,通過在該框架內運行的代碼繪製。

我的第一次嘗試是爲每個幀分配一個幀緩衝區。但是有一個問題 - OpenGL的內部狀態在一幀正在繪製時發生變化,如果下一幀沒有全面重置每個已知的OpenGL狀態,則可能會產生副作用。這違背了我的要求,即每個框架應該被隔離並且不會互相影響。

我的下一個嘗試是每幀使用上下文。我爲每一幀創建了一個獨特的上下文。我正在使用共享資源,以便我可以爲每個幀創建當前幀,將每個幀渲染到自己的幀緩衝區/紋理,然後eglMakeCurrent返回到全局,以將每個紋理組合到最終屏幕。

這在隔離實例方面做得很好,但是.. eglMakeCurrent是很慢很慢。只要其中4個可以讓它花費一秒或更多的時間來渲染屏幕。

我可以採取什麼方法?有沒有一種方法可以加速上下文切換,或通過某種方式避免上下文切換每幀保存OpenGL狀態?

回答

-1

這裏的問題是試圖以通用的平臺和操作系統無關的方式來做到這一點。如果你選擇一個特定的平臺,有很好的解決方案。在Windows上,有wgl和glut庫,它們將爲您提供多個窗口,並且同時運行完全獨立的OpenGL上下文。它們被稱爲Windows,而不是幀。你也可以使用DirectX代替OpenGL。 Angle使用DirectX。在Linux上,解決方案是用於OpenGL的X11。無論哪種情況,擁有高質量的OpenGL驅動程序都至關重要。沒有Intel Extreme芯片組驅動程序。如果您想在Android或iOS上執行此操作,那麼需要不同的解決方案。 Khronos.org OpenGL ES論壇最近有關於Android案例的帖子。

+0

即使直接使用平臺提供的EGL和OpenGL ES庫,繞過ANGLE,eglMakeCurrent的問題仍存在於許多平臺上。根本問題是eglMakeCurrent通常是一個昂貴的調用,因爲EGL規範有效地要求驅動程序在eglMakeCurrent返回之前內部調用glFlush。 glFlush可以燒燬很多CPU。 EGLContext交換也在驅動程序驗證其內部GL狀態機器時發生抖動。 – Chadversary

0

我有一個建議,可以消除eglMakeCurrent的開銷,同時允許您使用您當前的方法。

當前EGLContext的概念是線程本地的。我建議在進程的主線程中創建所有上下文,然後在每個上下文中創建一個線程,並將一個上下文傳遞給每個線程。在每個線程的初始化過程中,它將在它擁有的上下文中調用eglMakeCurrent,並且不會再次調用eglMakeCurrent。希望在ANGLE的實現中,上下文的線程本地存儲被高效地實現,並且沒有不必要的同步開銷。