BufferQueue i Gralloc

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

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

Producenci i konsumenci BufferQueue

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

Niektóre cechy BufferQueue, takie jak maksymalna liczba buforów, które może pomieścić, są określane wspólnie przez producenta i konsumenta. Jednak BufferQueue przydziela bufory zgodnie z potrzebami. Bufory są zachowywane, chyba że zmienią się ich właściwości; na przykład, jeśli producent żąda buforów o innym rozmiarze, stare bufory są zwalniane, a nowe bufory 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 za pomocą Systrace

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

Aby korzystać z Systrace, włącz tagi gfx , view i sched . Obiekty BufferQueue są wyświetlane w śladzie. Na przykład, jeśli wykonasz ślad podczas odtwarzania filmu Grafika's Play (SurfaceView) , wiersz oznaczony SurfaceView poinformuje Cię, ile buforów znajdowało się w kolejce w danym momencie.

Wartość wzrasta, gdy aplikacja jest aktywna, co wyzwala renderowanie ramek przez dekoder MediaCodec. Wartość maleje, gdy SurfaceFlinger pracuje i zużywa bufory. Podczas wyświetlania wideo przy 30 fps, wartość kolejki zmienia się od 0 do 1, ponieważ wyświetlacz ~60 fps może nadążyć za źródłem. SurfaceFlinger budzi się tylko wtedy, gdy jest coś 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 film Grafika firmy Play (TextureView) i pobierzesz nowy ślad, zobaczysz wiersz oznaczony com.android.grafika / com.android.grafika.PlayMovieActivity . To jest główna warstwa interfejsu użytkownika, która jest kolejną kolejką BufferQueue. Ponieważ TextureView renderuje się w warstwie interfejsu użytkownika, a nie w osobnej warstwie, wszystkie aktualizacje sterowane wideo są tutaj wyświetlane.

Gralloc

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

  • Jak często pamięć będzie dostępna z oprogramowania (CPU)
  • Jak często pamięć będzie dostępna 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 piksele RGBA_8888 , a producent wskazuje, że dostęp do bufora będzie możliwy z oprogramowania (co oznacza, że ​​aplikacja dotknie pikseli na procesorze), 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 chce sterownik GLES, na przykład zamawianie BGRA, nieliniowe swizzled layouty 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 nakładki są jedynym sposobem wyświetlania zawartości DRM (bufory chronione DRM nie są dostępne dla SurfaceFlinger lub sterownika OpenGL ES).

Wideo chronione DRM może być prezentowane tylko na płaszczyźnie nakładki. Odtwarzacze wideo obsługujące treści chronione muszą być zaimplementowane z SurfaceView. Oprogramowanie działające na niechronionym sprzęcie nie może odczytywać ani zapisywać bufora; ścieżki chronione sprzętowo muszą pojawić się na nakładce Hardware Composer (to znaczy, że chronione filmy 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 .