BufferQueue i Gralloc

Klasa BufferQueue łączy komponenty generujące bufory danych graficznych ( producentów ) z komponentami, które akceptują dane do wyświetlenia lub dalszego przetwarzania ( konsumenci ). Prawie wszystko, co przenosi bufory danych graficznych w systemie, opiera się na BufferQueue.

Alokator pamięci Gralloc wykonuje alokacje buforów i jest implementowany przez dwa interfejsy HIDL specyficzne dla producenta (patrz hardware/interfaces/graphics/allocator/ i hardware/interfaces/graphics/mapper/ ). Funkcja allocate() przyjmuje oczekiwane argumenty (szerokość, wysokość, format piksela), a także zestaw flag użycia.

Producenci i konsumenci BufferQueue

Konsumenci tworzą strukturę danych BufferQueue i są jej właścicielami i mogą istnieć w innych procesach niż ich producenci. Gdy producent potrzebuje bufora, żąda wolnego bufora od BufferQueue, wywołując dequeueBuffer() , określając szerokość, wysokość, format pikseli i flagi użycia buforów. Następnie producent wypełnia bufor i zwraca bufor do kolejki, wywołując queueBuffer() . Następnie konsument pozyskuje bufor za pomocą acquireBuffer() i korzysta z jego zawartości. Gdy konsument skończy, zwraca bufor do kolejki, wywołując releaseBuffer() . Struktura synchronizacji kontroluje sposób, w jaki bufory przechodzą przez potok graficzny systemu Android.

Niektóre cechy BufferQueue, takie jak maksymalna liczba buforów, które może przechowywać, są określane wspólnie przez producenta i konsumenta. Jednak BufferQueue przydziela bufory, gdy ich potrzebuje. Bufory są zachowywane, chyba że zmieni się charakterystyka; na przykład, jeśli producent zażąda buforów o innym rozmiarze, stare bufory są zwalniane, a nowe są przydzielane na żądanie.

Zawartość bufora nigdy nie jest kopiowana przez BufferQueue, ponieważ przenoszenie tak dużej ilości danych jest nieefektywne. Zamiast tego bufory są zawsze przekazywane przez uchwyt.

Śledzenie BufferQueue z Systrace

Aby zrozumieć, w jaki sposób poruszają się bufory graficzne, użyj Systrace , narzędzia, które rejestruje aktywność urządzenia w krótkim okresie. Kod graficzny na poziomie systemu jest dobrze oprzyrządowany, podobnie jak znaczna część odpowiedniego kodu struktury aplikacji.

Aby użyć Systrace, włącz tagi gfx , view i sched . Obiekty BufferQueue są wyświetlane w śladzie. Na przykład, jeśli wykonasz śledzenie, gdy jest uruchomione wideo Grafika Grafika (SurfaceView) , wiersz z etykietą SurfaceView informuje, ile buforów zostało ustawionych w kolejce w danym momencie.

Wartość wzrasta, gdy aplikacja jest aktywna, co wyzwala renderowanie ramek przez dekoder MediaCodec. Wartość zmniejsza się, gdy SurfaceFlinger działa i zużywa bufory. Podczas wyświetlania wideo przy 30 fps wartość kolejki waha się od 0 do 1, ponieważ wyświetlacz ~ 60 fps może nadążać za źródłem. SurfaceFlinger budzi się tylko wtedy, gdy jest do zrobienia, a nie 60 razy na sekundę. System próbuje uniknąć pracy i wyłącza VSYNC, jeśli nic nie aktualizuje ekranu.

Jeśli przełączysz się na wideo Play w Grafika (TextureView) i pobierzesz nowy ślad, zobaczysz wiersz oznaczony jako com.android.grafika / com.android.grafika.PlayMovieActivity . To jest główna warstwa interfejsu użytkownika, która jest kolejną BufferQueue. Ponieważ TextureView renderuje się na warstwie interfejsu użytkownika, a nie na osobnej warstwie, wszystkie aktualizacje sterowane wideo są tutaj wyświetlane.

Gralloc

Sprzęt HAL alokatora Gralloc hardware/libhardware/include/hardware/gralloc.h dokonuje alokacji buforów za pomocą flag użycia. Flagi użycia obejmują takie atrybuty, jak:

  • Jak często pamięć będzie uzyskiwana z oprogramowania (CPU)
  • Jak często pamięć będzie uzyskiwana ze sprzętu (GPU)
  • Czy pamięć będzie używana jako tekstura OpenGL ES (GLES)
  • Czy pamięć będzie używana przez koder wideo

Na przykład, jeśli format bufora producenta określa RGBA_8888 pikseli, a producent wskazuje, że bufor będzie dostępny z oprogramowania (co oznacza, że ​​aplikacja będzie dotykać pikseli procesora), Gralloc tworzy bufor z 4 bajtami na piksel w kolejności RGBA. Jeśli zamiast tego producent określi, że jego bufor będzie dostępny tylko ze sprzętu i jako tekstura GLES, Gralloc może zrobić wszystko, czego zażąda sterownik GLES, na przykład porządkowanie BGRA, nieliniowe układy zawijane i alternatywne formaty kolorów. Zezwolenie sprzętowi na używanie preferowanego formatu może poprawić wydajność.

Niektórych wartości nie można łączyć na niektórych platformach. Na przykład flaga kodera wideo może wymagać pikseli YUV, więc dodanie dostępu do oprogramowania i określenie RGBA_8888 nie powiedzie się.

Uchwyt zwrócony przez Gralloc może być przekazywany między procesami przez Binder.

Chronione bufory

Flaga użycia GRALLOC_USAGE_PROTECTED umożliwia wyświetlanie bufora graficznego tylko przez ścieżkę chronioną sprzętowo. Te płaszczyzny nakładania są jedynym sposobem wyświetlania zawartości DRM (bufory chronione DRM nie są dostępne przez SurfaceFlinger ani sterownik OpenGL ES).

Wideo chronione DRM może być prezentowane tylko na płaszczyźnie nakładki. Odtwarzacze wideo obsługujące zawartość chronioną muszą być implementowane z SurfaceView. Oprogramowanie działające na niezabezpieczonym sprzęcie nie może odczytać ani zapisać bufora; Ścieżki chronione sprzętowo muszą pojawić się na nakładce Hardware Composer (to znaczy chronione wideo znikają z ekranu, jeśli Hardware Composer przełączy się na kompozycję OpenGL ES).

Aby uzyskać szczegółowe informacje na temat treści chronionych, zobacz DRM .