在具備 HDMI 或 DisplayPort 外接螢幕的裝置 (例如 Android TV 機上盒 (STB) 和 over-the-top (OTT) 裝置),顯示模式和支援的 HDR 類型等顯示模式可能會動態改變。這項變更可能會因 HDMI 熱插頭信號而發生,例如使用者切換螢幕時,或是在沒有連接的螢幕的情況下啟動裝置。Android 12 以上版本包含用於處理熱插拔和動態顯示功能的架構變更。
本頁面說明如何在 Composer HAL 實作中處理螢幕熱點和顯示功能變更。此外,也會探討如何管理相關聯的 framebuffer,以及如何避免發生這類情況。
更新顯示功能
本節說明 Android 架構如何處理 Composer HAL 啟動的顯示功能變更。
在 Android 可以正確處理顯示功能的變更之前,原始設備製造商 (OEM) 必須實作 Composer HAL,使其使用 onHotplug(display, connection=CONNECTED)
來通知架構,指出顯示功能的任何變更。實作完畢後,Android 會處理顯示功能的變更,如下所示:
- 偵測顯示功能變更時,架構會收到
onHotplug(display, connection=CONNECTED)
通知。 - 架構在收到通知時,會捨棄其顯示狀態,並使用
getActiveConfig
、getDisplayConfigs
、getDisplayAttribute
、getColorModes
、getHdrCapabilities
和getDisplayCapabilities
方法,透過 HAL 的新功能重新建立通知。 - 架構重新建立新的顯示狀態後,會將
onDisplayChanged
回呼傳送至監聽這類事件的應用程式。
架構會在後續的 onHotplug(display, connection=CONNECTED)
事件上重新分配 framebuffer。如要進一步瞭解如何正確管理 Framebuffer 記憶體,以免在配置新的 framebuffer 期間發生故障,請參閱「用戶端 framebuffer 管理」。
處理常見的連線情境
本節說明當主要螢幕連接和中斷連線時,如何正確處理實作中的各種連線情境。
Android 架構為行動裝置所設計,因此無法內建支援中斷的主要螢幕。相反地,在主要螢幕中斷連線時,HAL 必須在與架構互動時,將主要螢幕替換為預留位置螢幕。
STB 和電視連接器如果已連線至外部連接螢幕 (可中斷連線),可能會發生以下情況。如要實作這些情境的支援功能,請使用下表的資訊:
情境 | 使用方式 |
---|---|
啟動時未連接任何螢幕 |
|
主要螢幕已實際連線 |
|
主要螢幕已中斷連線 |
|
非 HDMI 連線注意事項
Android TV 僅支援下列解析度:
- 720x1280
- 1080x1920
- 2160x3840
- 4320x7680
當 STB 或電視 Dongle 嘗試顯示不支援的解析度 (例如透過 CVBS 連線使用 480i 時),系統會向使用者顯示錯誤訊息。
如果 STB 或電視 Dongle 同時具有 HDMI 和非 HDMI 連線,則 HDMI 連線會成為主要螢幕,且非 HDMI 連線處於未啟用狀態。因此,在非 HDMI 連線保持連線的情況下,如果 HDMI 連線中斷,事件會傳送至 SurfaceFlinger,且非 HDMI 螢幕的功能必須透過 getDisplayAttribute
和其他 iComposerClient
API (例如 getHdrCapabilities
) 反映。
使用序列設定 ID 防止競爭狀況
如果 Composer HAL 與呼叫 setActiveConfig
或 setActiveConfigWithConstraints
的架構同時更新支援的顯示設定,可能會發生競爭狀況。解決方法是導入 Composer HAL,以便使用依序 ID 並避免這個問題。
本節說明競爭狀況的發生方式,接著會詳細說明如何實作 Composer HAL,使其使用依序 ID 來避免發生這類狀況。
當「未」將新的依序 ID 指派給新的顯示設定時,請考慮以下事件順序,進而導致競爭狀況:
支援的顯示設定 ID 如下:
- id=1,1080x1920 60 Hz
- id=2,1080x1920 50 Hz
同時,Composer HAL 會處理顯示設定的變更,並將其內部狀態更新為一組新的顯示設定,如下所示:
- id=1、2160x3840 60 Hz
- id=2、2160x3840 50 Hz
- id=3,1080x1920 60 Hz
- id=4,1080x1920 50 Hz
Composer HAL 會傳送
onHotplug
事件至架構,以通知支援的模式集已變更。Composer HAL 會收到
setActiveConfig(display, config=1)
(來自步驟 2)。HAL 解讀架構要求將設定變更要求為 2160x3840 60 Hz,但實際上需要 1080x1920 60 Hz。
使用非循序 ID 指派的程序在此結束,但對於所需的設定變更有錯誤解讀。
設定 Composer HAL 以使用序列 ID
為避免發生這種競爭狀況,原始設備製造商 (OEM) 必須實作 Composer HAL,如下所示:
- Composer HAL 更新支援的顯示設定時,會將新的依序 ID 指派給新的顯示設定。
- 如果架構使用無效的設定 ID 呼叫
setActiveConfig
或setActiveConfigWithConstraints
,Composer HAL 會忽略呼叫。
這些步驟可以用來避免競爭狀況,如以下討論所示。
將新的序列 ID 指派給新的顯示設定時,請考慮以下事件順序:
支援的顯示設定 ID 如下:
- id=1,1080x1920 60 Hz
- id=2,1080x1920 50 Hz
處理顯示設定的變更時,系統會從下一個未使用的整數開始指派下一組設定 ID,如下所示:
id=3,2160x3840 60 Hz
id=4、2160x3840 50 Hz
id=5,1080x1920 60 Hz
id=6,1080x1920 50 Hz
Composer HAL 會傳送
onHotplug
事件至架構,以通知支援的模式集已變更。Composer HAL 會收到
setActiveConfig(display, config=1)
(來自步驟 2)。由於 ID 已失效,Composer HAL 會忽略呼叫。
架構接收及處理步驟 4 的
onHotplug
事件。這個函式會使用getDisplayConfigs
和getDisplayAttribute
函式呼叫 Composer HAL。有了這些功能,架構就能識別所需的解析度和刷新率 1080x1920 和 60 Hz 的新 ID (5)。架構會傳送另一個
setActiveConfig
事件 (更新 ID 為 5)。Composer HAL 會收到步驟 5 的
setActiveConfig(display, config=5)
。HAL 正確解讀架構要求將設定變更為 1080x1920 60 Hz。
如上例所示,使用依序 ID 指派的程序可確保競爭條件已避免,並更新正確的顯示設定變更。