4. /594
0. VSync & 브라우저
•서로 다른 계층의 이 두 요소는 어떤 관계를 맺고 있을까
•VSync(Vertical synchronization) - 하드웨어 시그널
•브라우저 - 유저레벨 애플리케이션
•VSync 는 브라우저의 이 API 들과 어떤 연관이 있을까
•requestIdleCallback
•requestAnimationFrame
6. /596
1.1 모니터는 어떻게 화면을 업데이트 할까
•모니터의 화면 업데이트는 그래픽 드라
이버를 통해 이루어짐
•그래픽 드라이버는 그래픽 버퍼에 저장
된 픽셀 데이터(이미지)로 모니터 화면
업데이트
Graphic Driver
Buffer
7. /597
1.1 모니터는 어떻게 화면을 업데이트 할까
•어플리케이션은 새 픽셀 데이터 생성
을 위한 데이터 또는 커맨드를 그래픽
드라이버에 전달 (ex, OpenGL API)
•그래픽 드라이버는 새 픽셀 데이터를
그래픽 드라이버 메모리 영역에 생성 Graphic Driver
Applications
Buffer
데이터/커맨드
8. /598
1.1 모니터는 어떻게 화면을 업데이트 할까
•그래픽 드라이버는 애플리케이
션이 만든 데이터를 Back
buffer 메모리 영역에 구성
•모니터 화면은 Front buffer 에
저장된 데이터를 이용하여 업데
이트 (Double buffering)
8
Graphic Driver
Applications
Back
Buffer
데이터/커맨드
Front
Buffer
9. /599
1.1 모니터는 어떻게 화면을 업데이트 할까
•애플리케이션이 화면을 완성하면 화
면 업데이트를 그래픽 드라이버에
요청
•Back buffer와 Front buffer를 스
왑(swap)합니다
Graphic Driver
Applications
Back
Buffer
Swap
Front
Buffer
10. /5910
1.1 모니터는 어떻게 화면을 업데이트 할까
•모니터는 화면은 일정한 시간 간격으로 변경됨 (ex, 60Hz)
•모니터 화면을 업데이트 해야할 때 드라이버는 그래픽 메모리의
front buffer에 저장된 프레임으로 화면 업데이트
•다음 모니터 화면 업데이트 때 새로운 이미지를 보여주고 싶을때는
리프레시 전에 화면 업데이트(Swap) 요청을 해야함
12. /5912
1.3 Tearing 방지 - VSync
•Tearing 이 일어나지 않으려면 Monitor
refresh 동안 Front buffer 의 데이터가
변경되지 않아야 함
•VSync (Vertical Synchronization) 동
안 Monitor refresh 가 진행됨 vsync pulse vsync
Monitor
refresh
vertical
blank
interval
13. /5913
1.3 Tearing 방지 - VSync
•60hz 모니터의 경우 1/60 초 마다
VSync pulse 가 발생
•Tearing 을 방지하기위해 VSync pulse
동안 버퍼 스왑을 금지
•VSync 정보를 통해 Monitor refresh 가
언제 일어나는지 알 수 있음
vsync pulse vsync
Monitor
refresh
vertical
blank
interval
14. /5914
1.3 Tearing 방지 - VSync
•VSync 를 사용하지 않는 것의 의미
•Monitor refresh 를 신경쓰지 않고 원할 때 버퍼 스왑을 하겠
다는 뜻
•Tearing 이 발생할 수 있음
15. /5915
1.4 추가 읽기
•“The Illusion of Motion” by Paul Bakaus
• https://paulbakaus.com/tutorials/performance/the-illusion-of-motion/
22. /5922
2.4 Smooth 애니메이션 프레임 타이밍
Monitor
refresh
시간
Frame 2Frame 1 Frame 3 Frame…Idle
•일정한 프레임 간 시간 간격 으로 매끄러운 애니메이션 구현이 가능
•자원 절약 & Idle 타임 활용
23. /5923
2.3 Janky 애니메이션의 프레임 타이밍
Monitor
refresh
시간
Frame 2Frame 1 Frame 3 Frame 4 Frame 5 Frame 6
X X
•사용자에게 보여지지 않을 프레임 생성으로 인한 자원 낭비
•고르지 않는 프레임 간 시간 간격(Δt)으로 부자연스러운 애니메이션으로 보여질 수 있음
Δt2Δt1
26. /5926
3.1 타이머 사용
•16.6ms 주기의 타이머
•Monitor refresh interval 과 align 이 안되어 프레임 드랍 발생
타이머
시간
Frame 2Frame 1 Frame 3 Frame…
refresh
16.6ms
frame drop
27. /5927
3.2 Refresh 주기에 맞추려면
•VSync 정보가 필요
• 프레임 시작 시간 (frame time)
• 프레임간 시간 차이(frame interval)
Monitor
refresh
시간
Frame 2Frame 1 Frame 3 Frame…
frame
time
frame
interval
28. /5928
3.3 VSync 정보 알아내기 - Windows
•DWM 이 사용되는 경우
•Desktop Window Manager (vista 부터 가능)
•DwmGetCompositionTimingInfo()
•DWM 이 사용되지 않는 경우
•MonitorFromWindow()
•GetMonitorInfo()
29. /5929
3.3 VSync 정보 알아내기 - Android
•Choreographer (since API Level16)
•시스템의 VSync 를 기반으로 animation, input, drawing
task 들의 타이밍을 컨트롤
•프레임 타임의 시작 시점을 알기 위해서는
Choreographer.FrameCallback 을 구현하여 등록
•Choreographer.postFrameCallback()
•등록한 callback 은 새 프레임 타임 시작 시점에 호출
30. /5930
3.3 VSync 정보 알아내기 - OSX
•CVDisplayLink - Core Video display link
•CVDisplayLinkSetOutputCallback()
•콜백함수는 DisplayLink 가 새 프레임을 원할때 호출됨
•콜백함수에 전달되는 파라미터를 통해 다음 프레임 타임과 인
터벌을 알 수 있음
•별도의 high-priority 쓰레드에서 동작
31. /5931
3.3 VSync 정보 알아내기 - iOS
•CADisplayLink
•OS 에서 제공하는 타이머로 디스플레이의 refresh rate 와 동기
화가 필요할 때 사용
•등록한 selector 는 프레임 타임 시작시 호출
•+ displayLinkWithTarget:selector:
•duration/frameInterval 속성을 통해 다음 프레임 타임 시간을
예측할 수 있음
32. /5932
3.3 vsync 정보 알아내기 - Linux
•X window 그래픽 서버를 이용
•GLX extension- GLX_OML_sync_control,
GLX_SGI_video_sync
•Frame time, frame interval
•XRandR - Resize and Rotate protocol
•신뢰성있는 refresh rate 제공
•정확한 frame interval 을 구할 수 있음
33. /5933
3.4 VSync 활용하여 프레임 타이밍 구성
•Callback 방식
•안드로이드/iOS/OSX
•시스템에서 프레임 시작시간에 callback 을 호출
•Callback 호출 시 프레임 타이밍을 잡을 수 있음
34. /5934
3.4 VSync 활용하여 프레임 타이밍 구성
•Querying 방식
•Windows/Linux
•시스템을 통해 VSync 정보를 가져옴
•타이머를 활용하여 예상되는 시간에 프레임 구성 시작
35. /5935
3.4 VSync 활용하여 프레임 타이밍 구성
•Callback 방식
•Callback 이 호출될 때 interval 을 예측하여 정확한 프레임 타
임을 계산
Callback 실행
시간
Frame 2Frame 1 Frame 3 Frame…
refresh
36. /5936
3.4 VSync 활용하여 프레임 타이밍 구성
타이머
시간
Frame 2Frame 1 Frame 3 Frame…
refresh
•Querying 방식
•프레임 마다 VSync 정보를 갱신하여 정확한 주기의
타이머 설정
Fetch vsync info &
adjust timer
37. /5937
3.4 VSync 활용하여 프레임 타이밍 구성
•VSync query 오버헤드
•OSX (CVDisplayLink)는 high-priority thread 가 생성됨
•GPU driver 마다 오버헤드가 다를 수 있음 - 측정이 필요
•일정 주기마다 갱신하는것도 한가지 방법 (ex, 5초에 한번씩)
38. /5938
3.5 Summary
•브라우저는 VSync 정보를 활용하여 Display refresh 와 매칭되
는 프레임 타이밍을 구성하고 있음
•여러분이 사용하는 툴킷들은 어떻게 프레임 타이밍을 잡고 있을까
요?
•사용중인 다양한 GUI 툴킷/프레임워크들이 어떤 타이밍에 frame
callback 을 호출시키주는 지 알아보는 것도 재밌을것 같습니다.
40. /5940
4.1 브라우저 내부 태스크 스케줄링
•브라우저는 한번의 프레임 생성을 위해 많은 일을 수행
•정확한 프레임 타임과 deadline 을 통해 효율적으로 처리하도록
노력
Frame Frame
JS
LayoutPaint
CompositeRaster
Input
Raster
deadline
Input
42. /5942
4.2 웹 애플리케이션 스케줄링
•제 때 호출되는 draw callback 이 있어야 매끄러운 애니메이션
구현이 가능 (타이머로는 힘듬)
•제 때 호출 되는 idle callback 이 제공되면 중요한 일들을 방해하
지 않으면서 idle task 수행이 가능
43. /5943
4.2 웹 애플리케이션 스케줄링
•브라우저에서의 draw callback
•window.requestAnimationFrame
•브라우저에서의 idle callback
•window.requestIdleCallback (new API)
44. /5944
4.2 window.requestAnimationFrame
•Animation task 는 언제 실행되고, 화면에 나타나게 될까?
function animate(time) {
document.getElementById("animated").style.left =
(time - animationStartTime) % 2000 / 4 + "px";
window.requestAnimationFrame(animate);
}
(function() {
animationStartTime = window.performance.now();
requestId = window.requestAnimationFrame(animate);
})();
45. /5945
4.2 window.requestAnimationFrame
“
The expectation is that the user agent will run tasks
from the animation task source at a regular interval
matching the display's refresh rate.
Running tasks at a lower rate can result in animations
not appearing smooth.
Running tasks at a higher rate can cause extra
computation to occur without a user-visible benefit.
“
http://w3c.github.io/animation-timing/
49. /5949
4.3 window.requestIdleCallback
function myNonEssentialwork(deadline) {
while (deadline.timeRemaining > 0 && tasks.length > 0)
doWorkIfNeeded();
if (tasks.length >0 )
window.requestIdleCallback(myNonEssentialWork);
}
window.requestIdleCallback(myNonEssentialWork);
https://developers.google.com/web/updates/2015/08/27/using-requestidlecallback
•Idle task 는 언제 실행이 될까?
50. /5950
4.3 window.requestIdleCallback
“
Cooperatively schedule background tasks such
that they do not introduce delays to other high
priority tasks that share the same event loop,
such as input processing, animations and
frame compositing
“
http://w3c.github.io/requestidlecallback
51. /5951
4.3 window.requestIdleCallback
•Idle task 가 high-priority task 를 방해하지 않으려면 현재 프레
임 타임 내에서 정확한 Idle time 이 계산되어야 함
•즉, 다음 프레임이 언제 시작될 지가 정확히 파악이 되어야 Idle
task에게 timeRemaining 정보를 줄 수 있음
•그렇지 않으면 Idle task 로 인해 다른 중요한 task 가 지연 될 수
있음
56. /5956
5. Summary
•VSync 란 무엇인가
•애플리케이션에서 VSync 정보는 어떻게 얻을 수 있나
•VSync 정보를 활용하여 Display refresh rate 와 align 되는 프
레임 타이밍을 구성
•브라우저의 requestAnimationFrame, requestIdleCallback
API 는 VSync 를 기반으로 동작