Android4.2.2 SurfaceFlinger启动流程详解(一)

http://www.2cto.com/kf/201403/287865.html


这周继续我的Blog,前面几篇博文简单的介绍了阅读Android FW的源码所需要的基础知识,主要和C++相关。从这篇博文开始将会和大家一起学习并总结SurfaceFlinger模块在Android中的相关内容,本文主要描述的是SurfaceFlinger的详细启动流程。

 

1.SurfaceFlinger在哪里启动?

在android系统中一个核心的Service都有ServiceManager管理,核心Service启动一般是在SystemServer来启动,但是比较重要的Service会在Zygote启动前,由init进程来负责直接启动。故SurfaceFlinger作为一个核心Service,一般有下面2种启动方式。

a.在systemserver中如何启动。

源码目录/android/frameworks/base/cmds/system_server/library/system_init.cpp.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
extern C status_t system_init()
{
     ALOGI(Entered system_init());
 
     sp<processstate> proc(ProcessState::self());
 
     sp<iservicemanager> sm = defaultServiceManager();
     ALOGI(ServiceManager: %p
, sm.get());
 
     sp<grimreaper> grim = new GrimReaper();
     sm->asBinder()->linkToDeath(grim, grim.get(), 0 );
 
     char propBuf[PROPERTY_VALUE_MAX];
     property_get(system_init.startsurfaceflinger, propBuf, 1 );
     if (strcmp(propBuf, 1 ) == 0 ) {
         // Start the SurfaceFlinger
         SurfaceFlinger::instantiate();
     }
 
     property_get(system_init.startsensorservice, propBuf, 1 );
     if (strcmp(propBuf, 1 ) == 0 ) {
         // Start the sensor service
         SensorService::instantiate();
     }
......
}</grimreaper></iservicemanager></processstate>

在这里可以看到在systemserver的启动过程中,property_get通过获取system_init.startsurfaceflinger的属性值,这个属性值一般在init.rc中进配置,如果该数值为0,则赋值propBuf=1,故以此会使用system_init中来启动SF。

 

b.相对比上面的启动,另一种启动就是直接像ServiceManager一样,作为init进程中的一个Service来启动。

在init.rc中添加如下配置代码:

# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

启动SurfaceFlinger的过程:

?
1
2
3
4
5
6
469 service surfaceflinger /system/bin/surfaceflinger
470     class main
471     user system
472     group graphics drmrpc
473     onrestart restart zygote
474

对于Service如何启动,可以查看Blog:android系统启动流程启动画面学习之init和init.rc分析的相关内容即可理解。

 

2.以第二种方式启动来进一步分析SF,看看SurfaceFlinger的main函数源码。

路径:android/frameworks/native/cmds/surfaceflinger/main_surfaceflinger.cpp

?
1
2
3
4
5
6
7
int main( int argc, char ** argv) {
     SurfaceFlinger::publishAndJoinThreadPool( true );
     // When SF is launched in its own process, limit the number of
     // binder threads to 4.
     ProcessState::self()->setThreadPoolMaxThreadCount( 4 );
     return 0 ;
}

要开始结束SurfaceFlinger的函数处理过程时,有必要先进SF的基本UML图提出来,如下所示:

align=middle

 

step1: 调用publishAndJoinThreadPool函数:

该函数是C++里一个带默认参数的函数的,这里传入的参数的true。

?
1
2
3
4
5
6
7
     static void publishAndJoinThreadPool(bool allowIsolated = false ) {
         sp<iservicemanager> sm(defaultServiceManager());
         sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
         ProcessState::self()->startThreadPool();
         IPCThreadState::self()->joinThreadPool();
     }
</iservicemanager>

这里会涉及到和ServerManger的交互,变量sm是SM在当前进程的一个代理proxy,用于Binder驱动的交互,而addService正是将SurfaceFlinger做为一个核心的系统服务注册到SM当中。随后就是当前进程由ProcessState通过依次调用会新run起来一个thread如下所示,Poolthread继承与Thread类,故一旦run起来就运行thread的run函数故而依旧前面介绍的thread类是依次会执行PoolThread类的readyToRun和threadLoop;

?
1
2
3
4
5
6
7
8
9
10
11
12
void ProcessState::spawnPooledThread(bool isMain)
{
     if (mThreadPoolStarted) {
         int32_t s = android_atomic_add( 1 , &mThreadPoolSeq);
         char buf[ 16 ];
         snprintf(buf, sizeof(buf), Binder_%X, s);
         ALOGV(Spawning new pooled thread, name=%s
, buf);
         sp<thread> t = new PoolThread(isMain);
         t->run(buf);
     }
}</thread>

在对应的threadLoop里面可以找到IPCThreadState::self()->joinThreadPool(mIsMain);即新建一个IPCThreadState进程间通信的线程状态类,该类的函数joinThreadPool
即是与Binder驱动交互的接口,核心是和内核Binder驱动进行talkWithDriver()以及executeCommand(), 因为当前的SurfaceFlinger已经进入了正常的运行状态。

当然在本主线程也会 调用IPCThreadState::self()->joinThreadPool();进行Binder间的通信,确保通信的稳定性。

 

step2: 回归SurfaceFlinger对象的创建
作为继承了public BinderService模板类的SF,他的创建就在上文提到的publishAndJoinThreadPool函数中的

?
1
sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);

new SERVICE() = new SurfaceFlinger().从这里该进入SF的创建和相关初始化了

SF类的定义和初始化成员函数的文件目录:

源文件/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp;头文件/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.h;

如下是SF的狗构造函数,首先对基类BnSurfaceComposer、Thread进行初始化

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SurfaceFlinger::SurfaceFlinger()
     :   BnSurfaceComposer(), Thread( false ),
         mTransactionFlags( 0 ),
         mTransactionPending( false ),
         mAnimTransactionPending( false ),
         mLayersRemoved( false ),
         mRepaintEverything( 0 ),
         mBootTime(systemTime()),
         mVisibleRegionsDirty( false ),
         mHwWorkListDirty( false ),
         mDebugRegion( 0 ),
         mDebugDDMS( 0 ),
         mDebugDisableHWC( 0 ),
         mDebugDisableTransformHint( 0 ),
         mDebugInSwapBuffers( 0 ),
         mLastSwapBufferTime( 0 ),
         mDebugInTransaction( 0 ),
         mLastTransactionTime( 0 ),
         mBootFinished( false )

这里乘热打铁来看thread类,很容易知道必然有地方会run起thread类所属的线程,好吧接下去揭开谜底所在,来看这个:

?
1
2
3
4
5
6
7
8
9
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(); //等待线程完成相关的初始化
}

OK这个onFirstRef似乎特别熟悉,的确在Android FrameWork中的SP、RefBase、weakref_impl,Thread类里面详细说明了他的由来,其实也就是和RefBase的关系特别密切。一般new一个SP的模板类,会最终调用该类对象对Refase重载的onFirstRef()。这里就可以看到进行了mEventQueue(在介绍SF的消息机制时再深入分析)的初始化以及启动一个run函数。故最终调用SF的readyToRun和threadLoop。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值