圖層和顯示畫面是兩個原始元素,代表組合作業和與顯示硬體的互動。
圖層
圖層是組合中最重要的單位。圖層是 surface 和 SurfaceControl
例項的組合。每個圖層都有一組屬性,用於定義與其他圖層的互動方式。下表說明圖層屬性。
資源 | 說明 |
---|---|
位置 | 定義圖層在螢幕上的顯示位置。包含圖層邊緣的位置和相對於其他圖層的 Z 順序等資訊 (也就是圖層應置於其他圖層前方還是後方)。 |
內容 | 定義圖層上顯示的內容,應如何在位置屬性定義的邊界內顯示。包含裁剪 (可擴展部分內容,以填滿圖層邊界) 和轉換 (可顯示旋轉或翻轉的內容) 等資訊。 |
樂曲 | 定義此圖層應如何與其他圖層合成。包含alpha 合成的混合模式和圖層層級 alpha 值等資訊。 |
最佳化 | 提供的資訊並非正確合成的圖層所必需,但可供硬體合成器 (HWC) 裝置使用,以便最佳化其執行合成作業的方式。包含圖層可見區域和圖層自上一個影格以來更新的部分等資訊。 |
螢幕
顯示是另一個重要的組合單位。系統可以有多個螢幕,並可在正常系統運作期間新增或移除螢幕。系統會根據 HWC 或架構的要求,新增/移除螢幕。當外部螢幕連線或與裝置中斷連線時,HWC 裝置會要求新增或移除螢幕,這稱為熱插拔。用戶端會要求虛擬螢幕,其內容會轉譯至螢幕外緩衝區,而不是實體螢幕。
虛擬螢幕
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
擷取啟用螢幕的動作,然後逐格播放。