Warstwy i wyświetlacze to 2 podstawowe elementy, które reprezentują kompozycję i interakcje ze sprzętem wyświetlającym.
Warstwy
Warstwa to najważniejsza jednostka kompozycji. Warstwa to połączenie powierzchni i instancji SurfaceControl
.
Każda warstwa ma zestaw właściwości, które określają, jak współdziała z innymi warstwami. Właściwości warstwy zostały opisane w tej tabeli:
Właściwość | Opis |
---|---|
Pozycyjne | Określa, gdzie warstwa pojawia się na wyświetlaczu. Zawiera informacje takie jak położenie krawędzi warstwy i jej kolejność Z względem innych warstw (czy powinna znajdować się przed innymi warstwami, czy za nimi). |
Treść | Określa, jak treści wyświetlane w warstwie powinny być prezentowane w granicach określonych przez właściwości pozycji. Zawiera informacje takie jak przycinanie (aby rozszerzyć część treści i wypełnić granice warstwy) i przekształcanie (aby wyświetlić obrócone lub odwrócone treści). |
Kompozycja | Określa, w jaki sposób warstwa powinna być łączona z innymi warstwami. Zawiera informacje takie jak tryb mieszania i wartość alfa dla całej warstwy na potrzeby komponowania alfa. |
Optymalizacja | Zawiera informacje, które nie są ściśle niezbędne do prawidłowego złożenia warstwy, ale mogą być używane przez urządzenie Hardware Composer (HWC) do optymalizacji sposobu, w jaki wykonuje ono kompozycję. Zawiera informacje takie jak widoczny region warstwy i część warstwy, która została zaktualizowana od czasu poprzedniej klatki. |
Wyświetlacze
Wyświetlanie to kolejny ważny element kompozycji. System może mieć wiele wyświetlaczy, a wyświetlacze można dodawać i usuwać podczas normalnej pracy systemu. Wyświetlacze są dodawane lub usuwane na żądanie HWC lub na żądanie platformy. Urządzenie HWC wysyła żądania dodania lub usunięcia wyświetlaczy, gdy wyświetlacz zewnętrzny jest podłączany do urządzenia lub odłączany od niego. Nazywa się to podłączaniem na gorąco. Klienci żądają wirtualnych wyświetlaczy, których zawartość jest renderowana w buforze poza ekranem, a nie na fizycznym wyświetlaczu.
Wirtualne wyświetlacze
SurfaceFlinger obsługuje wyświetlacz wewnętrzny (wbudowany w telefon lub tablet), wyświetlacze zewnętrzne (np. telewizor podłączony przez HDMI) i co najmniej jeden wyświetlacz wirtualny, który udostępnia w systemie złożone dane wyjściowe. Wirtualne wyświetlacze mogą służyć do nagrywania ekranu lub przesyłania go przez sieć. Klatki wygenerowane na potrzeby wirtualnego wyświetlacza są zapisywane w kolejce buforów.
Wirtualne wyświetlacze mogą korzystać z tego samego zestawu warstw co wyświetlacz główny (stos warstw) lub mieć własny zestaw. W przypadku wirtualnego wyświetlacza nie ma synchronizacji pionowej, więc synchronizacja pionowa wyświetlacza wewnętrznego wywołuje kompozycję dla wszystkich wyświetlaczy.
W implementacjach HWC, które je obsługują, wyświetlacze wirtualne można łączyć za pomocą OpenGL ES (GLES), HWC lub obu tych interfejsów. W przypadku implementacji, które nie obsługują tej funkcji, wyświetlacze wirtualne są zawsze łączone za pomocą GLES.
Studium przypadku: screenrecord
Polecenie screenrecord
umożliwia użytkownikowi nagrywanie wszystkiego, co pojawia się na ekranie, jako pliku MP4 na dysku. Aby to zrobić, system otrzymuje złożone klatki z SurfaceFlingera, zapisuje je w enkoderze wideo, a następnie zapisuje zakodowane dane wideo w pliku. Kodeki wideo są zarządzane przez oddzielny proces (mediaserver
), więc duże bufory graficzne muszą być przenoszone w systemie. Aby utrudnić zadanie, celem jest nagranie filmu w 60 kl./s w pełnej rozdzielczości. Kluczem do efektywnego działania tej funkcji jest BufferQueue.
Klasa MediaCodec
umożliwia aplikacji dostarczanie danych w postaci surowych bajtów w buforach lub za pomocą powierzchni. Gdy screenrecord
poprosi o dostęp do enkodera wideo, proces mediaserver
utworzy kolejkę buforów, połączy się z jej stroną konsumencką, a następnie przekaże stronę producenta z powrotem do screenrecord
jako powierzchnię.
Narzędzie screenrecord
wysyła następnie do SurfaceFlingera prośbę o utworzenie wirtualnego wyświetlacza, który odzwierciedla główny wyświetlacz (czyli ma wszystkie te same warstwy), i kieruje go do wysyłania danych wyjściowych na powierzchnię pochodzącą z procesu screenrecord
.mediaserver
W tym przypadku SurfaceFlinger jest producentem buforów, a nie konsumentem.
Po zakończeniu konfiguracji screenrecord
jest wywoływany, gdy pojawią się zakodowane dane. W miarę rysowania przez aplikacje ich bufory są przesyłane do SurfaceFlingera, który łączy je w jeden bufor wysyłany bezpośrednio do kodera wideo w procesie mediaserver
. Pełne klatki nigdy nie są widoczne dla procesu screenrecord
. Wewnętrznie proces mediaserver
ma własny sposób przenoszenia buforów, który również przekazuje dane za pomocą uchwytu, co minimalizuje obciążenie.
Studium przypadku: symulowanie ekranów dodatkowych
Menedżer okien może poprosić usługę SurfaceFlinger o utworzenie widocznej warstwy, w przypadku której usługa SurfaceFlinger działa jako odbiorca BufferQueue. Możesz też poprosić usługę SurfaceFlinger o utworzenie wirtualnego wyświetlacza, w przypadku którego usługa SurfaceFlinger działa jako producent BufferQueue.
Jeśli połączysz wirtualny wyświetlacz z widoczną warstwą, powstanie zamknięta pętla, w której złożony ekran będzie wyświetlany w oknie. To okno jest teraz częścią złożonych danych wyjściowych, więc przy następnym odświeżeniu złożony obraz w oknie będzie również zawierać zawartość okna. Aby zobaczyć, jak to działa, włącz Opcje programisty w Ustawieniach, wybierz Symuluj wyświetlacze dodatkowe i włącz okno. Aby zobaczyć działanie wyświetlaczy dodatkowych, użyj screenrecord
, aby zarejestrować moment włączenia wyświetlacza, a następnie odtwórz go klatka po klatce.