Android源码之SurfaceFlinger的启动(二)

page6

我们看一下Thread的run函数的实现:

1status_tThread::run(constchar*name,int32_tpriority,size_tstack)

2{

3Mutex::Autolock_l(mLock);

4

5if(mRunning){

6//threadalreadystarted

7returnINVALID_OPERATION;

8}

9

10//resetstatusandexitPendingtotheirdefaultvalue,sowecan

11//tryagainafteranerrorhappened(eitherbelow,orinreadyToRun())

12mStatus=NO_ERROR;

13mExitPending=false;

14mThread=thread_id_t(-1);

15

16//holdastrongreferenceonourself

17mHoldSelf=this;

18

19mRunning=true;

20

21boolres;

22if(mCanCallJava){

23res=createThreadEtc(_threadLoop,

24this,name,priority,stack,&mThread);

25}else{

26res=androidCreateRawThreadEtc(_threadLoop,

27this,name,priority,stack,&mThread);

28}

29

30if(res==false){

31mStatus=UNKNOWN_ERROR;//somethinghappened!

32mRunning=false;

33mThread=thread_id_t(-1);

34mHoldSelf.clear();//"this"mayhavegoneawayafterthis.

35

36returnUNKNOWN_ERROR;

37}

38

39//DonotrefertomStatushere:Thethreadisalreadyrunning(may,infact

40//alreadyhaveexitedwithavalidmStatusresult).TheNO_ERRORindication

41//heremerelyindicatessuccessfullystartingthethreadanddoesnot

42//implysuccessfultermination/execution.

43returnNO_ERROR;

44

45//ExitingscopeofmLockisamemorybarrierandallowsnewthreadtorun

46}

第22-24行(Thread->run)会调用createThreadEtc函数来创建一个

第25-28行(Thread->run)会调用androidCreateRawThreadEtc函数来创建一个线程.关于androidCreateRawThreadEtc函数的详细分析可以参考page7文件.

当创建完一个新线程之后,这个线程就会以_threadLoop函数作为入口来执行,关于Thread的_threadLoop函数的详细分析可以参考page8文件.

由_threadLoop函数的分析可以知道,这里会首先调用SurfaceFlinger的readyToRun函数,关于SurfaceFlinger的readyToRun函数的详细分析可以参考page9文件.

page7

在这里,我们看一下Thread的androidCreateRawThreadEtc函数的实现:

1intandroidCreateRawThreadEtc(android_thread_func_tentryFunction,

2void*userData,

3constchar*threadName,

4int32_tthreadPriority,

5size_tthreadStackSize,

6android_thread_id_t*threadId)

7{

8pthread_attr_tattr;

9pthread_attr_init(&attr);

10pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

11

12#ifdefHAVE_ANDROID_OS/*valgrindisrejectingRT-prioritycreatereqs*/

13if(threadPriority!=PRIORITY_DEFAULT||threadName!=NULL){

14//Nowthatthepthread_thasamethodtofindtheassociated

15//android_thread_id_t(pid)frompthread_t,itwouldbepossibletoavoid

16//thistrampolineinsomecasesastheparentcouldsettheproperties

17//forthechild.However,therewouldbearaceconditionbecausethe

18//childbecomesreadyimmediately,anditdoesn'tworkforthename.

19//prctl(PR_SET_NAME)onlyworksforself;prctl(PR_SET_THREAD_NAME)was

20//proposedbutnotyetaccepted.

21thread_data_t*t=newthread_data_t;

22t->priority=threadPriority;

23t->threadName=threadName?strdup(threadName):NULL;

24t->entryFunction=entryFunction;

25t->userData=userData;

26entryFunction=(android_thread_func_t)&thread_data_t::trampoline;

27userData=t;

28}

29#endif

30

31if(threadStackSize){

32pthread_attr_setstacksize(&attr,threadStackSize);

33}

34

35errno=0;

36pthread_tthread;

37intresult=pthread_create(&thread,&attr,

38(android_pthread_entry)entryFunction,userData);

39pthread_attr_destroy(&attr);

40if(result!=0){

41ALOGE("androidCreateRawThreadEtcfailed(entry=%p,res=%d,errno=%d)\n"

42"(androidthreadPriority=%d)",

43entryFunction,result,errno,threadPriority);

44return0;

45}

46

47//Notethat*threadIDisdirectlyavailabletotheparentonly,asitis

48//assignedafterthechildstarts.Usememorybarrier/lockifthechild

49//orotherthreadsalsoneedaccess.

50if(threadId!=NULL){

51*threadId=(android_thread_id_t)thread;//XXX:thisisnotportable

52}

53return1;

54}

第37-38行(Thread->androidCreateRawThreadEtc)会调用pthread_create函数来创建一个线程,并以entryFunction作为线程的入口函数.

page8

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

1intThread::_threadLoop(void*user)

2{

3Thread*constself=static_cast<Thread*>(user);

4

5sp<Thread>strong(self->mHoldSelf);

6wp<Thread>weak(strong);

7self->mHoldSelf.clear();

8

9#ifdefHAVE_ANDROID_OS

10//thisisveryusefulfordebuggingwithgdb

11self->mTid=gettid();

12#endif

13

14boolfirst=true;

15

16do{

17boolresult;

18if(first){

19first=false;

20self->mStatus=self->readyToRun();

21result=(self->mStatus==NO_ERROR);

22

23if(result&&!self->exitPending()){

24//Binderthreads(andmaybeothers)relyonthreadLoop

25//runningatleastonceafterasuccessful::readyToRun()

26//(unless,ofcourse,thethreadhasalreadybeenaskedtoexit

27//atthatpoint).

28//Thisisbecausethreadsareessentiallyusedlikethis:

29//(newThreadSubclass())->run();

30//Thecallerthereforedoesnotretainastrongreferenceto

31//thethreadandthethreadwouldsimplydisappearafterthe

32//successful::readyToRun()callinsteadofenteringthe

33//threadLoopatleastonce.

34result=self->threadLoop();

35}

36}else{

37result=self->threadLoop();

38}

39

40//establishascopeformLock

41{

42Mutex::Autolock_l(self->mLock);

43if(result==false||self->mExitPending){

44self->mExitPending=true;

45self->mRunning=false;

46//clearthreadIDsothatrequestExitAndWait()doesnotexitif

47//calledbyanewthreadusingthesamethreadIDasthisone.

48self->mThread=thread_id_t(-1);

49//notethatinterestedobserversblockedinrequestExitAndWaitare

50//awokenbybroadcast,butblockedonmLockuntilbreakexitsscope

51self->mThreadExitedCondition.broadcast();

52break;

53}

54}

55

56//Releaseourstrongreference,toletachancetothethread

57//todieapeacefuldeath.

58strong.clear();

59//Andimmediately,re-acquireastrongreferenceforthenextloop

60strong=weak.promote();

61}while(strong!=0);

62

63return0;

64}

第18-38行(Thread->_threadLoop)会判断如果线程第一次执行会首先执行readyToRun函数,紧接着会不停地执行threadLoop函数.

page9

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

1status_tSurfaceFlinger::readyToRun()

2{

3ALOGI("SurfaceFlinger'smainthreadreadytorun."

4"InitializinggraphicsH/W...");

5

6//initializeEGLforthedefaultdisplay

7mEGLDisplay=eglGetDisplay(EGL_DEFAULT_DISPLAY);

8eglInitialize(mEGLDisplay,NULL,NULL);

9

10//InitializetheH/Wcomposerobject.Theremayormaynotbean

11//actualhardwarecomposerunderneath.

12mHwc=newHWComposer(this,

13*static_cast<HWComposer::EventHandler*>(this));

14

15//initializetheconfigandcontext

16EGLintformat=mHwc->getVisualID();

17mEGLConfig=selectEGLConfig(mEGLDisplay,format);

18mEGLContext=createGLContext(mEGLDisplay,mEGLConfig);

19

20LOG_ALWAYS_FATAL_IF(mEGLContext==EGL_NO_CONTEXT,

21"couldn'tcreateEGLContext");

22

23//initializeournon-virtualdisplays

24for(size_ti=0;i<DisplayDevice::NUM_DISPLAY_TYPES;i++){

25DisplayDevice::DisplayTypetype((DisplayDevice::DisplayType)i);

26mDefaultDisplays[i]=newBBinder();

27wp<IBinder>token=mDefaultDisplays[i];

28

29//set-upthedisplaysthatarealreadyconnected

30if(mHwc->isConnected(i)||type==DisplayDevice::DISPLAY_PRIMARY){

31//Allnon-virtualdisplaysarecurrentlyconsideredsecure.

32boolisSecure=true;

33mCurrentState.displays.add(token,DisplayDeviceState(type));

34sp<FramebufferSurface>fbs=newFramebufferSurface(*mHwc,i);

35sp<SurfaceTextureClient>stc=newSurfaceTextureClient(

36static_cast<sp<ISurfaceTexture>>(fbs->getBufferQueue()));

37sp<DisplayDevice>hw=newDisplayDevice(this,

38type,isSecure,token,stc,fbs,mEGLConfig);

39if(i>DisplayDevice::DISPLAY_PRIMARY){

40//FIXME:currentlywedon'tgetblank/unblankrequests

41//fordisplaysotherthanthemaindisplay,sowealways

42//assumeaconnecteddisplayisunblanked.

43ALOGD("markingdisplay%dasacquired/unblanked",i);

44hw->acquireScreen();

45}

46mDisplays.add(token,hw);

47}

48}

49

50//weneedaGLcontextcurrentinafewplaces,wheninitializing

51//OpenGLES(seebelow),orcreatingalayer,

52//orwhenatextureis(asynchronously)destroyed,andforthat

53//weneedavalidsurface,soit'sconvenienttousethemaindisplay

54//forthat.

55sp<constDisplayDevice>hw(getDefaultDisplayDevice());

56

57//initializeOpenGLES

58DisplayDevice::makeCurrent(mEGLDisplay,hw,mEGLContext);

59initializeGL(mEGLDisplay);

60

61//starttheEventThread

62mEventThread=newEventThread(this);

63mEventQueue.setEventThread(mEventThread);

64

65//initializeourdrawingstate

66mDrawingState=mCurrentState;

67

68

69//We'renowreadytoacceptclients...

70mReadyToRunBarrier.open();

71

72//setinitialconditions(e.g.unblankdefaultdevice)

73initializeDisplays();

74

75//startbootanimation

76startBootAnim();

77

78returnNO_ERROR;

79}

第12-13行(SurfaceFlinger->readyToRun)会创建一个HWComposer对象来初始化成员变量mHwc,mHwc是底层操作Fb文件的.

第24-48行(SurfaceFlinger->readyToRun)会为每一个显示设备申请一个DisplayDevice对象,

第62行(SurfaceFlinger->readyToRun)会创建一个EventThread对象,并初始化成员变量mEventThread.关于EventThread的创建过程可以参考page10文件.

因为mEventThread是一个Sp类型的成员变量,因此这里会导致EventThread的onFirstRef函数的调用,关于EventThread的onFirstRef函数的详细分析可以参考page11文件.

第63行(SurfaceFlinger->readyToRun)会调用MessageQueue的setEventThread函数来和EventThread创建连接,关于MessageQueue的setEventThread函数的详细分析可以参考page12文件.

page10

在这篇文章里,我们来看一下EventThread的创建过程.我们先来看一下EventThread类的继承体系:

classEventThread:publicThread

很显然,EventThread只是一个线程.

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

1EventThread::EventThread(constsp<SurfaceFlinger>&flinger)

2:mFlinger(flinger),

3mUseSoftwareVSync(false),

4mDebugVsyncEnabled(false){

5

6for(int32_ti=0;i<HWC_DISPLAY_TYPES_SUPPORTED;i++){

7mVSyncEvent[i].header.type=DisplayEventReceiver::DISPLAY_EVENT_VSYNC;

8mVSyncEvent[i].header.id=0;

9mVSyncEvent[i].header.timestamp=0;

10mVSyncEvent[i].vsync.count=0;

11}

12}