每個開發人員都應該了解有關 Surface、SurfaceHolder、EGLSurface、SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceFlinger 和 Vulkan 的知識。
本頁介紹了 Android 系統級圖形架構的基本元素以及應用程式框架和多媒體系統如何使用它們。重點是圖形資料緩衝區如何在系統中移動。如果您想知道為什麼 SurfaceView 和 TextureView 的行為方式如此,或者表面和 EGLSurface 如何交互,那麼您來對地方了。
假設您對 Android 裝置和應用程式開發有一定的了解。您不需要了解應用程式框架的詳細知識,並且很少提及 API 調用,但該資料不會與其他公共文件重疊。目標是提供渲染輸出幀所涉及的重要事件的詳細信息,以幫助您在設計應用程式時做出明智的選擇。為了實現這一點,我們從下往上工作,描述 UI 類別如何運作,而不是如何使用它們。
本節包括幾個頁面,涵蓋從背景資料到 HAL 詳細資訊再到用例的所有內容。它首先解釋 Android 圖形緩衝區,描述合成和顯示機制,然後繼續介紹為合成器提供資料的更高層級的機制。我們建議按下面列出的順序閱讀頁面,而不是跳到聽起來有趣的主題。
低階組件
- BufferQueue 和 gralloc 。 BufferQueue 將產生圖形資料緩衝區的物件(生產者)連接到接受資料以進行顯示或進一步處理的物件(消費者)。緩衝區分配是透過gralloc記憶體分配器執行的,該分配器透過供應商特定的 HAL 介面實現。
- SurfaceFlinger、Hardware Composer 和虛擬顯示器。 SurfaceFlinger 接受來自多個來源的資料緩衝區,將它們組合起來,然後將它們傳送到顯示器。硬體合成器 HAL (HWC) 確定將緩衝區與可用硬體進行合成的最有效方法,並且虛擬顯示器使合成輸出在系統內可用(記錄螢幕或透過網路發送螢幕)。
- Surface、畫布和 SurfaceHolder 。 Surface 會產生一個經常被 SurfaceFlinger 使用的緩衝區佇列。當渲染到表面上時,結果最終會儲存在緩衝區中並發送給消費者。 Canvas API 提供了直接在表面上繪圖的軟體實作(具有硬體加速支援)(OpenGL ES 的低階替代方案)。與視圖相關的任何內容都涉及 SurfaceHolder,其 API 可取得和設定表面參數,例如大小和格式。
- EGLSurface 和 OpenGL ES 。 OpenGL ES (GLES)定義了一個圖形渲染 API,旨在與EGL結合使用,EGL 是一個可以透過作業系統建立和存取視窗的函式庫(要繪製紋理多邊形,請使用GLES 呼叫;要將渲染放在螢幕上,請使用EGL 呼叫)。本頁也介紹了 ANativeWindow,它是 Java Surface 類別的 C/C++ 等效項,用於從本機程式碼建立 EGL 視窗表面。
- 伏爾甘。 Vulkan 是一種低開銷、跨平台的 API,用於高效能 3D 圖形。與 OpenGL ES 一樣,Vulkan 提供了在應用程式中創建高品質即時圖形的工具。 Vulkan 的優點包括減少 CPU 開銷以及支援SPIR-V 二進位中間語言。
進階組件
- SurfaceView 和 GLSurfaceView 。 SurfaceView 結合了表面和視圖。 SurfaceView 的視圖元件由 SurfaceFlinger(而不是應用程式)合成,從而能夠從單獨的執行緒/進程進行渲染,並與應用程式 UI 渲染隔離。 GLSurfaceView 提供協助程式類別來管理 EGL 上下文、執行緒間通訊以及與活動生命週期的互動(但不需要使用 GLES)。
- 表面紋理。 SurfaceTexture 結合了表面和 GLES 紋理來建立一個 BufferQueue,而您的應用程式是該 BufferQueue 的使用者。當生產者對新緩衝區進行排隊時,它會通知您的應用程序,您的應用程式會釋放先前持有的緩衝區,從佇列中獲取新緩衝區,並進行EGL 呼叫以使該緩衝區可作為外部紋理供GLES 使用。 Android 7.0 增加了對安全紋理影片播放的支持,從而可以對受保護的影片內容進行 GPU 後處理。
- 紋理視圖。 TextureView 將視圖與 SurfaceTexture 組合在一起。 TextureView 包裝了一個 SurfaceTexture 並負責回應回呼並取得新的緩衝區。繪製時,TextureView 使用最近接收的緩衝區的內容作為其資料來源,在視圖狀態指示的任何位置和方式進行渲染。視圖合成始終使用 GLES 執行,這意味著內容更新也可能導致其他視圖元素重繪。