在SurfaceFlinger的构造方法中调用了DispSync的init方法对DispSync进行初始化,
1mPrimaryDispSync.init(hasSyncFramework, dispSyncPresentTimeOffset);
调用流程图如下,

DispSync的构造方法如下,
1
2
3
4
5
6DispSync::DispSync(const char* name) : mName(name), mRefreshSkipCount(0), mThread(new DispSyncThread(name)) { }
创建了DispSyncThread 线程。
DispSyncThread是 DispSync的内部类,继承于Thread,
1class DispSyncThread: public Thread {
DispSync的init方法主要逻辑如下,
1,运行DispSyncThread 线程,并设置调度策略,
1
2
3
4
5
6
7mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); struct sched_param param = {0}; param.sched_priority = 2; if (sched_setscheduler(mThread->getTid(), SCHED_FIFO, ¶m) != 0) { ALOGE("Couldn't set SCHED_FIFO for DispSyncThread"); }
2,重置并开始进行同步信号,
1
2
3reset(); beginResync();
3,添加监听事件,
1
2
3
4if (!mIgnorePresentFences && kEnableZeroPhaseTracer) { addEventListener("ZeroPhaseTracer", 0, new ZeroPhaseTracer()); }
对于Thread 线程,调用逻辑顺序如下,
Thread被创建,
Thread中的run被调用,
__threadLoop()被调用,
readyToRun()被调用,
然后循环调用threadLoop()。
并且在threadLoop()返回false时,可以退出循环。
// threadLoop能够循环其实是因为调用它的_threadLoop()方法里面有一个while循环。
DispSyncThread的threadLoop方法主要逻辑如下,
1, 计算下一次的vsync时间,如果这个时间还没到,就wait一段时间差,
1
2
3
4
5
6
7
8if (targetTime == INT64_MAX) { ALOGV("[%s] Waiting forever", mName); err = mCond.wait(mMutex); } else { ALOGV("[%s] Waiting until %" PRId64, mName, ns2us(targetTime)); err = mCond.waitRelative(mMutex, targetTime - now); }
2,首先调用gatherCallbackInvocationsLocked方法获取监听对象,
然后调用fireCallbackInvocations方法,进行监听事件的回调,
1
2
3
4callbackInvocations = gatherCallbackInvocationsLocked(now); ••• fireCallbackInvocations(callbackInvocations);
fireCallbackInvocations方法如下,
1
2
3
4for (size_t i = 0; i < callbacks.size(); i++) { callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime); }
那么,是调用哪个的onDispSyncEvent方法呢?
调用的是SurfaceFlinger_hwc1.cpp的内部类DispSyncSource的onDispSyncEvent方法,
详细论述见EventThread章节。
DispSyncSource的onDispSyncEvent方法如下,
1
2
3
4
5
6
7Mutex::Autolock lock(mCallbackMutex); callback = mCallback; ••• if (callback != NULL) { callback->onVSyncEvent(when); }
此处的mCallback 是EventThread对象.在EventThread的enableVSyncLocked方法中调用DispSyncSource的setCallback方法进行赋值,
1
2
3
4mVsyncEnabled = true; mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this)); mVSyncSource->setVSyncEnabled(true);
DispSyncSource的setCallback方法如下,
1
2
3
4
5virtual void setCallback(const sp<VSyncSource::Callback>& callback) { Mutex::Autolock lock(mCallbackMutex); mCallback = callback; }
EventThread的onVSyncEvent方法如下,
1
2
3
4
5
6
7Mutex::Autolock _l(mLock); mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; mVSyncEvent[0].header.id = 0; mVSyncEvent[0].header.timestamp = timestamp; mVSyncEvent[0].vsync.count++; mCondition.broadcast();
首先为DisplayEventReceiver Event类型的事件对象mVSyncEvent进行赋值,然后唤醒等待的EventThread线程。下面分析EventThread线程,看看是如何休眠的。
最后
以上就是纯情柜子最近收集整理的关于DispSync 分析的全部内容,更多相关DispSync内容请搜索靠谱客的其他文章。
发表评论 取消回复