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}