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