Grafika

Ikona HAL grafiki Androida

Struktura Androida oferuje różnorodne interfejsy API do renderowania grafiki 2D i 3D, które współdziałają z implementacjami sterowników graficznych producenta, dlatego ważne jest, aby dobrze zrozumieć, jak te interfejsy API działają na wyższym poziomie. Na tej stronie przedstawiono warstwę abstrakcji sprzętu graficznego (HAL), na której zbudowane są te sterowniki. Zanim przejdziesz dalej do tej sekcji, zapoznaj się z następującymi terminami:

canvas (termin ogólny), Canvas (element API)
Płótno to powierzchnia rysunkowa, która obsługuje łączenie rzeczywistych bitów z bitmapą lub obiektem Surface . Canvas zawiera metody standardowego komputerowego rysowania bitmap, linii, okręgów, prostokątów, tekstu itd. i jest powiązana z bitmapą lub powierzchnią. Płótno to najprostszy i najłatwiejszy sposób rysowania obiektów 2D na ekranie. Klasą bazową jest Canvas .
rysowalny
Element do rysowania to skompilowany zasób wizualny, którego można użyć jako tła, tytułu lub innej części ekranu. Element do rysowania jest zwykle ładowany do innego elementu interfejsu użytkownika, na przykład jako obraz tła. Obiekt do rysowania nie może odbierać zdarzeń, ale przypisuje różne inne właściwości, takie jak stan i harmonogram, aby umożliwić podklasy, takie jak obiekty animacji lub biblioteki obrazów. Wiele obiektów do rysowania jest ładowanych z plików zasobów do rysowania — plików XML lub bitmap opisujących obraz. Zasoby do rysowania są kompilowane w podklasy android.graphics.drawable . Aby uzyskać więcej informacji na temat rysunków i innych zasobów, zobacz Zasoby .
zasób układu
Zasób układu to plik XML opisujący układ ekranu aktywności. Aby uzyskać więcej informacji, zobacz Zasób układu .
dziewięć poprawek (9-łatka, NinePatch)
Dziewięć łatek to zasób mapy bitowej o zmiennym rozmiarze, którego można używać w przypadku tła lub innych obrazów na urządzeniu. Aby uzyskać więcej informacji, zobacz Dziewięć poprawek .
OpenGL ES
OpenGL ES to wieloplatformowy interfejs API do renderowania grafiki 2D i 3D. Android udostępnia biblioteki OpenGL ES do renderowania 3D z akceleracją sprzętową. W przypadku renderowania 2D płótno jest prostszą opcją. OpenGL ES jest dostępny w zestawie Android Native Development Kit (NDK) . Pakiety android.opengl i javax.microedition.khronos.opengles udostępniają funkcjonalność OpenGL ES.
powierzchnia (termin ogólny), Surface (element API)
Powierzchnia reprezentuje blok pamięci, który zostaje nałożony na ekran. Powierzchnia zawiera płótno do rysowania i zapewnia różne metody pomocnicze do rysowania warstw i zmiany rozmiaru obiektu Surface . Użyj klasy SurfaceView zamiast bezpośrednio klasy Surface .
widok powierzchni (termin ogólny), SurfaceView (element API)
Widok powierzchni to obiekt View , który otacza obiekt Surface do rysowania i udostępnia metody dynamicznego określania jego rozmiaru i formatu. Widok powierzchniowy umożliwia rysowanie niezależnie od wątku interfejsu użytkownika w przypadku operacji wymagających dużych zasobów, takich jak gry lub podglądy z kamery, ale w rezultacie wymaga dodatkowej pamięci. Widok powierzchni obsługuje zarówno grafikę płótna, jak i grafikę OpenGL ES. Klasą bazową obiektu SurfaceView jest SurfaceView .
temat
Motyw to zestaw właściwości, takich jak rozmiar tekstu i kolor tła, połączonych razem w celu zdefiniowania różnych domyślnych ustawień wyświetlania. Android udostępnia kilka standardowych motywów, wymienionych w R.style i poprzedzonych Theme_ .
widok (termin ogólny), View (element API)
Widok rysuje prostokątny obszar na ekranie i obsługuje kliknięcie, naciśnięcie klawisza i inne zdarzenia interakcji. Klasa View jest klasą bazową dla większości komponentów układu działania lub ekranu okna dialogowego, takich jak pola tekstowe i okna. Obiekt View odbiera wywołania od swojego obiektu nadrzędnego (zobacz ViewGroup ), aby sam się narysować i informuje swój obiekt nadrzędny o preferowanym rozmiarze i lokalizacji, które mogą nie być przestrzegane przez obiekt nadrzędny. Aby uzyskać więcej informacji, zobacz View .
grupa widoków (termin ogólny), ViewGroup (element API)
Grupa widoków grupuje zestaw widoków podrzędnych. Grupa widoków jest odpowiedzialna za podejmowanie decyzji o umiejscowieniu widoków podrzędnych i o tym, jak duże mogą być, a także za wywoływanie każdego z nich do samodzielnego narysowania, jeśli to konieczne. Niektóre grupy widoków są niewidoczne i służą wyłącznie do celów układu, podczas gdy inne mają wewnętrzny interfejs użytkownika, taki jak przewijane pole listy. Grupy widoków znajdują się w pakiecie widget , ale należy rozszerzyć klasę ViewGroup .
hierarchia widoku
Hierarchia widoków to układ obiektów widoków i grup widoków, który definiuje interfejs użytkownika dla każdego komponentu aplikacji. Hierarchia składa się z grup widoków, które zawierają jeden lub więcej widoków podrzędnych lub grup widoków. Wizualną reprezentację hierarchii widoków na potrzeby debugowania i optymalizacji można uzyskać, korzystając z przeglądarki hierarchii dostarczonej z zestawem SDK systemu Android.
Wulkan
Vulkan to wieloplatformowy interfejs API o niskim nakładzie pracy, zapewniający wysoką wydajność grafiki 3D.
widżet
Widget to jedna z zestawu w pełni zaimplementowanych podklas widoków, które renderują elementy formularzy i inne komponenty interfejsu użytkownika, takie jak pole tekstowe lub wyskakujące menu. Ponieważ widget jest w pełni zaimplementowany, sam obsługuje pomiary, rysowanie i reagowanie na zdarzenia na ekranie. Widżety znajdują się w pakiecie android.widget .
okno (termin ogólny), Window (element API)
W aplikacji na Androida okno to obiekt wywodzący się z klasy abstrakcyjnej Window , który określa elementy okna ogólnego, takie jak wygląd i działanie, tekst paska tytułu oraz lokalizacja i zawartość menu. Okna dialogowe i działania wykorzystują implementację klasy Window do renderowania obiektu Window . Nie musisz implementować klasy Window ani używać okien w swojej aplikacji.

Twórcy aplikacji rysują obrazy na ekranie na trzy sposoby: za pomocą Canvas , OpenGL ES lub Vulkan .

Komponenty graficzne Androida

Bez względu na to, z jakiego narzędzia renderowania korzystają programiści API, wszystko jest renderowane na powierzchni. Powierzchnia reprezentuje stronę producenta kolejki buforów, która jest często używana przez SurfaceFlinger. Każde okno utworzone na platformie Android jest wspierane przez powierzchnię. Wszystkie wyrenderowane widoczne powierzchnie są łączone na wyświetlaczu przez SurfaceFlinger.

Poniższy diagram pokazuje, jak kluczowe komponenty współpracują ze sobą:

komponenty renderujące obraz

Rysunek 1. Sposób renderowania powierzchni.

Główne komponenty opisano poniżej:

Producenci strumieni obrazu

Producentem strumienia obrazu może być wszystko, co produkuje bufory graficzne do wykorzystania. Przykłady obejmują dekodery wideo OpenGL ES, Canvas 2D i mediaserver.

Konsumenci strumienia obrazów

Najpopularniejszym konsumentem strumieni obrazów jest SurfaceFlinger, usługa systemowa, która zużywa aktualnie widoczne powierzchnie i łączy je na wyświetlaczu przy użyciu informacji dostarczonych przez Menedżera okien. SurfaceFlinger to jedyna usługa, która może modyfikować zawartość wyświetlacza. SurfaceFlinger używa OpenGL i Hardware Composer do komponowania grupy powierzchni.

Inne aplikacje OpenGL ES również mogą wykorzystywać strumienie obrazów, na przykład aplikacja aparatu zużywająca strumień obrazu podglądu z kamery. Aplikacje inne niż GL również mogą być konsumentami, na przykład klasa ImageReader.

Kompozytor sprzętu

Abstrakcja sprzętowa dla podsystemu wyświetlania. SurfaceFlinger może delegować pewne prace związane z kompozycją do Hardware Composer, aby odciążyć OpenGL i GPU. SurfaceFlinger działa jak kolejny klient OpenGL ES. Na przykład, gdy SurfaceFlinger aktywnie łączy jeden lub dwa bufory w trzeci, używa OpenGL ES. To sprawia, że ​​komponowanie zużywa mniej energii niż wykonywanie wszystkich obliczeń przez procesor graficzny.

Drugą połowę pracy wykonuje Hardware Composer HAL , który stanowi centralny punkt renderowania grafiki w systemie Android. Program Hardware Composer musi obsługiwać zdarzenia, z których jedno to VSYNC (inne to hotplug obsługujący technologię plug-and-playHDMI).

Graloc

Do przydzielania pamięci wymaganej przez producentów obrazów potrzebny jest moduł alokacji pamięci graficznej (Gralloc). Aby uzyskać szczegółowe informacje, zobacz Gralloc HAL .

Przepływ danych

Poniższy diagram przedstawia potok graficzny systemu Android:

przepływ danych graficznych

Rysunek 2. Graficzny przepływ danych przez Androida

Obiekty po lewej stronie to moduły renderujące tworzące bufory graficzne, takie jak ekran główny, pasek stanu i interfejs użytkownika systemu. SurfaceFlinger jest kompozytorem, a Hardware Composer jest kompozytorem.

Kolejka buforowa

BufferQueues zapewniają spoiwo pomiędzy komponentami graficznymi Androida. Są to pary kolejek, które pośredniczą w stałym cyklu buforów od producenta do konsumenta. Gdy producenci przekażą swoje bufory, SurfaceFlinger jest odpowiedzialny za umieszczenie wszystkiego na wyświetlaczu.

Zobacz poniższy diagram przedstawiający proces komunikacji BufferQueue.

Proces komunikacji BufferQueue

Rysunek 3. Proces komunikacji BufferQueue

BufferQueue zawiera logikę, która łączy producentów strumieni obrazów i konsumentów strumieni obrazów. Przykładami producentów obrazów są podglądy z kamer tworzone przez kamery HAL lub gry OpenGL ES. Przykładami konsumentów obrazów są SurfaceFlinger lub inna aplikacja wyświetlająca strumień OpenGL ES, na przykład aplikacja aparatu wyświetlająca wizjer aparatu.

BufferQueue to struktura danych, która łączy pulę buforów z kolejką i wykorzystuje Binder IPC do przekazywania buforów pomiędzy procesami. Interfejs producenta, czyli to, co przekazujesz komuś, kto chce wygenerować bufory graficzne, to IGraphicBufferProducer (część SurfaceTexture ). BufferQueue jest często używany między innymi do renderowania na urządzeniu Surface i korzystania z niego przez konsumenta GL.

BufferQueue może działać w trzech różnych trybach:

Tryb synchroniczny — BufferQueue domyślnie działa w trybie synchronicznym, w którym każdy bufor przychodzący od producenta jest wysyłany do konsumenta. W tym trybie żaden bufor nie jest nigdy odrzucany. A jeśli producent będzie zbyt szybki i utworzy bufory szybciej, niż są opróżniane, zablokuje się i będzie czekał na wolne bufory.

Tryb nieblokujący — BufferQueue może również działać w trybie nieblokującym, w którym w takich przypadkach generuje błąd, zamiast czekać na bufor. W tym trybie żaden bufor nie jest nigdy odrzucany. Jest to przydatne, aby uniknąć potencjalnych zakleszczeń w oprogramowaniu, które może nie rozumieć złożonych zależności struktury graficznej.

Tryb odrzucania — na koniec BufferQueue można skonfigurować tak, aby odrzucał stare bufory zamiast generować błędy lub czekać. Na przykład, jeśli przeprowadzasz renderowanie GL do widoku tekstury i rysujesz tak szybko, jak to możliwe, bufory muszą zostać usunięte.

Aby wykonać większość tej pracy, SurfaceFlinger działa jako kolejny klient OpenGL ES. Na przykład, gdy SurfaceFlinger aktywnie łączy jeden lub dwa bufory w trzeci, używa OpenGL ES.

Drugą połowę pracy wykonuje Hardware Composer HAL. Ta warstwa HAL działa jako centralny punkt całego renderowania grafiki Androida.