Android源码之SurfaceFlinger的启动(三)

Awara 2017-04-20

page11

我们来看一下SurfaceFlinger的onFirstRef函数的定义:

1voidEventThread::onFirstRef(){

2run("EventThread",PRIORITY_URGENT_DISPLAY+PRIORITY_MORE_FAVORABLE);

3}

我靠,又调用run函数,这会导致又启动了一个线程.

同样的,这也会导致readyToRun和threadLoop函数的.

EventThread的readyToRun函数是从Thread类继承而来的,是个空函数.

而EventThread的threadLoop函数的定义如下:

1boolEventThread::threadLoop(){

2DisplayEventReceiver::Eventevent;

3Vector<sp<EventThread::Connection>>signalConnections;

4signalConnections=waitForEvent(&event);

5

6//dispatcheventstolisteners...

7constsize_tcount=signalConnections.size();

8for(size_ti=0;i<count;i++){

9constsp<Connection>&conn(signalConnections[i]);

10//nowseeifwestillneedtoreportthisevent

11status_terr=conn->postEvent(event);

12if(err==-EAGAIN||err==-EWOULDBLOCK){

13//Thedestinationdoesn'taccepteventsanymore,it'sprobably

14//full.Fornow,wejustdroptheeventsonthefloor.

15//FIXME:Notethatsomeeventscannotbedroppedandwouldhave

16//tobere-sentlater.

17//Right-nowwedon'thavetheabilitytodothis.

18ALOGW("EventThread:droppingevent(%08x)forconnection%p",

19event.header.type,conn.get());

20}elseif(err<0){

21//handleanyothererroronthepipeasfatal.theonly

22//reasonablethingtodoistoclean-upthisconnection.

23//Themostcommonerrorwe'llgethereis-EPIPE.

24removeDisplayEventConnection(signalConnections[i]);

25}

26}

27returntrue;

28}

EventThread的threadLoop函数的主要逻辑就是不停地等待事件,然后交给Connection去处理.

page12

我们来分析一下MessageQueue的setEventThread函数的逻辑实现,setEventThread函数的定义如下所示:

1voidMessageQueue::setEventThread(constsp<EventThread>&eventThread)

2{

3mEventThread=eventThread;

4mEvents=eventThread->createEventConnection();

5mEventTube=mEvents->getDataChannel();

6mLooper->addFd(mEventTube->getFd(),0,ALOOPER_EVENT_INPUT,MessageQueue::cb_eventReceiver,this);

7}

第4行(MessageQueue->setEventThread)会调用EventThread的createEventConnection函数,关于createEventConnection函数的详细分析可以参考page13文件.

第5行(MessageQueue->setEventThread)会调用Connection的getDataChannel来得到一个BitTube对象并初始化,getDataChannel函数的定义如下所示:

sp<BitTube>EventThread::Connection::getDataChannel()const{

returnmChannel;

}

第6行(MessageQueue->setEventThread)会首先调用BitTube的getFd函数来得到一个文件操作符,并加入到MessageQueue的Looper里.

我们先看一下BitTube的getFd函数的定义,如下所示:

intBitTube::getFd()const

{

returnmReceiveFd;

}

BitTube的getFd函数会返回用于接受的文件操作符,这样当有数据写入该文件操作符的时候就会唤醒这个Looper处理该消息,也就是说EventThread线程收到事件会交给SurfaceFlinger的Main线程取处理了,这样就把EventThread线程和Main线程绑定到一起了.

EventThread发过来的消息的处理函数是调用的MessageQueue的cb_eventReceiver函数,关于cb_eventReceiver函数的详细分析可以参考page14文件.

page13

在这里,我们看一下EventThread的createEventConnection函数的具体实现,createEventConnection函数的定义如下:

sp<EventThread::Connection>EventThread::createEventConnection()const{

returnnewConnection(const_cast<EventThread*>(this));

}

createEventConnection函数只是返回了一个Connection对象.

Connection类的构造函数的定义如下:

EventThread::Connection::Connection(

constsp<EventThread>&eventThread)

:count(-1),mEventThread(eventThread),mChannel(newBitTube())

{

}

可以看到,Connection的mChannel会用一个BitTube来初始化,BitTube的类的声明如下:

classBitTube:publicRefBase

BitTube类的构造函数的定义如下:

1BitTube::BitTube()

2:mSendFd(-1),mReceiveFd(-1)

3{

4intsockets[2];

5if(socketpair(AF_UNIX,SOCK_SEQPACKET,0,sockets)==0){

6intsize=SOCKET_BUFFER_SIZE;

7setsockopt(sockets[0],SOL_SOCKET,SO_SNDBUF,&size,sizeof(size));

8setsockopt(sockets[0],SOL_SOCKET,SO_RCVBUF,&size,sizeof(size));

9setsockopt(sockets[1],SOL_SOCKET,SO_SNDBUF,&size,sizeof(size));

10setsockopt(sockets[1],SOL_SOCKET,SO_RCVBUF,&size,sizeof(size));

11fcntl(sockets[0],F_SETFL,O_NONBLOCK);

12fcntl(sockets[1],F_SETFL,O_NONBLOCK);

13mReceiveFd=sockets[0];

14mSendFd=sockets[1];

15}else{

16mReceiveFd=-errno;

17ALOGE("BitTube:pipecreationfailed(%s)",strerror(-mReceiveFd));

18}

19}

可以看出,BitTube构造函数只是创建了两个文件操作符,一个用户读,一个用于写.

page14

在这篇文章里,我们分析一下MessageQueue的cb_eventReceiver函数的实现:

intMessageQueue::cb_eventReceiver(intfd,intevents,void*data){

MessageQueue*queue=reinterpret_cast<MessageQueue*>(data);

returnqueue->eventReceiver(fd,events);

}

cb_eventReceiver函数又会调用eventReceiver函数,MessageQueue的eventReceiver函数的定义如下:

1intMessageQueue::eventReceiver(intfd,intevents){

2ssize_tn;

3DisplayEventReceiver::Eventbuffer[8];

4while((n=DisplayEventReceiver::getEvents(mEventTube,buffer,)>0){

5for(inti=0;i<n;i++){

6if(buffer[i].header.type==DisplayEventReceiver::DISPLAY_EVENT_VSYNC){

7#ifINVALIDATE_ON_VSYNC

8mHandler->dispatchInvalidate();

9#else

10mHandler->dispatchRefresh();

11#endif

12break;

13}

14}

15}

16return1;

17}

第4行(MessageQueue->eventReceiver)会在mEventTube上调用DisplayEventReceiver的getEvents函数,关于DisplayEventReceiver的getEvents函数的详细分析可以参考page15文件.

page15

在这篇文章里,我们分析一下DisplayEventReceiver的getEvents函数的实现:

1ssize_tDisplayEventReceiver::getEvents(DisplayEventReceiver::Event*events,size_tcount){

2returnDisplayEventReceiver::getEvents(mDataChannel,events,count);

3}

两个参数的getEvents又会调用三个参数的重载版本,该函数的定义如下:

1ssize_tDisplayEventReceiver::getEvents(constsp<BitTube>&dataChannel,Event*events,size_tcount)

2{

3returnBitTube::recvObjects(dataChannel,events,count);

4}

getEvents函数最终会调用BitTube的recvObjects函数,而传入的文件操作符正是成员变量mEventTube.

BitTube的recvObjects函数的定义如下:

1ssize_tBitTube::recvObjects(constsp<BitTube>&tube,void*events,size_tcount,size_tobjSize)

2{

3ssize_tnumObjects=0;

4for(size_ti=0;i<count;i++){

5char*vaddr=reinterpret_cast<char*>(events)+objSize*i;

6ssize_tsize=tube->read(vaddr,objSize);

7if(size<0){

8//erroroccurred

9returnsize;

10}elseif(size==0){

11//nomoremessages

12break;

13}

14numObjects++;

15}

16returnnumObjects;

17}

第6行(BitTube->recvObjects)会在该BitTube上调用read函数来接受数据,BitTube的read函数的定义如下所示:

1ssize_tBitTube::read(void*vaddr,size_tsize)

2{

3ssize_terr,len;

4do{

5len=::recv(mReceiveFd,vaddr,size,MSG_DONTWAIT);

6err=len<0?errno:0;

7}while(err==EINTR);

8if(err==EAGAIN||err==EWOULDBLOCK){

9//EAGAINmeansthatwehavenon-blockingI/Obuttherewas

10//nodatatoberead.Nothingtheclientshouldcareabout.

11return0;

12}

13returnerr==0?len:-err;

14}

第5行(BitTube->read)会在mReceiveFd文件操作符上读取size大小的数据,并保存到地址vaddr里去.

相关推荐