Grafiki

Ikona HAL Grafiki na Androida

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. Na tej stronie przedstawiamy warstwę abstrakcji sprzętu graficznego (HAL), na której są oparte te sterowniki. Zanim przejdziesz do dalszej części tej sekcji, zapoznaj się z tymi terminami:

canvas (termin ogólny), Canvas (element interfejsu API)
Płótno to powierzchnia do rysowania, która obsługuje łączenie rzeczywistych bitów z pikselową mapą bitową lub obiektem Surface. Klasa Canvas zawiera metody standardowego rysowania bitmap, linii, kół, prostokątów, tekstu itp., a także jest powiązana z bitmapą lub powierzchnią. Płótno to najprostszy sposób rysowania obiektów 2D na ekranie. Klasa podstawowa to Canvas.
element, który można przeciągnąć
Rysunek to skompilowany zasób wizualny, który może być używany jako tło, tytuł lub inna część ekranu. Element rysowalny jest zwykle wczytywany do innego elementu interfejsu użytkownika, na przykład 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ć korzystanie z podklas, takich jak obiekty animacji czy biblioteki obrazów. Wiele obiektów do rysowania jest wczytywanych z plików zasobów do rysowania. Są to pliki XML lub bitmapy opisujące obraz. Zasoby do rysowania są kompilowane do podklas android.graphics.drawable. Więcej informacji o elementach rysowanych i innych zasobach znajdziesz w artykule Omówienie zasobów aplikacji.
zasób layoutu
Zasób układu to plik XML opisujący układ ekranu aktywności. Więcej informacji znajdziesz w artykule Zasoby układu.
nine-patch (9-patch, NinePatch)
Nine-Patch to bitmapowy zasób, którego rozmiar można zmieniać. Można go używać do tworzenia tła lub innych obrazów na urządzeniu. Więcej informacji znajdziesz w artykule Nine-patch.
OpenGL ES
OpenGL ES to wieloplatformowy interfejs API do renderowania grafiki 2D i 3D. Android udostępnia biblioteki OpenGL ES do akceleracji sprzętowej renderowania 3D. W przypadku renderowania 2D prostszym rozwiązaniem jest użycie płótna. Interfejs OpenGL ES jest dostępny w pakiecie Native Development Kit (NDK) na Androida. Pakiety android.opengl i javax.microedition.khronos.opengles udostępniają funkcje OpenGL ES.
surface (termin ogólny), Surface (element interfejsu API)
Powierzchnia reprezentuje blok pamięci, który jest łączony z ekranem. Powierzchnia zawiera płótno do rysowania i zawiera różne metody pomocnicze do rysowania warstw oraz do zmiany rozmiaru obiektu Surface. Zamiast klasy Surface użyj klasy SurfaceView.
widok powierzchni (termin ogólny), SurfaceView (element interfejsu API)
Widok powierzchni to obiekt 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 użytkownika 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.
motyw
Motyw to zestaw właściwości, takich jak rozmiar tekstu i kolor tła, które razem definiują różne domyślne ustawienia wyświetlania. Android udostępnia kilka standardowych motywów, które są wymienione w R.style i poprzedzielane znakiem Theme_.
view (termin ogólny), View (element interfejsu API)
Widok wyświetla prostokątny obszar na ekranie i obsługuje kliknięcia, naciśnięcia klawiszy i inne zdarzenia interakcji. Klasa 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 preferowanym rozmiarze i lokalizacji, które mogą nie być respektowane przez obiekt nadrzędny. Więcej informacji znajdziesz na stronie View.
view group (termin ogólny), ViewGroup (element interfejsu API)
Grupa widoku grupuje podrzędne widoki. Grupa widoków odpowiada za określanie położenia widoków podrzędnych i ich rozmiaru, a także wywoływanie ich do rysowania w odpowiednich przypadkach. Niektóre grupy widoków są niewidoczne i służą tylko do tworzenia układu, a inne mają interfejs własny, np. listę z przewijaniem. Grupy widoku znajdują się w pakiecie android.widget, ale rozszerzają klasę ViewGroup.
wyświetlić hierarchię
Hierarchia widoków to układ obiektów widoku i grupy widoków, który definiuje interfejs użytkownika dla każdego komponentu aplikacji. Hierarchia składa się z grup widoków zawierających co najmniej 1 widok podrzędny lub grupę widoków. Aby debugować i optymalizować hierarchię widoku, możesz wyświetlić jej wizualizację za pomocą przeglądarki hierarchii, która jest dostarczana z pakietem Android SDK.
Vulkan
Vulkan to interfejs API o niskim obciążeniu, który umożliwia tworzenie wydajnych grafik 3D.
widżet
Widżet to jeden z zestawu w pełni zaimplementowanych podklas widoku, które renderują elementy formularza i inne komponenty interfejsu, takie jak pole tekstowe czy menu wyskakujące. Widget jest w pełni zaimplementowany, dlatego obsługuje pomiar, rysowanie i reagowanie na zdarzenia ekranu. 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 i wrażenia użytkownika, 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ą kluczowe komponenty:

komponenty renderowania obrazu,

Rysunek 1. Sposób renderowania powierzchni.

Główne komponenty są opisane w następnych sekcjach.

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 zgrywa 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 komponentu sprzętowego (HWC) do tworzenia grupy powierzchni.

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 HWC, aby odciążyć OpenGL i kartę graficzną. SurfaceFlinger działa jak zwykły klient OpenGL ES. Gdy SurfaceFlinger aktywnie łączy jeden lub dwa bufory w trzeci, na przykład, używa OpenGL ES. Dzięki temu kompozytowanie 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. Urządzenie HWC 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). Szczegółowe informacje znajdziesz w artykule Kolejka buforów i Gralloc.

Przepływ danych

Ten diagram przedstawia ścieżkę grafiki na Androidzie:

przepływ danych graficznych.

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 HWC jest kompozytorem.

BufferQueue

kolejki buforowe stanowią łącznik między komponentami graficznymi Androida. Są to 2 kolejki, które pośredniczą w ciągłym cyklu buforów od producenta do konsumenta. Po przekazaniu przez producentów buforów SurfaceFlinger odpowiada za złożenie wszystkich elementów na ekranie.

Poniższy diagram przedstawia proces komunikacji z koleją buforową:

Proces komunikacji z kolejka bufora

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 interfejsu 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). BufferQueue jest często używany do renderowania na powierzchni i konsumowania za pomocą konsumenta GL, między innymi.

BufferQueue może działać w 3 trybach:

tryb podobny do synchronicznego,
Bufor kolejki domyślnie działa w trybie asynchronicznym, 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, blokuje i czeka na puste bufory.
tryb nieblokujący
BufferQueue może też działać w trybie niezablokowanym, w którym zamiast czekać na bufor generuje błąd. W tym trybie nie jest też odrzucany żaden bufor. 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 odrzucenia
Bufor kolejki może być skonfigurowany 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 łączy 1 lub 2 bufory w 3 bufory, używa do tego OpenGL ES.

Drugą połowę pracy wykonuje sterownik sprzętowy HAL. Ten HAL pełni rolę centralnego punktu do renderowania grafiki na Androida.