Android 12(S) 圖像顯示系統 - 基本概念(一)



必讀:

Android 12(S) 圖像顯示系統 - 開篇


請關注公眾號,閱讀 修正錯誤、基於最新Android版本的解讀 !

1 前言

Android圖形系統是系統框架中一個非常重要的子系統,與其它子系統一樣,Android 框架提供了各種用於 2D 和 3D 圖形渲染的 API供開發者使用來創建絢麗多彩的應用APP。圖形渲染的 API的底層可與制造商的圖形驅動程序實現代碼交互,了解這些API的工作原理及圖形系統框架層的處理邏輯可以幫助我們更好的使用這些功能。

本系列文章將側重於圖形系統BufferQueue的知識做分析講解。BufferQueues 是 Android 圖形組件之間的粘合劑,BufferQueue 類將生成圖形數據緩沖區的組件(producers)連接到接受數據以便進行顯示或進一步處理的組件(consumers)。幾乎所有在系統中移動圖形數據緩沖區的內容都依賴於 BufferQueue。理解BufferQueue的工作邏輯及圖形緩沖區移動流程對於我們學習Android圖形系統工作機制非常重要。

本篇作為該系列的開篇,我們將從Android圖形系統的一些基本概念入手。

接下來就開始我們的學習之旅。

注:本系列文章的分析及代碼均基於Android 12(S) Source Code,可參考:http://aospxref.com/ http://aosp.opersys.com/


 

2 Android圖形系統基本概述


 

2.1 Android 圖形組件

Android圖形系統涉及到非常多的組件,比如 Surface、SurfaceHolder、EGLSurface、SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceFlinger等,比如下圖展示的:

低級別組件

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

高級別組件

  • SurfaceView 和 GLSurfaceView。SurfaceView 結合了 Surface 和 View。SurfaceView 的 View 組件由 SurfaceFlinger(而不是應用)合成,從而可以通過單獨的線程/進程渲染,並與應用界面渲染隔離。GLSurfaceView 提供了用於管理 EGL 上下文、線程間通信以及與 Activity 生命周期的交互的輔助程序類(但不是必須使用 GLES)。
  • SurfaceTexture。 SurfaceTexture 將 Surface 和 GLES 紋理相結合來創建 BufferQueue,而您的應用是 BufferQueue 的消費者。當生產者將新的緩沖區排入隊列時,它會通知您的應用。您的應用會依次釋放先前占用的緩沖區,從隊列中獲取新緩沖區並執行 EGL 調用,從而使 GLES 可將此緩沖區作為外部紋理使用。Android 7.0 添加了對安全紋理視頻播放的支持,以便對受保護的視頻內容進行 GPU 后處理。
  • TextureView。 TextureView 結合了 View 和 SurfaceTexture。TextureView 對 SurfaceTexture 進行包裝,並負責響應回調以及獲取新的緩沖區。在繪圖時,TextureView 使用最近收到的緩沖區的內容作為其數據源,根據 View 狀態指示,在它應該渲染的任何位置和以它應該采用的任何渲染方式進行渲染。View 合成始終通過 GLES 來執行,這意味着內容更新可能會導致其他 View 元素重繪。

Android圖形組件相互配合、溝通,共同組成一個完善的圖形顯示子系統,同時在Java level與Native level面向開發者提供了可編程的接口。


 

2.2 Android 圖形組件協同工作

無論開發者使用什么渲染 API,一切內容都會渲染到 Surface 上。Surface 表示緩沖區隊列中的生產者,而緩沖區隊列通常會被 SurfaceFlinger 消耗。在 Android 平台上創建的每個窗口都由 Surface 提供支持。所有被渲染的可見 Surface 都被 SurfaceFlinger 合成到屏幕。

下圖顯示了關鍵組件如何協同工作:

 

對於Android 12 后的系統,我自己理解下圖來表示各個組件間的協同工作:

或者如下這個圖:

 

 

從工作流程的角度去看,主要組件如下所述:

圖像流生產者(Image Stream Producers)

圖像流生產者可以是生成圖形緩沖區以供消耗的任何內容。例如 OpenGL ES、Canvas 2D 和 mediaserver 視頻解碼器。

圖像流消費者(Image stream consumers)

圖像流的最常見消費者是 SurfaceFlinger,該系統服務會消耗當前可見的 Surface,並使用窗口管理器中提供的信息將它們合成到屏幕。SurfaceFlinger 是可以修改所顯示部分內容的唯一服務。SurfaceFlinger 使用 OpenGL 和 Hardware Composer 來合成一組 Surface。

其他 OpenGL ES 應用也可以消耗圖像流,例如相機應用會消耗相機預覽圖像流。非 GL 應用也可以是使用方,例如 ImageReader 類。

硬件混合渲染器(Hardware Composer)

顯示子系統的硬件抽象實現。SurfaceFlinger 可以將某些合成工作委托給硬件混合渲染器(HWC),以分擔 OpenGL 和 GPU 上的工作量。SurfaceFlinger 只是充當另一個 OpenGL ES 客戶端。因此,在 SurfaceFlinger 將一個或兩個緩沖區合成到第三個緩沖區中的過程中,它會使用 OpenGL ES。這會讓合成的功耗比通過 GPU 執行所有計算時更低。

硬件混合渲染器 HAL 則進行另一半的工作,是所有 Android 圖形渲染的中心點。Hardware Composer 必須支持事件,其中之一是 VSYNC(另一個是支持即插即用 HDMI 的熱插拔)。

Gralloc可以理解為圖形內存分配器,用來分配和管理圖像生產者請求的內存(即圖形數據緩沖區Graphic Buffers)


二的次方

有關 Android graphics pipeline的描述,請參見下圖:圖形數據流

 

  • 左側的對象是生成圖形緩沖區的渲染器,如主屏幕、狀態欄和系統界面。
  • SurfaceFlinger 是合成器,接受多個來源的圖形顯示數據,將他們合成,然后發送到顯示設備。
  • 硬件混合渲染器HWC是制作器。SurfaceFlinger與HWC配合用來將 Surface 合成到屏幕

BufferQueues 是 Android 圖形組件之間的粘合劑。它們是一對圖像緩沖區隊列,可以調解緩沖區從生產者到消費者的固定周期。一旦生產者移交其緩沖區,SurfaceFlinger 便會負責將所有內容合成到顯示部分。

有關 BufferQueue 通信過程,請參見下圖。

 

BufferQueue 包含將圖像流生產者與圖像流消費者結合在一起的邏輯。BufferQueue 類是 Android 中所有圖形處理操作的核心。它的作用很簡單:將生成圖形數據緩沖區的一方(生產方)連接到接受數據以進行顯示或進一步處理的一方(消耗方)。幾乎所有在系統中移動圖形數據緩沖區的內容都依賴於 BufferQueue。

通過上圖我們可以大概看到BufferQueue的工作過程:

  1. 圖像生產者通過調用dequeue方法向BufferQueue請求一塊圖形緩沖區內存,即一塊GraphicBuffer;
  2. 圖像生產者將產生的圖像數據(比如相機預覽的圖像或解碼器解碼出的視頻幀)寫入圖形緩沖區GraphicBuffer,並通過queue方法提交給BufferQueue;
  3. BufferQueue收到圖形緩沖區GraphicBuffer的入隊列消息,通知圖像消費者調用acquire方法取得已填充數據的buffer進行處理或顯示;
  4. 圖像消費者處理完畢,調用release方法把buffer歸還給BufferQueue,這個buffer之后可再重復使用;
  5. 圖像生產者、BufferQueue、圖像消費者協調工作,圖形緩沖區buffer在三者之間協調流轉,圖像便流暢的顯示或處理。

 

3 小結

通過上面的一些介紹,我們對Android圖形系統的一些基本組成及概念有了一個大概的了解。為了更深刻的理解這些抽象的內容,下一篇文章我們將從Native Level入手,基於Android圖形系統API寫作一個簡單的圖形處理小程序。

 


必讀:

Android 12(S) 圖像顯示系統 - 開篇


 

 

 

 


參考

https://www.jianshu.com/p/824a9ddf68b9

https://www.cnblogs.com/1996swg/p/9790209.html

https://source.android.com/devices/graphics

https://www.pianshen.com/article/98181094083/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM