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

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

欢迎和大家交流。qq:1037701636 email:gzzaigcn2012@gmail.com

 

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<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p\n", 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();
    }
......
}

在这里可以看到在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图提出来,如下所示:

 

 

step1: 调用publishAndJoinThreadPool函数:

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

    static void publishAndJoinThreadPool(bool allowIsolated = false) {
        sp<IServiceManager> 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<Thread> 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<SurfaceFlinger>模板类的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。

 

 

 


 


 

 

SurfaceFlingerSurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlingerSurfaceFlinger 服务是在 服务是在 服务是在 SystemSystemSystemSystemSystem 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 进程中启动的,并且负责统管理设备帧缓冲区。 SurfaceFlingerSurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlingerSurfaceFlinger 服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件服务在启动的过程中, 会创建两个线其用来监控制台事件而另外个线程用来渲染系统的 而另外个线程用来渲染系统的 而另外个线程用来渲染系统的 而另外个线程用来渲染系统的 而另外个线程用来渲染系统的 而另外个线程用来渲染系统的 而另外个线程用来渲染系统的 UI 。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值