圖像

Android Graphics HAL 圖示

Android 架構提供多種 2D 和 3D 圖形算繪 API,可與製造商實作的圖形驅動程式互動,因此請務必深入瞭解這些 API 的運作方式。本頁面將介紹這些驅動程式所建構的圖形硬體抽象層 (HAL)。繼續本節之前,請先熟悉下列用語:

畫布 (一般用語)、Canvas (API 元素)
畫布是繪圖表面,可處理實際位元與點陣圖或 Surface 物件的合成作業。Canvas 類別提供的方法可繪製標準電腦點陣圖、線條、圓形、矩形、文字等,並繫結至點陣圖或表面。畫布是繪製螢幕上 2D 物件最簡單的方式。基礎類別為 Canvas
可繪項目
可繪項目是經過編譯的視覺資源,可用於背景、標題或畫面的其他部分。可繪項目通常會載入其他 UI 元素,例如做為背景圖片。可繪項目無法接收事件,但會指派各種其他屬性 (例如狀態和排程),以啟用動畫物件或圖片程式庫等子類別。許多可繪物件都是從可繪資源檔案載入,也就是描述圖片的 XML 或點陣圖檔案。可繪製資源會編譯為 android.graphics.drawable 的子類別。如要進一步瞭解可繪項目和其他資源,請參閱「應用程式資源總覽」。
版面配置資源
版面配置資源是 XML 檔案,用於說明活動畫面的版面配置。詳情請參閱「版面配置資源」。
nine-patch (9-patch、NinePatch)
Nine-patch 是可調整大小的點陣圖資源,可用於裝置上的背景或其他圖片。詳情請參閱「九格修補程式」。
OpenGL ES
OpenGL ES 是一種跨平台 API,可算繪 2D 和 3D 圖形。Android 提供 OpenGL ES 程式庫,用於硬體加速 3D 算繪。如果是 2D 算繪,畫布是較簡單的選項。OpenGL ES 位於 Android Native Development Kit (NDK) 中。android.opengljavax.microedition.khronos.opengles 套件會公開 OpenGL ES 功能。
介面 (一般用語)、Surface (API 元素)
:介面代表要合成到螢幕的記憶體區塊。介面會保留用於繪製的畫布,並提供各種輔助方法來繪製圖層和調整 Surface 物件大小。請改用 SurfaceView 類別,而非直接使用 Surface 類別。
介面檢視區塊 (一般用語)、SurfaceView (API 元素)
表面檢視區塊是包裝 Surface 物件的 View 物件,用於繪製內容,並公開方法來動態指定大小和格式。SurfaceView 可獨立於 UI 執行緒繪製,適用於遊戲或相機預覽等耗用大量資源的作業,但會因此使用額外記憶體。SurfaceView 同時支援畫布和 OpenGL ES 圖形。SurfaceView 物件的基底類別為 SurfaceView
主題
主題是一組屬性,例如文字大小和背景顏色,這些屬性會組合在一起,定義各種預設顯示設定。Android 提供幾種標準主題,列於 R.style,並以 Theme_ 為前置字元。
檢視 (一般用語)、View (API 元素)
檢視區塊會在畫面上繪製矩形區域,並處理點擊、按鍵和 其他互動事件。View 類別是活動或對話方塊畫面中大多數版面配置元件 (例如文字方塊和視窗) 的基礎類別。View 物件會接收來自父項物件的呼叫 (請參閱 ViewGroup),以便自行繪製,並向父項物件告知偏好大小和位置,但父項物件可能不會遵守這些資訊。詳情請參閱 View
檢視群組 (一般用語)、ViewGroup (API 元素)
檢視區塊群組會將一組子項檢視畫面分組。檢視區塊群組負責決定子項檢視畫面放置的位置和大小,以及在適當時間呼叫每個子項檢視畫面自行繪製。有些檢視畫面群組是隱藏的,僅供版面配置使用,有些則具有內建 UI,例如捲動清單方塊。檢視群組位於 android.widget 套件中,但會擴充 ViewGroup 類別。
檢視區塊階層
檢視區塊階層是檢視區塊和檢視區塊群組物件的排列方式,可定義應用程式每個元件的使用者介面。階層包含一或多個子項檢視區塊或檢視區塊群組的檢視區塊群組。您可以使用 Android SDK 隨附的階層檢視器,取得檢視區塊階層的視覺化表示法,以便進行偵錯和最佳化。
Vulkan
Vulkan 是一款低負載的跨平台 API,可用於製作高品質 3D 圖像。
小工具
小工具是一組完整實作的檢視區塊子類別,可算繪表單元素和其他 UI 元件,例如文字方塊或彈出式選單。由於小工具已完整實作,因此會自行處理測量、繪製及回應畫面事件。小工具位於 android.widget 套件中。
視窗 (一般用語)、Window (API 元素)
在 Android 應用程式中,視窗是衍生自 Window 抽象類別的物件,可指定一般視窗的元素,例如外觀和風格、標題列文字,以及選單的位置和內容。對話方塊和活動會使用 Window 類別的實作項目,來算繪 Window 物件。您不需要在應用程式中實作 Window 類別或使用視窗。

應用程式開發人員可以透過三種方式將圖像繪製成螢幕畫面:使用 Canvas OpenGL ES Vulkan

Android 圖像元件

無論開發人員使用哪種算繪 API,所有內容都會算繪到表面上。這個介面代表緩衝區佇列的生產者端,通常由 SurfaceFlinger 耗用。在 Android 平台上建立的每個視窗都會以介面為後盾。SurfaceFlinger 會將所有顯示的介面合成到螢幕上。

下圖顯示主要元件如何協同運作:

圖片顯示元件

圖 1. 平台如何算繪。

以下各節將說明主要元件。

影像串流製作人

圖片串流製作工具可以是任何產生圖形緩衝區供使用的項目。例如 OpenGL ES、Canvas 2D 和 mediaserver 影片解碼器。

映像檔串流消費者

最常見的圖像串流消費者是 SurfaceFlinger,這個系統服務會使用 Window Manager 提供的資訊,取用目前可見的介面,並將其合成到螢幕上。只有 SurfaceFlinger 服務可以修改螢幕內容。SurfaceFlinger 會使用 OpenGL 和硬體合成器 (HWC) 合成一組介面。

其他 OpenGL ES 應用程式也可以使用圖像串流,例如相機應用程式使用相機預覽圖像串流。非 GL 應用程式也可以是消費者,例如 ImageReader 類別。

硬體 Composer

顯示子系統的硬體抽象化。SurfaceFlinger 可以將特定合成工作委派給 HWC,藉此卸載 OpenGL 和 GPU 的工作。SurfaceFlinger 只是另一個 OpenGL ES 用戶端。因此,當 SurfaceFlinger 主動將一或兩個緩衝區合成到第三個緩衝區時,會使用 OpenGL ES。因此,相較於讓 GPU 執行所有運算,合成作業的耗電量較低。

硬體 Compositor HAL 負責執行另一半的工作,是所有 Android 圖像算繪的中心點。HWC 必須支援事件,其中一個是 VSync (另一個是熱插拔,用於支援隨插即用的 HDMI)。

Gralloc

圖像記憶體分配器 (Gralloc) 可分配圖像製作工具要求的記憶體。詳情請參閱「BufferQueue 和 Gralloc」。

資料流程

下圖說明 Android 圖形管道:

圖形資料流程

圖 2. Android 的圖形資料流程。

左側的物件是產生圖形緩衝區的算繪器,例如主畫面、狀態列和系統 UI。SurfaceFlinger 是合成器,HWC 則是合成器。

BufferQueue

BufferQueue 可在 Android 圖形元件之間提供黏著劑。這是一對佇列,可調解從生產者到消費者的緩衝區持續循環。製作人交出緩衝區後,SurfaceFlinger 負責將所有內容合成到螢幕上。

下圖說明 BufferQueue 通訊程序:

BufferQueue 通訊程序

圖 3. BufferQueue 通訊程序。

BufferQueue 包含將圖片串流製作工具和圖片串流消費者繫結在一起的邏輯。舉例來說,相機 HAL 產生的相機預覽畫面或 OpenGL ES 遊戲,都是圖像產生器。圖像消費者的例子包括 SurfaceFlinger,或是顯示 OpenGL ES 串流的其他應用程式,例如顯示相機觀景窗的相機應用程式。

BufferQueue 是一種資料結構,可將緩衝區集區與佇列合併,並使用 Binder 程序間通訊 (IPC) 在程序之間傳遞緩衝區。製作工具介面 (或您傳遞給要產生圖像緩衝區的人員) 是 IGraphicBufferProducer (SurfaceTexture 的一部分)。BufferQueue 通常用於算繪至 Surface,並透過 GL Consumer 使用,以及其他工作。

BufferQueue 可以透過三種不同模式運作:

類似同步的模式
根據預設,BufferQueue 會以類似同步的模式運作,也就是從生產者傳入的每個緩衝區,都會在取用者端輸出。在這個模式下,系統一律不會捨棄緩衝區。如果製作工具速度過快,建立緩衝區的速度超過緩衝區排空速度,就會遭到封鎖並等待可用緩衝區。
非封鎖模式
BufferQueue 也可以在非封鎖模式下運作,在這些情況下,系統會產生錯誤,而不是等待緩衝區。在這個模式下,系統也不會捨棄任何緩衝區。這有助於避免應用程式軟體中可能發生的死結,因為應用程式軟體可能無法瞭解圖形架構的複雜依附元件。
捨棄模式
BufferQueue 可設定為捨棄舊緩衝區,而不是產生錯誤或等待。舉例來說,如果對紋理檢視區塊執行 GL 算繪,並盡快繪製,就必須捨棄緩衝區。

為執行大部分工作,SurfaceFlinger 只是另一個 OpenGL ES 用戶端。因此,當 SurfaceFlinger 主動將一或兩個緩衝區合成到第三個緩衝區時,會使用 OpenGL ES。

Hardware Composer HAL 則會執行另一半的工作。這個 HAL 是所有 Android 圖像算繪的中心點。