Android P 显示流程分析---EventThread MessageQueue 交互分析
Posted Give.Me.Five
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android P 显示流程分析---EventThread MessageQueue 交互分析相关的知识,希望对你有一定的参考价值。
上篇分析SurfaceFlinger的init()里创建了几个线程,主要用于界面刷新。里面涉及了一个EventThread和MessageQueue。我们来看看像界面刷新这种高频的事件通知及处理,Google是如何设计的。
EventThread的初始化
EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
//创建一个线程,实际做事的也是这个线程处理的
mThread = std::thread(&EventThread::threadMain, this);
...
创建connection
其它一些线程需要将事件推给EventThread去处理,需要中间有一个连接者与EventThread交互,EventThread里面就创建出来了一个内部类Connection,负责连接交互的工作
sp<BnDisplayEventConnection> EventThread::createEventConnection() const
return new Connection(const_cast<EventThread*>(this));
class Connection : public BnDisplayEventConnection
public:
virtual status_t postEvent(const DisplayEventReceiver::Event& event);
private:
void requestNextVsync() override;
上篇SurfaceFlinger.init()中实例化一个EventThread之后,就调用了mEventQueue->setEventThread(mSFEventThread.get()),
void MessageQueue::setEventThread(android::EventThread* eventThread)
...
mEventThread = eventThread;
mEvents = eventThread->createEventConnection();
...
sp<BnDisplayEventConnection> EventThread::createEventConnection() const
return new Connection(const_cast<EventThread*>(this));
MessageQueue中的mEvents就是一个connection对象。就是它就将MessageQueue与EventThread连接起来了。
我们再来看看EventHandler 的那个线程启动之后,做了哪些事情:
void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS
std::unique_lock<std::mutex> lock(mMutex);
while (mKeepRunning)
DisplayEventReceiver::Event event;
Vector<sp<EventThread::Connection> > signalConnections;
signalConnections = waitForEventLocked(&lock, &event);
// dispatch events to listeners...
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
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK)
ALOGW("EventThread: dropping event (%08x) for connection %p", event.header.type,conn.get());
else if (err < 0)
removeDisplayEventConnectionLocked(signalConnections[i]);
总体来说是获取事件,将获取到的事件放到BitTube中去,具体的获取事件的waitForEventLocked是如何做的呢?
Vector<sp<EventThread::Connection> > EventThread::waitForEventLocked(
std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* event)
Vector<sp<EventThread::Connection> > signalConnections;
while (signalConnections.isEmpty() && mKeepRunning)
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
if (mInterceptVSyncsCallback)
mInterceptVSyncsCallback(timestamp);
*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;)
sp<Connection> connection(mDisplayEventConnections[i].promote());
if (connection != nullptr)
bool added = false;
if (connection->count >= 0)
// we need vsync events because at least
// one connection is waiting for it
waitForVSync = true;
if (timestamp)
// we consume the event only if it's time
// (ie: we received a vsync event)
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;
...
// note: !timestamp implies signalConnections.isEmpty(), because we
// don't populate signalConnections if there's no vsync pending
if (!timestamp && !eventPending)
// wait for something to happen
if (waitForVSync)
// This is where we spend most of our time, waiting
// for vsync events and new client registrations.
//
// If the screen is off, we can't use h/w vsync, so we
// use a 16ms timeout instead. It doesn't need to be
// precise, we just need to keep feeding our clients.
//
// We don't want to stall if there's a driver bug, so we
// use a (long) timeout when waiting for h/w vsync, and
// generate fake events when necessary.
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
// Nobody is interested in vsync, so we just want to sleep.
// h/w vsync should be disabled, so this will wait until we
// get a new connection, or an existing connection becomes
// interested in receiving vsync again.
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;
waitForEventLocked 就如果vsyncEvent和pendingEvent里已经存在事件,就将其取出指定给event,然后遍历出所有的mDisplayEventConnections, 找且需要的connection, 将他们一一添加到signalConnections中, 如果没有找到需要connection, 就设置mCondition.wait(*lock), 条件加锁等待,直到此条件被唤醒。
我们上面EventThread的threadMain分析到将获取的signalConnections中的connection遍历出来,然后将通过调用 connection的postEvent 将event事件加入到BitTube中。
MessageQueue的作用
surfaceFlinger很多事件都是通过MessageQueue来处理的,SurfaceFlinger里的mEventQueue就是MessageQueue的对象指针。
void SurfaceFlinger::waitForEvent()
mEventQueue->waitMessage();
void SurfaceFlinger::signalTransaction()
mEventQueue->invalidate();
void SurfaceFlinger::signalLayerUpdate()
mEventQueue->invalidate();
void SurfaceFlinger::signalRefresh()
mRefreshPending = true;
mEventQueue->refresh();
void SurfaceFlinger::run()
do
waitForEvent();
while (true);
以上这些都是通过MessageQueue去调用实现的。那我们再具体看看MessageQueue里是如何实现的。
void MessageQueue::invalidate()
mEvents->requestNextVsync();
void EventThread::Connection::requestNextVsync()
mEventThread->requestNextVsync(this);
void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection)
std::lock_guard<std::mutex> lock(mMutex);
if (connection->count < 0)
connection->count = 0;
mCondition.notify_all();
invalidate 主要是为了唤醒waitForEventLocked , 让EventThread继续执行。
void MessageQueue::refresh()
mHandler->dispatchRefresh();
void MessageQueue::Handler::dispatchRefresh()
if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0)
mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
void MessageQueue::Handler::handleMessage(const Message& message)
switch (message.what)
...
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
void SurfaceFlinger::onMessageReceived(int32_t what)
...
case MessageQueue::REFRESH:
handleMessageRefresh();
break;
void SurfaceFlinger::handleMessageRefresh()
ATRACE_CALL();
mRefreshPending = false;
nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
preComposition(refreshStartTime);
rebuildLayerStacks();
setUpHWComposer();
doDebugFlashRegions();
doTracing("handleRefresh");
logLayerStats();
doComposition();
postComposition(refreshStartTime);
mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
mHadClientComposition = false;
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId)
const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
mHadClientComposition = mHadClientComposition ||
getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
mVsyncModulator.onRefreshed(mHadClientComposition);
mLayersWithQueuedFrames.clear();
最后调用到了SurfaceFlinger的handleMessageRefresh(), 里面涉及到图层的合成了。
到这里EventThread和MessageQueue就分析完了。
以上是关于Android P 显示流程分析---EventThread MessageQueue 交互分析的主要内容,如果未能解决你的问题,请参考以下文章
Android P 显示流程---Display设备初始化过程分析
Android P 显示流程分析---EventThread MessageQueue 交互分析
Android P 显示流程分析--- buffer的生产消费者模式