EGLSurfaces 和 OpenGL ES

Android 使用OpenGL ES (GLES) API 來渲染圖形。為了建立 GLES 上下文並為 GLES 渲染提供視窗系統,Android 使用EGL 庫。 GLES 呼叫渲染紋理多邊形,而 EGL 呼叫將渲染結果顯示在螢幕上。

在使用 GLES 進行繪製之前,您需要建立一個 GL 上下文。在 EGL 中,這意味著建立一個 EGLContext 和一個 EGLSurface。 GLES 操作適用於目前上下文,該上下文是透過執行緒本地儲存存取的,而不是作為參數傳遞。渲染程式碼應在目前 GLES 執行緒上執行,而不是在 UI 執行緒上執行。

EGL表面

EGLSurface 可以是由 EGL 分配的離屏緩衝區(稱為pbuffer ) ,也可以是由作業系統分配的視窗。呼叫eglCreateWindowSurface()函數建立EGL視窗表面。 eglCreateWindowSurface()將一個視窗物件作為參數,在 Android 上它是一個表面。 Surface 是 BufferQueue 的生產者端。使用者(SurfaceView、SurfaceTexture、TextureView 或 ImageReader)建立表面。當您呼叫eglCreateWindowSurface()時,EGL建立一個新的EGLSurface物件並將其連接到視窗物件的BufferQueue的生產者介面。從那時起,渲染到該 EGLSurface 會導致緩衝區出列、渲染到緩衝區中並排隊供消費者使用。

EGL 不提供鎖定/解鎖呼叫。發出繪圖指令,然後呼叫eglSwapBuffers()提交目前幀。方法名稱來自傳統的前後緩衝區交換,但實際實作可能有所不同。

一次只能有一個 EGLSurface 與一個表面關聯(只能有一個生產者連接到 BufferQueue),但如果您銷毀 EGLSurface,它就會與 BufferQueue 斷開連接並讓其他東西連接。

給定線程可以透過更改當前內容在多個 EGLSurface 之間切換。 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 的同義詞,因此您可以將其中一個強制轉換為另一個。