圖層和顯示畫面是兩個原始元素,代表組合作業和與顯示硬體的互動。
圖層
「圖層」是最重要的構成單位。圖層是 surface 和 SurfaceControl
例項的組合。每個圖層都有一組屬性,可定義與其他圖層的互動方式。圖層屬性的說明如下表所示。
資源 | 說明 |
---|---|
定位 | 定義圖層在螢幕上的顯示位置。包含圖層邊緣的位置和相對於其他圖層的 Z 順序等資訊 (也就是圖層應位於其他圖層前方還是後方)。 |
內容 | 定義在位置屬性定義的邊界內,圖層顯示內容的方式。包含裁剪 (可擴展部分內容,以填滿圖層邊界) 和轉換 (可顯示旋轉或翻轉的內容) 等資訊。 |
樂曲 | 定義此圖層應如何與其他圖層合成。包含alpha 合成的混合模式和圖層層級 alpha 值等資訊。 |
最佳化 | 提供的資訊並非正確合成的圖層所必需,但可供硬體合成器 (HWC) 裝置使用,以便最佳化合成方式。包含圖層的可見區域和圖層的哪個部分自上一個影格更新以來已更新的資訊。 |
螢幕
顯示是另一個重要的組合單位。系統可以有多個螢幕,並可在正常系統作業期間新增或移除螢幕。畫面會依 HWC 的要求或架構的要求來新增/移除螢幕。當外接螢幕連線或與裝置中斷連線時,HWC 裝置會要求新增或移除螢幕,這稱為「hotplugging」。用戶端會要求虛擬螢幕,其內容會轉譯至螢幕外緩衝區,而不是實體螢幕。
虛擬螢幕
SurfaceFlinger 支援內建螢幕 (內建於手機或平板電腦)、外接螢幕 (例如透過 HDMI 連接的電視),以及在系統內提供合成輸出的虛擬螢幕。虛擬螢幕可用於錄製螢幕畫面,或透過網路傳送螢幕畫面。為虛擬螢幕產生的影格會寫入 BufferQueue。
虛擬螢幕可能會與主要螢幕共用一組圖層 (圖層堆疊),也可能有自己的圖層。虛擬顯示器沒有 VSYNC,因此內部顯示器的 VSYNC 會觸發所有顯示器的組合。
在支援 HWC 的實作項目中,虛擬螢幕可以與 OpenGL ES (GLES)、HWC 或 GLES 和 HWC 合成。在未支援的實作項目中,虛擬顯示螢幕一律會使用 GLES 進行合成。
個案研究:screenrecord
screenrecord
指令可讓使用者將畫面上顯示的所有內容記錄為磁碟上的 .mp4
檔案。為實現這項功能,系統會接收來自 SurfaceFlinger 的經過合成的影格,將影格寫入影片編碼器,然後將經過編碼的影片資料寫入檔案。影片編解碼是由個別程序 (mediaserver
) 管理,因此大型圖形緩衝區必須在系統中移動。為了增加難度,目標是錄製 60 fps 影片,且解析度為全解析度。要讓這項工作順利進行,關鍵在於 BufferQueue。
MediaCodec
類別可讓應用程式在緩衝區或透過介面,以原始位元組的形式提供資料。當 screenrecord
要求存取影片編碼器時,mediaserver
程序會建立 BufferQueue,並將其連結至消費者端,然後將生產者端傳回至 screenrecord
做為介面。
screenrecord
公用程式會要求 SurfaceFlinger 建立鏡像主螢幕的虛擬螢幕 (也就是具有所有相同的圖層),並指示將輸出內容傳送至來自 mediaserver
處理程序的途徑。在這種情況下,SurfaceFlinger 是緩衝區的生產端,而非消費者。
設定完成後,當系統顯示編碼的資料時,就會觸發 screenrecord
。應用程式繪製時,其緩衝區會傳送至 SurfaceFlinger,後者會將這些緩衝區合成單一緩衝區,並直接傳送至 mediaserver
程序中的影片編碼器。screenrecord
程序不會看到完整的影格。在內部,mediaserver
程序會以自己的方式移動緩衝區,並透過句柄傳遞資料,盡可能減少額外負擔。
個案研究:模擬次要顯示器
WindowManager 可要求 SurfaceFlinger 建立可見圖層,供 SurfaceFlinger 做為 BufferQueue 用戶。您也可以要求 SurfaceFlinger 建立虛擬螢幕,SurfaceFlinger 會充當 BufferQueue 供應者。
如果您將虛擬顯示裝置連接至可見圖層,系統就會建立封閉迴路,在視窗中顯示合成的畫面。該視窗現在是合成輸出的一部分,因此在下次重新整理時,視窗內的合成圖片也會顯示視窗內容。如要查看實際運作情形,請在「設定」中啟用「開發人員選項」,選取「模擬次要螢幕」,然後啟用視窗。如要查看次要螢幕的實際運作情形,請使用 screenrecord
擷取啟用螢幕的動作,然後逐格播放。