반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

코딩하기 좋은날

Android Graphics 번역 4편 - SurfaceFlinger와 Hardware composer 본문

Android

Android Graphics 번역 4편 - SurfaceFlinger와 Hardware composer

huiung 2022. 7. 5. 00:12
반응형

참조: https://source.android.com/devices/graphics/surfaceflinger-windowmanager, https://source.android.com/devices/graphics/hwc

 

하드웨어 컴포저 HAL  |  Android 오픈소스 프로젝트  |  Android Open Source Project

하드웨어 컴포저 HAL 하드웨어 컴포저(HWC) HAL은 버퍼를 가용한 하드웨어와 합성하기 위한 가장 효율적인 방식을 파악합니다. HAL로서는 구현이 기기와 관련이 있으며 보통 디스플레이 하드웨어 OE

source.android.com

 

안드로이드에서 모든 그래픽 요소들의 중심에는 BufferQueue라는 클래스가 있다. 이것의 역할은 그래픽 데이터 버퍼들을 생성하는 컴포넌트(Producer)와 이 데이터를 받아 디스플레이 하거나 추가 프로세싱을 하려는 컴포넌트(Consumer)를 연결시켜주는 것이다. Producer와 Consumer는 서로 다른 프로세스에 존재할 수 있으며 시스템 전반에 걸쳐 그래픽 데이터 버퍼를 이동시키는 거의 모든 작업들이 BufferQueue를 통해 처리된다.

SurfaceFlinger

SurfaceFlinger는 BufferQueue와 SurfaceControl을 통하거나, ASurfaceControl을 통해서 2가지의 방법으로 buffer를 얻는다.

BufferQueue와 SurfaceControl을 통한 방법은 앱이 foreground로 진입할 때, WindowManager로부터 buffer를 요청한다. WindowManager는 SurfaceFlinger로부터 layer를 요청한다. 한 layer는 BufferQueue와 SurfaceControl(display frame과 같은 layer의 metadata를 포함하고 있다)을 포함하고 있는 Surface들의 조합이다. SurfaceFlinger는 layer를 만들고 그것을 WindowManager에게 보낸다. WindowManager는 그때, 앱에 Surface를 보내고 앱의 특징을 조작하기 위해서 SurfaceControl은 유지한다.

 

Andorid10은 ASurfaceControl을 추가했다. SurfaceFlinger가 buffer를 얻는 또다른 방법이다. ASurfaceControl은 Surface와 SurfaceControl을 SurfaceFlinger로 전송되는 하나의 트랜잭션 패키지로 결합한다. ASurfaceControl은 앱이 ASurfaceTransactions를 통해 업데이트하는 layer와 연결된다. 그런 다음 앱은 latch time, 획득 시간 등과 같은 정보가 포함된 ASurfaceTransactionStats를 전달하는 콜백을 통해 ASurfaceTransactions에 대한 정보를 얻는다.

 

앱은 언제든지 버퍼를 제출할 수 있지만 SurfaceFlinger는 장치에 따라 다를 수 있는 디스플레이 refersh 사이에만 buffer를 받기 위해 깨어난다. 이러한 동작은 메모리 사용을 최소화 하며, refersh중 화면을 업데이트할때 발생할 수 있는 tearing현상을 피할 수 있게 한다.

 

화면이 refreshe 될 때, 화면은 SurfaceFlinger에게 VSYNC신호를 보낸다. SurfaceFlinger가 VSYNC 신호를 받을 때, 새로운 buffer를 찾기 위해 layer list를 살펴본다. 만약 새로운 buffer가 있다면, SurfaceFlinger는 buffer를 얻고 그렇지 않다면 이전에 사용한 buffer를 유지한다. SurfaceFlinger는 항상 무언가를 표시하기 때문에 항상 하나의 buffer에 고정되어 있다. 만약 제출된 buffer가 없다면 해당 레이어는 무시된다.

 

SurfaceFlinger는 visible layer의 모든 buffer를 수집한 뒤, HWC 에게 어떻게 합성을 진행할 것인지 물어본다. 만약 HWC가 layer를 client position이라고 마킹하면 SurfaceFlinger는 해당 레이어를 직접 합성한다. 그리고 결과물을 HWC에게 넘겨준다.

Hardware Composer

Hardware Composer HAL(”HWC”)는 안드로이드 3.0에서 최초로 소개 됐다. HWC의 주요 목적은 사용 가능한 하드웨어를 가지고 여러 버퍼들을 가장 효율적으로 합성하는 방법을 결정하는 것이다. HAL로서 HWC의 구현은 디바이스에 특화되며, 디스플레이 하드웨어 OEM 업체들에 의해 구현된다.

이러한 접근 방식의 장점은 언제 overlay planes를 고려해야 하는지 인식하기 쉽다는 것이다. overlay planes의 목적은 GPU보다는 디스플레이 하드웨어에서 여러 버퍼들을 합성하게 하는 것이다. 예를 들어 안드로이드 디바이스의 세로모드(portrait)에서 상단의 status bar, 하단의 navigation bar, 이외에 application이 있다고 해보자. 각 레이어의 컨텐츠들은 별도의 버퍼들로 구성된다. App컨텐츠는 스크래치 버퍼에 렌더링을 하며 그 위에 status bar를 렌더링 하고 그 위에 navigation bar를 렌더링함으로써 합성된 스크래치 버퍼의 내용을 디스플레이 하드웨어로 넘긴다(여기서는 GPU에 의해 합성이 일어난다). 또는 세개의 버퍼 모두를 디스플레이 하드웨어로 넘기고 디스플레이 하드웨어에게 각각 버퍼 데이터를 스크린의 각 영역에 렌더링 하라고 얘기할 수도 있다(이것은 HWC를 이용한 합성 방법이다). 후자의 접근 방법이 훨씬 효율적일 수 있다.

디스플레이 프로세서들마다 그 기능들은 상당히 다르다. overlay의 개수, 어떤 레이어들이 회전이나 블렌딩 될 수 있는지, layer의 포지셔닝 및 오버랩에 대한 제한들에 대해서 API를 통해 표현하기 어려울 수 있다. 그래서 HWC는 아래와 같이 동작한다.

  1. SurfaceFlinger는 HWC에게 전체 layer list를 제공하고 이걸 어떻게 처리하고 싶은지 물어본다.
  2. HWC는 이러한 질문에 대해 각 layer에 overlay 또는 GLES 합성 이라고 표시해서 응답한다.
  3. SurfaceFlinger는 GLES 합성을 처리하거나, 출력 버퍼를 HWC에 전달하고, 나머지 작업을 HWC에 맡긴다.
    type    |          source crop              |           frame           name
------------+-----------------------------------+--------------------------------
        HWC | [    0.0,    0.0,  320.0,  240.0] | [   48,  411, 1032, 1149] SurfaceView
        HWC | [    0.0,   75.0, 1080.0, 1776.0] | [    0,   75, 1080, 1776] com.android.grafika/com.android.grafika.PlayMovieSurfaceActivity
        HWC | [    0.0,    0.0, 1080.0,   75.0] | [    0,    0, 1080,   75] StatusBar
        HWC | [    0.0,    0.0, 1080.0,  144.0] | [    0, 1776, 1080, 1920] NavigationBar
  FB TARGET | [    0.0,    0.0, 1080.0, 1920.0] | [    0,    0, 1080, 1920] HWC_FRAMEBUFFER_TARGET

위의 표는 스크린 상에 무슨 레이어가 있는지를 알려준다. 또한 각 레이어들이 overlay(”HWC”)로 처리되는지 OpenGL ES 합성(”GLES”)방식으로 처리되는 지를 보여준다.

 

FB TARGET layer는 GLES 합성의 출력 결과가 나오는 부분이다. 위 표에서 overlay(HWC)를 이용한 모든 layer가 스크린에 보여졌기 때문에, FB TARGET은 이번 프레임에서는 이용되지 않는다. overlay를 가지지 않은 디바이스의 경우, 모든 합성은 GLES로 처리되고, 합성 결과가 프레임 버퍼에 쓰여질 것이다.

overlay plane의 또다른 중요한 역할이 있다. 그것은 DRM 컨텐츠를 보여주는 유일한 방식이라는 것이다.(SurfaceView만이 DRM을 재생할 수 있는 이유) DRM이 걸린 버퍼들은 SurfaceFlinger나 GLES 드라이버를 통해 접근할 수 없으며, 이것은 HWC를 GLES 합성 방식으로 변경하면 비디오가 사라질 수 있다는 것을 의미한다.

 

overlay plane은 화면에서 아무 것도 변경되지 않는 경우 GL composition보다 덜 효율적일 수 있다. overlay 콘텐츠에 투명한 픽셀이 있고 겹치는 layer가 혼합된 경우 특히 그렇다. 이러한 경우 HWC는 일부 또는 모든 레이어에 대해 GLES composition을 요청하고 합성된 버퍼를 유지할 수 있다. SurfaceFlinger가 동일한 버퍼 집합을 합성하도록 요청하면 HWC는 이전에 합성된 스크래치 버퍼를 표시할 수 있다. 이것은 유휴 장치의 배터리 수명을 향상시킬 수 있다.

안드로이드 기기는 일반적으로 4개의 overlay plane을 지원한다. 이보다 더 많은 layer를 합성하려고 하면 시스템에서 일부 layer에 GLES 합성을 사용하게 된다. 즉, 앱에서 사용하는 layer 수가 전력 소비 및 성능에 측정 가능한 영향을 미칠 수 있음을 의미한다.

반응형