EventControlThread: 控制硬件vsync的开关
DispSyncThread: 软件产生vsync的线程
SF EventThread: 该线程用于SurfaceFlinger接收vsync信号用于渲染
App EventThread: 该线程用于接收vsync信号并且上报给App进程,App开始画图
从这4个线程,可以将vsync分为4种不同的类型
HW vsync, 真实由硬件产生的vsync信号
SW vsync, 由DispSync产生的vsync信号
SF vsync, SF接收到的vsync信号
App vsync, App接收到的vsync信号
这里我们着重看看SF EventThread.
先大致了解下BitTube,其实现是socketpairt套接字,用于传递消息。
Buffer大小是4KB。
void SurfaceFlinger::init() {
...
// start the EventThread
mEventThreadSource =
std::make_unique(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs,
true, "app");
mEventThread = std::make_unique(mEventThreadSource.get(),
[this]() { resyncWithRateLimit(); },
impl::EventThread::InterceptVSyncsCallback(),
"appEventThread");
mSfEventThreadSource =
std::make_unique(&mPrimaryDispSync,
SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread =
std::make_unique(mSfEventThreadSource.get(),
[this]() { resyncWithRateLimit(); },
[this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
},
"sfEventThread");
......
}
EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
: mVSyncSource(src),
mResyncWithRateLimitCallback(resyncWithRateLimitCallback),
mInterceptVSyncsCallback(interceptVSyncsCallback) {
for (auto& event : mVSyncEvent) {
event.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
event.header.id = 0;
event.header.timestamp = 0;
event.vsync.count = 0;
}
// 绑定thread函数
mThread = std::thread(&EventThread::threadMain, this);
// 设置thread名称
pthread_setname_np(mThread.native_handle(), threadName);
pid_t tid = pthread_gettid_np(mThread.native_handle());
// Use SCHED_FIFO to minimize jitter
constexpr int EVENT_THREAD_PRIORITY = 2;
struct sched_param param = {0};
param.sched_priority = EVENT_THREAD_PRIORITY;
if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for EventThread");
}
set_sched_policy(tid, SP_FOREGROUND);
}
void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
std::unique_lock lock(mMutex);
while (mKeepRunning) {
DisplayEventReceiver::Event event;
Vector > signalConnections;
// 2.4 阻塞等待事件
signalConnections = waitForEventLocked(&lock, &event);
// 分发事件给connection
const size_t count = signalConnections.size();
for (size_t i = 0; i < count; i++) {
const sp& conn(signalConnections[i]);
// 2.5 分发事件
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
// The destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
// FIXME: Note that some events cannot be dropped and would have
// to be re-sent later.
// Right-now we don't have the ability to do this.
//ALOGW("EventThread: dropping event (%08x) for connection %p", event.header.type,
// conn.get());
} else if (err < 0) {
// handle any other error on the pipe as fatal. the only
// reasonable thing to do is to clean-up this connection.
// The most common error we'll get here is -EPIPE.
removeDisplayEventConnectionLocked(signalConnections[i]);
}
}
}
}
// This will return when (1) a vsync event has been received, and (2) there was
// at least one connection interested in receiving it when we started waiting.
Vector > EventThread::waitForEventLocked(
std::unique_lock* lock, DisplayEventReceiver::Event* event) {
Vector > signalConnections;
while (signalConnections.isEmpty() && mKeepRunning) {
bool eventPending = false;
bool waitForVSync = false;
size_t vsyncCount = 0;
nsecs_t timestamp = 0;
for (int32_t i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; i++) {
timestamp = mVSyncEvent[i].header.timestamp;
if (timestamp) {
// 当timestamp不为0时,说明有事件发生
if (mInterceptVSyncsCallback) {
mInterceptVSyncsCallback(timestamp);
}
*event = mVSyncEvent[i];
// 置timestamp为0,标记为当前事件被消费
mVSyncEvent[i].header.timestamp = 0;
vsyncCount = mVSyncEvent[i].vsync.count;
break;
}
}
// mDisplayEventConnections保存的是注册的Connection的,
// SF EventThread线程里只有一个Connection, 而这个Connection主要是用来渲染
// 而如果是APP EventThread, 这里会有多个connection
size_t count = mDisplayEventConnections.size();
if (!timestamp && count) {
// 没有vsync事件, 来看下是否有其它pending的event, 这里主要是hotplug的事件
eventPending = !mPendingEvents.isEmpty();
if (eventPending) {
// we have some other event to dispatch
*event = mPendingEvents[0];
mPendingEvents.removeAt(0);
}
}
for (size_t i = 0; i < count;) {
sp connection(mDisplayEventConnections[i].promote());
if (connection != nullptr) {
bool added = false;
// Connection->count的值大小含义如下:
// 1. >=1: 表示持续接收Vsync信号
// 2. ==0: 只接收一次Vsync信号
// 3. ==-1: 不接收Vsync信号
if (connection->count >= 0) {
// 如果有 connection->count >= 0,说明需要Vsync信号
waitForVSync = true;
if (timestamp) { // 大于0.说明有事件
// 处理本次事件
if (connection->count == 0) {
// fired this time around
connection->count = -1;
signalConnections.add(connection);
added = true;
} else if (connection->count == 1 ||
(vsyncCount % connection->count) == 0) {
// continuous event, and time to report it
signalConnections.add(connection);
added = true;
}
}
}
if (eventPending && !timestamp && !added) {
// we don't have a vsync event to process
// (timestamp==0), but we have some pending
// messages.
signalConnections.add(connection);
}
++i;
} else {
// we couldn't promote this reference, the connection has
// died, so clean-up!
mDisplayEventConnections.removeAt(i);
--count;
}
}
// Here we figure out if we need to enable or disable vsyncs
if (timestamp && !waitForVSync) {
// 收到Vsync信号,但是没有Connection监听,所以关闭Vsync
disableVSyncLocked();
} else if (!timestamp && waitForVSync) {
// 有Connection监听,但是还没有Vsync信号,所以打开Vsync
enableVSyncLocked();
}
// 没有事件发生
if (!timestamp && !eventPending) {
if (waitForVSync) { // 如果有connection监听,则需要等待Vsync事件
// 以防止硬件Driver出问题,设置一个超时时间16ms
bool softwareSync = mUseSoftwareVSync;
auto timeout = softwareSync ? 16ms : 1000ms;
if (mCondition.wait_for(*lock, timeout) == std::cv_status::timeout) {
if (!softwareSync) {
ALOGW("Timed out waiting for hw vsync; faking it");
}
// FIXME: how do we decide which display id the fake
// vsync came from ?
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
mVSyncEvent[0].vsync.count++;
}
} else {
// 没有connection监听,也没有收到事件,则一直等待
mCondition.wait(*lock);
}
}
}
// here we're guaranteed to have a timestamp and some connections to signal
// (The connections might have dropped out of mDisplayEventConnections
// while we were asleep, but we'll still have strong references to them.)
return signalConnections;
}
当EventThread初始化进入时,由于没有Connection,timestamp也为0,直接进入waitForEventLocked一直等待。
status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
通过BitTube发送事件。
sfEventThread添加Connection是在这个线程启动后就添加的。
void SurfaceFlinger::init() {
......
mEventQueue->setEventThread(mSFEventThread.get());
mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
......
}
void MessageQueue::setEventThread(android::EventThread* eventThread) {
if (mEventThread == eventThread) {
return;
}
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
}
mEventThread = eventThread;
// 3.3 创建Connection
mEvents = eventThread->createEventConnection();
// 3.4 建立BitTube连接
mEvents->stealReceiveChannel(&mEventTube);
// 3.5 接受BitTube事件,调用cb_eventReceiver方法
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
this);
}
sp EventThread::createEventConnection() const {
return new Connection(const_cast(this));
}
EventThread::Connection::Connection(EventThread* eventThread)
// 注意这里的count是被赋值为-1,也就是不接收Vsync事件
: count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
void EventThread::Connection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strong reference on us
mEventThread->registerDisplayEventConnection(this);
}
在Connection对象生成之后,就被注册到其对应的EventThread中
status_t EventThread::registerDisplayEventConnection(
const sp& connection) {
std::lock_guard lock(mMutex);
// 添加到mDisplayEventConnections集合中
mDisplayEventConnections.add(connection);
// waitForEventLocked 可以继续执行了。
mCondition.notify_all();
return NO_ERROR;
}
注册connection后,waitForEventLocked便可以开始继续执行了。但是由于只有这一个connection,而且这个connection.count 还是 -1,所以最后还是会在waitForEventLocked中一直等待Vsync事件
status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
// 将Connection的mChannel复制
outChannel->setReceiveFd(mChannel.moveReceiveFd());
return NO_ERROR;
}
SurfaceFlinger::initializeDisplays
SurfaceFlinger::onInitializeDisplays
SurfaceFlinger::setTransactionState
SurfaceFlinger::setTransactionFlags
SurfaceFlinger::signalTransaction
MessageQueue::invalidate
EventThread::Connection::requestNextVsync
EventThread::requestNextVsync
也就是说当显示屏准备完毕,sfEventThread就可以开始监听Vsync信号了
void EventThread::requestNextVsync(const sp& connection) {
std::lock_guard lock(mMutex);
if (mResyncWithRateLimitCallback) {
mResyncWithRateLimitCallback();
}
if (connection->count < 0) {
connection->count = 0; // 只接受一次Vsync信号
mCondition.notify_all();
}
}
当SF EventThread收到Vsync信号时,最终会通过BitTube发送给对应connection的receiver[2.5]。
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast(data);
return queue->eventReceiver(fd, events);
}
int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
ssize_t n;
DisplayEventReceiver::Event buffer[8];
while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
for (int i = 0; i < n; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
mHandler->dispatchInvalidate();
break;
}
}
}
return 1;
}
void MessageQueue::Handler::dispatchInvalidate() {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
转到SufaceFlinger主线程中处理了。
当显示屏准备完毕后,SF EventThread请求一次Vsync信号。那么走到waitForEventLocked中,会调用enableVSyncLocked方法开启硬件Vsync信号。
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// mUseSoftwareVSync也就是显示屏power状态
// 灭屏为true,亮屏置为false
if (!mVsyncEnabled) {
mVsyncEnabled = true;
mVSyncSource->setCallback(this);
mVSyncSource->setVSyncEnabled(true);
}
}
mDebugVsyncEnabled = true;
}
void DispSyncSource::setVSyncEnabled(bool enable) {
std::lock_guard lock(mVsyncMutex);
if (enable) {
status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
static_cast(this),
mLastCallbackTime);
if (err != NO_ERROR) {
ALOGE("error registering vsync callback: %s (%d)", strerror(-err), err);
}
// ATRACE_INT(mVsyncOnLabel.c_str(), 1);
} else {
status_t err = mDispSync->removeEventListener(static_cast(this),
&mLastCallbackTime);
if (err != NO_ERROR) {
ALOGE("error unregistering vsync callback: %s (%d)", strerror(-err), err);
}
// ATRACE_INT(mVsyncOnLabel.c_str(), 0);
}
mEnabled = enable;
}
开启Vsync信号就是添加EventListener,关闭就是将这个listener移除
status_t DispSync::addEventListener(const char* name, nsecs_t phase, Callback* callback) {
Mutex::Autolock lock(mMutex);
return mThread->addEventListener(name, phase, callback);
}
接下来就是到了DispSync部分了。
大致流程如下:
图片转自:https://www.jianshu.com/p/d3e4b1805c92 强烈推荐仔细阅读