什么是Vsync同步机制?
Vsync(垂直同步信号量),用来同步渲染,让AppUI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。
Vsync要解决的问题:
Vsync要解决的问题
为什么会产生这样的问题?
CPU负责对UI进行更新,GPU负责对UI进行渲染,两者的频率不一致,会导致CPU还未更新完成,就被GPU渲染到了屏幕上。所以会出现图片上的问题。
如何解决这个问题?
解决这个问题的方法就是让CPU和GPU以相同的节奏进行工作。如下图所示
Vsync
让CPU和GPU以相同的频率进行工作,这就是Vsync要做的工作。Vsync以固定的频率发出信号,每当收到CPU先对UI进行更新,然后GPU再进行绘制,这样就可以解决上面的问题了。
那Android的Vsync机制是如何进行的呢?
Android的Vsync整体框架图
disp_sync_arch.png
这张图可以很明显的看出Vsync事件的传递过程。
Vsync信号并不是有硬件直接产生,而是由DispSync线程产生的。DispSync会根据HWC产生的VSync进行采样,创建模型,然后输出了SW_VSYNC信号,SW_VSYNC再根据SF和APP的phase offset做调整,分别输出给Vsync-sf和Vsync-app。
再看下几个类之间的关系图
HWC产生硬件Vsync信号
在分析HWComposer的时候,HWComposer中会注册硬件Vsync时间回调,在硬件Vsync时间到来的时候,回调HWComposer的vsync函数。
void HWComposer::vsync(int disp, int64_t timestamp) {
if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
{
Mutex::Autolock _l(mLock);
//记录对应硬件设备Vsync信号产生的时间
mLastHwVSync[disp] = timestamp;
}
//然后直接通知SurfaceFlinger的onVsyncReceived函数
mEventHandler.onVSyncReceived(disp, timestamp);
}
}
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
bool needsHwVsync = false;
{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
//如果是主显示设备的Vsync信号,且当前硬件Vsync事件是打开的,则调用DispSync的addResyncSample函数
//将硬件VSync事件添加到DispSYnc的样本中,用于创建软件Vsync时间模型
if (type == 0 && mPrimaryHWVsyncEnabled) {
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}
//更加样本采样结果,决定是否要关掉硬件Vsync事件。
if (needsHwVsync) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
}
}
HWComposer接收到硬件的Vsync事件并没有直接传递给系统使用,而是通过SurfaceFlinger将Vsync事件,添加到了DispSync的Vsync事件样本,当DispSync采样完成后,则会停止硬件Vsync事件,由软件Vsync根据样本的计算结果产生Vsync事件。
mPrimaryHWVsyncEnabled变量控制DispSync是否需要采集样本,当模型Vsync周期