每一個開發(fā)者都應(yīng)該了解的關(guān)于 Surface,SurfaceHolder,EGLSurface,SurfaceView昭抒,GLSurfaceView,SurfaceTexture炼杖,TextureView灭返,SurfaceFlinger,和 Vulkan 的東西嘹叫。
本頁描述 Android 系統(tǒng)級圖形架構(gòu)的必要元素及應(yīng)用框架和多媒體系統(tǒng)如何使用它們婆殿。重點是圖形數(shù)據(jù)的緩沖區(qū)如何在系統(tǒng)中移動。如果你曾經(jīng)想知道為什么 SurfaceView 和 TextureView 有著那樣的行為罩扇,或 Surface 和 EGLSurface 如何交互婆芦,那你就來對地方了怕磨。
假設(shè)讀者熟悉 Android 設(shè)備和應(yīng)用開發(fā)。你不需要關(guān)于應(yīng)用框架的詳細知識消约,這里只會提到少量的 API 調(diào)用肠鲫,但這里的資料與其它公開的文檔不重疊。目標是提供關(guān)于渲染一幀用以輸出中牽涉的重要事件的詳情或粮,以幫助你在設(shè)計應(yīng)用時做出明智的選擇导饲。為了實現(xiàn)這一點,我們從底層開始氯材,描述 UI 類如何工作渣锦,而不是它們?nèi)绾问褂谩?/p>
這一節(jié)包含幾頁,覆蓋了從背景資料到 HAL 細節(jié)到使用案例的所有東西氢哮。這里從解釋 Android 圖形緩沖區(qū)開始袋毙,描述合成和顯示機制,然后是提供了數(shù)據(jù)合成器的更高層機制冗尤。我們建議你按下面列出的順序閱讀听盖,而不是直接跳到聽起來很有趣的主題。
底層組件
BufferQueue 和 gralloc裂七。BufferQueue 連接生成圖形數(shù)據(jù)緩沖區(qū)的東西(生產(chǎn)者)和接收數(shù)據(jù)來顯示或進一步處理的東西(消費者)皆看。緩沖區(qū)分配通過 gralloc 內(nèi)存分配器執(zhí)行, gralloc 內(nèi)存分配器通過一個特定于供應(yīng)商的 HAL 接口實現(xiàn)背零。
SurfaceFlinger腰吟,Hardware Composer,和虛擬顯示設(shè)備捉兴。SurfaceFlinger 接受來自于多個源的數(shù)據(jù)緩沖區(qū)蝎困,組合它們录语,然后發(fā)送給顯示設(shè)備倍啥。Hardware Composer HAL (HWC) 決定通過可用硬件和虛擬顯示設(shè)備以最高效的方式組合緩沖區(qū)使合成的輸出在系統(tǒng)內(nèi)可用(記錄屏幕或通過網(wǎng)絡(luò)發(fā)送屏幕)。
Surface澎埠,Canvas虽缕,和 SurfaceHolder。Surface 生產(chǎn)常常由 SurfaceFlinger 消費的緩沖區(qū)隊列蒲稳。當在一個 Surface 上渲染時氮趋,結(jié)果最終被放入緩沖區(qū)中,并被傳送給消費者江耀。Canvas APIs 為直接在一個 Surface (OpenGL ES 的低級替代品)繪制提供了一個軟件實現(xiàn)(通過硬件加速支持)剩胁。與 View 有關(guān)的任何事情都涉及到 SurfaceHolder,通過它的 API 可以獲取或設(shè)置 Surface 參數(shù)祥国,比如大小和格式等昵观。
EGLSurface 和 OpenGL ES晾腔。OpenGL ES (GLES) 定義了一個與 EGL 結(jié)合使用的圖形渲染 API,一個知道如何通過操作系統(tǒng)創(chuàng)建和訪問窗口的庫(繪制紋理多邊形啊犬,使用 GLES 調(diào)用灼擂;在屏幕上放置渲染結(jié)果,使用EGL調(diào)用觉至;)剔应。這頁還描述了 ANativeWindow,Java Surface 類的 C/C++ 等價物语御,用于在本地層代碼中創(chuàng)建一個 EGL 窗口峻贮。
Vulkan。Vulkan 是一個低開銷应闯,跨平臺的高性能 3D 圖形 API月洛。像 OpenGL ES 一樣,Vulkan 提供了在應(yīng)用中創(chuàng)建高品質(zhì)實時圖形的工具嚼黔。Vulkan 的優(yōu)勢包括降低 CPU 開銷并支持 SPIR-V Binary Intermediate 語言。
高層組件
SurfaceView 和 GLSurfaceView惜辑。SurfaceView 結(jié)合了一個 Surface 和一個 View唬涧。SurfaceView 的 View 組件由 SurfaceFlinger 合成 (而不是應(yīng)用)盛撑,可以在一個分開的線程/進程中渲染碎节,并與應(yīng)用的 UI 渲染隔離介粘。GLSurfaceView 提供了輔助類來管理 EGL contexts姻采,線程間通信雅采,及與 Activity 生命周期的交互(但使用 GLES 不是必需的)。
SurfaceTexture。SurfaceTexture 結(jié)合了一個 Surface 和 GLES texture 來創(chuàng)建一個 BufferQueue刑棵,你的應(yīng)用是該 BufferQueue 的消費者巴刻。當生產(chǎn)者入隊了一個新 buffer,它通知你的應(yīng)用蛉签,這反過來釋放了之前持有的 buffer胡陪,從隊列中獲取新的 buffer茂附,執(zhí)行 EGL 調(diào)用使得 buffer 可以作為 GLES 的一個外部 texture 使用。Android 7.0 添加了對安全 texture video playback的支持督弓,使得 GPU 可以后處理受保護的視頻內(nèi)容营曼。
TextureView。TextureView 結(jié)合了一個 View 和一個 SurfaceTexture愚隧。TextureView 包裝了一個 SurfaceTexture 并負責響應(yīng)回調(diào)和獲取新 buffers蒂阱。當繪制時,TextureView 使用最近接收的 buffer 的內(nèi)容作為它的數(shù)據(jù)源狂塘,根據(jù) View 的狀態(tài)繪制它录煤。View 合成總是由 GLES 執(zhí)行,意味著更新內(nèi)容可能導(dǎo)致其它的 View 元素也被重繪荞胡。