VSync(即V-Sync垂直同步)的具体含义和用途文章不细说,看下图的VSync的位置大致也就知道它的用途(简单理解成是硬件定时中断貌似也可以,周期性的硬件中断,频率为60Hz,周期为0.0167s,也就是16ms)。
本文主要关注以下几个问题: \
(1)VSync是如何产生的? \
(2)VSync是如何分发到应用进程的?
VSync事件一般由硬件周期性产生,如果没有相应的硬件产生VSync事件,则通过软件模拟。下面主要看下从硬件产生VSync事件。
bool VSyncThread::threadLoop()
{
if (mFakeVSync) {
performFakeVSync();//软件模拟产生
}
else {
performVSync();//硬件产生
}
return true;
}
void VSyncThread::performVSync()
{
uint64_t timestamp = 0;
uint32_t crt = (uint32_t)×tamp;
//调用kernel等待VSync信号
int err = ioctl(mCtx->mDispInfo[HWC_DISPLAY_PRIMARY].fd,
MXCFB_WAIT_FOR_VSYNC, crt);
if ( err < 0 ) {
ALOGE("FBIO_WAITFORVSYNC error: %s\n", strerror(errno));
return;
}
//回调至HWComposer类的hook_vsync方法 详见第3节
mCtx->m_callback->vsync(mCtx->m_callback, 0, timestamp);
..........
}
在上面分析到了HWComposer类,hook_vsync实现如下:
void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,
int64_t timestamp) {
cb_context* ctx = reinterpret_cast(
const_cast(procs));
ctx->hwc->vsync(disp, timestamp);
}
ctx->hwc指向的就是当前的this指针,也就是当前的对象,因此调用的就是当前对象的vsync函数,看一下这个函数:
void HWComposer::vsync(int disp, int64_t timestamp) {
if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
........
mEventHandler.onVSyncReceived(disp, timestamp);
}
}
最重要的就是调用了mEventHandler.onVSyncReceived()函数,这里mEventHandler是在HWComposer初始化的,实际上就是创建当前HWComposer对象的SurfaceFlinger对象,因此该函数回调至SurfaceFlinger.onVSyncReceived()函数,故HWC硬件产生的同步信号就可以到达SurfaceFlinger里面了。onVSyncReceived的实现如下:
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
.........
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
.......
#endif
}
mPrimaryDispSync是一个DispSync对象,其初始化是在surfaceflinger::init()完成的。
回调的流程为DispSync.addResyncSample—–>DispSync.DispSyncThread.updateModel,如下所示:
bool DispSync::addResyncSample(nsecs_t timestamp) {
.......
updateModelLocked();
.......
}
void DispSync::updateModelLocked() {
.......
mThread->updateModel(mPeriod, mPhase);
}
mThread指的是DispSyncThread线程,故上述调用的是DispSyncThread线程中的updateModel方法。
void updateModel(nsecs_t period, nsecs_t phase) {
.......
mCond.signal();//唤醒被阻塞的DispSyncThread线程
}
DispSyncThread线程在实时监测,一旦监测到退出信号就会退出阻塞
virtual bool threadLoop() {
while (true) {
.........
err = mCond.wait(mMutex);//线程阻塞等待
.........
//从mEventListeners中收集所有满足时间条件的EventListener 详见第3.2.1节
callbackInvocations = gatherCallbackInvocationsLocked(now);
.........
fireCallbackInvocations(callbackInvocations);//详见第3.2.2节
.........
}
在surfaceflinger::init中创建DispSyncSource对象,执行构造函数时会调用addEventListener进行初始化
class DispSyncSource : public VSyncSource, private DispSync::Callback {
public:
DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
const char* label) :
mValue(0),
mTraceVsync(traceVsync),
mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
mVsyncEventLabel(String8::format("VSYNC-%s", label)),
mDispSync(dispSync),
mCallbackMutex(),
mCallback(),
mVsyncMutex(),
mPhaseOffset(phaseOffset),
mEnabled(false) {}
virtual void setVSyncEnabled(bool enable) {
Mutex::Autolock lock(mVsyncMutex);
if (enable) {
status_t err = mDispSync->addEventListener(mPhaseOffset,
static_cast(this));//this指的是当前的surfaceflinger对象
} else {
status_t err = mDispSync->removeEventListener(
static_cast(this));
}
mEnabled = enable;
}
status_t DispSync::addEventListener(nsecs_t phase,
const sp<Callback>& callback) {
Mutex::Autolock lock(mMutex);
return mThread->addEventListener(phase, callback);//callback即surfaceflinger对象
}
status_t addEventListener(nsecs_t phase, const sp<DispSync::Callback>& callback) {
.......
listener.mCallback = callback;//callback即surfaceflinger对象
mEventListeners.push(listener);
mCond.signal();
return NO_ERROR;
}
Vector gatherCallbackInvocationsLocked(nsecs_t now) {
........
if (t < now) {
CallbackInvocation ci;
ci.mCallback = mEventListeners[i].mCallback;//mCallback即surfaceflinger对象
ci.mEventTime = t;
callbackInvocations.push(ci);
mEventListeners.editItemAt(i).mLastEventTime = t;
}
return callbackInvocations;
}
void fireCallbackInvocations(const Vector& callbacks) {
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);//回调至surfaceflinger对象的onDispSyncEvent方法
}
}
virtual void onDispSyncEvent(nsecs_t when) {
sp<VSyncSource::Callback> callback;
{
Mutex::Autolock lock(mCallbackMutex);
callback = mCallback;//mCallback指的是EventThread对象
if (mTraceVsync) {
mValue = (mValue + 1) % 2;
ATRACE_INT(mVsyncEventLabel.string(), mValue);
}
}
if (callback != NULL) {
callback->onVSyncEvent(when);//调用至EventThread
}
}
void EventThread::onVSyncEvent(nsecs_t timestamp) {
.......
mCondition.broadcast();//发广播释放线程阻塞
}
先看一下EventThread的线程实现如下:
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
Vector< sp > signalConnections;
signalConnections = waitForEvent(&event); //等待事件
// dispatch events to listeners...
const size_t count = signalConnections.size();
for (size_t i=0 ; iconst sp& conn(signalConnections[i]);
// now see if we still need to report this event
status_t err = conn->postEvent(event);//消息继续上报
........
}
return true;
}
Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
DisplayEventReceiver::Event* event)
{
Mutex::Autolock _l(mLock);
Vector< sp<EventThread::Connection> > signalConnections;
do {
.......
mCondition.wait(mLock);//线程阻塞等待
......
} while (signalConnections.isEmpty());
return signalConnections;
}
postEvent会调用DisplayEventReceiver::sendEvents()->BitTube::sendObjects();然后通过BitTube与jni进行通信,调用NativeDisplayEventReceiver::handleEvent()
int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) {
.......
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {//processPendingEvents获取信号
ALOGV("receiver %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
this, vsyncTimestamp, vsyncDisplayId, vsyncCount);
mWaitingForVsync = false;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);//信号分发
}
return 1; // keep the callback
}
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);//回调Java层
ALOGV("=zsx= receiver %p ~ Returned from vsync handler.", this);
}
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}
由上面分析可知,将回调至Choreographer.java中FrameDisplayEventReceiver类中的onVsync方法。
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
.......
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
private final class FrameHandler extends Handler {
public void handleMessage(Message msg) {//根据不同消息类型进行处理
switch (msg.what) {
case MSG_DO_FRAME:
doFrame(System.nanoTime(), 0);
break;
case MSG_DO_SCHEDULE_VSYNC:
doScheduleVsync();
break;
case MSG_DO_SCHEDULE_CALLBACK:
doScheduleCallback(msg.arg1);
break;
}
}
}