在这篇博文将会和大家一起分享我所学到的一点SurfaceFlinger中的事件和消息处理机制。
在前面的博文中,可以发现在SurfaceFlinger中的OnFirstRef里面有如下函数:
- void SurfaceFlinger::onFirstRef()
- {
- mEventQueue.init(this);
- run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);//启动一个新的thread线程,调用thread类的run函数
- // Wait for the main thread to be done with its initialization
- mReadyToRunBarrier.wait();//等待线程完成相关的初始化
- }
step1: mEventQueue.init(),事件队列MessageQueue初始化
- void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
- {
- mFlinger = flinger;
- mLooper = new Looper(true);//新建一个消息队列,其内部为建立一个epoll的pipe
- mHandler = new Handler(*this);//新建消息处理句柄
- }
这里看到了两个类Looper和Handler,听说这两个类一般是用来构成消息处理机制,下面就看看他的复杂性吧。
step2:Looper对象的新建
- {
- int wakeFds[2];
- int result = pipe(wakeFds);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno);
- mWakeReadPipeFd = wakeFds[0];
- mWakeWritePipeFd = wakeFds[1];//新建管道,2个fd描述符
- result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d",
- errno);
- result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d",
- errno);
- // Allocate the epoll instance and register the wake pipe.
- mEpollFd = epoll_create(EPOLL_SIZE_HINT);//epoll关注EPOLL_SIZE_HINT的文件数
- LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
- struct epoll_event eventItem;
- memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
- eventItem.events = EPOLLIN;
- eventItem.data.fd = mWakeReadPipeFd;//监听可读管道mWakeReadPipeFd
- result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);//注册上述的信息,用于epoll_wait
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d",
- errno);
- }
上述代码分别完成了新建一个管道pipe,使用epoll_create和epoll_ctrl来完成对读管道的监听,看是否有数据写入写管道。
step3:在SF新启动线程的readyToRun里面有mEventThread = new EventThread(this);//新建一个事件线程用于创建event的消息,处理VSYC同步事件。
EventThread这里姑且理解为事件线程,他继承了thread类,故会启动一个新的线程,先走完当前线程函数。主要用于处理VSYC的同步事件
- EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
- : mFlinger(flinger),
- mUseSoftwareVSync(false),
- mDebugVsyncEnabled(false) {
- for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {
- mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- mVSyncEvent[i].header.id = 0;
- mVSyncEvent[i].header.timestamp = 0;
- mVSyncEvent[i].vsync.count = 0;//初始化同步事件
- }
- }
复杂的地方在这里:
- void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
- {
- mEventThread = eventThread;
- mEvents = eventThread->createEventConnection();//建立连接
- mEventTube = mEvents->getDataChannel();
- mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
- MessageQueue::cb_eventReceiver, this);// return mReceiveFd;,cb_eventReceiver
- }
分解为一下几步:
1.new Connecton,connection是eventthread的内部类。
- sp<EventThread::Connection> EventThread::createEventConnection() const {
- return new Connection(const_cast<EventThread*>(this));
- }
- EventThread::Connection::Connection(
- const sp<EventThread>& eventThread)
- : count(-1), mEventThread(eventThread), mChannel(new BitTube())
- {
- }
2. new BitTube()本质就是新建了一个Socket本地进程间通信,socketpair即可用读也可以写,其中socket[0]作为了用于读取数据,socket[1]作为用于写入数据
- BitTube::BitTube()
- : mSendFd(-1), mReceiveFd(-1)
- {
- int sockets[2];
- if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {//unix本地套接字
- int size = SOCKET_BUFFER_SIZE;
- setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
- setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
- setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
- setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
- fcntl(sockets[0], F_SETFL, O_NONBLOCK);
- fcntl(sockets[1], F_SETFL, O_NONBLOCK);
- mReceiveFd = sockets[0];
- mSendFd = sockets[1];
- } else {
- mReceiveFd = -errno;
- ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
- }
- }
3.获取mChannel变量属于BitTube类
- mEventTube = mEvents->getDataChannel();
4.将不同的文件描述符添加到mLooper中
- int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) {
- return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);//建立回调函数
- }
fd = mEventTube->getFd(),返回的是之前的mReceived(Socket[0])接收管道。events: ALOOPER_EVENT_INPUT
callback: MessageQueue::cb_eventReceiver回调函数,这里会新的建立一个SimpleLooperCallback对象
继续add调用会将fd加入到epoll轮询里面,同时所有的信息都会添加到一个Request结构体里面,最终将request信息维护到成员mRequests中去。
- Request request;
- request.fd = fd;
- request.ident = ident;
- request.callback = callback;
- request.data = data;
- struct epoll_event eventItem;
- memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
- eventItem.events = epollEvents;
- eventItem.data.fd = fd;
- ssize_t requestIndex = mRequests.indexOfKey(fd);
- if (requestIndex < 0) {//新的句柄
- int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);//设置epoll参数,添加fd注册
- if (epollResult < 0) {
- ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno);
- return -1;
- }
- mRequests.add(fd, request);
step4:SF新线程进入threadloop
- bool SurfaceFlinger::threadLoop() {
- waitForEvent();//一个新的线程在等待事件消息
- return true;
- }
- void SurfaceFlinger::waitForEvent() {
- mEventQueue.waitMessage();
- }
依次调用流程:mLooper->pollOnce,Looper::pollAll, Looper::pollInner(int timeoutMillis)为止一直处于循环检测状态,消息的监听与处理都是在这里进行的,下面对该函数进行深入分析。
- int Looper::pollInner(int timeoutMillis) {
- #if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
- #endif
- // Adjust the timeout based on when the next message is due.
- if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
- if (messageTimeoutMillis >= 0
- && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
- timeoutMillis = messageTimeoutMillis;
- }
- #if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
- this, mNextMessageUptime - now, timeoutMillis);
- #endif
- }
- // Poll.
- int result = ALOOPER_POLL_WAKE;
- mResponses.clear();
- mResponseIndex = 0;
- struct epoll_event eventItems[EPOLL_MAX_EVENTS];
- int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);//epoll等待
- // Acquire lock.
- mLock.lock();
- // Check for poll error.
- if (eventCount < 0) {
- if (errno == EINTR) {
- goto Done;
- }
- ALOGW("Poll failed with an unexpected error, errno=%d", errno);
- result = ALOOPER_POLL_ERROR;
- goto Done;
- }
- // Check for poll timeout.
- if (eventCount == 0) {
- #if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - timeout", this);
- #endif
- result = ALOOPER_POLL_TIMEOUT;
- goto Done;
- }
- // Handle all events.
- #if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
- #endif
- for (int i = 0; i < eventCount; i++) {
- int fd = eventItems[i].data.fd;
- uint32_t epollEvents = eventItems[i].events;
- if (fd == mWakeReadPipeFd) {//只是简单的wake,一般是消息发出
- if (epollEvents & EPOLLIN) {
- awoken();
- } else {
- ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
- }
- } else {
- ssize_t requestIndex = mRequests.indexOfKey(fd);//事件
- if (requestIndex >= 0) {
- int events = 0;
- if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
- if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
- if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
- if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
- pushResponse(events, mRequests.valueAt(requestIndex));//相关请求写入mResponses里面进行请求的处理
- } else {
- ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
- "no longer registered.", epollEvents, fd);
- }
- }
- }
- Done: ;
- // Invoke pending message callbacks.消息的handle处理
- mNextMessageUptime = LLONG_MAX;
- while (mMessageEnvelopes.size() != 0) {//消息包络组里面有信息
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);//提取一个消息包
- if (messageEnvelope.uptime <= now) {
- // Remove the envelope from the list.
- // We keep a strong reference to the handler until the call to handleMessage
- // finishes. Then we drop it so that the handler can be deleted *before*
- // we reacquire our lock.
- { // obtain handler
- sp<MessageHandler> handler = messageEnvelope.handler;
- Message message = messageEnvelope.message;
- mMessageEnvelopes.removeAt(0);
- mSendingMessage = true;
- mLock.unlock();
- #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
- ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
- this, handler.get(), message.what);
- #endif
- handler->handleMessage(message);//MessageHandler消息的handle处理
- } // release handler
- mLock.lock();
- mSendingMessage = false;
- result = ALOOPER_POLL_CALLBACK;
- } else {
- // The last message left at the head of the queue determines the next wakeup time.
- mNextMessageUptime = messageEnvelope.uptime;
- break;
- }
- }
- // Release lock.
- mLock.unlock();
- // Invoke all response callbacks.,处理请求的回调函数
- for (size_t i = 0; i < mResponses.size(); i++) {
- Response& response = mResponses.editItemAt(i);
- if (response.request.ident == ALOOPER_POLL_CALLBACK) {
- int fd = response.request.fd;
- int events = response.events;
- void* data = response.request.data;
- #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
- ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
- this, response.request.callback.get(), fd, events, data);
- #endif
- int callbackResult = response.request.callback->handleEvent(fd, events, data);//调用addfd的回调函数ALooper_callbackFunc
- if (callbackResult == 0) {
- removeFd(fd);
- }
- // Clear the callback reference in the response structure promptly because we
- // will not clear the response vector itself until the next poll.
- response.request.callback.clear();
- result = ALOOPER_POLL_CALLBACK;
- }
- }
- return result;
- }
- int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
- if (timeoutMillis <= 0) {
- int result;
- do {
- result = pollOnce(timeoutMillis, outFd, outEvents, outData);
- } while (result == ALOOPER_POLL_CALLBACK);
- return result;
- } else {
- nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
- + milliseconds_to_nanoseconds(timeoutMillis);
- for (;;) {
- int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
- if (result != ALOOPER_POLL_CALLBACK) {
- return result;
- }
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
- if (timeoutMillis == 0) {
- return ALOOPER_POLL_TIMEOUT;
- }
- }
- }
- }
1.epoll_wait进入轮询等待有数据可以读取。
2.epoll_wait等打有eventcount产生,开始对其节进行解析,假设现在epoll检测到了数据,则继续执行
3.前面可以知道epoll检测的文件描述符包括Pipe产生的mWakeReadPipeFd,双工通信socketpair的mReceived两个。
4、那么在哪来会触发后者呢,我们要回归到eventthread的threadloop函数,这里是在检测底层硬件的VSYC信号,先来看看他的实现
- bool EventThread::threadLoop() {
- DisplayEventReceiver::Event event;
- Vector< sp<EventThread::Connection> > signalConnections;
- signalConnections = waitForEvent(&event);//轮询等待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) {
- // 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.
- removeDisplayEventConnection(signalConnections[i]);
- }
- }
- return true;
- }
首先是要waitForEvent进入事件循环检测,在收到事件信号后,就是对连接信号的解析,这里是获取eventthread内部类Connection来进行事件的传递。依次调用如下:
DisplayEventReceiver::sendEvents(mChannel, &event, 1)——>BitTube::sendObjects(dataChannel, events, count);回到了前面的socket管道通信中来了,继续看
DisplayEventReceiver::sendEvents(mChannel, &event, 1)DisplayEventReceiver::sendEvents
- ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
- void const* events, size_t count, size_t objSize)
- {
- ssize_t numObjects = 0;
- for (size_t i=0 ; i<count ; i++) {
- const char* vaddr = reinterpret_cast<const char*>(events) + objSize * i;
- ssize_t size = tube->write(vaddr, objSize);
- if (size < 0) {
- // error occurred
- return size;
- } else if (size == 0) {
- // no more space
- break;
- }
- numObjects++;
- }
- return numObjects;
- }
这里是将Vsync这个evnet变量进行打包,多个event的话还需要循环进行,然后调用write函数:
- ssize_t BitTube::write(void const* vaddr, size_t size)
- {
- ssize_t err, len;
- do {
- len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
- err = len < 0 ? errno : 0;
- } while (err == EINTR);
- return err == 0 ? len : -err;
- }
很清楚的是调用了socket专属的send函数,而这里的fd正是mSendFd,而epoll_wait那里等待就是mRecieved的读管道口。这样就可以通过进程间通信,触发我们的SF的2号线程epoll_wait进行处理。
下面我们继续回到Looper::pollInner这个复杂的函数内部,在epoll_wait执行之后,主要是先对message进行业务的处理,然后才是对应的event的事件回调。
- if (requestIndex >= 0) {
- int events = 0;
- if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
- if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
- if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
- if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
- pushResponse(events, mRequests.valueAt(requestIndex))
上述代码完成的是将epoll的事件类型转为ALOOPER自身的类型,这里是事件输入。pushResponse主要是将mRequests中的事件请求从Looper维护的内存里面提取出来,requestIndex = mRequests.indexOfKey(fd)可以看到,这个请求的索引值是通过当前的fd来提取的,而之前保存的时候正是通过fd来关联的。
- void Looper::pushResponse(int events, const Request& request) {
- Response response;
- response.events = events;
- response.request = request;
- mResponses.push(response);
- }
mResponses里面存储着events,request等信息,主要在下面对回调解析时使用。
- // Invoke all response callbacks.,处理请求的回调函数
- for (size_t i = 0; i < mResponses.size(); i++) {
- Response& response = mResponses.editItemAt(i);
- if (response.request.ident == ALOOPER_POLL_CALLBACK) {
- int fd = response.request.fd;
- int events = response.events;
- void* data = response.request.data;
- #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
- ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
- this, response.request.callback.get(), fd, events, data);
- #endif
- int callbackResult = response.request.callback->handleEvent(fd, events, data);//调用addfd的回调函数ALooper_callbackFunc
- if (callbackResult == 0) {
- removeFd(fd);
- }
- // Clear the callback reference in the response structure promptly because we
- // will not clear the response vector itself until the next poll.
- response.request.callback.clear();
- result = ALOOPER_POLL_CALLBACK;
- }
- }
在前面addFd处,将SF的EventThread新建的BitTube添加到了mLooper里面,当时的fd设置的request的ident就是ALOOPER_POLL_CALLBACK。接着取出响应response的信息,开始进行准备回调handleEvent().那么这个callback是什么呢?还是要回到addfd里面,可以看到request.callback = callback;这样可以定位到mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,MessageQueue::cb_eventReceiver, this); 故这里的callback MessageQueue的成员函数cb_eventReceiver,但是他是作为new SimpleLooperCallback(callback)初始化到了一个SimpleLoopeCallback对象中,而该类继承了LooperCallback这个基类,也就是说callback->handleEvent()也就是调用派生类SimpleLooperCallback的handleEvent(),如下:
- int SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
- return mCallback(fd, events, data);
- }
的确,mCallBack才是ALooper_callbackFunc这个函数指针,当初是赋值为了cb_eventReceiver,故回调该函数。
- int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
- MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
- return queue->eventReceiver(fd, events);
- }
而上面的data一就是MessageQueue::setEventThread时传入的this即SurfaceFlinger的mMessageQueue成员,现在开始执行事件的接收,其实就是开始做消息的发送了,也就是进入消息处理机制。
- 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;
- }
getevents最终是调用recv来获得基于Unix域单连接的socket端发send过来的数据,判断数据的类型是不是显示帧同步事件,可以很容易的看到在EventThread的waitevent中的event事件结构体初始化:
- for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {
- mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- mVSyncEvent[i].header.id = 0;
- mVSyncEvent[i].header.timestamp = 0;
- mVSyncEvent[i].vsync.count = 0;//初始化同步事件
- }
故直接进入mHandler->dispatchRefresh()函数,
- void MessageQueue::Handler::dispatchRefresh() {
- if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
- }
- }
- void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- sendMessageAtTime(now, handler, message); //及时发送消息
- }
- void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
- const Message& message) {
- #if DEBUG_CALLBACKS
- ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d",
- this, uptime, handler.get(), message.what);
- #endif
- size_t i = 0;
- { // acquire lock
- AutoMutex _l(mLock);
- size_t messageCount = mMessageEnvelopes.size();
- while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
- i += 1;
- }
- MessageEnvelope messageEnvelope(uptime, handler, message);
- mMessageEnvelopes.insertAt(messageEnvelope, i, 1);//加入消息包到loop中去
- // Optimization: If the Looper is currently sending a message, then we can skip
- // the call to wake() because the next thing the Looper will do after processing
- // messages is to decide when the next wakeup time should be. In fact, it does
- // not even matter whether this code is running on the Looper thread.
- if (mSendingMessage) {
- return;
- }
- } // release lock
- // Wake the poll loop only when we enqueue a new message at the head.
- if (i == 0) {
- wake();//在消息队列头检测到有一个新的消息后唤醒
- }
- }
。sendMessageAtTime这里理解为及时发送消息,那消息是以什么形式存在的呢?其实可以注意到Message message传入的类型为Refresh。 size_t messageCount = mMessageEnvelopes.size();来获取Looper中所存在的消息包的个数,可以看到如果之前looper还有消息没有处理,那么i+=1,直到当前消息放在最后,实现的代码如下,将消息加入到了mMessageEnvelops中去了。
MessageEnvelope messageEnvelope(uptime, handler, message);
mMessageEnvelopes.insertAt(messageEnvelope, i, 1);//加入消息包到loop中去
那么怎么触发消息的处理呢,如果只有当前的一个消息,直接wake()之前的pollInner内的epoll_wai函数,做消息的处理,接着就看pollInner内的消息处理机制吧:
- // Invoke pending message callbacks.消息的handle处理
- mNextMessageUptime = LLONG_MAX;
- while (mMessageEnvelopes.size() != 0) {//消息包络组里面有信息
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);//提取一个消息包
- if (messageEnvelope.uptime <= now) {
- // Remove the envelope from the list.
- // We keep a strong reference to the handler until the call to handleMessage
- // finishes. Then we drop it so that the handler can be deleted *before*
- // we reacquire our lock.
- { // obtain handler
- sp<MessageHandler> handler = messageEnvelope.handler;
- Message message = messageEnvelope.message;
- mMessageEnvelopes.removeAt(0);
- mSendingMessage = true;
- mLock.unlock();
- #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
- ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
- this, handler.get(), message.what);
- #endif
- handler->handleMessage(message);//MessageHandler消息的handle处理
- } // release handler
- mLock.lock();
- mSendingMessage = false;
- result = ALOOPER_POLL_CALLBACK;
- } else {
- // The last message left at the head of the queue determines the next wakeup time.
- mNextMessageUptime = messageEnvelope.uptime;
- break;
- }
- }
核心的过程解析messageEnvelope消息包,取出对应的消息以及消息处理的handle,进行处理,那么立即的handle是什么呢?回归到mHandler->dispatchRefresh()——》MessageQueue::Handler::dispatchRefresh()里面可以看到 mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));,这个handle就是mHandle啦,故来看MessageQueue的内部Handle的成员函数handleMessage,很高兴的是,果然与之前设置的message.what结合在一起了。最终把消息的处理权还是提交给了mFlinger
- 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;
- }
- }
onMessageReceived——>handleMessageRefresh处理屏幕刷新这个消息,主要调用composer来完成。
- void SurfaceFlinger::handleMessageRefresh() {//处理layer的刷新,实际是调用SF绘图
- ATRACE_CALL();
- preComposition();
- rebuildLayerStacks();
- setUpHWComposer();
- doDebugFlashRegions();
- doComposition();
- postComposition();
- }
通过以上内容就走完了Surface的屏幕刷新事件提交以及事件处理,消息触发,以及消息的处理。最终还是回归到SurfaceFlinger来完成最终的消息处理。本文最终将SF的消息和事件处理机制总结成以下的流程图,加速理解。蓝色核心框图是SurfaceFlinger的主要业务和服务的处理线程。