Co każdy deweloper powinien wiedzieć o powierzchniach, SurfaceHolder, EGLSurface, SurfaceView, GLSurfaceView, SurfaceTexture, TextureView, SurfaceFlinger i Vulkan.
Na tej stronie opisaliśmy najważniejsze elementy architektury grafiki na poziomie systemu Androida oraz sposób ich używania przez system aplikacji i multimediów. Naciskamy tu na to, jak bufory danych graficznych poruszają się w systemie. Jeśli zastanawiasz się, dlaczego SurfaceView i TextureView zachowują się w taki sposób lub jak powierzchnie i EGLSurface ze sobą współdziałają, to trafiłeś we właściwe miejsce.
Zakładamy, że znasz już urządzenia z Androidem i proces tworzenia aplikacji. Nie musisz mieć szczegółowej wiedzy o ramce aplikacji i nie musisz używać wielu wywołań interfejsu API, ale materiał nie pokrywa się z inną publiczną dokumentacją. Celem jest dostarczenie szczegółowych informacji o istotnych zdarzeniach związanych z renderowaniem ramki na potrzeby wyjścia, aby pomóc Ci w podejmowaniu świadomych decyzji podczas projektowania aplikacji. Aby to osiągnąć, pracujemy od dołu do góry, opisując działanie klas interfejsu użytkownika, a nie sposób ich użycia.
Ta sekcja zawiera kilka stron, na których znajdziesz wszystko, od informacji ogólnych po szczegóły dotyczące HAL i przypadki użycia. Najpierw wyjaśniono w nim działanie buforów graficznych Androida, a potem opisano mechanizmy na wyższym poziomie, które dostarczają danych do kompozytora. Zalecamy czytanie stron w podanej poniżej kolejności, zamiast pomijania tematów, które wydają się interesujące.
Komponenty niskiego poziomu
- BufferQueue i gralloc. BufferQueue łączy element generujący bufory danych graficznych (producent) z elementem, który akceptuje dane do wyświetlenia lub dalszego przetwarzania (konsument). Przydzielanie buforów jest wykonywane za pomocą modułu alokacji pamięci gralloc zaimplementowanego za pomocą interfejsu HAL konkretnego producenta.
- SurfaceFlinger, Hardware Composer i wyświetlacze wirtualne. SurfaceFlinger przyjmuje bufory danych z różnych źródeł, łączy je i wysyła do wyświetlacza. Interfejs sprzętowy usługi komponowania (HWC) określa najbardziej wydajny sposób łączenia buforów z dostępnym sprzętem, a wyświetlacze wirtualne udostępniają z kombinowany sygnał wyjściowy w systemie (nagrywanie ekranu lub wysyłanie go przez sieć).
- Powierzchnia, kanwa i SurfaceHolder. Powierzchnia generuje kolejkę buforową, która jest często używana przez SurfaceFlinger. Gdy renderowanie odbywa się na powierzchni, wynik trafia do bufora, który jest wysyłany do odbiorcy. Interfejsy API Canvas zapewniają implementację oprogramowania (z obsługą przyspieszania sprzętowego) do rysowania bezpośrednio na powierzchni (alternatywa do OpenGL ES na niskim poziomie). Wszystko, co ma związek z widokiem, wymaga użycia obiektu SurfaceHolder, którego interfejsy API umożliwiają pobieranie i ustawianie parametrów powierzchni, takich jak rozmiar i format.
- EGLSurface i OpenGL ES. OpenGL ES (GLES) definiuje interfejs API do renderowania grafiki, który można łączyć z EGL, czyli biblioteką, która może tworzyć okna i dostępować do nich za pomocą systemu operacyjnego (aby rysować teksturowane wielokąty, używaj wywołań GLES; aby wyświetlać renderowanie na ekranie, używaj wywołań EGL). Na tej stronie znajdziesz też informacje o ANativeWindow, czyli odpowiedniku klasy Java Surface w języku C/C++, która służy do tworzenia okna EGL z użyciem kodu natywnego.
- Vulkan. Vulkan to interfejs API o niskim obciążeniu, który umożliwia tworzenie wydajnej grafiki 3D. Podobnie jak OpenGL ES, Vulkan udostępnia narzędzia do tworzenia wysokiej jakości grafiki w czasie rzeczywistym w aplikacjach. Zalety Vulkana to m.in. zmniejszenie obciążenia procesora i obsługa języka pośredniego SPIR-V w postaci binarnej.
Komponenty ogólne
- SurfaceView i GLSurfaceView. SurfaceView łączy powierzchnię i widok. Komponenty widoku SurfaceView są łączone przez SurfaceFlingera (a nie przez aplikację), co umożliwia renderowanie z osobnego wątku lub procesu i izolację od renderowania interfejsu aplikacji. GLSurfaceView udostępnia klasy pomocnicze do zarządzania kontekstami EGL, komunikacji między wątkami i interakcji z cyklem życia aktywności (nie jest to jednak wymagane do korzystania z GLES).
- SurfaceTexture. SurfaceTexture łączy powierzchnię i teksturę GLES, aby utworzyć kolejkę buforów, której aplikacja jest konsumentem. Gdy producent wstawia nowy bufor do kolejki, wysyła powiadomienie do aplikacji, która zwalnia poprzednio przechowywany bufor, pobiera nowy bufor z kolejki i wywołuje EGL, aby udostępnić go GLES jako zewnętrzną teksturę. Android 7.0 dodał obsługę odtwarzania zabezpieczonych tekstur wideo, co umożliwia procesowi GPU przetwarzanie zabezpieczonych treści wideo.
- TextureView. TextureView łączy widok z SurfaceTexture. TextureView otacza SurfaceTexture i odpowiada za reagowanie na wywołania zwrotne oraz pozyskiwanie nowych buforów. Podczas rysowania TextureView używa zawartości ostatnio otrzymanego bufora jako źródła danych, renderując obraz w dowolnym miejscu i w dowolny sposób, zgodnie ze stanem widoku. Składowanie widoku jest zawsze wykonywane za pomocą GLES, co oznacza, że aktualizacje zawartości mogą powodować ponowne rysowanie innych elementów widoku.