日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SurfaceFlinger 和 Hardware Composer

發(fā)布時間:2024/4/11 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SurfaceFlinger 和 Hardware Composer 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

擁有圖形數(shù)據(jù)緩沖區(qū)是很精彩的,但是當你在你的設(shè)備屏幕上看到它們時生活甚至更美好。那就是 SurfaceFlinger 和 Hardware Composer HAL 做的事情。

SurfaceFlinger

SurfaceFlinger 的角色是接收來自于多個源的數(shù)據(jù)緩沖區(qū),組合它們,并將它們發(fā)送給顯示設(shè)備。曾經(jīng)一段時期這是通過軟將數(shù)據(jù)塊傳送到硬件 framebuffer (比如 /dev/graphics/fb0) 完成的,但那些日子已經(jīng)過去許久了。

當一個應(yīng)用來到前臺,WindowManager 服務(wù)向 SurfaceFlinger 請求一塊繪制 surface。SurfaceFlinger 創(chuàng)建一個 layer(其主要的組件是一個 BufferQueue),而
SurfaceFlinger 將作為其消費者。生產(chǎn)者端的 Binder 對象通過 WindowManager 被傳遞給應(yīng)用,然后它可以開始直接向 SurfaceFlinger 發(fā)送幀。

注意:這一節(jié)使用 SurfaceFlinger 術(shù)語,WindowManager 使用術(shù)語 window 而不是 layer. . . 并使用 layer 表示其它一些東西。( 可以認為 SurfaceFlinger 應(yīng)該被稱為LayerFlinger。)

大多數(shù)應(yīng)用于任何時間在屏幕上具有三個 layers:屏幕頂部的狀態(tài)欄,底部或側(cè)面的導(dǎo)航欄,以及應(yīng)用程序 UI。一些應(yīng)用具有更多,一些更少(比如默認的 home 應(yīng)用有一個單獨的壁紙 layer,而全屏游戲可能會隱藏狀態(tài)欄)。每個 layer 可以被獨立地更新。狀態(tài)欄和導(dǎo)航欄由一個系統(tǒng)進程渲染,而應(yīng)用 layers 有應(yīng)用渲染,兩者之間沒有協(xié)調(diào)。

設(shè)備顯示器以一定頻率刷新,在手機和平板上典型的是每秒鐘 60 幀。如果顯示的內(nèi)容在刷新中間更新,則將看到花屏;因此只在周期中間更新內(nèi)容很重要。當可以安全更新內(nèi)容時,系統(tǒng)收到來自于顯示器的信號。出于歷史原因我們稱它為 VSYNC 信號。

刷新頻率可能會隨著時間而改變,比如依賴于當前的條件,一些設(shè)備的范圍在 58 到 62fps。對于 HDMI 連接的電視機,理論上可以下降到 24 或 48Hz 來匹配視頻。由于每個刷新周期我們只能更新屏幕一次,以 200 fps 提交緩沖區(qū)來顯示將是巨大的浪費,因為大多數(shù)幀將從不會被看到。

不是在應(yīng)用提交緩沖區(qū)時采取行動,SurfaceFlinger 而是在顯示器為顯示一些新東西做好準備時才喚醒。

當 VSYNC 信號到達時,SurfaceFlinger 遍歷它的 layers 列表尋找新的緩沖區(qū)。如果它找到了一個新的,它獲取它;如果沒有,它繼續(xù)使用之前獲取的緩沖區(qū)。SurfaceFlinger 總是想要一些東西來顯示,因此它會掛在一個緩沖區(qū)上。如果沒有緩沖區(qū)已經(jīng)提交給一個 layer,則該 layer 被忽略。

在 SurfaceFlinger 收集了所有可見的 layers 的緩沖區(qū)之后,它詢問 Hardware Composer 應(yīng)該如何執(zhí)行組合。

Hardware Composer

Hardware Composer HAL (HWC) 在 Android 3.0 中被引入,并已經(jīng)穩(wěn)定發(fā)展多年。它的主要目標是通過可用硬件確定組合緩沖區(qū)的最有效方式。作為 HAL,其實現(xiàn)是特定于設(shè)備的,且通常由顯示設(shè)備硬件 OEM 完成。

當考慮 覆蓋平面(overlay planes) 時,這種方法的價值很容易識別,其目的是在顯示硬件而不是 GPU 中將多個緩沖區(qū)組合在一起。比如,考慮一個典型的豎直方向的 Android 手機,其狀態(tài)欄在頂部,導(dǎo)航欄在底部,應(yīng)用內(nèi)容在其余的地方。每個 layers 的內(nèi)容在單獨的緩沖區(qū)中。你可以使用下列方法中的一種處理組合:

  • 將應(yīng)用內(nèi)容渲染到暫存緩沖區(qū)中,然后將狀態(tài)欄渲染在它的上面,導(dǎo)航欄位于其上,最后將暫存緩沖區(qū)傳遞給顯示硬件。

  • 將所有三個緩沖區(qū)傳遞給顯示硬件,并告訴它從不同的緩沖區(qū)為不同的屏幕部分讀取數(shù)據(jù)。

后一種方法可以顯著提高效率。

顯示處理器功能差異很大。overlays 的數(shù)量,layers 是否可以旋轉(zhuǎn)或混合,以及位置和重疊上的限制,可能非常難以通過一個 API 來描述。HWC 試圖通過一系列的決定容納這些多樣性:

  • SurfaceFlinger 為 HWC 提供完整的 layers 的列表并詢問,“你想要如何處理它?”。

  • HWC 通過將每個 layer 標記為 overlay 或 GLES composition 來進行響應(yīng)。

  • SurfaceFlinger 關(guān)心任何 GLES composition,并把輸出緩沖區(qū)傳給 HWC,讓 HWC 處理其余的事情。

  • 由于硬件供應(yīng)商可以定制或裁剪決定作出的代碼,因此可以從每個設(shè)備中獲得最佳性能。

    當屏幕上的東西沒有改變時,overlay 平面可能比 GL composition 更低效。當 overlay 內(nèi)容具有透明像素且覆蓋的 layers 被混合在一起時尤其如此。在這種情況下,HWC 可以選擇為一些或所有 layers 請求 GLES composition 并保留組合的緩沖區(qū)。如果 SurfaceFlinger 回來請求組合相同的緩沖區(qū)集合,HWC 可以繼續(xù)展示之前組合好的臨時緩沖區(qū)。這可以提升空閑的設(shè)備的電池續(xù)航能力。

    運行 Android 4.4 及更新版本的設(shè)備典型地支持四個 overlay 平面。試圖組合比 overlays 更多的 layers 會導(dǎo)致系統(tǒng)為它們中的一些使用 GLES composition,這意味著一個應(yīng)用使用的 layers 的數(shù)量可能對電源消耗和性能有著重大的影響。

    虛擬顯示器

    SurfaceFlinger 支持一個主顯示器(比如手機或平板內(nèi)置的東西),一個外部顯示器(比如通過 HDMI 連接的電視機),以及一個或多個使組合后的輸出在系統(tǒng)中可用的虛擬顯示器。虛擬顯示器可用于記錄屏幕或通過網(wǎng)絡(luò)發(fā)送。

    虛擬顯示器可以共享主顯示器相同的 layers 集合(layer 棧)或擁有它們自己的集合。虛擬顯示器沒有 VSYNC,因此主顯示器的 VSYNC 用于觸發(fā)所有顯示器的組合
    (composition) 。

    在老版本的 Android 中,虛擬顯示器總是通過 GLES 組合,而 Hardware Composer 只管理主顯示器的組合。在 Android 4.4 中,Hardware Composer 獲得了參與虛擬顯示器組合的能力。

    如你期待的那樣,為一個虛擬顯示器產(chǎn)生的幀被寫入 BufferQueue。

    案例研究:screenrecord

    screenrecord 命令 允許你將屏幕上出現(xiàn)的所有東西記錄為磁盤上的 .mp4 文件。為了實現(xiàn)它,我們不得不從 SurfaceFlinger 接收組合之后的幀,將它們寫入視頻編碼器,然后將編碼的視頻數(shù)據(jù)寫入一個文件。視頻編解碼由一個單獨的進程 (mediaserver) 管理,因此我們不得不在系統(tǒng)中移動巨大的圖形緩沖區(qū)。使這件事情更具挑戰(zhàn)性的是,我們還要試圖以全解析度記錄 60fps 的視頻。使這件事情高效工作的關(guān)鍵是 BufferQueue。

    MediaCodec 類允許一個應(yīng)用以緩沖區(qū)中的原始字節(jié)提供數(shù)據(jù),或通過一個 Surface。當 screenrecord 請求訪問一個視頻編碼器時,mediaserver 創(chuàng)建一個 BufferQueue,將它自己與消費者一端相連,然后將生產(chǎn)者端作為一個 Surface 傳回給 screenrecord。

    screenrecord 命令然后請求 SurfaceFlinger 創(chuàng)建一個鏡像主顯示器的虛擬顯示器 (比如它具有所有相同的 layers),然后指示它將輸出發(fā)送給來自于 mediaserver 的 Surface。在這種情況下,SurfaceFlinger 是緩沖區(qū)的生產(chǎn)者而不是消費者。

    配置完成之后,screenrecord 等待編碼的數(shù)據(jù)出現(xiàn)。隨著應(yīng)用的繪制,它們的緩沖區(qū)進入 SurfaceFlinger,SurfaceFlinger 將它們組合為一個單獨的緩沖區(qū)并直接發(fā)送給 mediaserver 中的視頻編碼器。screenrecord 進程甚至從來不會看到完整的幀。在內(nèi)部,mediaserver 有著它自己的移動緩沖區(qū)的方式,即通過句柄傳遞數(shù)據(jù),以最小化開銷。

    案例研究:模擬二次顯示

    WindowManager 可以請求 SurfaceFlinger 創(chuàng)建一個可見的 layer,其中 SurfaceFlinger 作為 BufferQueue 的消費者。它還可以請求 SurfaceFlinger 創(chuàng)建一個虛擬顯示器,其中 SurfaceFlinger 作為 BufferQueue 的生產(chǎn)者。如果你將它們連接到一起會如何呢,配置一個虛擬顯示器顯示渲染到一個可見 layer 的東西?

    你創(chuàng)建了一個閉環(huán),其中組合后的屏幕出現(xiàn)在一個窗口中。然后窗口現(xiàn)在是組合后的輸出的一部分了,因此在下一次刷新窗口內(nèi)組合后的圖像將也顯示窗口的內(nèi)容(然后 海龜下面還是海龜一路下來)。為了看到這種行為,啟用設(shè)置中的 Developer options,選擇 Simulate secondary displays,并啟用一個窗口。為了加分,請使用 screenrecord 捕獲啟用顯示的行為,然后逐幀播放。

    原文

    總結(jié)

    以上是生活随笔為你收集整理的SurfaceFlinger 和 Hardware Composer的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。