该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录
本章关键点总结 & 说明:
本章节思维导图如上。主要讲述了SurfaceFlinger 处理Vsync机制的流程。分析到处理消息这一部分。
1 SurfaceFlinger使用VSync流程框架
APP将产生的界面提交Buffer时会调用queueBuffer的操作,最后会通知SF合成界面。SF需要合成界面的时候,发送请求Vsync信号请求给EventThread(SF),EventThread(SF) 再向DispSyncThread线程发送请求,DispSyncThread线程收到请求后,延迟offset2后将VSync-SF发送给EventThread(SF) 并唤醒, EventThread(SF)在收到Vsync-SF后唤醒SF,SF开始合成新界面。整体框架如下所示:
2 SurfaceFlinger使用VSync流程 源码分析
2.1 分析模式
以上面的框架为基础,这里详细分析下该流程。当应用程序构造好数据后 通知SurfacFlinger,这部分在之前的章节中过已经分享过,因此这里代码直接从框架图的 第2步 开始分析。
2.2 SF向EventThread-SF 请求VSync
这里实际上是继续 章节4(Android GUI系统之SurfaceFlinger(04)应用端分析3-提交Buffer)的分析,mFlinger->signalLayerUpdate(),代码如下:
void SurfaceFlinger::signalLayerUpdate() {
mEventQueue.invalidate();
}
这里就是 唤醒 另外一个线程EventThread-SF,继续分析mEventQueue.invalidate,代码实现如下:
void MessageQueue::invalidate() {
#if INVALIDATE_ON_VSYNC
mEvents->requestNextVsync();
#else
mHandler->dispatchInvalidate();
#endif
}
mEvents是EventThread::Connection类型的,对应的代码如下:
void EventThread::Connection::requestNextVsync() {
mEventThread->requestNextVsync(this);
}
这里继续分析EventThread的requestNextVsync方法,代码实现如下:
void EventThread::requestNextVsync(
const sp<EventThread::Connection>& connection) {
Mutex::Autolock _l(mLock);
if (connection->count < 0) {
connection->count = 0;
mCondition.broadcast();
}
}
这里条件变量唤醒了当前的线程EventThread,那么另一个地方的wait被唤醒,这里就是EventThread::waitForEvent方法中的mCondition.wait(mLock),被唤醒后继续执行。
2.3 EventThread-SF向 DispSyncThread请求VSync
首先分析下EventThread线程的启动,即threadLoop的实现,代码如下:
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
Vector< sp<EventThread::Connection> > signalConnections;
//关键点1:等待事件
signalConnections = waitForEvent(&event);
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
// now see if we still need to report this event
//关键点2:post事件
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
//...
} else if (err < 0) {
//...
removeDisplayEventConnection(signalConnections[i]);
}
}
return true;
}
这里详细分析下waitForEvent,代码如下:
Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
DisplayEventReceiver::Event* event)
{
Mutex::Autolock _l(mLock);
Vector< sp<EventThread::Connection> > signalConnections;
do {
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) {
// we have a vsync event to dispatch
*event = mVSyncEvent[i];
mVSyncEvent[i].header.timestamp = 0;
vsyncCount = mVSyncEvent[i].vsync.count;
break;
}
}
if (!timestamp) {
// no vsync event, see if there are some other event
eventPending = !mPendingEvents.isEmpty();
if (eventPending) {
// we have some other event to dispatch
*event = mPendingEvents[0];
mPendingEvents.removeAt(0);
}
}
// find out connections waiting for events
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
sp<Connection> connection(mDisplayEventConnections[i].promote());
if (connection != NULL) {
bool added = false;
if (connection->count >= 0) {//表示需要得到VSync
waitForVSync = true;
if (timestamp) {
if (connection->count == 0) {
connection->count = -1;
signalConnections.add(connection);
added = true;
} else if (connection->count == 1 ||
(vsyncCount % connection->count) == 0) {
signalConnections.add(connection);
added = true;
}
}
}
if (eventPending && !timestamp && !added) {
signalConnections.add(connection);
}
} else {
mDisplayEventConnections.removeAt(i);
--i; --count;
}
}
// Here we figure out if we need to enable or disable vsyncs
if (timestamp && !waitForVSync) {
disableVSyncLocked();
} else if (!timestamp && waitForVSync) {
//如果需要Vsync,则调用该方法
enableVSyncLocked();
}
if (!timestamp && !eventPending) {
// wait for something to happen
if (waitForVSync) {
bool softwareSync = mUseSoftwareVSync;
nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);
if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {
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 {
//休眠,等待下一个VSync到来
mCondition.wait(mLock);
}
}
} while (signalConnections.isEmpty());
return signalConnections;
}
这里一旦表明需要VSync,则会调用关键方法enableVSyncLocked,代码实现如下:
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// never enable h/w VSYNC when screen is off
if (!mVsyncEnabled) {
mVsyncEnabled = true;
//这里的mVSyncSource是DispSyncSource类型的
//实际上是给DispSyncThread线程设置Callback
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);
}
}
mDebugVsyncEnabled = true;
sendVsyncHintOnLocked();
}
继续分析,mVSyncSource是DispSyncSource类的对象,因此setCallback的代码实现如下:
virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
Mutex::Autolock lock(mMutex);
mCallback = callback;
}
这里设置了callback,后面 DispSyncThread就可以在收到VSync信号时调用该callback方法了。
2.4 唤醒DispSyncThread
这里以HWC的VSyncThread(实际上软件硬件 实现最终结果都是一样的),也就是软件实现的VSync来分析,软件VsyncThread的线程代码实现如下:
bool HWComposer::VSyncThread::threadLoop() {
{ // scope for lock
Mutex::Autolock _l(mLock);
while (!mEnabled) {
mCondition.wait(mLock);
}
}
const nsecs_t period = mRefreshPeriod;
const nsecs_t now = systemTime(CLOCK_MONOTONIC);
nsecs_t next_vsync = mNextFakeVSync;
nsecs_t sleep = next_vsync - now;
if (sleep < 0) {
// we missed, find where the next vsync should be
sleep = (period - ((now - next_vsync) % period));
next_vsync = now + sleep;
}
mNextFakeVSync = next_vsync + period;
struct timespec spec;
spec.tv_sec = next_vsync / 1000000000;
spec.tv_nsec = next_vsync % 1000000000;
int err;
do {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
if (err == 0) {
mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
}
return true;
}
这里经过一段运算后,调用了 mHwc.mEventHandler.onVSyncReceived方法,mHwc.mEventHandler的值实际上就是SurafceFlinger,这在SurafceFlinger的init函数中有做,代码如下:
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
因此,这里继续分析SurafceFlinger的onVSyncReceived方法的实现,代码如下:
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
bool needsHwVsync = false;
{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
if (type == 0 && mPrimaryHWVsyncEnabled) {
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}
if (needsHwVsync) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
}
}
这里继续分析DispSync的addResyncSample的实现,代码如下:
bool DispSync::addResyncSample(nsecs_t timestamp) {
Mutex::Autolock lock(mMutex);
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
mResyncSamples[idx] = timestamp;
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++;
} else {
mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
}
updateModelLocked();
if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {
resetErrorLocked();
}
if (kIgnorePresentFences) {
return mThread->hasAnyEventListeners();
}
return mPeriod == 0 || mError > kErrorThreshold;
}
这里继续分析DispSync的updateModelLocked的实现,代码如下:
void DispSync::updateModelLocked() {
if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
nsecs_t durationSum = 0;
for (size_t i = 1; i < mNumResyncSamples; i++) {
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
size_t prev = (idx + MAX_RESYNC_SAMPLES - 1) % MAX_RESYNC_SAMPLES;
durationSum += mResyncSamples[idx] - mResyncSamples[prev];
}
mPeriod = durationSum / (mNumResyncSamples - 1);
double sampleAvgX = 0;
double sampleAvgY = 0;
double scale = 2.0 * M_PI / double(mPeriod);
for (size_t i = 0; i < mNumResyncSamples; i++) {
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
nsecs_t sample = mResyncSamples[idx];
double samplePhase = double(sample % mPeriod) * scale;
sampleAvgX += cos(samplePhase);
sampleAvgY += sin(samplePhase);
}
sampleAvgX /= double(mNumResyncSamples);
sampleAvgY /= double(mNumResyncSamples);
mPhase = nsecs_t(atan2(sampleAvgY, sampleAvgX) / scale);
if (mPhase < 0) {
mPhase += mPeriod;
}
// Artificially inflate the period if requested.
mPeriod += mPeriod * mRefreshSkipCount;
mThread->updateModel(mPeriod, mPhase);
}
}
这里继续分析mThread->updateModel的实现,代码如下:
void updateModel(nsecs_t period, nsecs_t phase) {
Mutex::Autolock lock(mMutex);
mPeriod = period;
mPhase = phase;
mCond.signal();
}
经过一系列的分析,SurafceFlinger的onVSyncReceived方法最终会唤醒DispSyncThread线程。
2.5 DispSyncThread唤醒EventThread
有mCond.signal()就有对应的mCond.wait(),该方法在线程执行体中threadloop中,threadloop的代码如下:
virtual bool threadLoop() {
status_t err;
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
nsecs_t nextEventTime = 0;
while (true) {
Vector<CallbackInvocation> callbackInvocations;
nsecs_t targetTime = 0;
{ // Scope for lock
Mutex::Autolock lock(mMutex);
if (mStop) {
return false;
}
if (mPeriod == 0) {
err = mCond.wait(mMutex);
//...
continue;
}
/*计算最近的EventThread的时间。
Eventthread发现connection>=0时,
向线程DispSyncThread注册成callback,成为listener
*/
nextEventTime = computeNextEventTimeLocked(now);
targetTime = nextEventTime;
bool isWakeup = false;
if (now < targetTime) {//休眠
err = mCond.waitRelative(mMutex, targetTime - now);
if (err == TIMED_OUT) {
isWakeup = true;
} else if (err != NO_ERROR) {
//...
}
}
now = systemTime(SYSTEM_TIME_MONOTONIC);
if (isWakeup) {
mWakeupLatency = ((mWakeupLatency * 63) +
(now - targetTime)) / 64;
if (mWakeupLatency > 500000) {
// Don't correct by more than 500 us
mWakeupLatency = 500000;
}
}
//手机所有的callback
callbackInvocations = gatherCallbackInvocationsLocked(now);
}
if (callbackInvocations.size() > 0) {
//调用callback
fireCallbackInvocations(callbackInvocations);
}
}
return false;
}
这里fireCallbackInvocations的调用Callback实际上最终调用的就是EventThread-SF的onVSyncEvent,代码如下:
void EventThread::onVSyncEvent(nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = 0;
mVSyncEvent[0].header.timestamp = timestamp;
mVSyncEvent[0].vsync.count++;
mCondition.broadcast();
}
至此EventThread-SF就被DispSyncThread给唤醒了。
2.6 EventThread-SF唤醒SurfaceFlinger
被DispSyncThread线程唤醒后,会执行对应的mCondition.wait,相关代码在waitforEvent中,相关代码如下:
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
Vector< sp<EventThread::Connection> > signalConnections;
//关键点1:等待事件
signalConnections = waitForEvent(&event);
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
// now see if we still need to report this event
//关键点2:post事件
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
//...
} else if (err < 0) {
//...
removeDisplayEventConnection(signalConnections[i]);
}
}
return true;
}
此时waitforEvent结束后,会进入到这个循环,会调用connection的 postEvent方法,继续分析,代码实现如下:
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);
}
前面发送消息后必然会有一个接收端。但接收端直接分析并不容易,我们需要从SF中查找,在SF的init的代码中 ,关注这段代码:
void SurfaceFlinger::init()
{
//...
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);//关键点
//...
}
专门分析mEventQueue.setEventThread(mSFEventThread)的实现,代码如下:
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);
}
这里主要是监听 EventThread是否有数据,专注分析MessageQueue::cb_eventReceiver的实现,代码如下:
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
return queue->eventReceiver(fd, events);
}
这里继续分析queue->eventReceiver,代码实现如下:
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) {
#if INVALIDATE_ON_VSYNC
mHandler->dispatchInvalidate();
#else
mHandler->dispatchRefresh();
#endif
break;
}
}
}
return 1;
}
这里DisplayEventReceiver::getEvents 和 之前的sendEvent操作相对应。即SF 执行init后一直监听事件,如果有的话,则调用
mHandler->dispatchInvalidate()方法。
2.7 处理
void MessageQueue::Handler::dispatchInvalidate() {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
这里实用了handler Message机制,因此直接看handleMessage的处理,如下:
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;
case TRANSACTION:
android_atomic_and(~eventMaskTransaction, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
这里的INVALIDATE对应mQueue.mFlinger->onMessageReceived(message.what)方法的执行,onMessageReceived代码实现如下:
void SurfaceFlinger::onMessageReceived(int32_t what) {
switch (what) {
case MessageQueue::TRANSACTION: {
handleMessageTransaction();
break;
}
case MessageQueue::INVALIDATE: {
//关键语句
bool refreshNeeded = handleMessageTransaction();//1
refreshNeeded |= handleMessageInvalidate();//2
refreshNeeded |= mRepaintEverything;
if (refreshNeeded) {
signalRefresh();//3
}
break;
}
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}
针对INVALIDATE消息,关键执行代码中标识的几句话。第7节我们详细分析这一部分。