圖形架構

每位開發人員都應瞭解的介面、SurfaceHolder、EGLSurface、SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceFlinger 和 Vulkan 相關知識。

本頁面說明 Android 系統層級圖形架構的重要元素,以及應用程式架構和多媒體系統如何使用這些元素。重點在於圖形資料緩衝區如何在系統中移動。如果您曾想知道 SurfaceView 和 TextureView 為何會以這種方式運作,或是表面和 EGLSurface 如何互動,那麼您就來對的地方了。

您必須對 Android 裝置和應用程式開發有一定程度的瞭解。您不需要深入瞭解應用程式架構,且只提到少數 API 呼叫,但資料不會與其他公開文件重疊。我們的目標是詳細說明轉譯輸出影格時涉及的重要事件,協助您在設計應用程式時做出明智的選擇。為達成這個目標,我們會由下而上進行說明,說明 UI 類別的運作方式,而非說明如何使用這些類別。

本節包含多個頁面,涵蓋背景素材、HAL 詳細資料和用途等所有內容。首先會說明 Android 圖形緩衝區,接著說明合成和顯示機制,然後繼續說明為合成器提供資料的較高層級機制。建議您按照下列順序閱讀網頁,而非跳到感興趣的主題。

低階元件

  • BufferQueue 和 gralloc。BufferQueue 會將產生圖形資料緩衝區的項目 (producer) 連結至接受資料以供顯示或進一步處理的項目 (consumer)。緩衝區配置作業會透過 gralloc 記憶體配置器執行,該配置器會透過供應商專屬的 HAL 介面實作。
  • SurfaceFlinger、硬體 Composer 和虛擬螢幕。SurfaceFlinger 會接受來自多個來源的資料緩衝區,將其合成,然後傳送至螢幕。硬體合成器 HAL (HWC) 會判斷以可用硬體合成緩衝區的最有效率方式,而虛擬螢幕會在系統中提供合成輸出內容 (錄製螢幕畫面或透過網路傳送螢幕畫面)。
  • Surface、Canvas 和 SurfaceHolder。途徑會產生緩衝區佇列,而 SurfaceFlinger 通常會使用此佇列。將內容算繪至畫面時,結果會儲存在緩衝區中,並傳送至消費者。Canvas API 提供軟體實作 (支援硬體加速),可直接在途徑上繪製圖形 (低階的 OpenGL ES 替代方案)。任何與檢視畫面相關的內容都會涉及 SurfaceHolder,其 API 可用於取得及設定表面參數,例如大小和格式。
  • EGLSurface 和 OpenGL ESOpenGL ES (GLES) 定義了圖形算繪 API,可與 EGL 結合使用。EGL 是可透過作業系統建立及存取視窗的程式庫 (如要繪製有紋理的多邊形,請使用 GLES 呼叫;如要將算繪結果顯示在螢幕上,請使用 EGL 呼叫)。本頁面也將介紹 ANativeWindow,這是 C/C++ 等同於 Java Surface 類別,用於透過原生程式碼建立 EGL 視窗介面。
  • Vulkan。Vulkan 是一種用於高效能 3D 圖形的低成本跨平台 API。與 OpenGL ES 一樣,Vulkan 提供工具,可讓您在應用程式中製作高品質的即時圖形。Vulkan 的優點包括降低 CPU 負擔,並支援 SPIR-V 二進位中介語言。

高階元件

  • SurfaceView 和 GLSurfaceView。SurfaceView 結合了介面和檢視畫面。SurfaceView 的檢視畫面元件是由 SurfaceFlinger 組合,而非應用程式,因此可從獨立的執行緒/處理程序進行轉譯,並與應用程式 UI 轉譯作業隔離。GLSurfaceView 提供輔助類別,用於管理 EGL 情境、執行緒間通訊,以及與活動生命週期的互動 (但不必使用 GLES)。
  • SurfaceTexture。SurfaceTexture 會結合介面和 GLES 紋理,建立應用程式可用的 BufferQueue。當產生器將新緩衝區排入佇列時,會通知您的應用程式,後者會依序釋放先前保留的緩衝區、從佇列中取得新緩衝區,並發出 EGL 呼叫,讓緩衝區可供 GLES 做為外部紋理使用。Android 7.0 新增了安全紋理影片播放功能,可讓 GPU 對受保護的影片內容進行後製。
  • TextureView。TextureView 會將檢視畫面與 SurfaceTexture 結合。TextureView 會包裝 SurfaceTexture,並負責回應回呼和取得新的緩衝區。繪圖時,TextureView 會使用最近收到的緩衝區內容做為資料來源,並在檢視畫面狀態指示的任何位置和方式中算繪。檢視區塊合成作業一律會使用 GLES,這表示內容更新可能會導致其他檢視區塊元素重新繪製。