Android 使用OpenGL ES (GLES) API 來渲染圖形。為了創建 GLES 上下文並為 GLES 渲染提供窗口系統,Android 使用EGL 庫。 GLES 調用渲染紋理多邊形,而 EGL 調用將渲染放在屏幕上。
在使用 GLES 繪圖之前,您需要創建一個 GL 上下文。在 EGL 中,這意味著創建一個 EGLContext 和一個 EGLSurface。 GLES 操作適用於當前上下文,該上下文通過線程本地存儲訪問,而不是作為參數傳遞。渲染代碼應該在當前 GLES 線程上執行,而不是在 UI 線程上。
EGLSurfaces
EGLSurface 可以是由 EGL 分配的屏幕外緩衝區,稱為pbuffer ,或者是由操作系統分配的窗口。調用eglCreateWindowSurface()
函數創建 EGL 窗口表面。 eglCreateWindowSurface()
將窗口對像作為參數,在 Android 上是一個表面。表面是 BufferQueue 的生產者端。消費者(即 SurfaceView、SurfaceTexture、TextureView 或 ImageReader)創建表面。當您調用eglCreateWindowSurface()
時,EGL 會創建一個新的 EGLSurface 對象並將其連接到窗口對象的 BufferQueue 的生產者接口。從那時起,渲染到該 EGLSurface 會導致緩衝區出列、渲染並排隊供消費者使用。
EGL 不提供鎖定/解鎖調用。發出繪圖命令,然後調用eglSwapBuffers()
來提交當前幀。方法名來源於傳統的前後緩衝交換,但實際實現可能會有所不同。
一次只能將一個 EGLSurface 與一個表面關聯(您只能將一個生產者連接到 BufferQueue),但如果您銷毀 EGLSurface,它會斷開與 BufferQueue 的連接並讓其他東西連接。
一個給定的線程可以通過改變什麼是current在多個 EGLSurfaces 之間切換。 EGLSurface 一次只能在一個線程上是當前的。
EGL 不是表面的另一個方面(如 SurfaceHolder)。 EGLSurface 是一個相關但獨立的概念。您可以在沒有表面支持的 EGLSurface 上繪圖,也可以使用沒有 EGL 的表面。 EGLSurface 只是為 GLES 提供了一個繪圖的地方。
有關 OpenGL ES 和 EGL 要求,請參閱 Android兼容性定義文檔。
原生窗口
公共表麵類是用 Java 編程語言實現的。 C/C++ 中的等價物是 ANativeWindow 類,由Android NDK半公開。您可以使用ANativeWindow_fromSurface()
調用從表面獲取 ANativeWindow。就像它的 Java 語言表親一樣,您可以鎖定它、在軟件中渲染以及解鎖和發布。基本的原生窗口類型是 BufferQueue 的生產者端。
要從本機代碼創建 EGL 窗口表面,請將 EGLNativeWindowType 的實例傳遞給eglCreateWindowSurface()
。 EGLNativeWindowType 是 ANativeWindow 的同義詞,因此您可以將一個轉換為另一個。