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.
Aby Android mógł prawidłowo obsługiwać zmiany w zakresie możliwości wyświetlania, producent OEM musi zaimplementować Composer HAL w taki sposób, aby używał onHotplug(display, connection=CONNECTED)
do powiadamiania platformy o wszelkich zmianach w zakresie możliwości wyświetlania. Po wdrożeniu tej funkcji Android obsługuje zmiany w możliwościach 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 ramki podczas kolejnych zdarzeń onHotplug(display, connection=CONNECTED)
. Więcej informacji o prawidłowym zarządzaniu pamięcią bufora ramki znajdziesz w artykule Zarządzanie buforem ramki klienta. Dzięki temu unikniesz błędów podczas przydzielania nowych buforów ramki.
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 wdrożyć obsługę tych scenariuszy, skorzystaj z informacji w tej tabeli:
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 interfejsach API 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 HAL kompozytora aktualizuje obsługiwane konfiguracje wyświetlania jednocześnie z wywoływaniem przez platformę funkcji setActiveConfig
lub setActiveConfigWithConstraints
. Rozwiązaniem jest wdrożenie Composer
HAL, aby używać kolejnych 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 platformy zdarzenie
onHotplug
, aby powiadomić o zmianie zestawu obsługiwanych trybów.Warstwa HAL usługi Composer otrzymuje wartość
setActiveConfig(display, config=1)
(z kroku 2).HAL interpretuje to tak, że platforma zażądała zmiany konfiguracji na 2160x3840 60 Hz, chociaż w rzeczywistości wybrano 1080x1920 60 Hz.
Proces korzystający z przypisywania identyfikatorów w sposób niesekwencyjny kończy się tutaj błędną interpretacją wybranej 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 platforma wywołuje funkcję
setActiveConfig
lubsetActiveConfigWithConstraints
z nieprawidłowym identyfikatorem konfiguracji, interfejs HAL kompozytora 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 usługi Composer otrzymuje wartość
setActiveConfig(display, config=1)
(z kroku 2).Warstwa HAL kompozytora ignoruje wywołanie, ponieważ identyfikator jest już nieważny.
Platforma otrzymuje i przetwarza zdarzenie
onHotplug
z kroku 4. Wywołuje HAL usługi Composer za pomocą funkcjigetDisplayConfigs
igetDisplayAttribute
. Dzięki tym funkcjom framework identyfikuje nowy identyfikator (5) dla wybranej rozdzielczości i częstotliwości odświeżania 1080x1920 i 60 Hz.Framework wysyła kolejne zdarzenie
setActiveConfig
ze zaktualizowanym identyfikatorem 5.Komponent Composer HAL otrzymuje wartość
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 potwierdza, że zapobiega wystąpieniu wyścigu i aktualizuje prawidłową konfigurację wyświetlania.