圖像

Android Graphics HAL 圖示

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

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

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

硬體 Composer

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

硬體 Composer HAL 會執行另一半的工作,也是所有 Android 圖形算繪作業的中心點。硬體編譯器必須支援事件,其中一個是 VSYNC (另一個是 hotplug,用於支援即插即用 HDMI)。

Gralloc

圖像記憶體配置器 (Gralloc) 需要分配圖像產生器要求的記憶體。詳情請參閱 Gralloc HAL

資料流程

請參閱下圖,瞭解 Android 圖形管線的運作方式:

圖形資料流

圖 2. 透過 Android 的圖形資料流

左側的物件是產生圖形緩衝區的轉譯器,例如主畫面、狀態列和系統 UI。SurfaceFlinger 是合成器,而硬體合成器是作曲家。

BufferQueue

BufferQueue 可在 Android 圖形元件之間提供連結。這兩個佇列會協調從生產者傳送至消費者的緩衝區持續循環。一旦產生者將緩衝區交出,SurfaceFlinger 就會負責將所有內容合成至螢幕上。

請參閱下圖,瞭解 BufferQueue 通訊程序。

BufferQueue 通訊程序

圖 3. BufferQueue 通訊程序

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

BufferQueue 是一種資料結構,結合了緩衝區集區和佇列,並使用 Binder IPC 在程序之間傳遞緩衝區。產生器介面 (或傳遞給想要產生圖形緩衝區的使用者) 為 IGraphicBufferProducer (SurfaceTexture 的一部分)。BufferQueue 通常用於將內容算繪至 Surface,並透過 GL 消費者等其他工作進行使用。

BufferQueue 可在三種不同模式下運作:

類似同步模式:BufferQueue 預設會以類似同步模式運作,其中從生產者傳入的每個緩衝區都會傳送至消費者。在這個模式中,系統不會丟棄任何緩衝區。如果產生器速度太快,且建立緩衝區的速度比耗盡緩衝區的速度還快,則會阻斷並等待空閒緩衝區。

非封鎖模式:BufferQueue 也可以在非封鎖模式下運作,在這種情況下,它會產生錯誤,而不是等待緩衝區。在這個模式中,系統也不會丟棄任何緩衝區。這在應用程式軟體中非常實用,因為這些軟體可能無法瞭解圖形架構的複雜依附元件。

棄用模式:最後,BufferQueue 可設定為棄用舊緩衝區,而非產生錯誤或等待。舉例來說,如果要盡可能快速地將 GL 算繪結果算繪至紋理檢視畫面並繪製,就必須捨棄緩衝區。

為了執行這項工作的大部分內容,SurfaceFlinger 會充當另一個 OpenGL ES 用戶端。因此,當 SurfaceFlinger 主動將一個或兩個緩衝區合成為第三個緩衝區時,就會使用 OpenGL ES。

硬體編寫器 HAL 會執行另一半的工作。此 HAL 會做為所有 Android 圖形算繪作業的中心點。