我是靠谱客的博主 纯情柜子,最近开发中收集的这篇文章主要介绍DispSync 分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在SurfaceFlinger的构造方法中调用了DispSync的init方法对DispSync进行初始化,

mPrimaryDispSync.init(hasSyncFramework, dispSyncPresentTimeOffset);

调用流程图如下,


DispSync的构造方法如下,

DispSync::DispSync(const char* name) :
   mName(name),
   mRefreshSkipCount(0),
   mThread(new DispSyncThread(name)) {
}

创建了DispSyncThread 线程。

DispSyncThread是 DispSync的内部类,继承于Thread,

class DispSyncThread: public Thread {

DispSync的init方法主要逻辑如下,

1,运行DispSyncThread 线程,并设置调度策略,

mThread->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,重置并开始进行同步信号,

reset();
beginResync();

3,添加监听事件,

if (!mIgnorePresentFences && kEnableZeroPhaseTracer) {
     addEventListener("ZeroPhaseTracer", 0, new ZeroPhaseTracer());
}

对于Thread 线程,调用逻辑顺序如下,

Thread被创建,

Thread中的run被调用,

__threadLoop()被调用,

readyToRun()被调用,

然后循环调用threadLoop()。

并且在threadLoop()返回false时,可以退出循环。

// threadLoop能够循环其实是因为调用它的_threadLoop()方法里面有一个while循环。

DispSyncThread的threadLoop方法主要逻辑如下,

1, 计算下一次的vsync时间,如果这个时间还没到,就wait一段时间差,

if (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方法,进行监听事件的回调,

callbackInvocations = gatherCallbackInvocationsLocked(now);
•••
fireCallbackInvocations(callbackInvocations);

fireCallbackInvocations方法如下,

for (size_t i = 0; i < callbacks.size(); i++) {
   callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}

那么,是调用哪个的onDispSyncEvent方法呢?

调用的是SurfaceFlinger_hwc1.cpp的内部类DispSyncSource的onDispSyncEvent方法,

详细论述见EventThread章节。

DispSyncSource的onDispSyncEvent方法如下,

Mutex::Autolock lock(mCallbackMutex);
callback = mCallback;
•••
if (callback != NULL) {
   callback->onVSyncEvent(when);
}

此处的mCallback 是EventThread对象.在EventThread的enableVSyncLocked方法中调用DispSyncSource的setCallback方法进行赋值,

mVsyncEnabled = true;
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);

DispSyncSource的setCallback方法如下,

virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
    Mutex::Autolock lock(mCallbackMutex);
    mCallback = callback;
}

EventThread的onVSyncEvent方法如下,

Mutex::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 分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部