BufferQueue i Gralloc

Klasa BufferQueue łączy komponenty generujące bufory danych graficznych ( producenci ) z komponentami akceptującymi 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 alokację buforów i jest realizowany poprzez dwa specyficzne dla dostawcy interfejsy HIDL (zobacz hardware/interfaces/graphics/allocator/ i hardware/interfaces/graphics/mapper/ ). Funkcja allocate() pobiera oczekiwane argumenty (szerokość, wysokość, format w pikselach), 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 metodę dequeueBuffer() , określając szerokość, wysokość, format pikseli i flagi użycia buforów. Następnie producent zapełnia bufor i zwraca go do kolejki, wywołując metodę queueBuffer() . Następnie konsument nabywa bufor za pomocą acquireBuffer() i wykorzystuje zawartość bufora. Gdy konsument skończy, zwraca bufor do kolejki, wywołując funkcję releaseBuffer() . Struktura synchronizacji kontroluje sposób przemieszczania się buforów w potoku graficznym systemu Android.

Niektóre cechy BufferQueue, takie jak maksymalna liczba buforów, jakie może pomieścić, są ustalane wspólnie przez producenta i konsumenta. Jednakże BufferQueue przydziela bufory w miarę ich potrzeb. Bufory pozostają zachowane, chyba że zmienią się właściwości; na przykład, jeśli producent zażąda buforów o innym rozmiarze, stare bufory zostaną zwolnione i na żądanie przydzielone zostaną nowe bufory.

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

Śledź kolejkę buforów za pomocą Systrace

Aby zrozumieć, w jaki sposób poruszają się bufory graficzne, użyj Systrace , narzędzia rejestrującego aktywność urządzenia w krótkim czasie. Kod graficzny na poziomie systemu jest dobrze oprzyrządowany, podobnie jak większość odpowiedniego kodu frameworka 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 śledzenie, gdy działa wideo Play grafiki (SurfaceView) , wiersz oznaczony SurfaceView informuje, ile buforów było w kolejce w danym momencie.

Wartość zwiększa się, gdy aplikacja jest aktywna, co wyzwala renderowanie klatek przez dekoder MediaCodec. Wartość maleje, gdy SurfaceFlinger pracuje i zużywa bufory. Podczas wyświetlania wideo z szybkością 30 klatek na sekundę wartość kolejki waha się od 0 do 1, ponieważ wyświetlacz ~60 klatek na sekundę może nadążać 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 wideo Play (TextureView) grafiki i pobierzesz nowy ślad, zobaczysz wiersz oznaczony jako com.android.grafika / com.android.grafika.PlayMovieActivity . Jest to główna warstwa interfejsu użytkownika, będąca kolejną kolejką BufferQueue. Ponieważ StructureView renderuje się w warstwie interfejsu użytkownika, a nie w osobnej warstwie, tutaj wyświetlane są wszystkie aktualizacje oparte na wideo.

Graloc

Alokator Gralloc HAL hardware/libhardware/include/hardware/gralloc.h wykonuje alokację buforów poprzez flagi użycia. Flagi użytkowania obejmują takie atrybuty, jak:

  • Jak często pamięć będzie dostępna z poziomu oprogramowania (CPU)
  • Jak często pamięć będzie dostępna ze sprzętu (GPU)
  • Określa, czy pamięć będzie używana jako tekstura OpenGL ES (GLES).
  • Określa, czy pamięć będzie używana przez koder wideo

Na przykład, jeśli format bufora producenta określa RGBA_8888 pikseli, a producent wskaże, że dostęp do bufora będzie możliwy z poziomu oprogramowania (co oznacza, że ​​aplikacja dotknie pikseli procesora), Gralloc utworzy bufor z 4 bajtami na piksel w kolejności RGBA. Jeśli zamiast tego producent określi, że dostęp do bufora będzie możliwy tylko ze sprzętu i jako tekstura GLES, Gralloc może zrobić wszystko, czego chce sterownik GLES, na przykład kolejność BGRA, nieliniowe układy swizzled 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 pomiędzy procesami poprzez Binder.

Chronione bufory

Flaga użycia Gralloc GRALLOC_USAGE_PROTECTED umożliwia wyświetlanie bufora graficznego tylko poprzez ścieżkę chronioną sprzętowo. Te płaszczyzny nakładek to jedyny sposób wyświetlania zawartości DRM (bufory chronione DRM nie są dostępne dla SurfaceFlinger ani sterownika OpenGL ES).

Wideo chronione systemem DRM może być prezentowane wyłącznie na płaszczyźnie nakładki. Odtwarzacze wideo obsługujące treści chronione muszą być zaimplementowane w SurfaceView. Oprogramowanie działające na niechronionym sprzęcie nie może odczytywać ani zapisywać bufora; ścieżki chronione sprzętowo muszą być widoczne na nakładce programu Hardware Composer (tzn. chronione pliki wideo znikają z wyświetlacza, jeśli program Hardware Composer przełączy się na kompozycję OpenGL ES).

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