Grafiki

Ikona Android Graphics HAL

Platforma Android oferuje różne interfejsy API renderowania grafiki 2D i 3D, które współpracują z implementacjami sterowników graficznych producentów. Dlatego ważne jest, aby dobrze rozumieć, jak te interfejsy API działają na wyższym poziomie. Na tej stronie przedstawiamy warstwę abstrakcji sprzętu graficznego (HAL), na której są oparte te sterowniki. Zanim przejdziesz do tej sekcji, zapoznaj się z tymi terminami:

canvas (termin ogólny), Canvas (element interfejsu API)
Canvas to powierzchnia rysowania, która obsługuje łączenie rzeczywistych bitów z bitmapą lub obiektem Surface. Klasa Canvas ma metody standardowego rysowania na komputerze bitmap, linii, okręgów, prostokątów, tekstu itp. i jest powiązana z bitmapą lub powierzchnią. Obszar rysowania to najprostszy sposób rysowania obiektów 2D na ekranie. Klasa bazowa to Canvas.
element, który można przeciągnąć
Obiekt rysowalny to skompilowany zasób wizualny, który może być używany jako tło, tytuł lub inna część ekranu. Obiekt rysowalny jest zwykle wczytywany do innego elementu interfejsu, np. jako obraz tła. Obiekt Drawable nie może odbierać zdarzeń, ale przypisuje różne inne właściwości, takie jak stan i planowanie, aby umożliwić działanie podklas, takich jak obiekty animacji lub biblioteki obrazów. Wiele obiektów rysowalnych jest wczytywanych z plików zasobów rysowalnych – plików XML lub bitmap, które opisują obraz. Zasoby rysowalne są kompilowane do podklas android.graphics.drawable. Więcej informacji o elementach rysowalnych i innych zasobach znajdziesz w artykule Omówienie zasobów aplikacji.
zasób układu,
Zasób układu to plik XML, który opisuje układ ekranu aktywności. Więcej informacji znajdziesz w sekcji Zasób układu.
9-patch (9-patch, NinePatch)
Nine-patch to bitmapa, której rozmiar można zmieniać i której można używać jako tła lub innych obrazów na urządzeniu. Więcej informacji znajdziesz w sekcji Nine-patch.
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 prostszym rozwiązaniem jest obszar rysowania. OpenGL ES jest dostępny w pakiecie Android Native Development Kit (NDK). Pakiety android.opengl i javax.microedition.khronos.opengles udostępniają funkcje OpenGL ES.
platforma (termin ogólny), Surface (element interfejsu API)
Powierzchnia to blok pamięci, który jest łączony na ekranie. Powierzchnia zawiera obszar rysowania i udostępnia różne metody pomocnicze do rysowania warstw i zmiany rozmiaru obiektu Surface. Użyj klasy SurfaceView zamiast klasy Surface.
widok powierzchni (termin ogólny), SurfaceView (element interfejsu 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 powierzchni umożliwia rysowanie niezależnie od wątku interfejsu, co jest przydatne w przypadku operacji wymagających dużej ilości zasobów, takich jak gry czy podgląd z kamery. Jednak w tym przypadku zużywana jest dodatkowa pamięć. Widok powierzchni obsługuje grafikę zarówno w przypadku płótna, jak i OpenGL ES. Klasą bazową obiektu SurfaceView jest SurfaceView.
motyw
Motyw to zestaw właściwości, takich jak rozmiar tekstu i kolor tła, które są połączone w celu zdefiniowania różnych domyślnych ustawień wyświetlania. Android udostępnia kilka standardowych motywów, które są wymienione w R.style i poprzedzone symbolem Theme_.
view (termin ogólny), View (element interfejsu API)
Widok rysuje prostokątny obszar na ekranie i obsługuje kliknięcia, naciśnięcia klawiszy i inne zdarzenia interakcji. Klasa View jest klasą bazową większości komponentów układu ekranu aktywności lub okna dialogowego, takich jak pola tekstowe i okna. Obiekt View otrzymuje wywołania z obiektu nadrzędnego (patrz ViewGroup), aby się narysować, i informuje obiekt nadrzędny o preferowanym rozmiarze i położeniu, które mogą nie być respektowane przez obiekt nadrzędny. Więcej informacji znajdziesz w sekcji View.
wyświetlanie grupy (termin ogólny), ViewGroup (element interfejsu API)
Grupa widoków grupuje zestaw widoków podrzędnych. Grupa widoków jest odpowiedzialna za określanie położenia widoków podrzędnych i ich rozmiaru, a także za wywoływanie każdego z nich w celu narysowania się w odpowiednim momencie. Niektóre grupy widoków są niewidoczne i służą tylko do określania układu, a inne mają wbudowany interfejs, np. przewijane pole listy. Widoki grup znajdują się w pakiecie android.widget, ale rozszerzają klasę ViewGroup.
hierarchia widoków
Hierarchia widoków to układ obiektów widoku i grupy widoków, który określa interfejs użytkownika dla każdego komponentu aplikacji. Hierarchia składa się z grup widoków zawierających co najmniej 1 widok lub grupę widoków podrzędnych. Aby uzyskać wizualną reprezentację hierarchii widoków na potrzeby debugowania i optymalizacji, możesz użyć przeglądarki hierarchii dostarczanej z pakietem Android SDK.
Vulkan
Vulkan to wieloplatformowy interfejs API o niskim narzucie do obsługi wydajnej grafiki 3D.
widżet
Widżet to jedna z w pełni zaimplementowanych podklas widoku, która renderuje elementy formularza i inne komponenty interfejsu, takie jak pole tekstowe lub menu wyskakujące. Widget jest w pełni zaimplementowany, więc sam zajmuje się pomiarami, rysowaniem i reagowaniem na zdarzenia na ekranie. Widżety znajdują się w pakiecie android.widget.
okno (termin ogólny), Window (element interfejsu API)
W aplikacji na Androida okno to obiekt pochodzący z klasy abstrakcyjnej Window, która określa elementy ogólnego okna, takie jak wygląd, tekst na pasku tytułu oraz lokalizacja i zawartość menu. Okna i aktywności używają implementacji klasy Window do renderowania obiektu Window. Nie musisz implementować klasy Window ani używać okien w aplikacji.

Deweloperzy aplikacji rysują obrazy na ekranie na 3 sposoby: za pomocą Canvas, OpenGL ES lub Vulkan.

Komponenty graficzne Androida

Niezależnie od tego, jakiego interfejsu API renderowania używają programiści, wszystko jest renderowane na powierzchni. Powierzchnia reprezentuje stronę producenta kolejki bufora, która jest często wykorzystywana przez SurfaceFlinger. Każde okno utworzone na platformie Android jest obsługiwane przez powierzchnię. Wszystkie widoczne powierzchnie są renderowane i łączone na wyświetlaczu przez SurfaceFlinger.

Ten diagram pokazuje, jak współpracują ze sobą kluczowe komponenty:

komponenty renderowania obrazów,

Rysunek 1. Jak renderowane są powierzchnie.

Główne komponenty są opisane w kolejnych sekcjach.

Producenci strumieni obrazów

Producentem strumienia obrazów może być dowolny element, który generuje bufory graficzne do wykorzystania. Przykłady to OpenGL ES, Canvas 2D i dekodery wideo serwera multimediów.

Odbiorcy strumienia obrazów

Najczęstszym odbiorcą strumieni obrazu jest SurfaceFlinger, czyli usługa systemowa, która wykorzystuje aktualnie widoczne powierzchnie i łączy je na wyświetlaczu za pomocą 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 (HWC) do tworzenia grupy powierzchni.

Strumienie obrazu mogą być też wykorzystywane przez inne aplikacje OpenGL ES, np. aplikację aparatu, która korzysta ze strumienia obrazu z podglądu kamery. Aplikacje inne niż GL mogą być również konsumentami, np. klasa ImageReader.

Kompozytor sprzętowy

Warstwa abstrakcji sprzętowej dla podsystemu wyświetlania. SurfaceFlinger może delegować niektóre zadania związane z komponowaniem do HWC, aby odciążyć OpenGL i procesor graficzny. SurfaceFlinger działa jak zwykły klient OpenGL ES. Gdy SurfaceFlinger aktywnie łączy jeden lub dwa bufory w trzeci, np. za pomocą interfejsu OpenGL ES. Dzięki temu kompozycja zużywa mniej energii niż w przypadku, gdy wszystkie obliczenia wykonuje GPU.

Warstwa HAL kompozytora sprzętowego wykonuje drugą połowę pracy i jest centralnym punktem wszystkich operacji renderowania grafiki w Androidzie. Sprzętowy kompozytor musi obsługiwać zdarzenia, z których jednym jest VSync (innym jest hotplug do obsługi HDMI typu plug-and-play).

Gralloc

Alokator pamięci graficznej (Gralloc) jest potrzebny do przydzielania pamięci wymaganej przez producentów obrazów. Więcej informacji znajdziesz w artykule BufferQueue i Gralloc.

Przepływ danych

Poniższy diagram przedstawia potok graficzny Androida:

przepływ danych graficznych,

Rysunek 2. Przepływ danych graficznych w Androidzie.

Obiekty po lewej stronie to renderery generujące bufory graficzne, takie jak ekran główny, pasek stanu i interfejs systemu. SurfaceFlinger to kompozytor, a HWC to kompozytor.

BufferQueue

Kolejki buforów stanowią połączenie między komponentami graficznymi Androida. Są to dwie kolejki, które pośredniczą w stałym cyklu buforów od producenta do konsumenta. Po przekazaniu buforów przez producentów SurfaceFlinger odpowiada za łączenie wszystkich elementów na wyświetlaczu.

Poniższy diagram ilustruje proces komunikacji BufferQueue:

Proces komunikacji BufferQueue

Rysunek 3. Proces komunikacji BufferQueue.

BufferQueue zawiera logikę, która łączy producentów strumieni obrazów z konsumentami strumieni obrazów. Przykłady producentów obrazów to podglądy z aparatu generowane przez HAL aparatu lub gry OpenGL ES. Przykłady odbiorców obrazu to SurfaceFlinger lub inna aplikacja wyświetlająca strumień OpenGL ES, np. aplikacja aparatu wyświetlająca wizjer.

BufferQueue to struktura danych, która łączy pulę buforów z kolejką i wykorzystuje komunikację międzyprocesową (IPC) Binder do przekazywania buforów między procesami. Interfejs producenta, czyli to, co przekazujesz osobie, która chce generować bufory graficzne, to IGraphicBufferProducer (część SurfaceTexture). BufferQueue jest często używany do renderowania na Surface i używania z GL Consumer, a także do innych zadań.

Kolejka buforów może działać w 3 różnych trybach:

tryb podobny do synchronicznego,
Domyślnie BufferQueue działa w trybie podobnym do synchronicznego, w którym każdy bufor pochodzący od producenta jest przekazywany do konsumenta. W tym trybie żaden bufor nie jest odrzucany. Jeśli producent jest zbyt szybki i tworzy bufory szybciej, niż są one opróżniane, blokuje się i czeka na wolne bufory.
tryb nieblokujący,
Kolejka buforów może też działać w trybie nieblokującym, w którym w takich przypadkach generuje błąd zamiast czekać na bufor. W tym trybie nie jest też odrzucany żaden bufor. Jest to przydatne, aby uniknąć potencjalnych zakleszczeń w oprogramowaniu aplikacji, które może nie rozumieć złożonych zależności platformy graficznej.
tryb odrzucania,
Kolejkę bufora można skonfigurować tak, aby odrzucała stare buforowane dane zamiast generować błędy lub czekać. Jeśli na przykład renderujesz za pomocą GL do widoku tekstury i rysujesz tak szybko, jak to możliwe, bufory muszą zostać usunięte.

W większości przypadków SurfaceFlinger działa jak zwykły klient OpenGL ES. Gdy SurfaceFlinger aktywnie łączy jeden lub dwa bufory w trzeci, korzysta na przykład z OpenGL ES.

Drugą połowę pracy wykonuje HAL kompozytora sprzętowego. Ta warstwa HAL jest centralnym punktem wszystkich operacji renderowania grafiki w Androidzie.