
Platforma Android oferuje różne interfejsy API do renderowania grafiki 2D i 3D, które współpracują z implementacjami sterowników graficznych przez producentów. Dlatego warto dobrze poznać działanie tych interfejsów API. Ta strona przedstawia warstwę abstrakcji sprzętu graficznego (HAL), na której są budowane te sterowniki. Zanim przejdziesz do tej sekcji, zapoznaj się z tymi warunkami:
Canvas
(element interfejsu API)Surface
. Canvas
zawiera metody standardowego rysowania bitmap, linii, kół, prostokątów, tekstu itp., a także jest powiązany z bitmapą lub powierzchnią. Płótno to najprostszy sposób rysowania obiektów 2D na ekranie. Klasa podstawowa to Canvas
.
android.graphics.drawable
.
Więcej informacji o elementach do rysowania i innych zasobach znajdziesz w artykule Zasoby.
android.opengl
i javax.microedition.khronos.opengles
udostępniają funkcje OpenGL ES.Surface
(element interfejsu API)Surface
. Zamiast klasy Surface
użyj klasy SurfaceView
.
SurfaceView
(element interfejsu API)View
, który otacza obiekt Surface
do rysowania i wyświetla metody służące do dynamicznego określania jego rozmiaru i formatu. Widok powierzchni umożliwia wyświetlanie niezależnie od wątku interfejsu w przypadku operacji wymagających dużej ilości zasobów, takich jak gry czy podgląd na kamerze, ale w efekcie zużywa dodatkową pamięć. Widok powierzchni obsługuje zarówno grafikę na płótnie, jak i OpenGL ES. Klasą podstawową obiektu SurfaceView
jest SurfaceView
.
R.style
i poprzedzielane znakiem Theme_
.View
(element interfejsu API)View
jest klasą podstawową dla większości komponentów układu aktywności lub ekranu dialogowego, takich jak pola tekstowe i okna. Obiekt View
otrzymuje wywołania od obiektu nadrzędnego (patrz ViewGroup
), aby narysować siebie, i informuje obiekt nadrzędny o swoim preferowanym rozmiarze i lokalizacji, które mogą nie być respektowane przez obiekt nadrzędny. Więcej informacji znajdziesz na stronie View
.
ViewGroup
(element interfejsu API)widget
, ale rozszerzają klasę ViewGroup
.
android.widget
. Window
(element interfejsu API)Window
, która określa elementy ogólnego okna, takie jak wygląd i styl, tekst na pasku tytułu oraz lokalizacja i zawartość menu. Dialogi i zadania korzystają z implementacji klasy Window
do renderowania obiektu Window
. Nie musisz implementować klasy Window
ani używać okien w aplikacji.Deweloperzy aplikacji wyświetlają obrazy na ekranie na 3 sposoby: za pomocą Canvas, OpenGL ES lub Vulkan.
Komponenty graficzne Androida
Niezależnie od tego, którego interfejsu API do renderowania używają deweloperzy, wszystko jest renderowane na powierzchni. Powierzchnia reprezentuje stronę producenta kolejki buforowej, która jest często używana przez SurfaceFlinger. Każde okno utworzone na platformie Android jest obsługiwane przez powierzchnię. Wszystkie wyrenderowane widoczne powierzchnie są łączone na wyświetlaczu przez SurfaceFlingera.
Ten schemat pokazuje, jak współpracują ze sobą najważniejsze komponenty:

Rysunek 1. Sposób renderowania powierzchni.
Główne elementy:
Producenci strumienia obrazów
Producentem strumienia obrazów może być wszystko, co tworzy bufory graficzne do wykorzystania. Przykłady to dekodery OpenGL ES, Canvas 2D i mediaserver.
Odbiorcy strumienia obrazów
Najczęstszym odbiorcą strumieni obrazów jest SurfaceFlinger, usługa systemowa, która pobiera aktualnie widoczne powierzchnie i z użyciem informacji dostarczonych przez menedżera okien komponuje je na wyświetlaczu. SurfaceFlinger to jedyna usługa, która może modyfikować zawartość wyświetlacza. SurfaceFlinger do tworzenia grupy powierzchni używa OpenGL i komponenta sprzętowego.
Strumienie obrazów mogą też używać inne aplikacje OpenGL ES, np. aplikacja aparatu, która korzysta ze strumienia obrazu podglądu aparatu. Aplikacje inne niż GL mogą też być konsumentami, np. klasa ImageReader.
Komponowanie sprzętu
Abstrakcyjna warstwa sprzętowa dla podsystemu wyświetlacza. SurfaceFlinger może delegować niektóre zadania związane z kompozycją do kompozytora sprzętowego, aby odciążyć OpenGL i kartę graficzną. SurfaceFlinger działa jak zwykły klient OpenGL ES. Gdy więc SurfaceFlinger aktywnie łączy jeden lub dwa bufory w trzeci, korzysta z OpenGL ES. Dzięki temu kompozycja będzie wymagać mniej mocy niż gdyby GPU wykonywał wszystkie obliczenia.
Moduł sprzętowy Composer HAL wykonuje drugą połowę pracy i jest centralnym punktem do renderowania grafiki na Androidzie. Komponent Hardware Composer musi obsługiwać zdarzenia, w tym VSYNC (inne to hotplug dla obsługi HDMI typu „plug and play”).
Gralloc
Do przydzielania pamięci żądanej przez producentów obrazu potrzebny jest moduł alokacji pamięci graficznej (Gralloc). Więcej informacji znajdziesz w artykule Gralloc HAL.
Przepływ danych
Schemat ścieżki przetwarzania grafiki w Androidzie:

Rysunek 2. Przepływ danych graficznych w Androidzie
Obiekty po lewej stronie to moduły renderujące, które tworzą bufory graficzne, takie jak ekran główny, pasek stanu i interfejs systemu. SurfaceFlinger jest kompozytorem, a Hardware Composer jest kompozytorem.
BufferQueue
kolejki buforowe stanowią element łączący komponenty graficzne Androida. To para kolejek, które pośredniczą w ciągłym cyklu buforów od producenta do konsumenta. Gdy producenci przekażą swoje bufory, SurfaceFlinger będzie odpowiedzialny za złożenie wszystkich elementów na wyświetlaczu.
Proces komunikacji z koleją buforów przedstawia diagram poniżej.

Rysunek 3. Proces komunikacji z koleją buforów
BufferQueue zawiera logikę, która łączy ze sobą producentów strumienia obrazów i odbiorców strumienia obrazów. Przykładami producentów obrazów są podglądy aparatu tworzone przez HAL aparatu lub gry OpenGL ES. Przykładami konsumentów obrazu są aplikacja SurfaceFlinger lub inna aplikacja wyświetlająca strumień OpenGL ES, na przykład aplikacja aparatu wyświetlająca wizjer aparatu.
Struktura danych BufferQueue łączy pulę buforów z koleją i używa Binder IPC do przekazywania buforów między procesami. Interfejs producenta, czyli to, co przekazujesz użytkownikowi, który chce generować bufory graficzne, to IGraphicBufferProducer (część SurfaceTexture). Kolejka buforów jest często używana do renderowania na powierzchni i do obsługi interfejsu GLConsumer.
BufferQueue może działać w 3 trybach:
Tryb podobny do synchronicznego – domyślnie kolejka buforowa działa w trybie podobnym do synchronicznego, w którym każdy bufor pochodzący od producenta jest wysyłany do konsumenta. W tym trybie nie jest odrzucany żaden bufor. Jeśli producent jest zbyt szybki i tworzy bufory szybciej niż są one wykorzystywane, zablokuje się i będzie czekać na puste bufory.
Tryb niezablokowany – kolejka buforowa może też działać w trybie niezablokowanym, w którym zamiast czekać na bufor generuje błąd. W tym trybie żaden bufor nie jest odrzucany. Jest to przydatne, aby uniknąć potencjalnych blokad w oprogramowaniu, które może nie rozumieć złożonych zależności w ramach graficznych.
Tryb odrzucania – na koniec kolejka buforów może być skonfigurowana tak, aby odrzucać stare bufory zamiast generować błędy lub czekać. Jeśli na przykład renderujesz GL do widoku tekstury i rysujesz tak szybko, jak to możliwe, musisz odrzucić bufory.
Aby wykonać większość tych zadań, SurfaceFlinger działa jako kolejny klient OpenGL ES. Gdy SurfaceFlinger aktywnie komponuje jeden lub dwa bufory w trzecim, używa OpenGL ES.
Drugą połowę pracy wykonuje sterownik sprzętowy HAL. Ten HAL pełni rolę centralnego punktu dla wszystkich funkcji renderowania grafiki na Androidzie.