Obiekty Surface umożliwiają aplikacjom renderowanie obrazów prezentowanych na ekranach. Interfejsy SurfaceHolder umożliwiają aplikacjom edytowanie i kontrolowanie powierzchni.
Powierzchnia
Powierzchnia stanowi interfejs umożliwiający producentowi wymianę buforów z konsumentem.
BufferQueue dla powierzchni wyświetlacza jest zwykle skonfigurowana do potrójnego buforowania. Bufory są przydzielane na żądanie, więc jeśli producent generuje bufory wystarczająco wolno, na przykład przy 30 kl./s na wyświetlaczu 60 kl./s, w kolejce mogą znajdować się tylko dwa przydzielone bufory. Przydzielanie buforów na żądanie pomaga zminimalizować zużycie pamięci. Podsumowanie buforów powiązanych z każdą warstwą można zobaczyć w danych wyjściowych dumpsys SurfaceFlinger
.
Większość klientów renderuje na powierzchniach przy użyciu 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łujesz API Canvas, które odpowiednio ustawia bajty w buforze. Aby mieć pewność, że bufor nie zostanie zaktualizowany przez dwóch klientów jednocześnie lub nie zostanie do niego zapisany podczas wyświetlania, zablokuj bufor, aby uzyskać do niego dostęp. Aby pracować z blokadami płótna, użyj następujących poleceń:
-
lockCanvas()
blokuje bufor renderowania na procesorze i zwraca Canvas do wykorzystania do rysowania. -
unlockCanvasAndPost()
odblokowuje bufor i wysyła go do kompozytora. -
lockHardwareCanvas()
blokuje bufor renderowania na GPU i zwraca płótno do wykorzystania do rysowania.
Gdy producent po raz pierwszy zażąda bufora od BufferQueue, bufor jest przydzielany i inicjowany na zero. Inicjalizacja jest konieczna, aby uniknąć przypadkowego udostępniania danych pomiędzy procesami. Jeśli jednak ponownie użyjesz bufora, poprzednia zawartość będzie nadal obecna. Jeśli wielokrotnie wywołasz metody lockCanvas()
i unlockCanvasAndPost()
bez rysowania czegokolwiek, producent będzie przełączać się między wcześniej wyrenderowanymi klatkami.
Kod blokady/odblokowania powierzchni zawiera odniesienie do wcześniej renderowanego bufora. Jeśli podczas blokowania powierzchni określisz zanieczyszczony obszar, kopiowane będą niezanieczyszczone 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.
Uchwyt powierzchniowy
SurfaceHolder to interfejs używany przez system do udostępniania aplikacji własności powierzchni. Niektórzy klienci pracujący z powierzchniami chcą SurfaceHolder, ponieważ interfejsy API umożliwiające pobieranie i ustawianie parametrów powierzchni są implementowane za pośrednictwem SurfaceHolder. SurfaceView zawiera SurfaceHolder.
Większość komponentów wchodzących w interakcję z widokiem obejmuje SurfaceHolder. Niektóre inne interfejsy API, takie jak MediaCodec, działają na samej powierzchni.