Surface i SurfaceHolder

Obiekty powierzchni umożliwiają aplikacjom renderowanie obrazów, które mają być wyświetlane na ekranach. Interfejsy SurfaceHolder umożliwiają aplikacjom edytowanie i kontrolowanie powierzchni.

Surface

Powierzchnia to interfejs, za pomocą którego producent może wymieniać bufory z konsumentem.

Powierzchnie wyświetlania zwykle używają kolejek buforów skonfigurowanych do buforowania potrójnego. Bufory są przydzielane na żądanie, więc jeśli producent generuje je wystarczająco wolno, np. przy 30 kl./s na wyświetlaczu 60 kl./s, w kolejce mogą być tylko 2 przydzielone bufory. Przydzielanie buforów na żądanie pomaga zminimalizować zużycie pamięci. Podsumowanie buforów powiązanych z każdą warstwą znajdziesz w dumpsys SurfaceFlinger.

Większość klientów renderuje na powierzchniach za pomocą OpenGL ES lub Vulkan. Niektórzy klienci renderują jednak elementy na powierzchniach za pomocą elementu canvas.

Renderowanie obszaru roboczego

Implementację obszaru roboczego zapewnia biblioteka graficzna Skia. Jeśli chcesz narysować prostokąt, wywołujesz interfejs Canvas API, który odpowiednio ustawia bajty w buforze. Aby mieć pewność, że bufor nie jest aktualizowany przez 2 klientów jednocześnie ani nie jest zapisywany podczas wyświetlania, zablokuj bufor, aby uzyskać do niego dostęp. Aby pracować z blokadami obszaru roboczego, użyj tych poleceń:

  • lockCanvas() blokuje bufor na potrzeby renderowania na procesorze i zwraca obiekt Canvas do rysowania.
  • unlockCanvasAndPost() odblokowuje bufor i wysyła go do kompozytora.
  • lockHardwareCanvas() blokuje bufor na potrzeby renderowania na GPU i zwraca obszar rysowania, którego można użyć do rysowania.

Gdy producent po raz pierwszy zażąda bufora z kolejki BufferQueue, bufor zostanie przydzielony i zainicjowany wartością zero. Inicjowanie jest konieczne, aby uniknąć przypadkowego udostępniania danych między procesami. Jeśli jednak użyjesz ponownie bufora, poprzednia zawartość nadal będzie w nim obecna. Jeśli wielokrotnie wywołasz funkcję lockCanvas()unlockCanvasAndPost() bez rysowania, producent będzie przełączać się między wcześniej wyrenderowanymi klatkami.

Kod blokowania/odblokowywania powierzchni zachowuje odniesienie do wcześniej wyrenderowanego bufora. Jeśli podczas blokowania powierzchni określisz nieczysty region, skopiuje on nieczyste piksele z poprzedniego bufora. Buforem zwykle zarządza SurfaceFlinger lub HWC, ale ponieważ musisz tylko odczytać dane z bufora, nie musisz czekać na wyłączny dostęp.

SurfaceHolder

SurfaceHolder to interfejs, którego system używa do udostępniania aplikacji powierzchni. Niektórzy klienci, którzy pracują z powierzchniami, chcą mieć SurfaceHolder, ponieważ interfejsy API do pobierania i ustawiania parametrów powierzchni są implementowane za pomocą SurfaceHolder. SurfaceView zawiera SurfaceHolder.

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