Composer HAL 中的熱插拔處理

顯示功能(例如顯示模式和支持的 HDR 類型)可以在具有外部連接顯示器(通過 HDMI 或 DisplayPort)的設備上動態更改,例如 Android 機頂盒 (STB) 和機頂盒 (OTT)設備。這種變化可能是 HDMI 熱插拔信號的結果,例如當用戶從一個顯示器切換到另一個顯示器或在沒有連接顯示器的情況下啟動設備時。從 Android 12 開始,對框架進行了更改以處理熱插拔和動態顯示功能。

本頁面介紹瞭如何在 Composer HAL 實現中處理顯示熱插拔和顯示功能更改。此外,它還討論瞭如何在這些情況下管理關聯的幀緩衝區並防止競爭條件。

更新顯示功能

本節介紹 Android 框架如何處理由 Composer HAL 發起的顯示功能更改。

之前的Android能夠妥善處理在顯示能力的變化,OEM必須實現作曲HAL使得它使用的onHotplug(display, connection=CONNECTED)通知的任何更改顯示能力的框架。一旦實現,Android 處理顯示功能的更改如下:

  1. 在檢測中顯示能力的變化時,框架接收onHotplug(display, connection=CONNECTED)通知。
  2. 在接收到通知時,框架降至其顯示狀態,並與來自HAL通過使用新功能重新創建它getActiveConfiggetDisplayConfigsgetDisplayAttributegetColorModesgetHdrCapabilitiesgetDisplayCapabilities方法。
  3. 一旦框架重新創建新的顯示狀態,它發送onDisplayChanged回調被監聽此類事件的應用程序。

該框架上重新分配之後的幀緩衝區onHotplug(display, connection=CONNECTED)事件。見管理幀緩衝存儲器中對如何處理這種信息。

處理常見的連接場景

本節介紹如何在您的實現中正確處理主顯示器連接和斷開連接時的各種連接場景。

Android 框架是為移動設備構建的,沒有對斷開連接的主顯示器的內置支持。相反,在主顯示器物理斷開連接的情況下,HAL 必須在與框架的交互中用佔位符顯示器替換主顯示器。

以下情況可能發生在機頂盒和電視加密狗中,它們具有可以斷開連接的外部連接顯示器。為了實現對這些場景的支持,請使用下表中的信息:

設想處理
啟動時沒有連接的顯示器
  • onHotplug(display, connection=CONNECTED)從作曲HAL到框架信號。
  • 用佔位符顯示狀態替換 Composer HAL 內的物理顯示狀態。

    注意:我們建議佔位符顯示為單一支持模式,分辨率為 1080x1920,刷新率為 60hz,因為大多數應用程序都支持這種顯示模式。

主顯示器已物理連接
主顯示器物理斷開
  • 發送另一個onHotplug(display, connection=CONNECTED)從作曲HAL到框架事件。
  • 用佔位符顯示狀態替換 Composer HAL 內的物理顯示狀態。佔位符顯示必須有一個單獨的顯示模式,從而使框架發送onDisplayChanged回調應用程序(因為該組支持的模式已經改變)。這種單一的顯示模式必須斷開連接之前的物理顯示的最後一個活動模式相匹配,使應用程序不會收到配置更改事件

管理幀緩衝內存

當在已經連接的顯示器接收後續onHotplug(display, connection=CONNECTED)通知事件,該框架重新分配與該顯示器相關聯的幀緩衝區。設備實現必須預見到這種行為並正確管理幀緩衝內存。在您的實施中使用以下準則:

  • 發送後續之前onHotplug(display, connection=CONNECTED)通知事件,一定要釋放的句柄的幀緩衝區,以便系統能夠正確解除分配它們,將它們重新分配了。如果解除分配不成功,則重新分配可能會因內存不足而失敗。

  • 我們建議為幀緩衝區分配一個專用內存池,該內存池與圖形內存緩衝區的其餘部分分開。

這很重要,因為在幀緩衝區的釋放和重新分配之間,第三方進程可以嘗試分配圖形內存。如果framebuffer使用同一個顯存池,並且顯存已滿,第三方進程可以佔用一個framebuffer之前分配的顯存,從而導致framebuffer重新分配內存不足(或者可能造成內存空間碎片化) .

使用順序配置 ID 來防止競爭條件

如果作曲家HAL與框架調用同時更新支持的顯示CONFIGS可能出現的競爭條件setActiveConfigsetActiveConfigWithConstraints 。解決方案是實現 Composer HAL 以使用順序 ID 並防止出現此問題。

本節介紹競爭條件可能如何發生,然後詳細介紹如何實現 Composer HAL 以便它使用順序 ID 來防止此類情況。

考慮以下事件序列,當新的連續 ID 未分配給新的顯示配置時,會導致競爭條件:

  1. 支持的顯示配置 ID 是:

    • ID = 1,1080×1920 60HZ
    • ID = 2,1080×1920為50hz
  2. 框架調用setActiveConfig(display, config=1)

  3. 同時,Composer HAL 處理顯示配置的更改並將其內部狀態更新為一組新的顯示配置,如下所示:

    • ID = 1,2160x3840 60HZ
    • ID = 2,2160x3840 50HZ
    • ID = 3,1080×1920 60HZ
    • ID = 4,1080×1920為50hz
  4. 作曲家HAL發送onHotplug事件到框架,以通知該組支持的模式已經改變。

  5. 作曲家HAL接收setActiveConfig(display, config=1)步驟2)。

  6. 該框架已請求配置更改2160x3840 60HZ,但在現實中1080×1920 60HZ的HAL解釋是需要的。

使用非順序 ID 分配的過程以對所需配置更改的誤解結束。

配置 Composer HAL 以使用順序 ID

為避免此類競爭條件,OEM 必須按如下方式實現 Composer HAL:

這些步驟用於防止競爭條件,如下面的討論所示。

當新的連續 ID 分配給新的顯示配置時,請考慮以下事件序列:

  1. 支持的顯示配置 ID 是:

    • ID = 1,1080×1920 60HZ
    • ID = 2,1080×1920為50hz
  2. 框架調用setActiveConfig(display, config=1)

  3. 當處理顯示配置的更改時,從下一個未使用的整數開始分配下一組配置 ID,如下所示:

    • ID = 3,2160x3840 60HZ

    • ID = 4,2160x3840 50HZ

    • ID = 5,1080×1920 60HZ

    • ID = 6,1080×1920為50hz

  4. 作曲家HAL發送onHotplug事件到框架,以通知該組支持的模式已經改變。

  5. 作曲家HAL接收setActiveConfig(display, config=1)步驟2)。

  6. Composer HAL 會忽略該調用,因為 ID 不再有效。

  7. 該框架接收並處理onHotplug從第4步的事件,它調用到使用的功能的作曲HAL getDisplayConfigsgetDisplayAttribute 。使用這些函數,框架為所需的分辨率和 1080x1920 和 60Hz 的刷新率識別新 ID (5)。

  8. 該框架發送另一個setActiveConfig為5的更新ID事件。

  9. 作曲家HAL接收setActiveConfig(display, config=5)從步驟5。

  10. HAL 正確解釋了框架已請求將配置更改為 1080x1920 60hz。

如上例所示,使用順序 ID 分配的過程可確保防止競爭條件並更新正確的顯示配置更改。