Surface 和 SurfaceHolder

Surface 物件使應用程式能夠渲染螢幕上要呈現的影像。 SurfaceHolder 介面使應用程式能夠編輯和控製表面。

表面

表面是生產者與消費者交換緩衝區的介面。

顯示表面的 BufferQueue 通常配置為三重緩衝。緩衝區是按需分配的,因此如果生產者生成緩衝區的速度足夠慢,例如在 60 fps 顯示器上以 30 fps 生成,則佇列中可能只有兩個分配的緩衝區。按需分配緩衝區有助於最大限度地減少記憶體消耗。您可以在dumpsys SurfaceFlinger輸出中查看與每一層關聯的緩衝區的摘要。

大多數客戶端使用OpenGL ESVulkan渲染到表面上。然而,一些客戶端使用畫布渲染到表面上。

畫布渲染

畫布實作由Skia 圖形庫提供。如果您想要繪製一個矩形,您可以呼叫 Canvas API,它會適當地設定緩衝區中的位元組。為了確保緩衝區不會同時被兩個客戶端更新,或在顯示時寫入,請鎖定緩衝區以存取它。使用以下命令來使用畫布鎖:

當生產者第一次從 BufferQueue 請求緩衝區時,緩衝區會被指派並初始化為零。初始化對於避免進程之間無意中共享資料是必要的。但是,如果您重複使用緩衝區,則先前的內容仍然存在。如果您重複呼叫lockCanvas()unlockCanvasAndPost()而不繪製任何內容,則生產者會在先前渲染的幀之間循環。

表面鎖定/解鎖程式碼保留對先前渲染的緩衝區的引用。如果在鎖定表面時指定髒區域,它將從前一個緩衝區複製非髒像素。 SurfaceFlinger 或 HWC 通常處理緩衝區;但因為我們只需要從緩衝區讀取,所以不需要等待獨佔存取。

表面支架

SurfaceHolder是系統用來與應用程式共用表面所有權的介面。一些使用表面的客戶端需要 SurfaceHolder,因為取得和設定表面參數的 API 是透過 SurfaceHolder 實現的。 SurfaceView包含 SurfaceHolder。

大多數與視圖互動的元件都涉及 SurfaceHolder。其他一些 API(例如 MediaCodec)在表面本身上運行。