Uchwyt powierzchniowy i powierzchniowy

Obiekty powierzchni umożliwiają aplikacjom renderowanie obrazów, które mają być prezentowane na ekranach. Interfejsy SurfaceHolder umożliwiają aplikacjom edycję i sterowanie powierzchniami.

Powierzchnia

Powierzchnia jest interfejsem dla producenta do wymiany buforów z odbiorcą.

BufferQueue dla powierzchni wyświetlania jest zwykle skonfigurowany do potrójnego buforowania. Bufory są przydzielane na żądanie, więc jeśli producent generuje bufory wystarczająco wolno, na przykład przy 30 fps na wyświetlaczu 60 fps, w kolejce mogą znajdować się tylko dwa przydzielone bufory. Przydzielanie buforów na żądanie pomaga zminimalizować zużycie pamięci. Możesz zobaczyć podsumowanie buforów związanych z każdą warstwą 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

Implementacja kanwy jest dostarczana przez bibliotekę grafiki Skia . Jeśli chcesz narysować prostokąt, wywołujesz interfejs API Canvas, który odpowiednio ustawia bajty w buforze. Aby upewnić się, że bufor nie jest aktualizowany przez dwóch klientów jednocześnie lub nie jest 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 procesorze i zwraca kanwę do użycia do rysowania.
  • unlockCanvasAndPost() odblokowuje bufor i wysyła go do kompozytora.
  • lockHardwareCanvas() blokuje bufor do renderowania na GPU i zwraca płótno używane do rysowania.

Gdy producent po raz pierwszy żąda bufora od BufferQueue, bufor jest przydzielany i inicjowany na zero. Inicjalizacja jest konieczna, aby uniknąć przypadkowego udostępniania danych między procesami. Jeśli jednak ponownie użyjesz bufora, poprzednia zawartość jest nadal obecna. Jeśli wielokrotnie wywołujesz lockCanvas() i unlockCanvasAndPost() bez rysowania czegokolwiek, producent przełącza się między wcześniej wyrenderowanymi ramkami.

Kod blokady/odblokowania powierzchni zachowuje odniesienie do poprzednio renderowanego bufora. Jeśli określisz brudny region podczas blokowania powierzchni, skopiuje on niebrudne piksele z poprzedniego bufora. SurfaceFlinger lub HWC zazwyczaj obsługują bufor; ale ponieważ potrzebujemy tylko czytać z bufora, nie trzeba czekać na wyłączny dostęp.

Uchwyt powierzchniowy

SurfaceHolder to interfejs używany przez system do współdzielenia własności powierzchni z aplikacjami. Niektórzy klienci, którzy pracują z powierzchniami, chcą SurfaceHolder, ponieważ interfejsy API do pobierania i ustawiania parametrów powierzchni są implementowane za pomocą SurfaceHolder. SurfaceView zawiera SurfaceHolder.

Większość komponentów wchodzących w interakcję z widokiem obejmuje uchwyt SurfaceHolder. Niektóre inne interfejsy API, takie jak MediaCodec, działają na samej powierzchni.