zoukankan      html  css  js  c++  java
  • Android SurfaceFlinger之SurfaceFlinger启动过程


    http://blog.csdn.net/ieearth/article/details/61202963


    SurfaceFlinger的启动脚本surfaceflinger.rc内容如下:

    service surfaceflinger /system/bin/surfaceflinger
        class core
        user system
        group graphics drmrpc readproc
        onrestart restart zygote
        writepid /dev/stune/foreground/tasks

    其main函数在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);
    
        // start the thread pool
        sp<ProcessState> ps(ProcessState::self());
        ps->startThreadPool();
    
        // instantiate surfaceflinger
        sp<SurfaceFlinger> flinger = new SurfaceFlinger();
    
        setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
    
        set_sched_policy(0, SP_FOREGROUND);
    
    #ifdef ENABLE_CPUSETS
        // Put most SurfaceFlinger threads in the system-background cpuset
        // Keeps us from unnecessarily using big cores
        // Do this after the binder thread pool init
        set_cpuset_policy(0, SP_SYSTEM);
    #endif
    
        // initialize before clients can connect
        flinger->init();
    
        // publish surface flinger
        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);
    
        struct sched_param param = {0};
        param.sched_priority = 2;
        if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
            ALOGE("Couldn't set SCHED_FIFO");
        }
    
        // run surface flinger in this thread
        flinger->run();
    
        return 0;
    }

    1、SurfaceFlinger首先忽略了SIGPIPE信号,为什么要这么做呢?因为在SurfaceFlinger的Client-Server模型中,或者说IPC机制中,很可能会触发SIGPIPE信号,而这个信号的默认动作是终止进程,并不是我们想要的行为,所以主动对SIGPIPE信号进行处理。

    2、接着,开启线程池,不过限制了线程的最大数量为4个,如果线程过多,可能会影响程序性能。

    3、随后,创建SurfaceFlinger对象,在其构造函数中,主要是一些成员变量的初始化工作,同时还有一个高逼格的DDMS配置,即Dalvik Debug Monitor Service,是一个调试神器。如果配置了DDMS,就会dlopen libsurfaceflinger_ddmconnection.so,并dlsym其中的DdmConnection_start,最后建立SurfaceFlinger与DDMS的连接。

    class SurfaceFlinger : public BnSurfaceComposer,
                           private IBinder::DeathRecipient,
                           private HWComposer::EventHandler
    
    SurfaceFlinger::SurfaceFlinger()
        :   BnSurfaceComposer(),
            mTransactionFlags(0),
            mTransactionPending(false),
            mAnimTransactionPending(false),
            mLayersRemoved(false),
            mRepaintEverything(0),
            mRenderEngine(NULL),
            mBootTime(systemTime()),
            mBuiltinDisplays(),
            mVisibleRegionsDirty(false),
            mGeometryInvalid(false),
            mAnimCompositionPending(false),
            mDebugRegion(0),
            mDebugDDMS(0),
            mDebugDisableHWC(0),
            mDebugDisableTransformHint(0),
            mDebugInSwapBuffers(0),
            mLastSwapBufferTime(0),
            mDebugInTransaction(0),
            mLastTransactionTime(0),
            mBootFinished(false),
            mForceFullDamage(false),
            mPrimaryDispSync("PrimaryDispSync"),
            mPrimaryHWVsyncEnabled(false),
            mHWVsyncAvailable(false),
            mHasColorMatrix(false),
            mHasPoweredOff(false),
            mFrameBuckets(),
            mTotalTime(0),
            mLastSwapTime(0)
    {
        ALOGI("SurfaceFlinger is starting");
    
        // debugging stuff...
        char value[PROPERTY_VALUE_MAX];
    
        property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
        mGpuToCpuSupported = !atoi(value);
    
        property_get("debug.sf.showupdates", value, "0");
        mDebugRegion = atoi(value);
    
        property_get("debug.sf.ddms", value, "0");
        mDebugDDMS = atoi(value);
        if (mDebugDDMS) {
            if (!startDdmConnection()) {
                // start failed, and DDMS debugging not enabled
                mDebugDDMS = 0;
            }
        }
        ALOGI_IF(mDebugRegion, "showupdates enabled");
        ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
    
        property_get("debug.sf.disable_backpressure", value, "0");
        mPropagateBackpressure = !atoi(value);
        ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
    
        property_get("debug.sf.disable_hwc_vds", value, "0");
        mUseHwcVirtualDisplays = !atoi(value);
        ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
    }

    因为这里的SurfaceFlinger对象是一个StrongPointer,所以首先会走到RefBase的onFirstRef,这里就做了一件事情,MessageQueue初始化,保存SurfaceFlinger,并创建了消息队列所需的Looper和Handler。

    void SurfaceFlinger::onFirstRef()
    {
        mEventQueue.init(this);
    }
    
    void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
    {
        mFlinger = flinger;
        mLooper = new Looper(true);
        mHandler = new Handler(*this);
    }

    4、SurfaceFlinger实例化后,设置进程优先级和事务处理策略。

    5、然后,进入如下的SurfaceFlinger::init,主要是EGL配置、event线程启动、硬件composer初始化等,而且著名的VSync也在这里出现了。

    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);
    
            // set SFEventThread to SCHED_FIFO to minimize jitter
            struct sched_param param = {0};
            param.sched_priority = 2;
            if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
                ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
            }
    
            // Get a RenderEngine for the given display / config (can't fail)
            mRenderEngine = RenderEngine::create(mEGLDisplay,
                    HAL_PIXEL_FORMAT_RGBA_8888);
        }
    
        // Drop the state lock while we initialize the hardware composer. We drop
        // the lock because on creation, it will call back into SurfaceFlinger to
        // initialize the primary display.
        mHwc = new HWComposer(this);
        mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
    
        Mutex::Autolock _l(mStateLock);
    
        // retrieve the EGL context that was selected/created
        mEGLContext = mRenderEngine->getEGLContext();
    
        LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
                "couldn't create EGLContext");
    
        // make the GLContext current so that we can create textures when creating
        // Layers (which may happens before we render something)
        getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
    
        mEventControlThread = new EventControlThread(this);
        mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
    
        // initialize our drawing state
        mDrawingState = mCurrentState;
    
        // set initial conditions (e.g. unblank default device)
        initializeDisplays();
    
        mRenderEngine->primeCache();
    
        // start boot animation
        startBootAnim();
    
        ALOGV("Done initializing");
    }

    6、在Android系统中有一个ServiceManager,专门用来管理所有的服务,而SurfaceFlinger不是由ServiceManager启动的,因此需要向ServiceManager注册SurfaceFlinger,同时还注册了GpuService。

    7、最后通过SurfaceFlinger::run,进入消息循环,SurfaceFlinger启动成功,开始工作。

    void SurfaceFlinger::run() {
        do {
            waitForEvent();
        } while (true);
    }


  • 相关阅读:
    如何编写测试用例
    bug的合规描述
    Linux常用命令学习
    测试用列设计
    软件质量管理
    测试的分类
    软件工程模型
    软件测试核心概念
    Thinking in C++ 第十三章 动态对象创建
    python urllib
  • 原文地址:https://www.cnblogs.com/ztguang/p/12644893.html
Copyright © 2011-2022 走看看