Warstwy i wyświetlacze to dwa prymitywy, które reprezentują kompozycję i interakcje z wyświetlaczem.
Warstwy
Warstwa to najważniejszy element kompozycji. Warstwa to połączenie powierzchni i wystąpienia SurfaceControl
. Każda warstwa ma zestaw właściwości, które określają jej interakcje z innymi warstwami. Właściwości warstwy zostały opisane w tabeli poniżej.
Właściwość | Opis |
---|---|
pozycjonowanie, | Określa, gdzie warstwa ma się wyświetlać. Obejmuje informacje takie jak pozycje krawędzi warstwy i jej kolejność Z względem innych warstw (czy ma być z przodu, czy z tyłu innych warstw). |
Treść | Określa, jak treści wyświetlane na warstwie powinny być prezentowane w ograniczeniach zdefiniowanych przez właściwości pozycyjne. Zawiera informacje takie jak przycinanie (rozszerzanie części treści w celu wypełnienia granic warstwy) i przekształcanie (wyświetlanie treści po obróceniu lub przewróceniu). |
Kompozycja | Określa sposób łączenia warstwy z innymi warstwami. Obejmuje informacje takie jak tryb mieszania i wartość alfa na poziomie warstwy na potrzeby kompozycji alfa. |
Optymalizacja | Zawiera informacje, które nie są niezbędne do prawidłowego złożenia warstwy, ale mogą być używane przez urządzenie sprzętowe (HWC) do optymalizacji procesu tworzenia kompozycji. Zawiera informacje takie jak widoczny obszar warstwy i który fragment warstwy został zaktualizowany od poprzedniego kadru. |
Wyświetlacze
Wyświetlanie to kolejna ważna jednostka kompozycji. System może mieć wiele wyświetlaczy, które można dodawać i usuwać podczas normalnej pracy systemu. Wyświetlacze są dodawane/usuwane na prośbę HWC lub na podstawie ram. Urządzenie HWC prosi o dodanie lub usunięcie wyświetlaczy, gdy wyświetlacz zewnętrzny jest podłączany lub odłączany od urządzenia. Jest to nazywane hotpluggingiem. Klienci proszą o wirtualne wyświetlacze, których zawartość jest renderowana do bufora poza ekranem zamiast na fizyczny wyświetlacz.
Wirtualne wyświetlacze
SurfaceFlingerobsługuje wyświetlacz wewnętrzny (wbudowany w telefon lub tablet), wyświetlacze zewnętrzne (np. telewizor podłączony przez HDMI) oraz co najmniej 1 wyświetlacz wirtualny, które udostępniają w systemie wyjście złożone. Ekrany wirtualne można wykorzystać do nagrywania ekranu lub przesyłania go przez sieć. Ramki wygenerowane dla wyświetlacza wirtualnego są zapisywane w kole buforowej.
Wyświetlacze wirtualne mogą korzystać z tego samego zestawu warstw co wyświetlacz główny (zbiór warstw) lub mieć własny zestaw. Synchronizacja pionowa nie jest dostępna w przypadku wyświetlacza wirtualnego, więc synchronizacja pionowa wyświetlacza wewnętrznego powoduje kompozycję wszystkich wyświetlaczy.
W implementacjach HWC, które je obsługują, wirtualne wyświetlacze mogą być złożone za pomocą OpenGL ES (GLES), HWC lub obu tych platform. W implementacjach, które nie obsługują tej funkcji, wyświetlacze wirtualne są zawsze złożone za pomocą biblioteki GLES.
Studium przypadku: screenrecord
Polecenie screenrecord
umożliwia użytkownikowi nagrywanie wszystkiego, co pojawia się na ekranie, w pliku .mp4
na dysku. Aby to zaimplementować, system odbiera złożone klatki z SurfaceFlingera, zapisuje je w enkoderze wideo, a potem zapisuje zakodowane dane wideo w pliku. Kodek wideo jest zarządzany przez osobny proces (mediaserver
), więc duże bufory graficzne muszą się przemieszczać w systemie. Aby zwiększyć trudność, celem jest nagrywanie filmów z częstotliwością 60 FPS w pełnej rozdzielczości. Kluczem do sprawnego działania jest kolejka buforowa.
Klasa MediaCodec
pozwala aplikacji na dostarczanie danych w postaci surowych bajtów w buforach lub za pomocą powierzchni. Gdy screenrecord
prosi o dostęp do kodera wideo, proces mediaserver
tworzy kolejkę buforową, łączy się z konsumentem, a następnie przekazuje producentowi z powrotem do screenrecord
jako powierzchnię.
Narzędzia screenrecord
prosi SurfaceFlingera o utworzenie wirtualnego wyświetlacza, który odzwierciedla wyświetlacz główny (czyli ma te same warstwy), i kieruje dane do wyświetlacza, który pochodzi z procesu mediaserver
. W tym przypadku SurfaceFlinger jest producentem buforów, a nie konsumentem.
Po zakończeniu konfiguracji reguła screenrecord
jest uruchamiany, gdy pojawiają się zakodowane dane. Gdy aplikacje wyświetlają obraz, ich bufory są przesyłane do SurfaceFlingera, który łączy je w jeden bufor, który jest wysyłany bezpośrednio do kodera wideo w procesie mediaserver
. Pełne ramki nigdy nie są widoczne dla procesu screenrecord
. Wewnętrznie proces mediaserver
ma własny sposób przemieszczania buforów, który umożliwia również przekazywanie danych za pomocą uchwytu, co minimalizuje obciążenie.
Studium przypadku: symulowanie ekranów dodatkowych
Okno może poprosić SurfaceFlingera o utworzenie widocznej warstwy, w której SurfaceFlinger działa jako odbiorca kolejki buforowej. Można też poprosić SurfaceFlingera o utworzenie wirtualnego wyświetlacza, w którym SurfaceFlinger działa jako producent kolejki buforowej.
Jeśli połączysz wyświetlacz wirtualny z widoczną warstwą, powstanie zamknięta pętla, w której złożony ekran będzie widoczny w oknie. To okno jest teraz częścią złożonego wyjścia, więc po następnym odświeżeniu złożony obraz w oknie będzie zawierać również zawartość okna. Aby zobaczyć, jak to działa, włącz Opcje programisty w Ustawieniach, wybierz Symuluj dodatkowe wyświetlacze i włącz okno. Aby zobaczyć działanie wyświetlaczy dodatkowych, użyj screenrecord
, aby zarejestrować proces włączania wyświetlacza, a następnie odtworzyć go klatka po klatce.