Android4.2.2 SurfaceFlinger的相关事件和消息处理机制

来源:互联网 发布:js排序 编辑:程序博客网 时间:2024/05/21 21:35

Android4.2.2 SurfaceFlinger的相关事件和消息处理机制


在这篇博文将会和大家一起分享我所学到的一点SurfaceFlinger中的事件和消息处理机制。

 

在前面的博文中,可以发现在SurfaceFlinger中的OnFirstRef里面有如下函数:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void SurfaceFlinger::onFirstRef()  
  2. {  
  3.     mEventQueue.init(this);  
  4.   
  5.     run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);//启动一个新的thread线程,调用thread类的run函数  
  6.   
  7.     // Wait for the main thread to be done with its initialization  
  8.     mReadyToRunBarrier.wait();//等待线程完成相关的初始化  
  9. }  

 

step1: mEventQueue.init(),事件队列MessageQueue初始化

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void MessageQueue::init(const sp<SurfaceFlinger>& flinger)  
  2. {  
  3.     mFlinger = flinger;  
  4.     mLooper = new Looper(true);//新建一个消息队列,其内部为建立一个epoll的pipe  
  5.     mHandler = new Handler(*this);//新建消息处理句柄  
  6. }  

这里看到了两个类Looper和Handler,听说这两个类一般是用来构成消息处理机制,下面就看看他的复杂性吧。

 

step2:Looper对象的新建

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. {  
  2.     int wakeFds[2];  
  3.     int result = pipe(wakeFds);  
  4.     LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);  
  5.   
  6.     mWakeReadPipeFd = wakeFds[0];  
  7.     mWakeWritePipeFd = wakeFds[1];//新建管道,2个fd描述符  
  8.   
  9.     result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);  
  10.     LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",  
  11.             errno);  
  12.   
  13.     result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);  
  14.     LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",  
  15.             errno);  
  16.   
  17.     // Allocate the epoll instance and register the wake pipe.  
  18.     mEpollFd = epoll_create(EPOLL_SIZE_HINT);//epoll关注EPOLL_SIZE_HINT的文件数  
  19.     LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);  
  20.   
  21.     struct epoll_event eventItem;  
  22.     memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union  
  23.     eventItem.events = EPOLLIN;  
  24.     eventItem.data.fd = mWakeReadPipeFd;//监听可读管道mWakeReadPipeFd  
  25.     result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);//注册上述的信息,用于epoll_wait  
  26.     LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",  
  27.             errno);  
  28. }  

上述代码分别完成了新建一个管道pipe,使用epoll_create和epoll_ctrl来完成对读管道的监听,看是否有数据写入写管道。

 

step3:在SF新启动线程的readyToRun里面有mEventThread = new EventThread(this);//新建一个事件线程用于创建event的消息,处理VSYC同步事件。

EventThread这里姑且理解为事件线程,他继承了thread类,故会启动一个新的线程,先走完当前线程函数。主要用于处理VSYC的同步事件

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. EventThread::EventThread(const sp<SurfaceFlinger>& flinger)  
  2.     : mFlinger(flinger),  
  3.       mUseSoftwareVSync(false),  
  4.       mDebugVsyncEnabled(false) {  
  5.   
  6.     for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {  
  7.         mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;  
  8.         mVSyncEvent[i].header.id = 0;  
  9.         mVSyncEvent[i].header.timestamp = 0;  
  10.         mVSyncEvent[i].vsync.count =  0;//初始化同步事件  
  11.     }  
  12. }  

复杂的地方在这里:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void MessageQueue::setEventThread(const sp<EventThread>& eventThread)  
  2. {  
  3.     mEventThread = eventThread;  
  4.     mEvents = eventThread->createEventConnection();//建立连接  
  5.     mEventTube = mEvents->getDataChannel();  
  6.     mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,  
  7.             MessageQueue::cb_eventReceiver, this);//   return mReceiveFd;,cb_eventReceiver  
  8. }  

分解为一下几步:

1.new Connecton,connection是eventthread的内部类。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. sp<EventThread::Connection> EventThread::createEventConnection() const {  
  2.     return new Connection(const_cast<EventThread*>(this));  
  3. }  
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. EventThread::Connection::Connection(  
  2.         const sp<EventThread>& eventThread)  
  3.     : count(-1), mEventThread(eventThread), mChannel(new BitTube())  
  4. {  
  5. }  

 

2. new BitTube()本质就是新建了一个Socket本地进程间通信,socketpair即可用读也可以写,其中socket[0]作为了用于读取数据,socket[1]作为用于写入数据

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. BitTube::BitTube()  
  2.     : mSendFd(-1), mReceiveFd(-1)  
  3. {  
  4.     int sockets[2];  
  5.     if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {//unix本地套接字  
  6.         int size = SOCKET_BUFFER_SIZE;  
  7.         setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));  
  8.         setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));  
  9.         setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));  
  10.         setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));  
  11.         fcntl(sockets[0], F_SETFL, O_NONBLOCK);  
  12.         fcntl(sockets[1], F_SETFL, O_NONBLOCK);  
  13.         mReceiveFd = sockets[0];  
  14.         mSendFd = sockets[1];  
  15.     } else {  
  16.         mReceiveFd = -errno;  
  17.         ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));  
  18.     }  
  19. }  


 3.获取mChannel变量属于BitTube类

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. mEventTube = mEvents->getDataChannel();  

 

4.将不同的文件描述符添加到mLooper中

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) {  
  2.     return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);//建立回调函数  
  3. }  

fd = mEventTube->getFd(),返回的是之前的mReceived(Socket[0])接收管道。events: ALOOPER_EVENT_INPUT
callback: MessageQueue::cb_eventReceiver回调函数,这里会新的建立一个SimpleLooperCallback对象

继续add调用会将fd加入到epoll轮询里面,同时所有的信息都会添加到一个Request结构体里面,最终将request信息维护到成员mRequests中去。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. Request request;  
  2. request.fd = fd;  
  3. request.ident = ident;  
  4. request.callback = callback;  
  5. request.data = data;  
  6.   
  7. struct epoll_event eventItem;  
  8. memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union  
  9. eventItem.events = epollEvents;  
  10. eventItem.data.fd = fd;  
  11.   
  12. ssize_t requestIndex = mRequests.indexOfKey(fd);  
  13. if (requestIndex < 0) {//新的句柄  
  14.     int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);//设置epoll参数,添加fd注册  
  15.     if (epollResult < 0) {  
  16.         ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno);  
  17.         return -1;  
  18.     }  
  19.     mRequests.add(fd, request);  


 step4:SF新线程进入threadloop

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. bool SurfaceFlinger::threadLoop() {  
  2.     waitForEvent();//一个新的线程在等待事件消息  
  3.     return true;  
  4. }  
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void SurfaceFlinger::waitForEvent() {  
  2.     mEventQueue.waitMessage();  
  3. }  

依次调用流程:mLooper->pollOnce,Looper::pollAll, Looper::pollInner(int timeoutMillis)为止一直处于循环检测状态,消息的监听与处理都是在这里进行的,下面对该函数进行深入分析。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int Looper::pollInner(int timeoutMillis) {  
  2. #if DEBUG_POLL_AND_WAKE  
  3.     ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d"this, timeoutMillis);  
  4. #endif  
  5.   
  6.     // Adjust the timeout based on when the next message is due.  
  7.     if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {  
  8.         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  
  9.         int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);  
  10.         if (messageTimeoutMillis >= 0  
  11.                 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {  
  12.             timeoutMillis = messageTimeoutMillis;  
  13.         }  
  14. #if DEBUG_POLL_AND_WAKE  
  15.         ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",  
  16.                 this, mNextMessageUptime - now, timeoutMillis);  
  17. #endif  
  18.     }  
  19.   
  20.     // Poll.  
  21.     int result = ALOOPER_POLL_WAKE;  
  22.     mResponses.clear();  
  23.     mResponseIndex = 0;  
  24.   
  25.     struct epoll_event eventItems[EPOLL_MAX_EVENTS];  
  26.     int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);//epoll等待  
  27.   
  28.     // Acquire lock.  
  29.     mLock.lock();  
  30.   
  31.     // Check for poll error.  
  32.     if (eventCount < 0) {  
  33.         if (errno == EINTR) {  
  34.             goto Done;  
  35.         }  
  36.         ALOGW("Poll failed with an unexpected error, errno=%d", errno);  
  37.         result = ALOOPER_POLL_ERROR;  
  38.         goto Done;  
  39.     }  
  40.   
  41.     // Check for poll timeout.  
  42.     if (eventCount == 0) {  
  43. #if DEBUG_POLL_AND_WAKE  
  44.         ALOGD("%p ~ pollOnce - timeout"this);  
  45. #endif  
  46.         result = ALOOPER_POLL_TIMEOUT;  
  47.         goto Done;  
  48.     }  
  49.   
  50.     // Handle all events.  
  51. #if DEBUG_POLL_AND_WAKE  
  52.     ALOGD("%p ~ pollOnce - handling events from %d fds"this, eventCount);  
  53. #endif  
  54.   
  55.     for (int i = 0; i < eventCount; i++) {  
  56.         int fd = eventItems[i].data.fd;  
  57.         uint32_t epollEvents = eventItems[i].events;  
  58.         if (fd == mWakeReadPipeFd) {//只是简单的wake,一般是消息发出  
  59.             if (epollEvents & EPOLLIN) {  
  60.                 awoken();  
  61.             } else {  
  62.                 ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);  
  63.             }  
  64.         } else {  
  65.             ssize_t requestIndex = mRequests.indexOfKey(fd);//事件  
  66.             if (requestIndex >= 0) {  
  67.                 int events = 0;  
  68.                 if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;  
  69.                 if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;  
  70.                 if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;  
  71.                 if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;  
  72.                 pushResponse(events, mRequests.valueAt(requestIndex));//相关请求写入mResponses里面进行请求的处理  
  73.             } else {  
  74.                 ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "  
  75.                         "no longer registered.", epollEvents, fd);  
  76.             }  
  77.         }  
  78.     }  
  79. Done: ;  
  80.   
  81.     // Invoke pending message callbacks.消息的handle处理  
  82.     mNextMessageUptime = LLONG_MAX;  
  83.     while (mMessageEnvelopes.size() != 0) {//消息包络组里面有信息  
  84.         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  
  85.         const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);//提取一个消息包  
  86.         if (messageEnvelope.uptime <= now) {  
  87.             // Remove the envelope from the list.  
  88.             // We keep a strong reference to the handler until the call to handleMessage  
  89.             // finishes.  Then we drop it so that the handler can be deleted *before*  
  90.             // we reacquire our lock.  
  91.             { // obtain handler  
  92.                 sp<MessageHandler> handler = messageEnvelope.handler;  
  93.                 Message message = messageEnvelope.message;  
  94.                 mMessageEnvelopes.removeAt(0);  
  95.                 mSendingMessage = true;  
  96.                 mLock.unlock();  
  97.   
  98. #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS  
  99.                 ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",  
  100.                         this, handler.get(), message.what);  
  101. #endif  
  102.                 handler->handleMessage(message);//MessageHandler消息的handle处理  
  103.             } // release handler  
  104.   
  105.             mLock.lock();  
  106.             mSendingMessage = false;  
  107.             result = ALOOPER_POLL_CALLBACK;  
  108.         } else {  
  109.             // The last message left at the head of the queue determines the next wakeup time.  
  110.             mNextMessageUptime = messageEnvelope.uptime;  
  111.             break;  
  112.         }  
  113.     }  
  114.   
  115.     // Release lock.  
  116.     mLock.unlock();  
  117.   
  118.     // Invoke all response callbacks.,处理请求的回调函数  
  119.     for (size_t i = 0; i < mResponses.size(); i++) {  
  120.         Response& response = mResponses.editItemAt(i);  
  121.         if (response.request.ident == ALOOPER_POLL_CALLBACK) {  
  122.             int fd = response.request.fd;  
  123.             int events = response.events;  
  124.             void* data = response.request.data;  
  125. #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS  
  126.             ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",  
  127.                     this, response.request.callback.get(), fd, events, data);  
  128. #endif  
  129.             int callbackResult = response.request.callback->handleEvent(fd, events, data);//调用addfd的回调函数ALooper_callbackFunc  
  130.             if (callbackResult == 0) {  
  131.                 removeFd(fd);  
  132.             }  
  133.             // Clear the callback reference in the response structure promptly because we  
  134.             // will not clear the response vector itself until the next poll.  
  135.             response.request.callback.clear();  
  136.             result = ALOOPER_POLL_CALLBACK;  
  137.         }  
  138.     }  
  139.     return result;  
  140. }  
  141.   
  142. int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {  
  143.     if (timeoutMillis <= 0) {  
  144.         int result;  
  145.         do {  
  146.             result = pollOnce(timeoutMillis, outFd, outEvents, outData);  
  147.         } while (result == ALOOPER_POLL_CALLBACK);  
  148.         return result;  
  149.     } else {  
  150.         nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)  
  151.                 + milliseconds_to_nanoseconds(timeoutMillis);  
  152.   
  153.         for (;;) {  
  154.             int result = pollOnce(timeoutMillis, outFd, outEvents, outData);  
  155.             if (result != ALOOPER_POLL_CALLBACK) {  
  156.                 return result;  
  157.             }  
  158.   
  159.             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  
  160.             timeoutMillis = toMillisecondTimeoutDelay(now, endTime);  
  161.             if (timeoutMillis == 0) {  
  162.                 return ALOOPER_POLL_TIMEOUT;  
  163.             }  
  164.         }  
  165.     }  
  166. }  

1.epoll_wait进入轮询等待有数据可以读取。

2.epoll_wait等打有eventcount产生,开始对其节进行解析,假设现在epoll检测到了数据,则继续执行

3.前面可以知道epoll检测的文件描述符包括Pipe产生的mWakeReadPipeFd,双工通信socketpair的mReceived两个。

4、那么在哪来会触发后者呢,我们要回归到eventthread的threadloop函数,这里是在检测底层硬件的VSYC信号,先来看看他的实现

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. bool EventThread::threadLoop() {  
  2.     DisplayEventReceiver::Event event;  
  3.     Vector< sp<EventThread::Connection> > signalConnections;  
  4.     signalConnections = waitForEvent(&event);//轮询等待event的发生,一般是硬件的请求  
  5.   
  6.     // dispatch events to listeners...  
  7.     const size_t count = signalConnections.size();  
  8.     for (size_t i=0 ; i<count ; i++) {  
  9.         const sp<Connection>& conn(signalConnections[i]);  
  10.         // now see if we still need to report this event  
  11.         status_t err = conn->postEvent(event);//发送事件,一般的硬件触发了事件的发生  
  12.         if (err == -EAGAIN || err == -EWOULDBLOCK) {  
  13.             // The destination doesn't accept events anymore, it's probably  
  14.             // full. For now, we just drop the events on the floor.  
  15.             // FIXME: Note that some events cannot be dropped and would have  
  16.             // to be re-sent later.  
  17.             // Right-now we don't have the ability to do this.  
  18.             ALOGW("EventThread: dropping event (%08x) for connection %p",  
  19.                     event.header.type, conn.get());  
  20.         } else if (err < 0) {  
  21.             // handle any other error on the pipe as fatal. the only  
  22.             // reasonable thing to do is to clean-up this connection.  
  23.             // The most common error we'll get here is -EPIPE.  
  24.             removeDisplayEventConnection(signalConnections[i]);  
  25.         }  
  26.     }  
  27.     return true;  
  28. }  

首先是要waitForEvent进入事件循环检测,在收到事件信号后,就是对连接信号的解析,这里是获取eventthread内部类Connection来进行事件的传递。依次调用如下:

DisplayEventReceiver::sendEvents(mChannel, &event, 1)——>BitTube::sendObjects(dataChannel, events, count);回到了前面的socket管道通信中来了,继续看
DisplayEventReceiver::sendEvents(mChannel, &event, 1)DisplayEventReceiver::sendEvents

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ssize_t BitTube::sendObjects(const sp<BitTube>& tube,  
  2.         void const* events, size_t count, size_t objSize)  
  3. {  
  4.     ssize_t numObjects = 0;  
  5.     for (size_t i=0 ; i<count ; i++) {  
  6.         const char* vaddr = reinterpret_cast<const char*>(events) + objSize * i;  
  7.         ssize_t size = tube->write(vaddr, objSize);  
  8.         if (size < 0) {  
  9.             // error occurred  
  10.             return size;  
  11.         } else if (size == 0) {  
  12.             // no more space  
  13.             break;  
  14.         }  
  15.         numObjects++;  
  16.     }  
  17.     return numObjects;  
  18. }  

这里是将Vsync这个evnet变量进行打包,多个event的话还需要循环进行,然后调用write函数:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ssize_t BitTube::write(void const* vaddr, size_t size)  
  2. {  
  3.     ssize_t err, len;  
  4.     do {  
  5.         len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);  
  6.         err = len < 0 ? errno : 0;  
  7.     } while (err == EINTR);  
  8.     return err == 0 ? len : -err;  
  9.   
  10. }  

很清楚的是调用了socket专属的send函数,而这里的fd正是mSendFd,而epoll_wait那里等待就是mRecieved的读管道口。这样就可以通过进程间通信,触发我们的SF的2号线程epoll_wait进行处理。

下面我们继续回到Looper::pollInner这个复杂的函数内部,在epoll_wait执行之后,主要是先对message进行业务的处理,然后才是对应的event的事件回调。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. if (requestIndex >= 0) {  
  2.                int events = 0;  
  3.                if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;  
  4.                if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;  
  5.                if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;  
  6.                if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;  
  7.                pushResponse(events, mRequests.valueAt(requestIndex))  

上述代码完成的是将epoll的事件类型转为ALOOPER自身的类型,这里是事件输入。pushResponse主要是将mRequests中的事件请求从Looper维护的内存里面提取出来,requestIndex = mRequests.indexOfKey(fd)可以看到,这个请求的索引值是通过当前的fd来提取的,而之前保存的时候正是通过fd来关联的。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void Looper::pushResponse(int events, const Request& request) {  
  2.     Response response;  
  3.     response.events = events;  
  4.     response.request = request;  
  5.     mResponses.push(response);  
  6. }  

mResponses里面存储着events,request等信息,主要在下面对回调解析时使用。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1.     // Invoke all response callbacks.,处理请求的回调函数  
  2.     for (size_t i = 0; i < mResponses.size(); i++) {  
  3.         Response& response = mResponses.editItemAt(i);  
  4.         if (response.request.ident == ALOOPER_POLL_CALLBACK) {  
  5.             int fd = response.request.fd;  
  6.             int events = response.events;  
  7.             void* data = response.request.data;  
  8. #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS  
  9.             ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",  
  10.                     this, response.request.callback.get(), fd, events, data);  
  11. #endif  
  12.             int callbackResult = response.request.callback->handleEvent(fd, events, data);//调用addfd的回调函数ALooper_callbackFunc  
  13.             if (callbackResult == 0) {  
  14.                 removeFd(fd);  
  15.             }  
  16.             // Clear the callback reference in the response structure promptly because we  
  17.             // will not clear the response vector itself until the next poll.  
  18.             response.request.callback.clear();  
  19.             result = ALOOPER_POLL_CALLBACK;  
  20.         }  
  21.     }  

在前面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(),如下:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int SimpleLooperCallback::handleEvent(int fd, int events, void* data) {  
  2.     return mCallback(fd, events, data);  
  3. }  

的确,mCallBack才是ALooper_callbackFunc这个函数指针,当初是赋值为了cb_eventReceiver,故回调该函数。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {  
  2.     MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);  
  3.     return queue->eventReceiver(fd, events);  
  4. }  

而上面的data一就是MessageQueue::setEventThread时传入的this即SurfaceFlinger的mMessageQueue成员,现在开始执行事件的接收,其实就是开始做消息的发送了,也就是进入消息处理机制。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int MessageQueue::eventReceiver(int fd, int events) {  
  2.     ssize_t n;  
  3.     DisplayEventReceiver::Event buffer[8];  
  4.     while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {//得到事件的数据  
  5.         for (int i=0 ; i<n ; i++) {  
  6.             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {  
  7. #if INVALIDATE_ON_VSYNC  
  8.                 mHandler->dispatchInvalidate();  
  9. #else  
  10.                 mHandler->dispatchRefresh();//刷新  
  11. #endif  
  12.                 break;  
  13.             }  
  14.         }  
  15.     }  
  16.     return 1;  
  17. }  

getevents最终是调用recv来获得基于Unix域单连接的socket端发send过来的数据,判断数据的类型是不是显示帧同步事件,可以很容易的看到在EventThread的waitevent中的event事件结构体初始化:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. for (int32_t i=0 ; i<HWC_DISPLAY_TYPES_SUPPORTED ; i++) {  
  2.     mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;  
  3.     mVSyncEvent[i].header.id = 0;  
  4.     mVSyncEvent[i].header.timestamp = 0;  
  5.     mVSyncEvent[i].vsync.count =  0;//初始化同步事件  
  6. }  

故直接进入mHandler->dispatchRefresh()函数,

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void MessageQueue::Handler::dispatchRefresh() {  
  2.     if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {  
  3.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));  
  4.     }  
  5. }  

 

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {  
  2.     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  
  3.     sendMessageAtTime(now, handler, message); //及时发送消息  
  4. }  

 

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,  
  2.         const Message& message) {  
  3. #if DEBUG_CALLBACKS  
  4.     ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d",  
  5.             this, uptime, handler.get(), message.what);  
  6. #endif  
  7.   
  8.     size_t i = 0;  
  9.     { // acquire lock  
  10.         AutoMutex _l(mLock);  
  11.   
  12.         size_t messageCount = mMessageEnvelopes.size();  
  13.         while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {  
  14.             i += 1;  
  15.         }  
  16.   
  17.         MessageEnvelope messageEnvelope(uptime, handler, message);  
  18.         mMessageEnvelopes.insertAt(messageEnvelope, i, 1);//加入消息包到loop中去  
  19.   
  20.         // Optimization: If the Looper is currently sending a message, then we can skip  
  21.         // the call to wake() because the next thing the Looper will do after processing  
  22.         // messages is to decide when the next wakeup time should be.  In fact, it does  
  23.         // not even matter whether this code is running on the Looper thread.  
  24.         if (mSendingMessage) {  
  25.             return;  
  26.         }  
  27.     } // release lock  
  28.   
  29.     // Wake the poll loop only when we enqueue a new message at the head.  
  30.     if (i == 0) {  
  31.         wake();//在消息队列头检测到有一个新的消息后唤醒  
  32.     }  
  33. }  

。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内的消息处理机制吧:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1.     // Invoke pending message callbacks.消息的handle处理  
  2.     mNextMessageUptime = LLONG_MAX;  
  3.     while (mMessageEnvelopes.size() != 0) {//消息包络组里面有信息  
  4.         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  
  5.         const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);//提取一个消息包  
  6.         if (messageEnvelope.uptime <= now) {  
  7.             // Remove the envelope from the list.  
  8.             // We keep a strong reference to the handler until the call to handleMessage  
  9.             // finishes.  Then we drop it so that the handler can be deleted *before*  
  10.             // we reacquire our lock.  
  11.             { // obtain handler  
  12.                 sp<MessageHandler> handler = messageEnvelope.handler;  
  13.                 Message message = messageEnvelope.message;  
  14.                 mMessageEnvelopes.removeAt(0);  
  15.                 mSendingMessage = true;  
  16.                 mLock.unlock();  
  17.   
  18. #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS  
  19.                 ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",  
  20.                         this, handler.get(), message.what);  
  21. #endif  
  22.                 handler->handleMessage(message);//MessageHandler消息的handle处理  
  23.             } // release handler  
  24.   
  25.             mLock.lock();  
  26.             mSendingMessage = false;  
  27.             result = ALOOPER_POLL_CALLBACK;  
  28.         } else {  
  29.             // The last message left at the head of the queue determines the next wakeup time.  
  30.             mNextMessageUptime = messageEnvelope.uptime;  
  31.             break;  
  32.         }  
  33.     }  

核心的过程解析messageEnvelope消息包,取出对应的消息以及消息处理的handle,进行处理,那么立即的handle是什么呢?回归到mHandler->dispatchRefresh()——》MessageQueue::Handler::dispatchRefresh()里面可以看到 mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));,这个handle就是mHandle啦,故来看MessageQueue的内部Handle的成员函数handleMessage,很高兴的是,果然与之前设置的message.what结合在一起了。最终把消息的处理权还是提交给了mFlinger

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void MessageQueue::Handler::handleMessage(const Message& message) {  
  2.     switch (message.what) {  
  3.         case INVALIDATE:  
  4.             android_atomic_and(~eventMaskInvalidate, &mEventMask);  
  5.             mQueue.mFlinger->onMessageReceived(message.what);  
  6.             break;  
  7.         case REFRESH:  
  8.             android_atomic_and(~eventMaskRefresh, &mEventMask);  
  9.             mQueue.mFlinger->onMessageReceived(message.what);//线程接收到了消息后处理  
  10.             break;  
  11.     }  
  12. }  

onMessageReceived——>handleMessageRefresh处理屏幕刷新这个消息,主要调用composer来完成。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void SurfaceFlinger::handleMessageRefresh() {//处理layer的刷新,实际是调用SF绘图  
  2.     ATRACE_CALL();  
  3.     preComposition();  
  4.     rebuildLayerStacks();  
  5.     setUpHWComposer();  
  6.     doDebugFlashRegions();  
  7.     doComposition();  
  8.     postComposition();  
  9. }  

 

通过以上内容就走完了Surface的屏幕刷新事件提交以及事件处理,消息触发,以及消息的处理。最终还是回归到SurfaceFlinger来完成最终的消息处理。本文最终将SF的消息和事件处理机制总结成以下的流程图,加速理解。蓝色核心框图是SurfaceFlinger的主要业务和服务的处理线程。


Android4.2.2 SurfaceFlinger的有关事件和消息处理机制

 

0 0
原创粉丝点击