SurfaceFlinger服务的启动



SurfaceFlinger服务的启动

 

SurfaceFlinger服务负责管理系统的帧缓冲区设备,并且负责渲染系统的UI,即各个应用程序的UI。因此,Android应用程序就需要通过Binder进程间通信机制来请求它来渲染自己的UI

 

当用户对手机进行操作时, 对应的数据流依次为:HW SpageInput DriverInput systemSystem logicSurfaceFlingerSFDisplay systemLCM Driver。当数据流中的某个环节出现问题的时候都可能造成死机。 关于SF问题的排查:1MTK机器上当我们按音量上下键可以正常显示调整情况,基本可以排除死机原因不是SurfaceFlinger引起的;2从抓取到的MTK log中我们也可以看出它被创建的时候` SurfaceFlinger: EventThread Client Pid (1580) created`以及` SurfaceFlinger: [SF client] NEW(0xae090960) for (804:system_server)`,说明SF是由system_server进程启动的服务之一。SF中已经导入了Watchdog 机制, 审查SurfaceFlinger 是否有卡住的情况, 对应在main log 里面会打印如:[SF-WD] detect SF maybe hang!!!这样的LOG, 并且会纪录卡顿的时机,如果持续卡顿,毫无疑问, SurfaceFlinger 已经卡住。

 

基于上述的认识,我们下面开始简单了解SurfaceFlinger服务的启动流程。

先放上一张SF服务启动的思维导图~~~

一、SurfaceFlingermain()函数

Path:./frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {

 

    signal(SIGPIPE, SIG_IGN);

    // When SF is launched in its own process, limit the number of

    // binder threads to 4.

    ProcessState::self()->setThreadPoolMaxThreadCount(4); //设置Binder线程池最大线程数为4

 

    // start the thread pool

    sp<ProcessState> ps(ProcessState::self());  //sp为强指针

    ps->startThreadPool();

 

    // instantiate surfaceflinger

    sp<SurfaceFlinger> flinger = new SurfaceFlinger();  //创建SF对象

 

    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY); //设置参数

    set_sched_policy(0, SP_FOREGROUND);

    set_cpuset_policy(0, SP_SYSTEM);

 

    // initialize before clients can connect

    flinger->init();   //调用SFinit()函数

 

    // publish surface flinger   //注册SF服务到ServiceManager

    sp<IServiceManager> sm(defaultServiceManager());

    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

 

    // publish GpuService

    sp<GpuService> gpuservice = new GpuService();

sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);

 

    // run surface flinger in this thread

    flinger->run();  //其实运行在EventThread线程上

    return 0;

}

Note:main()函数中主要是将SF服务注册到ServiceManager中,然后调用SurfaceFlingerinit()方法进一步完成一些初始化工作。

 

  1. SurfaceFlinger/init()

    void SurfaceFlinger::init() {

        ALOGI(  "SurfaceFlinger's main thread ready to run. "

                "Initializing graphics H/W...");

        { // Autolock scope

            Mutex::Autolock _l(mStateLock);

     

            // initialize EGL for the default display

            mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            eglInitialize(mEGLDisplay, NULL, NULL);

     

            //start the EventThread

            sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,

                    vsyncPhaseOffsetNs, true, "app");

            mEventThread = new EventThread(vsyncSrc, *this);

            sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,

                    sfVsyncPhaseOffsetNs, true, "sf");

            mSFEventThread = new EventThread(sfVsyncSrc, *this);

            mEventQueue.setEventThread(mSFEventThread);

    #endif

     

            // Get a RenderEngine for the given display / config (can't fail)

            mRenderEngine = RenderEngine::create(mEGLDisplay,

                    HAL_PIXEL_FORMAT_RGBA_8888);

        }

    ..........

        sp<Resync> resync = new Resync(this, HWC_DISPLAY_PRIMARY, sPropertiesState.mAppVSyncOffset);

        mPrimaryDispSync.setResync(resync);

    #endif // MTK_EMULATOR_SUPPORT

     

        // start the EventThread

        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,

                sPropertiesState.mAppVSyncOffset, true, "app");

        mEventThread = new EventThread(vsyncSrc, *this);

     

        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,

                sPropertiesState.mSfVSyncOffset, true, "sf", true);

         .................

        // initialize our drawing state

        mDrawingState = mCurrentState;

     

        // set initial conditions (e.g. unblank default device)

        initializeDisplays();

     

        // start boot animation

        startBootAnim();

     

        ALOGV("Done initializing");

    }

     

    Note:  init函数主要工作为:

     

  1. 初始化EGL图形库。

     

  2.  启动EventThread。监听和处理SurfaceFlinger中的事件。

     

    3.创建显示设备的抽象代表,负责和显示设备打交道。

     

    4. 创建显示设备对象。

     

    5.设置软件VSync信号周期。

     

    6.初始化显示设备,调用initializeDisplays完成。

     

    7.启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程。

  1. SurfaceFlinger/init()

    void SurfaceFlinger::run() {

        do {

            waitForEvent();

        } while (true);

    }

     

    void SurfaceFlinger::waitForEvent() {

        mEventQueue.waitMessage();

    }

     

    Note:mEventQueue是EventThread的实例对象,它会一直等待消息的到来,开始渲染UI。

     

    总结:其实在init()中创建显示设备过程,会涉及到SurfaceFlinger服务的控制台事件监控线程的创建过程;以及UI线程渲染的过程就不再一一分析。这里主要分析的是SF服务的一个启动。其次,在开关机中,如果我们能够看到开机动画的显示,说明SF服务已经启动起来了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值