Andoid SurfaceFlinger(二) VSYNC的开始,连续,结束
VSYNC的开始,连续,结束
一.VSYNC相关概念介绍
1.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的计算方式如下图所描述:
- 假如应用在24.9ms时向surfaceflinger申请app-vsync信号
- 在24.9ms基础上加上app-vsync的workduration和readyduration计算出时间点a
- 找出a的下一个HW_VSYNC的时间点:81ms
- 在a的的下一个HW_VSYNC的时间点上减去app-vsync的workduration和readyduration得到时间点b:48.8ms,改时间点就是未来app收到app-vsync的时间点
- 计算出surfaceflinger申请app-vsync信号的到时间点b的时间差:23.9ms,并设置定时
- 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();
}
}
结束
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)