EGLSurfaces 和 OpenGL ES
OpenGL ES 定義了一個渲染圖形的 API。它沒有定義窗口系統。為了使 GLES 可以工作于各種平臺之上,它被設計為與知道如何通過操作系統創建和訪問窗口的庫相結合。Android 使用的庫稱為 EGL。如果你想繪制紋理多邊形,你使用 GLES 調用;如果你想將渲染的東西放在屏幕上,則使用 EGL 調用。
在你可以通過 GLES 做任何事情之前,你需要創建一個 GL 上下文。在 EGL 中,這意味著創建一個 EGLContext 和一個 EGLSurface。GLES 操作應用于當前上下文,其通過線程局部存儲訪問而不是作為參數傳遞。這意味著你不得不小心你的渲染代碼正在哪個線程中執行,以及那個線程的當前上下文是哪個。
EGLSurfaces
EGLSurface 可以是一個 EGL 分配的離屏緩沖區 (稱為 "pbuffer") 或由操作系統分配的窗口。EGL 窗口 surfaces 由 eglCreateWindowSurface() 調用創建。它接收一個 "窗口對象" 作為參數,在 Android 上它可以是一個 SurfaceView,SurfaceTexture,SurfaceHolder 或 Surface -- 所有在底層具有 BufferQueue 的東西。當你執行這個調用時,EGL 創建一個新的 EGLSurface 對象,將它與窗口對象的 BufferQueue 的生產者接口連接。從那時起,向那個 EGLSurface 渲染將使得一個緩沖區被取出,向其中渲染,并放回以由消費者使用。(術語“窗口” 表示預期的用途,但請記住,輸出可能不會出現在顯示器上。)
EGL 不提供鎖定/解鎖調用。相反,你發出繪制命令并調用 eglSwapBuffers() 來提交當前的幀。方法名來自于傳統的交換前后臺緩沖區,但實際的實現可能非常不同。
同一時間只有一個 EGLSurface 可以與一個 Surface 關聯 -- 你只能有一個生產者與一個 BufferQueue 連接 -- 但是如果你銷毀了 EGLSurface 它將從 BufferQueue 斷開,并允許其它東西連接。
一個給定的線程可以通過修改什么是當前的 EGLSurface 在多個 EGLSurface 之間切換。同一時間一個 EGLSurface 只能是一個線程的當前 EGLSurface。
與 EGLSurface 有關的最常見的錯誤是假設它只是 Surface 的另一方面(像 SurfaceHolder 一樣)。它是相關但獨立的概念。你可以在一個后端沒有 Surface 支持的 EGLSurface 上繪制,且你可以不通過 EGL 使用 Surface。EGLSurface 僅僅給了 GLES 一個繪制的平面。
ANativeWindow
公共的 Surface 類是以 Java 編程語言實現的。C/C++ 中等價的東西是 ANativeWindow ,由 Android NDK 半曝光出來。你可以通過 ANativeWindow_fromSurface() 調用從 Surface 獲得 ANativeWindow。就像它的 Java 語言兄弟,你可以鎖定它,以軟件渲染,然后解鎖并post。
要在本地層代碼中創建一個 EGL 窗口 surface,你傳遞一個 EGLNativeWindowType 的實例給 eglCreateWindowSurface()。EGLNativeWindowType 只是 ANativeWindow 的一個同義詞,因此你可以自由地將一個強制類型轉換為另一個。
基本的 “本地窗口” 類型只是封裝了一個 BufferQueue 的生產者端的事實應該不會讓人感到意外。
原文
總結
以上是生活随笔為你收集整理的EGLSurfaces 和 OpenGL ES的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SurfaceFlinger 和 Har
- 下一篇: Vulkan