Wdrażanie HAL usługi Hardware Composer

Warstwy HAL narzędzia Hardware Composer (HWC) otrzymane z serwera SurfaceFlinger, która zmniejsza ilość kompozycji OpenGL ES (GLES) i GPU.

HWC wyodrębnia obiekty, takie jak nakładki i blitry 2D, do elementów złożonych i komunikuje się ze specjalistycznym sprzętem do kompozycji okien, w oknach złożonych. Używaj HWC do tworzenia okien złożonych zamiast Kompozyt SurfaceFlinger z GPU. Większość GPU nie jest zoptymalizowana pod kątem oraz kiedy GPU tworzy warstwy SurfaceFlinger, aplikacje nie mogą używać GPU do własnego renderowania.

Implementacje HWC powinny obsługiwać:

  • Co najmniej 4 nakładki:
    • Pasek postępu
    • Pasek systemowy
    • Aplikacja
    • Tapeta/tło
  • warstwy większe niż wyświetlacz (np. tapeta).
  • Równoczesne mnożenie wstępnie na piksel i mieszanie alfa na poszczególnych płaszczyznach mieszanie alfa
  • Ścieżka sprzętowa do odtwarzania chronionego filmu
  • Kolejność pakowania RGBA, formaty YUV oraz kafelki, wiry i kroki usługi

Aby wdrożyć HWC:

  1. wdrożyć nieoperacyjne urządzenie HWC i wysłać całą pracę z kompozycji do GLES.
  2. Zaimplementuj algorytm, który stopniowo przekaże kompozycję do HWC. Możesz na przykład przydzielić do nakładki tylko 3 lub 4 pierwsze powierzchnie. systemu HWC.
  3. Optymalizacja ogrzewania. Może to obejmować:
    • Wybieramy platformy, które maksymalizują obciążenie procesora graficznego wysyła je do systemu HWC.
    • Wykrywanie, czy ekran się aktualizuje. Jeśli nie, przekaż dostęp do GLES, a nie do HWC, aby oszczędzać energię. Gdy ekran należy kontynuować, przenosić kompozycję do urządzenia HWC.
    • Przygotowanie do typowych przypadków użycia, takich jak:
      • Ekran główny zawierający pasek stanu, pasek systemu i aplikację okno i animowane tapety
      • Gry pełnoekranowe w orientacji pionowej i poziomej
      • Film na pełnym ekranie z napisami i sterowaniem odtwarzaniem
      • Chronione odtwarzanie wideo
      • Tryb wielu okien podzielony na ekran

Elementy podstawowe HWC

HWC udostępnia 2 elementy podstawowe: warstwy i wyświetlacze, przedstawiają pracę nad kompozycją i jej interakcje z ekranem. HWC zapewnia też kontrolę nad VSYNC oraz wywołanie zwrotne do SurfaceFlinger, aby powiadomić go o wystąpieniu zdarzenia VSYNC.

Interfejs HIDL

Android 8.0 i nowsze wersje używają interfejsu HIDL o nazwie Composer HAL do obsługi interfejsu IPC w ramach bindera między HWC a SurfaceFlinger. Interfejs HAL Composer zastępuje starszy interfejs hwcomposer2.h. Jeśli dostawcy podają kod HAL usługi Composer po wdrożeniu HWC, Composer HAL bezpośrednio akceptuje wywołania HIDL SurfaceFlinger. Jeśli dostawcy udostępniają starszą implementację HWC, Composer HAL wczytuje wskaźniki funkcji z pliku hwcomposer2.h, i przekierowywanie wywołań HIDL do wywołań wskaźnika funkcji.

HWC udostępnia funkcje umożliwiające określenie właściwości danego wyświetlacza, przełączanie się między różnymi konfiguracjami wyświetlacza (np. rozdzielczość 4K lub 1080p) i trybami kolorów (np. domyślny kolor lub prawdziwy sRGB) oraz włączanie, wyłączanie wyświetlacza lub przełączanie go w tryb niskiego poboru mocy (jeśli jest obsługiwany).

Wskaźniki funkcji

Jeśli dostawcy bezpośrednio wdrażają usługę Composer HAL, SurfaceFlinger wywołuje swoje funkcje za pomocą HIDL IPC. Na przykład do utworzenia warstwy SurfaceFlinger wywołuje funkcję createLayer() w komponencie HAL usługi Composer.

Jeśli dostawcy wdrożą interfejs hwcomposer2.h, HAL usługi Composer we wskaźnikach funkcji hwcomposer2.h. W hwcomposer2.h komentarzach, Funkcje interfejsu HWC są przywoływane przez małe literyCamelCase, które nie występują w interfejsie jako nazwane pola. Prawie każda funkcja jest ładowana przez żądanie wskaźnik funkcji za pomocą parametru getFunction dostarczonego przez hwc2_device_t Na przykład funkcja createLayer jest wskaźnikiem funkcji typu HWC2_PFN_CREATE_LAYER, który jest zwracany, gdy do funkcji getFunction przekazana zostaje wartością zagregowana HWC2_FUNCTION_CREATE_LAYER.

Szczegółową dokumentację funkcji HAL w Composerze i funkcji przekazywania funkcji HWC znajdziesz w artykule composer. Szczegółową dokumentację dotyczącą wskaźników funkcji HWC znajdziesz w hwcomposer2.h.

Uchwyty do tworzenia warstw i wyświetlania

Warstwy i wyświetlacze są modyfikowane za pomocą uchwytów wygenerowanych przez HWC. Uchwyty są nieprzezroczyste dla SurfaceFlinger.

Gdy SurfaceFlinger tworzy nową warstwę, wywołuje funkcję createLayer, który zwraca typ Layer dla wartości bezpośrednich lub hwc2_layer_t w przypadku implementacji przekazywania. Gdy SurfaceFlinger modyfikuje właściwość tej warstwy, przekazuje wartość hwc2_layer_t do odpowiedniej funkcji modyfikacji wraz z innymi informacjami potrzebnymi do wprowadzenia modyfikacji. Typ elementu hwc2_layer_t jest wystarczająco duży, aby pomieścić wskaźnik lub indeksu.

Fizyczne wyświetlacze są tworzone przez podłączenie. Gdy fizyczny wyświetlacz jest HWC tworzy nick i przekazuje go do usługi SurfaceFlinger. przez wywołanie zwrotne Hotplug. Wyświetlacze wirtualne są tworzone przez SurfaceFlinger Wywołuję createVirtualDisplay(), aby poprosić o wyświetlenie. Jeśli HWC obsługuje kompozycję obrazu wirtualnego, zwraca nick. Następnie SurfaceFlinger przekazuje kompozycję wyświetlaczy do urządzenia HWC. Jeśli HWC nie obsługuje funkcji wirtualnych kompozycję wyświetlania, SurfaceFlinger tworzy nick i komponuje wyświetlacz.

Wyświetl operacje tworzenia kompozycji

Raz na VSYNC, SurfaceFlinger aktywuje się, jeśli ma nową zawartość do wieloskładnikową. Nowe treści mogą być nowymi buforami obrazów z aplikacji lub zmianą właściwości co najmniej jednej warstwy. Gdy SurfaceFlinger Wybudza:

  1. Obsługuje transakcje (jeśli występują).
  2. Włącza nowe bufory graficzne (jeśli są dostępne).
  3. Wykonuje nową kompozycję, jeśli krok 1 lub 2 spowodował zmianę. do wyświetlanej treści.

Aby wykonać nową kompozycję, SurfaceFlinger tworzy niszczy warstwy lub modyfikuje ich stany (stosownie do przypadku). Są one też aktualizowane warstw z ich bieżącą zawartością, używając wywołań takich jak setLayerBuffer lub setLayerColor. Gdy wszystkie warstwy zostaną zaktualizowany, SurfaceFlinger wywołuje validateDisplay, który informuje HWC, aby zbadać stan warstw i określić, jak koncentracja i kontynuować. Domyślnie SurfaceFlinger próbuje skonfigurować każdą warstwę w taki sposób, aby warstwa była skomponowana przez HWC; chociaż w niektórych gdy SurfaceFlinger łączy warstwy za pomocą kreacji zastępczej GPU.

Po wywołaniu validateDisplay SurfaceFlinger wywołuje getChangedCompositionTypes, aby sprawdzić, czy system HWC chce zmienić dowolny typ kompozycji warstwy przed wykonaniem polecenia kompozycji. Aby zaakceptować zmiany, SurfaceFlinger wywołuje funkcję acceptDisplayChanges.

Jeśli jakiekolwiek warstwy są oznaczone jako kompozycja SurfaceFlinger, SurfaceFlinger umieszcza je w buforze docelowym. SurfaceFlinger następnie wywołuje setClientTarget, aby dodać bufor do wyświetlacza, tak aby które można wyświetlić na ekranie lub skomponować z warstwami, które nie zostały oznaczone do kompozycji SurfaceFlinger. Jeśli żadne warstwy nie są oznaczone dla SurfaceFlinger pomija etap tworzenia kompozycji.

Na koniec SurfaceFlinger wywołuje metodę presentDisplay, aby to określić. zespół HWC dokończ proces kompozycji i wyświetli efekt końcowy.

Wiele wyświetlaczy

Android 10 obsługuje wiele fizycznych wyświetlaczy. Podczas projektowania implementacji HWC przeznaczonej do użytku na Androidzie 7.0 oznacza, że w definicji HWC nie występują pewne ograniczenia:

  • Zakładamy, że masz dokładnie 1 wyświetlacz wewnętrzny. Mechanizm jest wyświetlany podczas uruchamianie. Po podłączeniu wewnętrznego wyświetlacza do zasilania nie można zostaną odłączone.
  • Oprócz wewnętrznego wyświetlacza można podłączyć do zasilania dowolną liczbę wyświetlaczy zewnętrznych. podczas normalnego działania urządzenia. Framework zakłada, że wszystkie urządzenia peryferyjne po pierwszym wewnętrznym ekranie są ekranami zewnętrznymi, więc jeśli dodasz więcej ekranów wewnętrznych, zostaną one nieprawidłowo sklasyfikowane jako Display.TYPE_HDMI zamiast Display.TYPE_BUILT_IN.

Opisane powyżej operacje SurfaceFlinger są wykonywane na wyświetlacz, są realizowane po kolei dla wszystkich aktywnych wyświetlaczy, , nawet jeśli treść tylko jednego wyświetlacza jest zaktualizowana.

Jeśli na przykład wyświetlacz zewnętrzny zostanie zaktualizowany, sekwencja będzie wyglądać tak:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

Kompozycja wyświetlacza wirtualnego

Struktura wyświetlacza wirtualnego jest podobna do tej na wyświetlaczu zewnętrznym kompozycji. Różnica między kompozycją zasobów displayowych wirtualnych a fizyczną Struktura obrazu polega na tym, że ekrany wirtualne wysyłają dane wyjściowe do bufora Gralloca. zamiast na ekran. Komponent HWC zapisuje dane wyjściowe w buforze, zapewnia zabezpieczenie przed zakończeniem i wysyła je do odbiorcy (np. do kodera wideo, procesora graficznego, procesora centralnego itp.). Wyświetlacze wirtualne mogą używać 2D/Blitter lub nakładek, jeśli potok wyświetlania zapisuje dane w pamięci.

Tryby

Każda klatka jest w jednym z 3 trybów po wywołaniu przez SurfaceFlinger parametru Metoda ogrzewania/wentylacji/klimatyzacji validateDisplay():

  • GLES – układ GPU łączy wszystkie warstwy, zapis bezpośrednio do bufora wyjściowego. HWC nie uczestniczy w kompozycji.
  • MIESZANE – GPU nakłada niektóre warstwy na Framebuffer, i HWC komponują bufor klatek i pozostałe warstwy, bezpośrednio w buforze wyjściowym.
  • HWC – HWC łączy wszystkie warstwy i bezpośrednio zapisuje do bufora wyjściowego.

Format wyjściowy

Formaty danych wyjściowych wirtualnego bufora wyświetlacza zależą od trybu:

  • Tryb GLES – sterownik EGL ustawia format bufora wyjściowego w dequeueBuffer(), zwykle RGBA_8888. Użytkownik musi być w stanie zaakceptować format wyjściowy ustawiony przez sterownik, w przeciwnym razie bufor nie będzie można odczytać.
  • Tryby mieszane i HWC – czy konsument potrzebuje CPU konsument ustawia format. W przeciwnym razie format to IMPLEMENTATION_DEFINED, a Gralloc ustawia najlepszy format na podstawie: flagi wykorzystania. Na przykład Gralloc ustawia format YCbCr, jeśli konsument koder wideo i urządzenie HWC potrafią skutecznie zapisać format.

Ograniczenia synchronizacji

Bariery związane z synchronizacją są kluczowym aspektem grafiki Androida. systemu. Dzięki zabezpieczeniom procesor może działać niezależnie od równoczesnej pracy GPU, ale tylko wtedy, gdy zaistnieje prawdziwa zależność.

Na przykład, gdy aplikacja przesyła bufor tworzony GPU, przesyła też obiekt blokady synchronizacji. To ogrodzenie sygnalizuje, gdy Procesor graficzny zakończył zapisywanie w buforze.

HWC wymaga, aby GPU kończył bufory zapisu przed buforami. . Ogrodzenia synchronizacji są przekazywane przez rdzeń graficzny wraz z buforami i sygnałem, gdy bufory są zapisywane. Przed wyświetleniem bufora moduł sprawdza, czy ogrodzenie synchronizacji ma sygnał, a jeśli jest, wyświetla bufora.

Więcej informacji o ogrodzeniach synchronizacji znajdziesz w sekcji Hardware Composer Integracja