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

二的次方發表於2022-01-19




 

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 合成到螢幕。

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

影像渲染元件

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

影像流生產者(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 包含將影像流生產者與影像流消費者結合在一起的邏輯。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/

 

相關文章