熱插拔處理

顯示功能(例如顯示模式和支援的 HDR 類型)可以在具有外部連接顯示器(透過 HDMI 或 DisplayPort)的裝置上動態更改,例如 Android 電視機上盒 (STB) 和機上盒 (OTT)裝置。這種變化可能是由於 HDMI 熱插拔訊號而發生的,例如當使用者從一個顯示器切換到另一個顯示器或在沒有連接顯示器的情況下啟動裝置時。 Android 12 及更高版本對框架進行了更改,以處理熱插拔和動態顯示功能。

本頁描述了 Composer HAL 實作中顯示熱插拔的處理和顯示功能的變更。此外,它還討論瞭如何管理相關的幀緩衝區並防止這些情況下的競爭條件。

更新顯示功能

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

在 Android 能夠正確處理顯示功能的變更之前,OEM 必須實作 Composer HAL,以便它使用onHotplug(display, connection=CONNECTED)來通知框架顯示功能的任何變更。實現後,Android 會以以下方式處理顯示功能的變更:

  1. 在偵測到顯示功能的變化時,框架會收到onHotplug(display, connection=CONNECTED)通知。
  2. 收到通知後,框架會刪除其顯示狀態,並透過使用getActiveConfiggetDisplayConfigsgetDisplayAttributegetColorModesgetHdrCapabilitiesgetDisplayCapabilities方法,使用 HAL 中的新功能重新建立它。
  3. 框架重新建立新的顯示狀態後,它會將onDisplayChanged回呼傳送到正在偵聽此類事件的應用程式。

框架在後續onHotplug(display, connection=CONNECTED)事件中重新分配幀緩衝區。有關如何正確管理幀緩衝區記憶體以避免分配新幀緩衝區期間失敗的更多信息,請參閱客戶端幀緩衝區管理

處理常見連線場景

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

Android 框架是為行動裝置建置的,因此沒有對斷開連接的主顯示器的內建支援。相反,當主顯示器物理上斷開連接時,HAL 在與框架互動時必須用佔位符顯示器替換主顯示器。

在具有可斷開連接的外部連接顯示器的機上盒和電視適配器中可能會出現以下情況。要實現對這些場景的支持,請使用下表中的信息:

設想處理
啟動時未連接顯示器
  • onHotplug(display, connection=CONNECTED)訊號從 Composer HAL 發送到框架。
  • 將 Composer HAL 內的實體顯示狀態替換為佔位符顯示狀態。
主顯示器已實體連接
主顯示器已物理斷開連接
  • 將另一個onHotplug(display, connection=CONNECTED)事件從 Composer HAL 發送到框架。
  • 將 Composer HAL 內的實體顯示狀態替換為佔位符顯示狀態。佔位符顯示必須具有單一顯示模式,以便框架向應用程式發送onDisplayChanged回呼(因為支援的模式集已更改)。此單一顯示模式必須與斷開連接之前實體顯示器的最後一個活動模式匹配,以便應用程式不會收到配置變更事件

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

如果 Composer HAL 與呼叫setActiveConfigsetActiveConfigWithConstraints的框架同時更新支援的顯示配置,則可能會出現競爭條件。解決方案是實作 Composer HAL 以使用順序 ID 並防止此問題。

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

當新的連續 ID 未指派給新的顯示配置時,請考慮下列事件序列,從而導致競爭條件:

  1. 支援的顯示配置 ID 為:

    • id=1 , 1080x1920 60 赫茲
    • id=2 , 1080x1920 50 赫茲
  2. 框架呼叫setActiveConfig(display, config=1)

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

    • id=1 , 2160x3840 60 赫茲
    • id=2 , 2160x3840 50 赫茲
    • id=3 , 1080x1920 60 赫茲
    • id=4 , 1080x1920 50 赫茲
  4. Composer HAL 向框架發送onHotplug事件,以通知支援的模式集已更改。

  5. Composer HAL 接收setActiveConfig(display, config=1) (來自步驟 2)。

  6. HAL 解釋為框架已要求將配置更改為2160x3840 60 Hz ,儘管實際上需要1080x1920 60 Hz

使用非順序 ID 分配的過程在此結束,並誤解了所需的配置變更。

配置 Composer HAL 以使用順序 ID

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

  • 當 Composer HAL 更新支援的顯示配置時,它會為新的顯示配置指派新的連續 ID。
  • 當框架使用無效的配置 ID 呼叫setActiveConfigsetActiveConfigWithConstraints時,Composer HAL 會忽略該呼叫。

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

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

  1. 支援的顯示配置 ID 為:

    • id=1 , 1080x1920 60 赫茲
    • id=2 , 1080x1920 50 赫茲
  2. 框架呼叫setActiveConfig(display, config=1)

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

    • id=3 , 2160x3840 60 赫茲

    • id=4 , 2160x3840 50 赫茲

    • id=5 , 1080x1920 60 赫茲

    • id=6 , 1080x1920 50 赫茲

  4. Composer HAL 向框架發送onHotplug事件,以通知支援的模式集已更改。

  5. Composer HAL 接收setActiveConfig(display, config=1) (來自步驟 2)。

  6. 由於 ID 不再有效,Composer HAL 會忽略該呼叫。

  7. 框架接收並處理步驟 4 中的onHotplug事件。它使用函數getDisplayConfigsgetDisplayAttribute呼叫 Composer HAL。透過這些函數,框架可以識別新的 ID (5),以實現所需的解析度以及 1080x1920 和 60 Hz 的刷新率。

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

  9. Composer HAL 從步驟 5 接收setActiveConfig(display, config=5)

  10. HAL 正確解釋框架已要求將組態變更為 1080x1920 60 Hz。

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