Android(安卓)surfaceflinger (4) -Vsync产生上报流程
1、垂直同步信号
VSync(即V-Sync垂直同步)的具体含义和用途文章不细说,看下图的VSync的位置大致也就知道它的用途(简单理解成是硬件定时中断貌似也可以,周期性的硬件中断,频率为60Hz,周期为0.0167s,也就是16ms)。
本文主要关注以下几个问题: \
(1)VSync是如何产生的? \
(2)VSync是如何分发到应用进程的?
2、流程框图
3、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); ..........}
4、VSync信号上报过程
4.1 HWComposer至DispSyncThread过程
在上面分析到了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线程在实时监测,一旦监测到退出信号就会退出阻塞
4.2 DispSyncThread至EventThread过程
virtual bool threadLoop() { while (true) { ......... err = mCond.wait(mMutex);//线程阻塞等待 ......... //从mEventListeners中收集所有满足时间条件的EventListener 详见第3.2.1节 callbackInvocations = gatherCallbackInvocationsLocked(now); ......... fireCallbackInvocations(callbackInvocations);//详见第3.2.2节 ......... }
4.2.1 EventListener的初始化
在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; }
4.2.2 回调至EventThread
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();//发广播释放线程阻塞}
4.3 EventThread至jni
先看一下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方法。
5、Java层
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; } } }
更多相关文章
- Android内存管理哪些事
- 总结Android(安卓)Socket开发中可能遇到的问题
- Android(安卓)消息循环知识
- Android异步任务的处理方法
- API Guides——Toasts
- Android消息队列(二)--异步消息处理
- 文章标题:Android活动的生命周期
- 浅谈android的线程池
- Android内存小谈 - Birdmafly