개발자라면 알아야 하는 노출 영역, SurfaceHolder, EGLSurface, SurfaceView, GLSurfaceView, SurfaceTexture, TextureView, SurfaceFlinger 및 Vulkan 관련 정보입니다.
이 페이지에서는 Android 시스템 수준 그래픽 아키텍처의 필수 요소와 그 요소들이 앱 프레임워크와 멀티미디어 시스템에 사용되는 방식에 관해 설명합니다. 여기서는 그래픽 데이터의 버퍼가 시스템을 통해 이동하는 방식에 초점을 맞춥니다. SurfaceView 및 TextureView의 작동 방식 이유 또는 노출 영역과 EGLSurface의 상호작용 방식이 궁금했다면 여기서 궁금증을 해결할 수 있습니다.
이 문서는 여러분이 Android 기기 및 앱 개발에 어느 정도의 지식을 갖추고 있다고 가정합니다. 앱 프레임워크에 관한 상세한 지식도 필요 없고 API 호출도 거의 언급되지 않지만 자료가 다른 공개 문서와 중복되지는 않습니다. 이 문서는 사용자가 앱을 설계할 때 정보에 입각한 결정을 내릴 수 있도록 출력의 프레임 렌더링과 관련된 중요한 이벤트에 관한 세부정보를 제공하는 데 목적이 있습니다.
이 섹션에는 배경 자료부터 HAL 세부정보, 사용 사례에 이르는 다양한 내용을 다루는 여러 페이지가 포함되어 있습니다. 일단은 Android 그래픽 버퍼에 관한 설명에 이어 구성 및 디스플레이 메커니즘에 관해 설명한 후 컴포지터에 데이터를 제공하는 더 높은 수준의 메커니즘으로 넘어가게 됩니다. 흥미로운 주제로 넘어가기보다는 아래에 나열된 순서대로 페이지를 읽는 것이 좋습니다.
하위 수준의 구성 요소
- BufferQueue 및 gralloc. BufferQueue는 그래픽 데이터의 버퍼를 생성하는 요소(생산자)를 표시 또는 추가 처리를 위해 데이터를 받아들이는 요소(소비자)에 연결합니다. 버퍼 할당은 공급업체별 HAL 인터페이스를 통해 구현된 gralloc 메모리 할당자를 통해 수행됩니다.
- SurfaceFlinger, 하드웨어 컴포저 및 가상 디스플레이. SurfaceFlinger는 여러 소스의 데이터 버퍼를 수락하고 이를 합성한 다음 디스플레이로 전송합니다. 하드웨어 컴포저 HAL(HWC)은 버퍼를 가용한 하드웨어와 합성하기 위한 가장 효율적인 방식을 파악하며, 가상 디스플레이는 시스템 내에서 합성된 출력을 사용할 수 있도록 합니다(화면을 녹화하거나 네트워크를 통해 화면을 전송).
- 노출 영역, 캔버스 및 SurfaceHolder. 노출 영역은 SurfaceFlinger에 의해 자주 소비되는 버퍼 큐를 생성합니다. 노출 영역에 렌더링할 때는 소비자에 전달되는 버퍼에 결과가 종착합니다. 캔버스 API는 노출 영역에 직접 그리기를 수행할 수 있도록 소프트웨어 구현(및 하드웨어 가속 지원)을 제공합니다(OpenGL ES와 관련한 하위 수준의 대안). 뷰와 관련된 모든 요소에는 SurfaceHolder가 사용되며, SurfaceHolder의 API는 크기 및 형식과 같은 노출 영역 매개변수를 가져와 설정할 수 있게 해줍니다.
- EGLSurface 및 OpenGL ES. OpenGL ES(GLES)는 EGL과 결합되도록 설계된 그래픽 렌더링 API를 정의합니다. EGL은 운영체제를 통해 창을 생성하고 액세스하는 라이브러리(GLES 호출을 사용하여 텍스처 다각형 그리기, EGL 호출을 사용하여 렌더링을 화면에 배치)입니다. 이 페이지에서는 ANativeWindow에 관해서도 다룹니다. C/C++의 Java 노출 영역 클래스에 상응하는 이 클래스는 네이티브 코드에서 EGL 창 노출 영역을 생성합니다.
- Vulkan. Vulkan은 고성능 3D 그래픽을 위한 오버헤드가 낮은 교차 플랫폼 API입니다. OpenGL ES와 마찬가지로 Vulkan은 앱에서 고품질의 실시간 그래픽을 만들 수 있는 도구를 제공합니다. Vulkan은 CPU 오버헤드 감소, SPIR-V 바이너리 중간 언어 지원과 같은 이점도 제공합니다.
상위 수준의 구성요소
- SurfaceView 및 GLSurfaceView. SurfaceView는 노출 영역과 뷰를 결합합니다. SurfaceView의 뷰 구성요소는 앱이 아닌 SurfaceFlinger에 의해 합성되며, 별도 스레드/프로세스에서 렌더링하고 앱 UI 렌더링으로부터 격리가 가능하도록 지원합니다. GLSurfaceView는 EGL 컨텍스트, 스레드 간 통신 및 활동 수명 주기와의 상호작용을 관리하기 위한 helper 클래스를 제공합니다(하지만 GLES 사용에는 필요하지 않음).
- SurfaceTexture. SurfaceTexture는 노출 영역과 GLES 텍스처를 결합하여 앱이 소비자인 BufferQueue를 생성합니다. 생산자는 새 버퍼를 대기열에 등록할 때 앱에 알림을 전송하며, 이때 이전에 잡고 있던 버퍼를 해제하고 대기열에서 새 버퍼를 가져오고 EGL을 호출하여 버퍼를 GLES에 외부 텍스처로 제공합니다. Android 7.0에는 보호된 동영상 콘텐츠의 GPU 후처리가 가능한 보안 텍스처 동영상 재생에 관한 지원이 추가되었습니다.
- TextureView. TextureView는 뷰를 SurfaceTexture와 결합합니다. TextureView는 SurfaceTexture를 래핑하며, 콜백에 응답하고 새 버퍼를 가져오는 역할을 맡습니다. TextureView는 그리기를 수행할 때 가장 최근에 수신한 버퍼의 콘텐츠를 데이터 소스로 활용하여 뷰 상태에 명시된 내용에 따라 어디서든 어떻게든 렌더링을 수행합니다. 뷰 구성은 항상 GLES로 수행됩니다. 즉, 콘텐츠에 관한 업데이트로 인해 다른 뷰 요소도 다시 그려질 수 있습니다.