Uchwyt powierzchniowy i powierzchniowy

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.