2. 컴포지팅 정의 및 최적화 필요성
컴포지팅 동작 원리
클라이언트/렌더러/백엔드 동작 방식
PIXMAN/GL 렌더러 버퍼 관리
데미지/클리핑 관리
화면(프레임버퍼) 갱신
컴포지팅 최적화
버퍼 중복/복사 제거(zero-copy)
지연 모드(retained-mode)
하드웨어 가속 지원
하드웨어 레이어 지원
3.
4. 여러 화면을 하나의 화면으로 합쳐주는 것
SCENE GRAPH 각 화면의 위치 정보 관리
다양한 그래픽 관련 분야에서 활용
윈도우 매니저 여러 윈도우를 하나의 프레임버퍼로 합성
위젯 엔진 여러 위젯을 하나의 윈도우 화면으로 합성
…
window
window
framebufferwidget
widget
widget
widget window
widget
widgetwindow
copy
copy
copy
copy
5. 메모리 복사 최소화 메모리 사용을 최소화하고, 불필요한 메모리 전송을 줄여라!
제한된 자원의 스마트기기 활용 범위 확대
고해상도 디스플레이 등장 (레티나, 4K, …)
애니메이션 효과 일반화
지연 모드 지원 SCENE GRAPH 을 잘 관리하여 효과적인 렌더링을 하자!
윈도우 매니저는 SCENE GRAPH 관리 필수
효율적인 화면 갱신 및 불필요한 렌더링 제거 필수
하드웨어 가속 지원 CPU 대신 GPU 를 적극 활용하자!
3D 가속 지원 게임/서비스 지원 필수
컴포지팅을 위한 OpenGL 확장 기능 활용 필수
효과적인 하드웨어 레이어 활용 필수
6.
7. 클라이언트/렌더러/백엔드 동작 방식
클라이언트 버퍼 전달 방식 (클라이언트가 화면 버퍼를 서버에 전달하는 방식)
■ 공유 메모리(shm) vs GPU 메모리(drm)
렌더러 동작 방식 (서버가 여러 화면 버퍼를 합쳐서 프레임버퍼를 생성하는 방식)
■ CPU 에 의한 메모리 직접 복사 (pixman-renderer)
■ GPU 를 이용한 프레임버퍼 렌더링 (gl-renderer)
백엔드 지원 방식 (서버가 프레임버퍼를 스크린에 출력하는 방식)
■ 프레임버퍼(fb) vs GPU 제어(drm) vs 중첩 윈도우 매니저(wayland)
※ 렌더러/백엔드는 다양한 조합이 가능하며, 이에 따라 몇 가지 제약사항이 생길 수 있다.
(예를 들어, 프레임버퍼 백엔드는 PIXMAN 렌더러와 공유 메모리 버퍼만을 지원한다.)
application
(drm)
application
(shm)
drm-backend wayland-backendfb-backend
pixman-renderer gl-renderer
8. PIXMAN 렌더러 버퍼 관리
WAYLAND 는 로컬 기반 프로토콜이므로 레퍼런스 기반 버퍼 관리
■ 클라이언트는 서버에 버퍼를 복사하지 않고 공유 메모리에 대한 접근 허용
렌더러는 클라이언트와의 공유 메모리에 직접 접근하여 필요한 부
분을 프레임버퍼로 복사
application
(shm)
buffer
application
(shm)
buffer
compositor
(pixman-renderer)
framebuffer
buffer
buffer
copy
copy
9. GL 렌더러 버퍼 관리
클라이언트가 하드웨어 가속을 지원하는 경우 (drm)
■ 렌더러는 클라이언트가 생성한 프레임버퍼를 텍스처로 이용하여 렌더링
클라이언트가 공유 메모리를 지원하는 경우 (shm)
■ 렌더러는 클라이언트의 공유 메모리를 이용하여 텍스처 생성
이로 인해 경우에 따라, PIXMAN 렌더러보다 성능이 떨어질 수도 있다.
application
(shm)
buffer
application
(drm)
buffer
(framebuffer)
compositor
(gl-renderer)
framebuffer
texture
texture
texture
copy
10. 데미지(damage) 관리 목적
PIXMAN 과 GL 렌더러에서 다음 프레임버퍼를 생성하기 위한 메모
리 복사 최소화 (이전 프레임버퍼 재활용)
■ 동영상 압축 기술에서 사용하는 기술과 유사한 목적 (I/P 프레임)
이전 프레임버퍼에서 변경이 필요한 부분만 갱신하여 다음 프레임
버퍼로 재활용
■ 변경이 필요한 영역을 잘 계산하는 것이 핵심!!!
화면 변경이 필요한 경우
클라이언트가 버퍼의 내용을 갱신할 때
■ 클라이언트는 버퍼의 변경 범위를 서버에 전송
윈도우의 위치/크기/방향이 변경될 때
새로운 윈도우가 나타나거나 기존의 윈도우가 사라질 때
…
11. 클라이언트가 버퍼의 내용을 갱신할 때
이전에 사용했던, 변경 사항이 없는 부분은 그대로 재사용
WAYLAND 의 기본 프로토콜을 이용하여 윈도우 버퍼가 변경된 범
위를 전달 (wl_surface.damage)
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
buffer
buffer
buffer
damage
damage
copy
12. 윈도우의 위치/크기/방향이 변경될 때
윈도우의 위치(크기/방향)가 변경되어 아래 있던 윈도우가 화면에
보여지는 경우 발생
■ 아래 있던 윈도우에서 새롭게 보여지게 된 영역 변경
■ 위치가 변경된 윈도우를 새로운 위치에서 다시 그림
※ 이러한 이유로, 레퍼런스 기반 버퍼를 사용할 때는 클라이언트가 마지막 윈도우 버퍼를 항
상 유지할 필요가 있다. (마지막 윈도우 버퍼가 프레임버퍼에 한번 반영되었다고 끝이 아니다.)
window
(client)
buffer
window
(client)
buffer
compositor
(pixman-renderer)
framebuffer
buffer
buffer
compositor
(pixman-renderer)
framebuffer
buffer
buffer
copy
copy
13. 새로운 윈도우가 나타나거나 기존의 윈도우가 사라질 때
새로운 윈도우가 화면에 나타날 때 (왼쪽 그림)
■ 새로운 윈도우가 위치한 영역 변경
기존의 윈도우가 화면에서 사라질 때 (오른쪽 그림)
■ 아래 있던 윈도우에서 새롭게 보여지게 된 영역 변경
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
buffer
buffer
copy
window
(client)
buffer
compositor
(server)
framebuffer
buffer copy
14. 화면에 보여지지 않는 부분에서 일어나는 변경 무시
스크린의 영역을 벗어난 곳에 위치할 때
다른 윈도우에 가려져있을 때
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
buffer
buffer
window
(client)
buffer
window
(client)
buffer
compositor
(pixman-renderer)
framebuffer
bufferbuffer
15. 프레임버퍼를 디스플레이에 반영하는 과정
SCANOUT 프레임버퍼를 모니터 화면으로 전송
VBLANK(Vertical Blank) 다음 화면 갱신까지 대기
더블버퍼링 스캔아웃(front) 버퍼 + 업데이트(back) 버퍼
하나의 VBLANK 안에서 두 번 이상의 프레임버퍼 렌더링은 낭비
■ 일반적으로 초당 60회 화면 갱신 (초당 60번 VBLANK 이벤트 발생)
■ DRM 에서 PAGE_FLIP 명령어/이벤트 제공 (다음 VBLANK 에서 프레임버퍼 갱신)
scanout
vblank
scanout
vblank
…
60 hz
memory (CPU or GPU)
FRAMEBUFFER
(back)
CRTC
FRAMEBUFFER
(front)
compositor
16.
17. ZERO-COPY 윈도우 버퍼 공유 및 복사 최소화
가장 기본적인/필수적인 컴포지팅 최적화!!!
버퍼 중복 제거 클라이언트와 서버가 하나의 버퍼 공유
■ 레퍼런스 기반 버퍼 관리 (공유 메모리/DRM 기반 버퍼)
버퍼 복사 제거 화면이 변경된 부분만 갱신
■ SCENE GRAPH 을 이용한 효과적인 데미지/클리핑 관리
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
buffer
buffer
buffer
damage
damage
: 클라이언트 버퍼 공유
: 수정된 (damaged) 부분만 복사
copy
copy
copy
18. 데미지/클리핑 관리
최소 더블 버퍼링 필요 이전 프레임버퍼에서 변경된 부분만 갱신
■ 현재 프레임버퍼 모니터 출력
■ 이전 프레임버퍼 수정된 부분 갱신 후 다음 프레임버퍼로 사용
프레임버퍼 히스토리 관리 필수 (이전 프레임버퍼에 대한 정보 유지)
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
buffer
buffer
copy
copy
window
(client)
buffer
window
(client)
buffer
damage
compositor
(server)
copy
framebuffer (old)
buffer
buffer
damage
framebuffer
buffer
buffer
19. 지연 모드(retained-mode) vs 즉시 모드(immediate mode)
지연 모드는 클라이언트의 요청을 모아서 한번에 반영
■ 모든 그래픽 정보 유지/관리 (즉시 모드는 반대)
윈도우 매니저는 일반적으로 지연 모드를 사용하는 것이 유리
■ 화면 갱신 비율에 맞춰서 효율적인 렌더링 가능
■ SCENE GRAPH 을 이용하여 불필요한 렌더링 제거 (클리핑)
■ 수정된 부분이 다음 화면 갱신 전에 다시 변경이 된다면 무시 가능
scanout
vblank
scanout
vblank
…
60 hz
window
(client)
buffer
damage
(1st)
window
(client)
buffer
damage
(2st)
ignore
20. 2D 기반 컴포지팅에 OpenGL 을 사용할 때의 문제점
더블 버퍼링을 지원하지만 이전 프레임버퍼에 대한 보장 없음
3D 게임을 지원하는 목적으로 개발되었기 때문에 부분 갱신과 렌더
링에 대한 기능 지원 없음
…
2D 기반 컴포지팅을 위한 OpenGL 확장 기능 (최신)
BUFFER_AGE extension 프레임버퍼 히스토리 관리 지원
SUBIMAGE extension 텍스처 부분 갱신 지원
SWAP_BUFFERS_WITH_DAMAGE extension 부분 렌더링 지원
…
21. 프레임버퍼 히스토리 관리 기능
최근에 추가된 BUFFER_AGE extension 을 이용
이전 프레임버퍼에서 변경된 부분만 갱신하여 다음 프레임버퍼로
활용 가능
■ 이전 프레임버퍼에 이전 변경 사항 복사 (이전 프레임버퍼 현재 프레임버퍼로 변경된 영역)
■ 이전 프레임버퍼에 이번 변경 사항 복사 (현재 프레임버퍼 다음 프레임버퍼로 변경된 영역)
framebuffer (old)
buffer
buffer
framebuffer
buffer
buffer
framebuffer (next)
buffer
buffer
damage
window
(client)
buffer
damage
(1st)
window
(client)
buffer
damage
(2st)
damage
damage
22. 텍스처 부분 갱신 지원
SUBIMAGE extension 이용
GL 렌더러에서 공유 메모리 버퍼를 사용할 때 변경된 부분만 갱신
■ 기존에는 텍스처를 부분적으로 업데이트하는 것이 불가능
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
texture
texture
texture
damage copy damage
23. 부분 렌더링 지원
SWAP_BUFFERS_WITH_DAMAGE extension 이용
BUFFER_AGE extension 과 같이 사용
■ 이전 프레임버퍼에서 필요한 부분만 다시 렌더링 할 수 있도록 지원
■ 기존에는 전체 프레임버퍼를 한번에 렌더링하는 기능만 제공
■ 결국 해당 확장 기능이 없으면 이전 프레임버퍼를 재활용하는 것이 불가능
window
(client)
buffer
window
(client)
buffer
compositor
(server)
framebuffer
texture
texture
texture
damage
damage
rendering
24. 특정 서페이스 (예: 마우스 커서) 는 독립된 하드웨어 레이어 사용
수시로 변경되는 마우스 커서의 경우, 독립된 하드웨어 레이어를 사
용하지 않으면 위치가 변경될 때마다 전체 화면 렌더링 필요
■ 물론, 데미지 관리를 통해 부분 갱신을 잘 하면 성능 저하 최소화 가능
사용 시나리오에 맞는 적절한 하드웨어 레이어 분배 필요
APPLICATION
WINDOW
APPLICATION
WINDOW
APPLICATION
WINDOW
LAYER0
WINDOW
WINDOW
LAYER1
WINDOW
SCREEN
WINDOW
WINDOW
WINDOW