應用程式可透過 Surface 物件算繪要在螢幕上顯示的圖像。 應用程式可透過 SurfaceHolder 介面編輯及控制 Surface。
Surface
介面是供應商與消費者交換緩衝區的介面。
顯示介面通常會使用為三緩衝區設定的 BufferQueue。緩衝區是依需求分配,因此如果製作工具產生緩衝區的速度不夠快,例如在 60 FPS 的螢幕上以 30 FPS 的速度產生緩衝區,佇列中可能只會分配到兩個緩衝區。視需要配置緩衝區有助於減少記憶體用量。您可以查看 dumpsys SurfaceFlinger
輸出內容中每個圖層相關聯的緩衝區摘要。
大多數用戶端都會使用 OpenGL ES 或 Vulkan,在介面上算繪內容。不過,部分用戶端會使用畫布在介面上算繪。
畫布算繪
Skia Graphics Library 提供畫布實作。如要繪製矩形,請呼叫 Canvas API,在緩衝區中適當設定位元組。為確保緩衝區不會同時由兩個用戶端更新,或在顯示時寫入,請鎖定緩衝區以存取緩衝區。請使用下列指令處理畫布鎖定:
lockCanvas()
會鎖定緩衝區,以便在 CPU 上進行轉譯,並傳回用於繪圖的 Canvas。unlockCanvasAndPost()
會解鎖緩衝區,並傳送至合成器。lockHardwareCanvas()
會鎖定緩衝區,以便在 GPU 上進行轉譯,並傳回用於繪圖的畫布。
生產者首次向 BufferQueue 要求緩衝區時,系統會分配緩衝區並初始化為零。初始化作業是必要步驟,可避免在程序之間不慎共用資料。不過,如果重複使用緩衝區,先前的內容仍會存在。如果重複呼叫 lockCanvas()
和 unlockCanvasAndPost()
,但未繪製任何內容,製作工具會在先前算繪的影格之間循環。
表面鎖定/解除鎖定程式碼會保留先前算繪緩衝區的參照。如果在鎖定表面時指定髒區,系統會從先前的緩衝區複製非髒區像素。SurfaceFlinger 或 HWC 通常會處理緩衝區,但由於您只需要從緩衝區讀取資料,因此不必等待專屬存取權。
SurfaceHolder
SurfaceHolder 是系統用來與應用程式共用 Surface 擁有權的介面。部分使用介面的用戶端需要 SurfaceHolder,因為取得及設定介面參數的 API 是透過 SurfaceHolder 實作。SurfaceView 包含 SurfaceHolder。
與檢視區塊互動的大多數元件都涉及 SurfaceHolder。其他 API (例如 MediaCodec) 則會在介面上運作。