App/Sf的Vsync部分源码流程结合perfetto/systrace分析

hi,粉丝朋友们:
本节将使用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

本文章对应视频手把手教你学framework:
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

私聊作者+v(androidframework007)

七件套专题:在这里插入图片描述
点击这里 https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频:https://www.bilibili.com/video/BV1wc41117L4/

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值