Możliwości wyświetlania (np. tryby wyświetlania i obsługiwane typy HDR) mogą się dynamicznie zmieniać na urządzeniach z zewnętrznymi wyświetlaczami (z HDMI lub DisplayPort), takich jak dekodery Android TV i urządzenia OTT. Ta zmiana może nastąpić w wyniku sygnału hotplug HDMI, np. gdy użytkownik przełącza się z jednego wyświetlacza na inny lub uruchamia urządzenie bez podłączonego wyświetlacza. Android 12 i nowsze wersje zawierają zmiany w strukturze, które umożliwiają obsługę podłączania na gorąco i dynamicznych funkcji wyświetlania.
Na tej stronie opisujemy obsługę podłączania i odłączania wyświetlaczy podczas pracy oraz zmian w ich możliwościach w implementacji HAL kompozytora. Opisuje też, jak zarządzać powiązanym buforem ramki i zapobiegać sytuacjom wyścigu w tych przypadkach.
Aktualizowanie możliwości wyświetlania
W tej sekcji opisano, jak platforma Androida obsługuje zmiany w możliwościach wyświetlania zainicjowane przez Composer HAL.
Zanim Android będzie mógł prawidłowo obsługiwać zmiany w możliwościach wyświetlania, producent OEM musi wdrożyć Composer HAL w taki sposób, aby używał onHotplug(display, connection=CONNECTED)
do powiadamiania platformy o wszelkich zmianach w możliwościach wyświetlania. Po wdrożeniu tej funkcji Android obsługuje zmiany możliwości wyświetlania w ten sposób:
- Po wykryciu zmiany możliwości wyświetlania platforma otrzymuje powiadomienie
onHotplug(display, connection=CONNECTED)
. - Po otrzymaniu powiadomienia platforma porzuca stan wyświetlania i odtwarza go z nowymi możliwościami z HAL, korzystając z metod
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
igetDisplayCapabilities
. - Po odtworzeniu nowego stanu wyświetlania platforma wysyła wywołanie zwrotne
onDisplayChanged
do aplikacji, które nasłuchują takich zdarzeń.
Framework ponownie przydziela bufory klatek podczas kolejnych zdarzeń onHotplug(display, connection=CONNECTED)
. Więcej informacji o prawidłowym zarządzaniu pamięcią bufora ramki klienta, aby uniknąć błędów podczas przydzielania nowych buforów ramki, znajdziesz w artykule Zarządzanie buforem ramki klienta.
Obsługa typowych scenariuszy połączeń
W tej sekcji opisujemy, jak prawidłowo obsługiwać różne scenariusze połączeń w implementacjach, gdy wyświetlacz główny jest podłączony i odłączony.
Platforma Android została stworzona z myślą o urządzeniach mobilnych, dlatego nie ma wbudowanej obsługi odłączonego wyświetlacza głównego. Zamiast tego HAL musi zastąpić wyświetlacz podstawowy wyświetlaczem zastępczym w interakcjach z platformą w przypadku fizycznego odłączenia wyświetlacza podstawowego.
Poniższe sytuacje mogą wystąpić w przypadku dekoderów i dongli TV z zewnętrznymi wyświetlaczami, które można odłączyć. Aby zaimplementować obsługę tych scenariuszy, skorzystaj z informacji w tabeli poniżej:
Scenariusz | Obsługa |
---|---|
Brak podłączonego wyświetlacza podczas uruchamiania |
|
Wyświetlacz główny jest fizycznie podłączony |
|
Wyświetlacz główny jest fizycznie odłączony |
|
Uwagi dotyczące połączeń innych niż HDMI
Android TV obsługuje tylko te rozdzielczości:
- 720 x 1280
- 1080 x 1920
- 2160 x 3840
- 4320x7680
Gdy dekoder lub klucz sprzętowy do telewizora próbuje wyświetlić nieobsługiwaną rozdzielczość, np. 480i przez połączenie CVBS, użytkownikowi wyświetla się komunikat o błędzie.
Jeśli dekoder lub klucz sprzętowy telewizora ma zarówno złącze HDMI, jak i inne, złącze HDMI jest głównym wyświetlaczem, a inne złącze jest nieaktywne. W związku z tym, jeśli połączenie HDMI zostanie odłączone, a połączenie inne niż HDMI pozostanie aktywne, do SurfaceFlinger zostanie wysłane zdarzenie, a możliwości wyświetlacza innego niż HDMI muszą być odzwierciedlone w getDisplayAttribute
i innych interfejsach API iComposerClient
(np. getHdrCapabilities
).
Używanie kolejnych identyfikatorów konfiguracji, aby zapobiegać sytuacjom wyścigu
Sytuacje wyścigu mogą wystąpić, jeśli warstwa HAL kompozytora aktualizuje obsługiwane konfiguracje wyświetlania jednocześnie z wywoływaniem przez platformę funkcji setActiveConfig
lub setActiveConfigWithConstraints
.
Rozwiązaniem jest wdrożenie warstwy HAL usługi Composer, aby używać sekwencyjnych identyfikatorów i zapobiegać temu problemowi.
W tej sekcji opisujemy, jak mogą wystąpić warunki wyścigu, a następnie podajemy szczegółowe informacje o tym, jak wdrożyć HAL kompozytora, aby używał sekwencyjnych identyfikatorów i zapobiegał takim sytuacjom.
Rozważmy następującą sekwencję zdarzeń, w której nowe, kolejne identyfikatory NIE są przypisywane do nowych konfiguracji wyświetlania, co powoduje sytuację wyścigu:
Obsługiwane identyfikatory konfiguracji wyświetlania to:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
Platforma wywołuje funkcję
setActiveConfig(display, config=1)
.Równocześnie warstwa HAL kompozytora przetwarza zmianę konfiguracji wyświetlania i aktualizuje swój stan wewnętrzny do nowego zestawu konfiguracji wyświetlania, jak pokazano poniżej:
- id=1, 2160x3840 60 Hz
- id=2, 2160x3840 50 Hz
- id=3, 1080x1920 60 Hz
- id=4, 1080x1920 50 Hz
Composer HAL wysyła do frameworka zdarzenie
onHotplug
, aby powiadomić o zmianie zestawu obsługiwanych trybów.Komponent HAL Composer otrzymuje wartość
setActiveConfig(display, config=1)
(z kroku 2).HAL interpretuje, że platforma zażądała zmiany konfiguracji na 2160x3840 60 Hz, chociaż w rzeczywistości oczekiwano 1080x1920 60 Hz.
Proces wykorzystujący przypisywanie identyfikatorów w sposób niesekwencyjny kończy się w tym miejscu błędną interpretacją żądanej zmiany konfiguracji.
Konfigurowanie warstwy HAL kompozytora do używania kolejnych identyfikatorów
Aby uniknąć takich sytuacji wyścigu, producent OEM musi zaimplementować interfejs HAL Composera w ten sposób:
- Gdy Composer HAL zaktualizuje obsługiwane konfiguracje wyświetlania, przypisze do nich nowe, kolejne identyfikatory.
- Gdy framework wywołuje funkcję
setActiveConfig
lubsetActiveConfigWithConstraints
z nieprawidłowym identyfikatorem konfiguracji, warstwa HAL Composera ignoruje to wywołanie.
Te kroki zapobiegają wyścigom, co pokazano w dalszej części.
Rozważmy następującą sekwencję zdarzeń, gdy do nowych konfiguracji wyświetlania są przypisywane nowe, kolejne identyfikatory:
Obsługiwane identyfikatory konfiguracji wyświetlania to:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
Platforma wywołuje funkcję
setActiveConfig(display, config=1)
.Gdy zmiana konfiguracji wyświetlania zostanie przetworzona, następny zestaw identyfikatorów konfiguracji zostanie przypisany, zaczynając od następnej nieużywanej liczby całkowitej, jak pokazano poniżej:
id=3, 2160x3840 60 Hz
id=4, 2160x3840 50 Hz
id=5, 1080x1920 60 Hz
id=6, 1080x1920 50 Hz
Composer HAL wysyła do platformy zdarzenie
onHotplug
, aby powiadomić o zmianie zestawu obsługiwanych trybów.Warstwa HAL narzędzia Composer otrzymuje
setActiveConfig(display, config=1)
(z kroku 2).Warstwa HAL kompozytora ignoruje wywołanie, ponieważ identyfikator jest już nieważny.
Platforma odbiera i przetwarza zdarzenie
onHotplug
z kroku 4. Wywołuje interfejs HAL narzędzia Composer za pomocą funkcjigetDisplayConfigs
igetDisplayAttribute
. Dzięki tym funkcjom platforma identyfikuje nowy identyfikator (5) dla żądanej rozdzielczości i częstotliwości odświeżania 1080x1920 i 60 Hz.Framework wysyła kolejne zdarzenie
setActiveConfig
z zaktualizowanym identyfikatorem 5.Komponent HAL kompozytora otrzymuje
setActiveConfig(display, config=5)
z kroku 5.HAL prawidłowo interpretuje, że platforma zażądała zmiany konfiguracji na 1080 x 1920 px przy 60 Hz.
Jak pokazano w przykładzie powyżej, proces wykorzystujący sekwencyjne przypisywanie identyfikatorów zapobiega sytuacji wyścigu i zapewnia aktualizację prawidłowej konfiguracji wyświetlania.