Obiekty powierzchniowe umożliwiają aplikacjom renderowanie obrazów prezentowanych na ekranach. Interfejsy SurfaceHolder umożliwiają aplikacjom edytowanie powierzchni i sterowanie nimi.
Powierzchnia
Powierzchnia jest interfejsem dla producenta do wymiany buforów z konsumentem.
BufferQueue dla powierzchni wyświetlania jest zwykle skonfigurowany do potrójnego buforowania. Bufory są przydzielane na żądanie, więc jeśli producent generuje je wystarczająco wolno, na przykład przy 30 fps na ekranie 60 fps, w kolejce mogą znajdować się tylko dwa przydzielone bufory. Alokowanie buforów na żądanie pomaga zminimalizować zużycie pamięci. Możesz zobaczyć podsumowanie buforów skojarzonych z każdą warstwą w dumpsys SurfaceFlinger
wyjściowych dumpsys SurfaceFlinger
.
Większość klientów renderuje na powierzchniach za pomocą OpenGL ES lub Vulkan . Jednak niektórzy klienci renderują na powierzchniach za pomocą płótna.
Renderowanie na płótnie
Implementację płótna zapewnia biblioteka graficzna Skia . Jeśli chcesz narysować prostokąt, wywołaj interfejs API kanwy, który odpowiednio ustawia bajty w buforze. Aby upewnić się, że bufor nie jest aktualizowany jednocześnie przez dwóch klientów lub zapisywany podczas wyświetlania, zablokuj bufor, aby uzyskać do niego dostęp. Użyj następujących poleceń, aby pracować z blokadami kanwy:
-
lockCanvas()
blokuje bufor do renderowania na CPU i zwraca kanwę do użycia podczas rysowania. -
unlockCanvasAndPost()
odblokowuje bufor i wysyła go do kompozytora. -
lockHardwareCanvas()
blokuje bufor do renderowania na GPU i zwraca kanwę do użycia do rysowania.
Gdy producent po raz pierwszy zażąda bufora z BufferQueue, bufor jest przydzielany i inicjowany do zera. Inicjalizacja jest konieczna, aby uniknąć nieumyślnego udostępniania danych między procesami. Jeśli jednak ponownie użyjesz bufora, poprzednia zawartość będzie nadal obecna. Jeśli wielokrotnie wywołujesz lockCanvas()
i unlockCanvasAndPost()
bez rysowania czegokolwiek, producent unlockCanvasAndPost()
między poprzednio wyrenderowanymi klatkami.
Kod blokady / odblokowania powierzchni zachowuje odniesienie do wcześniej renderowanego bufora. Jeśli określisz brudny region podczas blokowania powierzchni, kopiuje on niebrudzące piksele z poprzedniego bufora. SurfaceFlinger lub HWC zazwyczaj obsługują bufor; ale ponieważ musimy tylko czytać z bufora, nie ma potrzeby czekać na wyłączny dostęp.
SurfaceHolder
SurfaceHolder to interfejs używany przez system do współdzielenia własności powierzchni z aplikacjami. Niektórzy klienci, którzy pracują z powierzchniami, potrzebują elementu SurfaceHolder, ponieważ interfejsy API do pobierania i ustawiania parametrów powierzchni są implementowane za pośrednictwem elementu SurfaceHolder. SurfaceView zawiera SurfaceHolder.
Większość komponentów, które współdziałają z widokiem, zawiera element SurfaceHolder. Niektóre inne interfejsy API, takie jak MediaCodec, działają na samej powierzchni.