圖形架構

每個開發人員都應該了解 Surface、SurfaceHolder、EGLSurface、SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceFlinger 和 Vulkan。

本頁介紹了 Android 系統級圖形架構的基本元素以及應用程序框架和多媒體系統如何使用它們。重點是圖形數據的緩衝區如何在系統中移動。如果您曾經想知道為什麼 SurfaceView 和 TextureView 會以它們的方式運行,或者表面和 EGLSurface 如何交互,那麼您來對地方了。

假設您熟悉 Android 設備和應用程序開發。您不需要應用程序框架的詳細知識,並且很少提及 API 調用,但該材料與其他公共文檔不重疊。目的是提供有關渲染輸出幀所涉及的重要事件的詳細信息,以幫助您在設計應用程序時做出明智的選擇。為了實現這一點,我們自下而上地工作,描述 UI 類是如何工作的,而不是如何使用它們。

本節包括幾個頁面,涵蓋從背景材料到 HAL 詳細信息再到用例的所有內容。它首先解釋了 Android 圖形緩衝區,描述了合成和顯示機制,然後繼續向合成器提供數據的更高級別的機制。我們建議按照下面列出的順序閱讀頁面,而不是跳到聽起來很有趣的主題。

低級組件

  • BufferQueue 和 gralloc 。 BufferQueue 將生成圖形數據緩衝區的東西(生產者)連接到接受數據以進行顯示或進一步處理的東西(消費者)。緩衝區分配是通過通過供應商特定 HAL 接口實現的gralloc內存分配器執行的。
  • SurfaceFlinger、Hardware Composer 和虛擬顯示器。 SurfaceFlinger 接受來自多個源的數據緩衝區,組合它們,然後將它們發送到顯示器。 Hardware Composer HAL (HWC) 確定使用可用硬件合成緩衝區的最有效方式,虛擬顯示器使合成輸出在系統內可用(記錄屏幕或通過網絡發送屏幕)。
  • 表面、畫布和 SurfaceHolder 。 Surface 會產生一個緩衝區隊列,通常由 SurfaceFlinger 使用。當渲染到表面上時,結果最終會在一個緩衝區中發送給消費者。 Canvas API 提供了一種軟件實現(具有硬件加速支持),用於直接在表面上繪圖(OpenGL ES 的低級替代方案)。與視圖有關的任何事情都涉及 SurfaceHolder,其 API 可以獲取和設置表面參數,例如大小和格式。
  • EGLSurface 和 OpenGL ESOpenGL ES (GLES)定義了一個圖形渲染 API,旨在與EGL結合,EGL 是一個可以通過操作系統創建和訪問窗口的庫(繪製紋理多邊形,使用 GLES 調用;將渲染放在屏幕上,使用 EGL 調用)。本頁還介紹了 ANativeWindow,它是 Java Surface 類的 C/C++ 等價物,用於從本機代碼創建 EGL 窗口表面。
  • 伏爾甘。 Vulkan 是用於高性能 3D 圖形的低開銷、跨平台 API。與 OpenGL ES 一樣,Vulkan 提供了用於在應用程序中創建高質量實時圖形的工具。 Vulkan 的優勢包括減少 CPU 開銷和支持SPIR-V 二進制中間語言。

高級組件

  • SurfaceView 和 GLSurfaceView 。 SurfaceView 結合了表面和視圖。 SurfaceView 的視圖組件由 SurfaceFlinger(而不是應用程序)組合而成,可以從單獨的線程/進程進行渲染,並與應用程序 UI 渲染隔離。 GLSurfaceView 提供幫助類來管理 EGL 上下文、線程間通信以及與活動生命週期的交互(但不是使用 GLES 所必需的)。
  • 表面紋理。 SurfaceTexture 結合了一個表面和 GLES 紋理來創建一個 BufferQueue,你的應用程序是它的消費者。當生產者對一個新緩衝區進行排隊時,它會通知您的應用程序,該應用程序又會釋放先前持有的緩衝區,從隊列中獲取新緩衝區,並進行 EGL 調用以使 GLES 可以將緩衝區作為外部紋理使用。 Android 7.0 增加了對安全紋理視頻播放的支持,支持對受保護的視頻內容進行 GPU 後處理。
  • 紋理視圖。 TextureView 將視圖與 SurfaceTexture 組合在一起。 TextureView 包裝了一個 SurfaceTexture 並負責響應回調和獲取新的緩衝區。繪製時,TextureView 使用最近接收到的緩衝區的內容作為其數據源,在視圖狀態指示的任何位置進行渲染。視圖合成始終使用 GLES 執行,這意味著對內容的更新也可能導致其他視圖元素重繪。