原文 App-Sf的Vsync部分源码流程结合perfetto-systrace分析

本节将使用perfetto的trace来巩固Vsync的源码分析的部分的流程。
具体抓取trace方法及相关操作建议:
a.抓取trace期间需要主要不能让画面一直刷新,因为这样一直刷新不方便看vsync的结束和开始
b.建议选着桌面,滑动桌面一下后停止1左右,再继续滑动,尽量让抓取的trace可以有如下图的间隔效果
c.需要在surfaceflinger中额外补充自己加的一些ATRACE代码方便追踪流程

1、app请求Vsync部分

这里我们回忆一下app的Vsync的申请,一般都是app主动申请的,一般都是应用端
Choreographer#scheduleVsyncLocked方法跨进程调用到Surfaceflinger端的requestNextVsync方法,具体trace如下图
应用端如下:

surfaceflinger作为服务端如下:

所有的Vsync逻辑其实就是从SurfaceFlinger的requestNextVsync方法开始的:

    binder::Status EventThreadConnection::requestNextVsync() {
        ATRACE_CALL();
        //这里加个ATRACE标准方便确定是app申请还是appSf申请的Vsync
        ATRACE_BEGIN(((impl::EventThread*)mEventThread)->toNameString());
        mEventThread->requestNextVsync(this);
        ATRACE_END();
        return binder::Status::ok();
    }

调用到了 mEventThread->requestNextVsync(this);
代码如下

    void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
        ATRACE_NAME("EventThread::requestNextVsync");
        if (connection->resyncCallback) {
            connection->resyncCallback();
        }

        std::lock_guard<std::mutex> lock(mMutex);

        if (connection->vsyncRequest == VSyncRequest::None) { //如果这个是第一次申请进入一般这里就是None
            connection->vsyncRequest = VSyncRequest::Single;
            ATRACE_NAME("connection->vsyncRequest None  notify_all");
            mCondition.notify_all();//第一次则会通过mCondition唤醒等待
        } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) { //这里代表前一次刚刚已经进入vsync,准备进入停止回调状态
            ATRACE_NAME("connection->vsyncRequest SingleSuppressCallback ");
            connection->vsyncRequest = VSyncRequest::Single; //这里不需要唤醒,代表thread运行等待vsync,需要靠vsync时间到了才唤醒
        }
    }

这里都会吧vsyncRequest变变成Single,最重要mCondition.notify_all()会唤醒一直等待的EventThread的线程,让他继续执行:
这里唤醒也可以通过perfetto看出来:

对于的代码:

    void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
        DisplayEventConsumers consumers;

        while (mState != State::Quit) {

             if (!mPendingEvents.empty()) {//检测是否有mPendingEvent,遍历各个Event,
                event = mPendingEvents.front();
                mPendingEvents.pop_front();

                switch (event->header.type) {
                    case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                        if (event->hotplug.connected && !mVSyncState) {
                            mVSyncState.emplace(event->header.displayId);
                        } else if (!event->hotplug.connected && mVSyncState &&
                                   mVSyncState->displayId == event->header.displayId) {
                            mVSyncState.reset();
                        }
                        break;

                    case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                        if (mInterceptVSyncsCallback) {
                            mInterceptVSyncsCallback(event->header.timestamp);
                        }
                        break;
                }
            }


            bool vsyncRequested = false;//初始化为false

            // Find connections that should consume this event.
            auto it = mDisplayEventConnections.begin();
            while (it != mDisplayEventConnections.end()) {//遍历一下所有的connection,和EventTread绑定的app链接
                if (const auto connection = it->promote()) {
                    vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;//这里会检测一下是前面设置过的request是不是还是None,明显前面设置成了Single

                    if (event && shouldConsumeEvent(*event, connection)) {//这里会判断当前event是否要让这个connection消费
                        consumers.push_back(connection);
                        ATRACE_FORMAT("shouldConsumeEvent consumers push %s",toString(*connection).c_str());
                    }

                    ++it;
                } else {
                    it = mDisplayEventConnections.erase(it);
                }
            }

            if (!consumers.empty()) {//进行相关的事件派发
                dispatchEvent(*event, consumers);
                consumers.clear();
            }
            ATRACE_FORMAT("vsyncRequested = %d",vsyncRequested);
            State nextState;
            //设置下一个nextstate,这里注意nextstate很关键,如果没有vsyncRequested,那么就nextstate就一定为Idle
            if (mVSyncState && vsyncRequested) {
                nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
            } else {
                ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
                nextState = State::Idle;
            }
            //nextState和当前state进行比较不相等进入
            if (mState != nextState) {
                if (mState == State::VSync) {//如果当前是vsync,那么nextState不是Vsync了说明vsync要停止
                    ATRACE_NAME("mVSyncSource->setVSyncEnabled(false)");
                    mVSyncSource->setVSyncEnabled(false);
                } else if (nextState == State::VSync) {//mState当前不是Vsync,下一个state是Vsync,就会进入以下关键方法
                    ATRACE_NAME("mVSyncSource->setVSyncEnabled(true)");
                    mVSyncSource->setVSyncEnabled(true);//调用启动vsync相关
                }
                //上面操作完成就代表状态已经切换
                mState = nextState;
            }

            if (event) {//如果有event不会进入下面的wait而是会继续从头开始执行
                continue;
            }

            // Wait for event or client registration/request.
            if (mState == State::Idle) {
                mCondition.wait(lock);//开始长时间没有vsync申请,就在这等待,第一次app申请时候就会唤醒这里
            } else {
                     // Generate a fake VSYNC after a long timeout in case the driver stalls. When the
                // display is off, keep feeding clients at 60 Hz.
                const std::chrono::nanoseconds timeout =
                        mState == State::SyntheticVSync ? 16ms : 1000ms;
                        //进行超时等待
                if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
                 //省略
                }
            }

        }
    }

EventThread的执行情况如下:

这里发现主要业务在 mVSyncSource->setVSyncEnabled(true)代码中,这里面开启了一系列的vsync计算和定时任务

大概上面可以看出调用栈如下:
VSyncSource->setVSyncEnabled(true)
----》 VSyncDispatchTimerQueue::schedule
----------》rearmTimerSkippingUpdateFor
--------------》setTimer
这样就完成了设置定时触发操作,具体这里不进行详细讲述定时这部分,因为较为复杂需要单独章节,这里大家只要知道最后获取了自己app的vsync触发时间targetTime,定时器设置了到时间就触发,回调相关的timeCallback方法。
到此就EventThread就执行到了等待定时等待状态,等待定时时间的到来。

2、Vsync时间到了后触发timeCallback

上面步骤的定时器触发后,回调执行是在单独的TimerDispatch线程,具体trace的体现如下:

来看看timeCallback里面又干啥了,代码如下:

    void VSyncDispatchTimerQueue::timerCallback() {
        ATRACE_CALL();

        std::vector<Invocation> invocations;
        {
          //遍历3个vsync,app,sf,appSf
            for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) {
                auto& callback = it->second;
                auto const wakeupTime = callback->wakeupTime();
                if (!wakeupTime) {//如果没有wakupTime直接下一个,因为压根没有vsync的任何申请踪迹
                    continue;
                }

                auto const readyTime = callback->readyTime();
                auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0));
                //判断的wakeupTime是不是比(mIntendedWakeupTime + mTimerSlack + lagAllowance)小,正常第一app请求肯定会进入这里
                if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) {
                    callback->executing();
                    invocations.emplace_back(Invocation{callback, *callback->lastExecutedVsyncTarget(),
                                                        *wakeupTime, *readyTime});
                }
            }

            mIntendedWakeupTime = kInvalidTime;//设置一个无穷大的值
            rearmTimer(mTimeKeeper->now());//重新准备设置定时器
        }

        for (auto const& invocation : invocations) {//开始回调上面获取的callback
            invocation.callback->callback(invocation.vsyncTimestamp, invocation.wakeupTimestamp,
                                          invocation.deadlineTimestamp);
        }
    }


主要干的几件事如下:

1、遍历3个类型vsync看看谁是有定时任务的,比较wakeupTime和intentedTime符合回调情况
2、符合回调情况的,会调用executing清除定时器,和wakeupTime,并吧intentedTime设置成很大数字
3、继续下一个rearmTimer定时任务
4、回调相关类型vsync,vsync到来

上面四个任务就是TimeDispatch完成的。
这里要注意一下mCallbacks这个变量哪来的,是怎么对应刚好就是app,appSf,sf,3个vsync的呢?
mCallbacks都是通过这个方法register来注册的:

    VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
            Callback callback, std::string callbackName) {
        std::lock_guard lock(mMutex);
        return CallbackToken{
                mCallbacks
                        .emplace(++mCallbackToken,//这里构造出来了VSyncDispatchTimerQueueEntry的实体
                                 std::make_shared<VSyncDispatchTimerQueueEntry>(std::move(callbackName),
                                                                                std::move(callback),
                                                                                mMinVsyncDistance))
                        .first->first};
    }

那么什么地方调用注册呢?实在构造VSyncCallbackRegistration时候

    VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncDispatch& dispatch,
                                                         VSyncDispatch::Callback callback,
                                                         std::string callbackName)
          : mDispatch(dispatch),
          //给mToken赋值时候,直接调用的注册callback返回的token
            mToken(dispatch.registerCallback(std::move(callback), std::move(callbackName))),
            mValidToken(true) {}

那么这个VSyncCallbackRegistration是在什么时候构造的呢?

对于sf是在MessageQueue中进行的:

    void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch,
                                 frametimeline::TokenManager& tokenManager,
                                 std::chrono::nanoseconds workDuration) {
        setDuration(workDuration);
        mVsync.tokenManager = &tokenManager;
        //构造VSyncCallbackRegistration
        mVsync.registration = std::make_unique<
                scheduler::VSyncCallbackRegistration>(dispatch,
                                                      std::bind(&MessageQueue::vsyncCallback, this,
                                                                std::placeholders::_1,
                                                                std::placeholders::_2,
                                                                std::placeholders::_3),
                                                      "sf");
    }

对于EventThread如下代码进行的:

      CallbackRepeater(VSyncDispatch& dispatch, VSyncDispatch::Callback cb, const char* name,
                         std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration,
                         std::chrono::nanoseconds notBefore)
              : mName(name),
                mCallback(cb),
                //构造VSyncCallbackRegistration
                mRegistration(dispatch,
                              std::bind(&CallbackRepeater::callback, this, std::placeholders::_1,
                                        std::placeholders::_2, std::placeholders::_3),
                              mName),
                mStarted(false),
                mWorkDuration(workDuration),
                mReadyDuration(readyDuration),
                mLastCallTime(notBefore) {}

那么上面就知晓各自的callback在哪里了。

接下来这里重点关注一下回调vsync部分的任务,app类型的vsync回调任务代码如下:
frameworks/native/services/surfaceflinger/Scheduler/DispSyncSource.cpp的CallbackRepeater的callback方法:

      void callback(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
            ATRACE_CALL();
            //调用mCallback方法,其实就是DispSyncSource::onVsyncCallback
            mCallback(vsyncTime, wakeupTime, readyTime);

            {
                std::lock_guard lock(mMutex);
                if (!mStarted) {//注意一下这个值哈,和前面的EventThread的中有停止Vsync有关系
                    ATRACE_NAME("callback return not  mRegistration.schedule");
                    return;
                }
                auto const scheduleResult =
                        mRegistration.schedule({.workDuration = mWorkDuration.count(),
                                                .readyDuration = mReadyDuration.count(),
                                                .earliestVsync = vsyncTime});
                LOG_ALWAYS_FATAL_IF(!scheduleResult.has_value(), "Error rescheduling callback");
            }
        }

这里的mCallback在哪里赋值的呢?

    DispSyncSource::DispSyncSource(VSyncDispatch& vSyncDispatch, VSyncTracker& vSyncTracker,
                                   std::chrono::nanoseconds workDuration,
                                   std::chrono::nanoseconds readyDuration, bool traceVsync,
                                   const char* name)
          : mName(name),
            mValue(base::StringPrintf("VSYNC-%s", name), 0),
            mTraceVsync(traceVsync),
            mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
            mVSyncTracker(vSyncTracker),
            mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
            mReadyDuration(readyDuration) {
            //这里进行了关键的DispSyncSource::onVsyncCallback传递到CallbackRepeater对象
        mCallbackRepeater =
                std::make_unique<CallbackRepeater>(vSyncDispatch,
                                                   std::bind(&DispSyncSource::onVsyncCallback, this,
                                                             std::placeholders::_1,
                                                             std::placeholders::_2,
                                                             std::placeholders::_3),
                                                   name, workDuration, readyDuration,
                                                   std::chrono::steady_clock::now().time_since_epoch());
    }

    //这里的第二个参数就是VSyncDispatch::Callback
        CallbackRepeater(VSyncDispatch& dispatch, VSyncDispatch::Callback cb, const char* name,
                         std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration,
                         std::chrono::nanoseconds notBefore)
              : mName(name),
                mCallback(cb),
                mRegistration(dispatch,
                              std::bind(&CallbackRepeater::callback, this, std::placeholders::_1,
                                        std::placeholders::_2, std::placeholders::_3),
                              mName),
                mStarted(false),
                mWorkDuration(workDuration),
                mReadyDuration(readyDuration),
                mLastCallTime(notBefore) {}

重点看看 DispSyncSource::onVsyncCallback方法:

    void DispSyncSource::onVsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime,
                                         nsecs_t readyTime) {
        ATRACE_CALL();
        VSyncSource::Callback* callback;
        {
            std::lock_guard lock(mCallbackMutex);
            callback = mCallback;
        }
        if (mTraceVsync) {
            mValue = (mValue + 1) % 2; //这里就是前面讲解的vsync的方波图展示部分靠这里
        }

        if (callback != nullptr) {//这里关键一步会调用到EventTread中
            callback->onVSyncEvent(targetWakeupTime, {vsyncTime, readyTime});
        }
    }


    void EventThread::onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) {
        std::lock_guard<std::mutex> lock(mMutex);
        //注意这里进行了PendingEvents的插入
        mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                           vsyncData.expectedPresentationTime,
                                           vsyncData.deadlineTimestamp));
        mCondition.notify_all();//进行线程唤醒,又切换回了EventThread工作了
    }

但是这里唤醒App的EventThread后trace中没看到具体干啥活,因为我们没有加相关ATRACE,加上一下相关TRACE如下:

明显看到这里其实就是开始派发Vsync相关的Event到app端。

callback这里除了onVsyncCallback之外,下一步就是执行新的一次schedule进行相关的定时触发Vsync任务。
代码就是上面callback方法的

      auto const scheduleResult =
                        mRegistration.schedule({.workDuration = mWorkDuration.count(),
                                                .readyDuration = mReadyDuration.count(),
                                                .earliestVsync = vsyncTime});

这里面又回到最开的是设置定时器任务了,启动下一个vsync的定时,这里其实就可以知道,也就是app发起第一次的vsync请求,一般都会有两个vsync定时任务哈。

3、app的vsync继续请求和sf的vsync申请

针对上面分析的已经知道了第一次的app请求vsync情况,但是一般app都是会很多次的vsync连续请求,因为比较少见就一次刷新情况。那么看看产生连续的vsync请求会是什么样。

明显看到第二次的requestVsync就和 第一次不一样了,这个时候的并没有唤醒app的EventThread线程。因为前面代码就说了这个情况

    void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {

        if (connection->vsyncRequest == VSyncRequest::None) { //如果这个是第一次申请进入一般这里就是None
            connection->vsyncRequest = VSyncRequest::Single;
            ATRACE_NAME("connection->vsyncRequest None  notify_all");
            mCondition.notify_all();//第一次则会通过mCondition唤醒等待
        } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) { //这里代表前一次刚刚已经进入vsync,准备进入停止回调状态
            ATRACE_NAME("connection->vsyncRequest SingleSuppressCallback ");
            connection->vsyncRequest = VSyncRequest::Single; //这里不需要唤醒,代表thread运行等待vsync,需要靠vsync时间到了才唤醒
        }
    }

也就是一旦Vsync的定时器启动后,EventThread的线程就会阻塞,知道定时器时间到了才会继续执行,后面的app的requestVsync根本不会唤醒。

那么他的唤醒靠谁呢?当然是靠第一次timeCallback时候的定时器触发啦

那么app的vsync就是这样循环只要不断有app的requestVsync,那么SurfaceFlinger的Vsync呢?

首先我们得知道sf的vsync也是由app层面进行queuebuffer后,通过跨进程setTransactionState方法调用到SurfaceFlinger端,SurfaceFlinger端会检测transation是否有相关的变化,有变化则触发申请vsync信号:

    void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
                                             const sp<IBinder>& applyToken, FrameHint frameHint) {
        ATRACE_CALL();
        modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
        std::atomic<int32_t> tmp =  getTransactionFlags();
        if (const bool scheduled = mTransactionFlags.fetch_or(mask) & mask; !scheduled) {
            ATRACE_BEGIN("scheduleCommit");
            scheduleCommit(frameHint);//申请vsync
            ATRACE_END();
        }
    }

    void SurfaceFlinger::scheduleCommit(FrameHint hint) {
       //省略部分
        mScheduler->scheduleFrame();
    }

    void MessageQueue::scheduleFrame() {
      //调用到了registration->schedule
        mVsync.scheduledFrameTime =
                mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
                                               .readyDuration = 0,
                                               .earliestVsync = mVsync.lastCallbackTime.count()});
    }
    //下面是VSyncCallbackRegistration的schedule
    ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
        if (!mValidToken) {
            return std::nullopt;
        }
        return mDispatch.get().schedule(mToken, scheduleTiming);
    }

上面的调用关系都很简单,没啥业务,直到调用到了dispatch的schedule才是核心

ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token,
                                                    ScheduleTiming scheduleTiming) {
    ScheduleResult result;
    {
        //这里又会调用到callback的schedule,其实就另一个重载方法,这里会获取出具体的wakeupTime等,是核心部分
        result = callback->schedule(scheduleTiming, mTracker, now);
        //这里会判断上面计算的wakeupTime是否小于mIntendedWakeupTime,小于才需要重新定时,如果大于就不需要了,直接return
        if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack) {
            rearmTimerSkippingUpdateFor(now, it);//启动定时任务相关
        }
    }

    return result;
}

来看看核心方法callback->schedule是怎么计算的这个wakeup等重要参数的:

    ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
                                                          VSyncTracker& tracker, nsecs_t now) {
        //核心方法,给一个时间点,然后可以获取到这个时间点对于的硬件vsync,即上屏的vsync时间点就是nextVsyncTime
        auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(
                std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration));
        //通过nextVsyncTime来获取唤醒时间部分
        auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
          //省略
        //上面计算出来的时间,然后包装到mArmedInfo中
        mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime};
        //返回时间点
        return getExpectedCallbackTime(nextVsyncTime, timing);
    }
    //其实是返回wakeuptime
    nsecs_t getExpectedCallbackTime(nsecs_t nextVsyncTime,
                                    const VSyncDispatch::ScheduleTiming& timing) {
        return nextVsyncTime - timing.readyDuration - timing.workDuration;
    }

核心方法是nextAnticipatedVSyncTimeFrom,这个方法很复杂,大家先把他当做个功能黑盒,后面会带大家详细分析。

所以Sf接收到跨进程transaction的请求后申请vsync,计算出来的vsync时间,从而得出wakeupTime,一般这里的wakeupTime会大于前面app
Vsync时候定时的wakeupTime,所以这里不会进行任何的定时。
结合trace看看vsync的情况:
sf的vsync申请触发部分情况:

和app vsync一起合作的解释部分:

这里展开一下app ,sf都被回调的trace,对应的代码就是上面的timeCallback方法:

4、app vsync结束部分

vsync有申请就肯定有结束,不可能app没有申请情况下,vsync还一直不断的运行,这样对于系统的功耗影响巨大,而且也是无用功,所以vsync坚持的原则就是有需要用时候app主动申请,不需要了就停止。
上面只分析了vsync怎么开始的,接下来分析vsync的结束部分逻辑

逻辑是如下情况:
时间到了timeCallback
-----》在onVsyncCallback里面会唤醒EventThread
-------》EventThread运行,但是因为没有app进行requestVsync了,所以vsyncRequest = 0
-----》EventThread继续执行时候发现没有vsyncRequest,故需要调用setVsyncEnbale(false)关闭定时
关闭定时器步骤trace:

该部分对应核心代码回顾:
app的EventThread执行时候,会把vsyncRequest变成0,代表没有app的vsync请求了

void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
    DisplayEventConsumers consumers;

    while (mState != State::Quit) {
        std::optional<DisplayEventReceiver::Event> event;
        ATRACE_FORMAT("threadMain");


        bool vsyncRequested = false;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
            //这里会进行遍历connection,有vsync那么就为true,没有就是false
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                //注意这里会对每个connection的vsyncRequest进行改变,注意这里的需要event不为null
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);

                }

                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
        }

//这个方法里面会改变每个connection的vsyncRequest
bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
                                     const sp<EventThreadConnection>& connection) const {
    switch (event.header.type) {


        case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: {
            return connection->mEventRegistration.test(
                    ISurfaceComposer::EventRegistration::modeChanged);
        }

        case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
            switch (connection->vsyncRequest) {
                case VSyncRequest::None:
                    return false;
                    //第一次SingleSuppressCallback后,就改成None
                case VSyncRequest::SingleSuppressCallback:
                    connection->vsyncRequest = VSyncRequest::None;
                    return false;
                case VSyncRequest::Single: {
                    if (throttleVsync()) {
                        return false;
                    }
                    //第一次Single后,就改成SingleSuppressCallback
                    connection->vsyncRequest = VSyncRequest::SingleSuppressCallback;
                    return true;
                }
                case VSyncRequest::Periodic:
                    if (throttleVsync()) {
                        return false;
                    }
                    return true;
                default:
                    return event.vsync.count % vsyncPeriod(connection->vsyncRequest) == 0;
            }

    }
}

总结如下:
1、EventThread最核心的vsyncRequest是app进行requestVsync进行改变成Single
2、vsync定时时间到会回调触发EventThread加入个event,event就是来派发Vsync事件给具体的connection即app,通过socket方式
3、消费了event同时,需要吧前面app设置的vsyncRequest变成SingleSuppressCallback
4、下次如果vsync再次触发,但是没见到新的app吧vsyncRequest变成Single,如果还是上次的SingleSuppressCallback,那么vsyncRequest就变成了None,变成None之后就会调用
mVSyncSource->setVSyncEnabled(false)关闭vsync

原文 App-Sf的Vsync部分源码流程结合perfetto-systrace分析


本文链接:[转]结合perfetto-systrace分析Vsync部分源码流程 - https://h89.cn/archives/293.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: Perfetto, Vsync, systrace

仅有一条评论

  1. 看的我热血沸腾啊https://www.237fa.com/

添加新评论