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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

SurfaceFlinger 和 Hardware Composer

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

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

SurfaceFlinger

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

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

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

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

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

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

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

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

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

Hardware Composer

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

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

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

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

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

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

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

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

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

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

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

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

    虛擬顯示器

    SurfaceFlinger 支持一個主顯示器(比如手機或平板內(nèi)置的東西),一個外部顯示器(比如通過 HDMI 連接的電視機),以及一個或多個使組合后的輸出在系統(tǒng)中可用的虛擬顯示器。虛擬顯示器可用于記錄屏幕或通過網(wǎng)絡發(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 類允許一個應用以緩沖區(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)。隨著應用的繪制,它們的緩沖區(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)容(然后 海龜下面還是海龜一路下來)。為了看到這種行為,啟用設置中的 Developer options,選擇 Simulate secondary displays,并啟用一個窗口。為了加分,請使用 screenrecord 捕獲啟用顯示的行為,然后逐幀播放。

    原文

    總結(jié)

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

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