一.VSYNC相关概念介绍

1.VSYNC种类

  • 硬件vsync(HW_VSYNC)

    指硬件屏幕上真实刷新的同步,由硬件产生
  • 软件vsync(SW_VSYNC)

由SurfaceFlinger中的基于硬件vsync产生的计算模型产生

  • app-vsync:控制app上帧的vsync,触发app进行doframe
  • appsf-vsync: 控制app上帧的vsync,触发app进行doframe 和 app-vsync相位上有一定的偏差,使用较少
  • sf-vsync:控制SurfaceFliner进行合成的vsync
软件vsync是基于硬件vsync产生的计算模型产生,为什么不直接使用硬件vsync呢?
  • 让每个使用的App和Surfacefliner去直接监听硬件vsync会导致上层直接连接到硬件,这样的耦合性太高了
  • App和Surfacefliner去直接监听硬件vsync的话,会导致功耗增大
  • vsync信号是固定周期的,用软件容易进行模拟。

通过命令:adb shell dumpsys SurfaceFlinger --dispsync
在这里插入图片描述
workduration:代表自身工作的理论耗时
readyduration:代表自身工作完成后,传递给下一模块处理的等待时间

以sf和app举例:app的workduration代表app绘制渲染一帧的理论耗时,app的readyduration代表app绘制渲染一帧完成后交给surfaceflinger处理的理耗时,sf的workduration代表sf处理这一帧的理论耗时,readyduration代表传递给下一模块处理的等待时间。

可见 app的readyduration== sf的 workduration,且sf的readyduration=0

2.vsync时刻的计算模型

workduration和readyduration在大多数情况下都是固定值,且对于sync计算来说是个固定值,是对于app和sf完成渲染和合成工作时间大概估计,vsync时间点的计算和这两个值有关系。

如下图所示,是app-sync的时间点计算示意图:
举例:
app-sync: workduration:16.6ms readyduration: 15.6ms,那么app-sync的计算方式如下图所描述:

在这里插入图片描述

  1. 假如应用在24.9ms时向surfaceflinger申请app-vsync信号
  2. 在24.9ms基础上加上app-vsync的workduration和readyduration计算出时间点a
  3. 找出a的下一个HW_VSYNC的时间点:81ms
  4. 在a的的下一个HW_VSYNC的时间点上减去app-vsync的workduration和readyduration得到时间点b:48.8ms,改时间点就是未来app收到app-vsync的时间点
  5. 计算出surfaceflinger申请app-vsync信号的到时间点b的时间差:23.9ms,并设置定时
  6. 23.9m后app申请的app-vsync时间到,surfaceflinger向app发送app-vsync信号

以上演示的以app-vsync为例的vsync计算过程,appsf-vsync和sf-vsync的计算过程类似,不同的是appsf-vsync和sf-vsync的workduration,readyduration是不同的值,以使得信号之间保持一定的相位差。

二.VSYNC的初次申请,连续申请,停止申请

EventThread概括
在初始化 SurfaceFlinger 时,创建了两个子线程(EventThread)用来分别向客户端派app-vsync事件和appsf-vsync事件,这两个EventThread最重要的区别是对应的workduration,readyduration是不同。
EventThread主要作用:

  • 处理app端建立连接的请求,建立过程中会保存连接信息,并生成一个socktpair并返回给app端,后续的vsync信号将会通过该socktpair发送给app
  • 接收app申请vsync的请求,并向对应的vsync信号软件模型进行申请
  • 当vsync信号到达时,分发vsync信号给有需求的app

在EventThread的初始化过程中会,会启动一个线程,在该线程中会执行EventThread::threaMain(),该函数是会执行一个while大循环,该循环的运行受状态机控制:

native\services\surfaceflinger\Scheduler\EventThread.h

enum class State {
        Idle,
        Quit,
        SyntheticVSync,
        VSync,
    };
  • Idle:循环会阻塞,此时表示当前处于空闲状态,等待app建立连接或请求Vsync信号后唤醒循环
  • Quit:循环将会退出
  • SyntheticVSync:表示由 EventThread 来提供虚假的 Vsync 信号
  • VSync:表示正常亮屏时请求,分发Vsync 信号

EventThreadConnection

class EventThreadConnection : public gui::BnDisplayEventConnection {
public:
	// 当vsync信号来临时,通过sockt-pair将信号发送给app
    virtual status_t postEvent(const DisplayEventReceiver::Event& event);
    // app通过binder跨进程调用此方法,将建立的socketpair返回给应用
    binder::Status stealReceiveChannel(gui::BitTube* outChannel) override;
    // binder跨进程方法跨进程调用此方法,将会向surfaceflinger请求一个vsync信号
    binder::Status requestNextVsync() override; // asynchronous
    VSyncRequest vsyncRequest = VSyncRequest::None;
    .....
}

app会向surfaceflinger建立连接,该连接就是EventThreadConnection,连接建立后会把该连接保存在EventThread的mDisplayEventConnections列表中。如上文代码所展示EventThreadConnection继承自BnDisplayEventConnection,故EventThreadConnection具有使用binder跨进程的能力,且是binder的服务端。建立连接后,app端会调用stealReceiveChannel方法将socketpair返回给app,后续的vsync信号将会使用该socketpair不断分发给app。

在EventThreadConnection 中除了代码中注释的三个重要的方法外,还有一个变量vsyncRequest ,类型为VSyncRequest :

enum class VSyncRequest {
    None = -2,
    // Single wakes up for the next two frames to avoid scheduler overhead
    Single = -1,
    // SingleSuppressCallback only wakes up for the next frame
    SingleSuppressCallback = 0,
    Periodic = 1,
    // Subsequent values are periods.
};

vsyncRequest保存着对应EventThreadConnection 申请vsync的状态

  • None:不请求
  • Single :该状态下会得到两次vsync回调
  • SingleSuppressCallback :该状态下会得到一次vsync回调
  • Periodic:亮屏下不使用该状态
    需要注意的是 Single状态下会收到两次vsync信号,能避免额外的唤醒循环。

接下来正式开始分析

以app向surfaceflinger申请app-vsync为例:

1.应用初次申请app-Vsync

应用端通过Choreographer向SurfaceFlinger请求一个app-Vsync,会调用到 EventThread::requestNextVsync()

native\services\surfaceflinger\Scheduler\EventThread.cpp

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

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

	// 第一次请求的时候 connection->vsyncRequest == VSyncRequest::None,进入如下逻辑,使得该连接的vsyncRequest = VSyncRequest::Single
    if (connection->vsyncRequest == VSyncRequest::None) {
        connection->vsyncRequest = VSyncRequest::Single;
        mCondition.notify_all();
    } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {
        connection->vsyncRequest = VSyncRequest::Single;
    }
}

目前:

  • mPendingEvents.isEmpty() = true(EventThread的属性需要向需要分发的事件)
  • mState = State::IDLE
  • connection->vsyncReques = VSyncRequest::Single (connection为刚才申请app-vsync的那个)
native\services\surfaceflinger\Scheduler\EventThread.cpp

void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
    DisplayEventConsumers consumers;
	// 第一次进入 mState != State::Quit
    while (mState != State::Quit) {
    	// 初始化一个event,设置为空
        std::optional<DisplayEventReceiver::Event> event;

        // Determine next event to dispatch.
        // mPendingEvents,存放着定时器唤醒后发给该EventThread的事件,目前为空,故该判断不会进入,event依然为空
        if (!mPendingEvents.empty()) {
            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;
            }
        }
		// 初始 vsyncRequested = false
        bool vsyncRequested = false;

        // 遍历所有连接
        auto it = mDisplayEventConnections.begin();
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
            	// 因为刚刚有一个connect请求app-sync,使得该connect的vsyncRequest = VSyncRequest::Single,故vsyncRequested=true
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                // event目前等于null,不会进入
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);
                }

                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
		// consumers目前为空,不会进入
        if (!consumers.empty()) {
            dispatchEvent(*event, consumers);
            consumers.clear();
        }
		// 新建nextState
        State nextState;
        // 目前 mVSyncState不为null,vsyncRequested为true,故进入以下逻辑
        if (mVSyncState && vsyncRequested) {
        	// mVSyncState->synthetic为false,故nextState  = State::VSyn
            nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
        } else {
            ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
            nextState = State::Idle;
        }
		// 目前 mState = State::IDLE, nextState = State::VSync,故进入以下逻辑
        if (mState != nextState) {
            if (mState == State::VSync) {
                mVSyncSource->setVSyncEnabled(false);
                // 进入如下逻辑
            } else if (nextState == State::VSync) {
            	// 去申请一个 VSync
                mVSyncSource->setVSyncEnabled(true);
            }
			// mState  = nextState = State::VSync
            mState = nextState;
        }
		// event依旧为null,不进入该逻辑
        if (event) {
            continue;
        }

        // Wait for event or client registration/request.
        // mState  = State::VSync,不进入该逻辑
        if (mState == State::Idle) {
            mCondition.wait(lock);
        } 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.
            //  mState != State::SyntheticVSync,timeout = 1000ms
            const std::chrono::nanoseconds timeout =
                    mState == State::SyntheticVSync ? 16ms : 1000ms;
            // 触发wait_for,暂时阻塞在此处,因为VSync很快就来,所以不会进入超时,即mCondition.wait_for(lock, timeout) != std::cv_status::timeout
            if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
                if (mState == State::VSync) {
                    ALOGW("Faking VSYNC due to driver stall for thread %s", mThreadName);
                    std::string debugInfo = "VsyncSource debug info:\n";
                    mVSyncSource->dump(debugInfo);
                    // Log the debug info line-by-line to avoid logcat overflow
                    auto pos = debugInfo.find('\n');
                    while (pos != std::string::npos) {
                        ALOGW("%s", debugInfo.substr(0, pos).c_str());
                        debugInfo = debugInfo.substr(pos + 1);
                        pos = debugInfo.find('\n');
                    }
                }

                LOG_FATAL_IF(!mVSyncState);
                const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
                const auto deadlineTimestamp = now + timeout.count();
                const auto expectedVSyncTime = deadlineTimestamp + timeout.count();
                mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now,
                                                   ++mVSyncState->count, expectedVSyncTime,
                                                   deadlineTimestamp));
            }
        }
    }
}

shouldConsumeEvent如下,逻辑非常简单,如下:
可见一个connection在多次调用到shouldConsumeEvent,connection->vsyncRequest是这样变化的:

1. VSyncRequest::Single
2. VSyncRequest::SingleSuppressCallback
3. VSyncRequest::None

native\services\surfaceflinger\Scheduler\EventThread.cpp

bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
                                     const sp<EventThreadConnection>& connection) const {
    const auto throttleVsync = [&] {
        return mThrottleVsyncCallback &&
                mThrottleVsyncCallback(event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                       connection->mOwnerUid);
    };

    switch (event.header.type) {
		......
        case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
            switch (connection->vsyncRequest) {
            	// 如果当前connection的connection->vsyncRequest = VSyncRequest::None 直接返回false
                case VSyncRequest::None:
                    return false;
                // 如果当前connection的connection->vsyncRequest = VSyncRequest::SingleSuppressCallback,
                // 使得connection->vsyncRequest = VSyncRequest::None;同时返回fasle
                case VSyncRequest::SingleSuppressCallback:
                    connection->vsyncRequest = VSyncRequest::None;
                    return false;
                // 如果当前connection的connection->vsyncRequest = VSyncRequest::Single,
                // 使得connection->vsyncRequest = VSyncRequest::SingleSuppressCallback;同时返回true
                case VSyncRequest::Single: {
                    if (throttleVsync()) {
                        return false;
                    }
                    connection->vsyncRequest = VSyncRequest::SingleSuppressCallback;
                    return true;
                }
               .......
    }
}

接上文,应用申请了一个app-vsync后,调用了DispSyncSource::setVSyncEnabled,参数enable = ture,因为以app申请app-vsyc举例
故此时的mWorkDuration 和 mReadyDuration是app-sync的。 同时该方法中可以调用 mCallbackRepeater->start()和mCallbackRepeater->stop(),可见这个方法和开启申请vsync和停止vsync均有关系。

native\services\surfaceflinger\Scheduler\DispSyncSource.cpp

void DispSyncSource::setVSyncEnabled(bool enable) {
    std::lock_guard lock(mVsyncMutex);
    if (enable) {
    	// 申请VSYNC阶段 enable = true
        mCallbackRepeater->start(mWorkDuration, mReadyDuration);
        // ATRACE_INT(mVsyncOnLabel.c_str(), 1);
    } else {
        mCallbackRepeater->stop();
        // ATRACE_INT(mVsyncOnLabel.c_str(), 0);
    }
    mEnabled = enable;
}

在app初次申请过程中,进一步调用到CallbackRepeater 的start,将会传入workDuration,和 readyDuration,同时将CallbackRepeater的mStarted设置为true
接着调用mRegistration.schedule(),后续将在app-vsync的软件模型基础上,计算出何时向app分发一个app-vsync,随后设置一个定时后并返回,这方面的分析将在后续博客中分析。

同时需要注意的是CallbackRepeater 除了start(),还有两个方法,简单描述作用:

  • start():向vsync的软件模型申请vsync信号
  • stop():向vsync的软件模型申请停止vsync信号
  • callback(): 当vsync时间到时,会回调到这里,接下来进一步会回调到 EventThread::onVSyncEvent()方法,来向app分发vsync事件。
    stop()和callback()将在后文中进一步分析
native\services\surfaceflinger\Scheduler\DispSyncSource.cpp

class CallbackRepeater {
	...
	void start(std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration) {
        std::lock_guard lock(mMutex);
        mStarted = true;
        mWorkDuration = workDuration;
        mReadyDuration = readyDuration;

        auto const scheduleResult =
                mRegistration.schedule({.workDuration = mWorkDuration.count(),
                                        .readyDuration = mReadyDuration.count(),
                                        .earliestVsync = mLastCallTime.count()});
        LOG_ALWAYS_FATAL_IF((!scheduleResult.has_value()), "Error scheduling callback");
    }
    ...

	void stop() {
        .....
    }
	
	...
	
	void callback(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
       ....
    }

}

2.第一个Vsync时间到达

app初次申请app-vsync后,Vsync时间到达后会触发到CallbackRepeater::callback(),如上文介绍CallbackRepeater时所描述:

native\services\surfaceflinger\Scheduler\DispSyncSource.cpp

class CallbackRepeater {
	void callback(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
        {
            std::lock_guard lock(mMutex);
            mLastCallTime = std::chrono::nanoseconds(vsyncTime);
        }
		// 回调到接下来进一步会回调到 EventThread::onVSyncEvent()方法,来向app分发vsync事件
        mCallback(vsyncTime, wakeupTime, readyTime);

        {
            std::lock_guard lock(mMutex);
            // 在start()中已经将mStarted设置为true
            if (!mStarted) {
                return;
            }
            // 继续调用mRegistration.schedule()向vsync软件模型申请一个vsync
            auto const scheduleResult =
                    mRegistration.schedule({.workDuration = mWorkDuration.count(),
                                            .readyDuration = mReadyDuration.count(),
                                            .earliestVsync = vsyncTime});
            LOG_ALWAYS_FATAL_IF(!scheduleResult.has_value(), "Error rescheduling callback");
        }
    }
}

如上,在callback中,会进一步回调到EventThread::onVSyncEvent()方法,来向app分发vsync事件,随后继续调用mRegistration.schedule()向vsync软件模型申请一个vsync,这里也许有疑问:vsync时间到,回调到这里时,除了分发了一次vsync事件后,还立即有申请了一个vsync,看起来似乎从此不需要申请vsync,vsync会按照节律不断的产生无法停止。事实并非如此,后续分析。

接上文在callback中,会进一步回调到EventThread::onVSyncEvent()方法
会向EventThread->mPendingEvents中添加一个event,随后唤醒mCondition的阻塞

native\services\surfaceflinger\Scheduler\EventThread.cpp

// timestamp:期望收到Vsync的时间,vsyncData.expectedPresentationTime:实际vsync时间, vsyncData.deadlineTimestamp:vsync脉冲时间 - readyDuration
void EventThread::onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) {
    std::lock_guard<std::mutex> lock(mMutex);

    LOG_FATAL_IF(!mVSyncState);
    // 向mPendingEvents中添加一个evnet
    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                       vsyncData.expectedPresentationTime,
                                       vsyncData.deadlineTimestamp));
    mCondition.notify_all();
}

上文中一直当app申请一个app-vsync进行了阻塞,如下:
以60的刷新率为例,app第一次申请app-vsync后,做多16.6ms后vsync信号到达,然后mCondition的阻塞,故最多阻塞16.6ms,不会到达1000ms的阻塞超时时间,故不会进入下面的逻辑,随后直接接入到threadMain()的下一次while循环。

native\services\surfaceflinger\Scheduler\EventThread.cpp

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

    while (mState != State::Quit) {
    	.......
    	// 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;
            // 从这里唤醒,且未超时,故不进入,随后进入while 的下一次循环
            if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
                	......
            }
        }
	}
}

随后进入到下一次while循环:
目前

  • mPendingEvent.isEmpty() = false,有一个前面添加的event
  • mState = State::VSync
  • connection->vsyncReques = VSyncRequest::Single (connection为刚才申请app-vsync的那个)

native\services\surfaceflinger\Scheduler\EventThread.cpp
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
	// consumers = null
    DisplayEventConsumers consumers;
	
	// 进入while的下一个循环
    while (mState != State::Quit) {
        std::optional<DisplayEventReceiver::Event> event;

        // Determine next event to dispatch.
        // mPendingEvents中已经有了一个event
        if (!mPendingEvents.empty()) {
        	// event此时等于vsync信号到来时键入的那个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;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        // 遍历所有mDisplayEventConnections
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
            	// 此时 之前申请app-vsync的connection->vsyncRequest  = VSyncRequest::Single
            	// 所以vsyncRequested  == true
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                // event不为空,且shouldConsumeEvent会使得 connection->vsyncReques  = VSyncRequest::VSyncRequest::SingleSuppressCallback
                // 且shouldConsumeEvent返回true,进入该判断
                if (event && shouldConsumeEvent(*event, connection)) {
                	// consumers中保存着需要消费此次event的connection
                    consumers.push_back(connection);
                }

                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
		// consumers此次不为空,向对应的connection发送vsync信号,后续分析
        if (!consumers.empty()) {
            // 分发Vsnc
            dispatchEvent(*event, consumers);
            // 分发完毕后,清空consumers
            consumers.clear();
        }

        State nextState;
        //此时 mVSyncState  == true vsyncRequested == true,则进入该判断
        if (mVSyncState && vsyncRequested) {
        	//  nextState = State::VSync
            nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
        } else {
            ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
            nextState = State::Idle;
        }
		// 此时mState == nextState == State::VSync,不进入如下判断。
        if (mState != nextState) {
            if (mState == State::VSync) {
                mVSyncSource->setVSyncEnabled(false);
            } else if (nextState == State::VSync) {
                mVSyncSource->setVSyncEnabled(true);
            }

            mState = nextState;
        }
		
		// 此时event !=null,进入判断
        if (event) {
        	// 立即开启下一次循环
            continue;
        }
		....
    }
}

立即进入下一次循环:

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

    while (mState != State::Quit) {
    	// event = null
        std::optional<DisplayEventReceiver::Event> event;

        // mPendingEvents的event已经被消费,此时 mPendingEvents.empty() = true,故不进入
        if (!mPendingEvents.empty()) {
            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;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        // 遍历所有mDisplayEventConnections
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
            	// 此时 之前申请app-vsync的connection->vsyncRequest  = VSyncRequest::Single
            	// 所以vsyncRequested  == true 
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                // 此时event = null,则不会执行shouldConsumeEvent,也不会进入下面的判断
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);
                }
                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
		
		// consumers.empty() = true,不会进入
        if (!consumers.empty()) {
            dispatchEvent(*event, consumers);
            consumers.clear();
        }

        State nextState;
        // 此时 mVSyncState  == true vsyncRequested == true,则进入该判断
        if (mVSyncState && vsyncRequested) {
        	// nextState依旧=State::VSync
            nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
        } else {
            ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
            nextState = State::Idle;
        }
		// 此时依旧mState == nextState == State::VSync,不进入如下判断。
        if (mState != nextState) {
            if (mState == State::VSync) {
                mVSyncSource->setVSyncEnabled(false);
            } else if (nextState == State::VSync) {
                mVSyncSource->setVSyncEnabled(true);
            }

            mState = nextState;
        }
		// event = null,不进入
        if (event) {
            continue;
        }

        // Wait for event or client registration/request.
        // mState = State::VSync,进入else 
        if (mState == State::Idle) {
            mCondition.wait(lock);
        } 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;
            // 在此wait
            if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
                if (mState == State::VSync) {
                   ......
                }
            }
        }
    }
}

最后分析上文中提到的vsync事通过dispatchEvent分发给应用:
遍历consumer,并通过sockt pair将vsync时间发送给应用

void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
                                const DisplayEventConsumers& consumers) {
    for (const auto& consumer : consumers) {
        DisplayEventReceiver::Event copy = event;
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
            const int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
            copy.vsync.vsyncData.frameInterval = frameInterval;
            generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp,
                                  event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                  event.vsync.vsyncData.preferredDeadlineTimestamp());
        }
        // 通过sockt通讯将Vsnc发送给应用
        switch (consumer->postEvent(copy)) {
            case NO_ERROR:
                break;

            case -EAGAIN:
                // TODO: Try again if pipe is full.
                ALOGW("Failed dispatching %s for %s", toString(event).c_str(),
                      toString(*consumer).c_str());
                break;

            default:
                // Treat EPIPE and other errors as fatal.
                removeDisplayEventConnectionLocked(consumer);
        }
    }
}

app第一次申请分发app-vsync结束后,接下来将会有两种情况
如下:

  • app接着申请app-vsync
  • app不再申请app-vsync

3.app接着申请app-vsync

紧接着app端通过Choreographer向SurfaceFlinger再次请求一个app-Vsync,会调用到 EventThread::requestNextVsync(),使得
connection->vsyncRequest 从VSyncRequest::SingleSuppressCallback变为 VSyncRequest::Single

native\services\surfaceflinger\Scheduler\EventThread.cpp

void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
	.....
    std::lock_guard<std::mutex> lock(mMutex);

	// 再次请求的时候 connection->vsyncRequest == VSyncRequest::None,进入如下逻辑,使得该连接的vsyncRequest = VSyncRequest::Single
    if (connection->vsyncRequest == VSyncRequest::None) {
        connection->vsyncRequest = VSyncRequest::Single;
        mCondition.notify_all();
     // 此时该app对应的connection->vsyncRequest = VSyncRequest::SingleSuppressCallback,进入else
    } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {
    	// 只是将vsyncRequest 设置为Single,并没有唤醒线程的循环
        connection->vsyncRequest = VSyncRequest::Single;
    }
}

如上,当app再次申请时,只是将对应的connection->vsyncRequest == VSyncRequest::SingleSuppressCallback,并未向初次申请那样去唤醒线程以继续进行循环。似乎停止到这里了,其实不然,还记得上文提到的CallbackRepeater,在收到回调后又会去申请一个vsync:

native\services\surfaceflinger\Scheduler\DispSyncSource.cpp

class CallbackRepeater {
	void callback(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
        {
            std::lock_guard lock(mMutex);
            mLastCallTime = std::chrono::nanoseconds(vsyncTime);
        }
		// 回调到接下来进一步会回调到 EventThread::onVSyncEvent()方法,来向app分发vsync事件
        mCallback(vsyncTime, wakeupTime, readyTime);

        {
            std::lock_guard lock(mMutex);
            // 在start()中已经将mStarted设置为true
            if (!mStarted) {
                return;
            }
            // 继续调用mRegistration.schedule()向vsync软件模型申请一个vsync
            auto const scheduleResult =
                    mRegistration.schedule({.workDuration = mWorkDuration.count(),
                                            .readyDuration = mReadyDuration.count(),
                                            .earliestVsync = vsyncTime});
            LOG_ALWAYS_FATAL_IF(!scheduleResult.has_value(), "Error rescheduling callback");
        }
    }
}

所以不久之后,回调中申请的vsync时间到,触发vsync的回调,再次触发回调,接下来进一步会回调到 EventThread::onVSyncEvent()方法 ,向mPendingEvents中添加一个event,会唤醒线程,继续进行循环,向app分发vsync事件:
具体执行过程和第一次第一个Vsync时间到达的处理流程一致。
至此应用申请第二次vsync的申请分发已经结束,因为在CallbackRepeater的void callback()会继续向软件vsync模型申请一个vsync,
一次只要应用不断的申请vsync,vsync信号就会不断的产生并下发给应用。
此时EventThreadConnection::VSyncRequest来实现一次VSYNC信号申请,将会收到两次回调的作用就体现出来:app在连续不断的申请vsync过程中除了第一次需要唤醒循环,向软件模拟的vsync模型申请vsync外,其他的vsync信号的申请均在回调中完成,不需要额外的循环唤醒,这将降低程序的开销

4.app不再申请app-vsync

紧接着app第一次申请app-vsync,并完成分发后,EventThread::threadMain被wait阻塞,因为因为在CallbackRepeater的void callback()会继续向软件vsync模型申请一个vsync,所以不久之后
所以不久之后,回调中申请的vsync时间到,触发vsync的回调,再次触发回调,接下来进一步会回调到 EventThread::onVSyncEvent()方法 ,向mPendingEvents中添加一个event,会唤醒线程,继续进行循环。


native\services\surfaceflinger\Scheduler\EventThread.cpp
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
	// consumers = null
    DisplayEventConsumers consumers;
	
	// 进入while的下一个循环
    while (mState != State::Quit) {
        std::optional<DisplayEventReceiver::Event> event;

        // Determine next event to dispatch.
        // mPendingEvents中已经有了一个event
        if (!mPendingEvents.empty()) {
        	// event此时等于vsync信号到来时键入的那个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;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        // 遍历所有mDisplayEventConnections
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
            	// 此时 之前申请app-vsync的connection->vsyncRequest  = VSyncRequest::SingleSuppressCallback
            	// 所以vsyncRequested  == true
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                // event不为空,且shouldConsumeEvent会使得 connection->vsyncReques  = None
                // 且shouldConsumeEvent返回false,不进入进入该判断
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);
                }
                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
		// 此时 consumers.isEmpty() = true,不进入判断
        if (!consumers.empty()) {
            dispatchEvent(*event, consumers);
            consumers.clear();
        }

        State nextState;
        //此时 mVSyncState  == true vsyncRequested == true,则进入该判断
        if (mVSyncState && vsyncRequested) {
        	//  nextState = State::VSync
            nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
        } else {
            ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
            nextState = State::Idle;
        }
		// 此时mState == nextState == State::VSync,不进入如下判断。
        if (mState != nextState) {
            if (mState == State::VSync) {
                mVSyncSource->setVSyncEnabled(false);
            } else if (nextState == State::VSync) {
                mVSyncSource->setVSyncEnabled(true);
            }

            mState = nextState;
        }
		
		// 此时event !=null,进入判断
        if (event) {
        	// 立即开启下一次循环
            continue;
        }
		....
    }
}

立即进入下一循环:

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

    while (mState != State::Quit) {
    	// event = null
        std::optional<DisplayEventReceiver::Event> event;

        // mPendingEvents的event已经被pop_front,此时 mPendingEvents.empty() = true,故不进入
        if (!mPendingEvents.empty()) {
            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;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        // 遍历所有mDisplayEventConnections
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
            	// 此时 之前申请app-vsync的connection->vsyncRequest  = VSyncRequest::None
            	// 所以vsyncRequested  == false
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                // 此时event = null,则不会执行shouldConsumeEvent,也不会进入下面的判断
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);
                }
                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
		
		// consumers.empty() = true,不会进入
        if (!consumers.empty()) {
            dispatchEvent(*event, consumers);
            consumers.clear();
        }

        State nextState;
        // 此时 mVSyncState  == true vsyncRequested == false,则进入该else判断
        if (mVSyncState && vsyncRequested) {
        	// nextState依旧=State::VSync
            nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
        } else {
            ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
            // 设置为idle
            nextState = State::Idle;
        }
		// 此时依旧mState == State::VSync,nextState == State::Idle;进入如下判断。
        if (mState != nextState) {
            if (mState == State::VSync) {
                mVSyncSource->setVSyncEnabled(false);
                // 进入该判断
            } else if (nextState == State::VSync) {
                mVSyncSource->setVSyncEnabled(true);
            }

            mState = nextState;
        }
		// event = null,不进入
        if (event) {
            continue;
        }

        // Wait for event or client registration/request.
        // mState = State::Idle,进入判断,线程wait
        if (mState == State::Idle) {
            mCondition.wait(lock);
        } else {
           ....
        }
    }
}
native\services\surfaceflinger\Scheduler\DispSyncSource.cpp

void DispSyncSource::setVSyncEnabled(bool enable) {
    std::lock_guard lock(mVsyncMutex);
    if (enable) {
        mCallbackRepeater->start(mWorkDuration, mReadyDuration);
        // ATRACE_INT(mVsyncOnLabel.c_str(), 1);
    // enable = false,进入else分支
    } else {
        mCallbackRepeater->stop();
        // ATRACE_INT(mVsyncOnLabel.c_str(), 0);
    }
    mEnabled = enable;
}

mStarted 设置为false,这样的话在CallbackRepeater的void callback()重复继续向软件vsync模型申请一个vsync后,vsync时间到后,回调到这里时因为mStarted = false,不会回调到EventThread::onVSyncEvent()方法,随后调用mRegistration.cancel();将会将正在定时的vsync取消掉。

native\services\surfaceflinger\Scheduler\DispSyncSource.cpp

class CallbackRepeater {
	void stop() {
        std::lock_guard lock(mMutex);
        LOG_ALWAYS_FATAL_IF(!mStarted, "DispSyncInterface misuse: callback already stopped");
        mStarted = false;
        mRegistration.cancel();
    }
}

结束

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐