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

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。

欢迎和大家交流。qq:1037701636 email:[email protected]

 

Android源码版本Version:4.2.2; 硬件平台 全志A31

 

这周继续我的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.

extern "C" status_t system_init()
{
    ALOGI("Entered system_init()");

    sp proc(ProcessState::self());

    sp sm = defaultServiceManager();
    ALOGI("ServiceManager: %p\n", sm.get());

    sp 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();
    }
......
}

在这里可以看到在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的过程:

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

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图提出来,如下所示:

 Android4.2.2 SurfaceFlinger启动流程详解(一)_第1张图片

 

step1: 调用publishAndJoinThreadPool函数:

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

    static void publishAndJoinThreadPool(bool allowIsolated = false) {
        sp sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }

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

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\n", buf);
        sp t = new PoolThread(isMain);
        t->run(buf);
    }
}

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

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

 

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

       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进行初始化

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类所属的线程,好吧接下去揭开谜底所在,来看这个:

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。

 

 

 


 


 

 

你可能感兴趣的:(视频采集与显示,android源码,我心所向之Android4.2)