SurfaceFlinger启动过程分析

278 阅读5分钟

surfaceFlinger 在init.rc中是作为一个service存在的它声明如下

service surfaceflinger /system/bin/surfaceflinger
    class main
    user system
    group graphics drmrpc
    onrestart restart zygote

从上面的内容可以看出,surfaceflinger所属的class为main,这和zygote时同级的。但它的启动并不需要带任何参数。同时由于surfaceflinger是service,说明它是单独的可执行程序,程序路径为/system/bin/surfaceflinger 运行在单独的进程里,另外,从最后一行也能看出sf重启时要重启zygote。

Surfaceflinger主程序对应的文件是frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp 所以我们从这个文件入手。

int main(int argc, char** argv) {
    // 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());
    ps->startThreadPool();//启动binder线程

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

#if defined(HAVE_PTHREADS)
    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
#endif
    set_sched_policy(0, SP_FOREGROUND);

    // initialize before clients can connect
    flinger->init();//SF的初始化 

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//添加到SM中

    // run in this thread
    flinger->run();//sf运行起来

    return 0;
}

sf的主程序中做了以下事情: 1.初始binder的运行环境 2.创建Sf对象,并对其进行初始化 3.将Sf服务添加到ServiceManger中,以便向其他进程提供服务 4.SF在自己的线程中开始运行

SurfaceFlinger作为服务进程,必然需要通过Binder进行IPC通信,所以在一开始需要对Binder环境进行初始化。接着创建了SurfaceFlinger对象

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger()
    :   BnSurfaceComposer(),
        mTransactionFlags(0),
        mTransactionPending(false),
        mAnimTransactionPending(false),
        mLayersRemoved(false),
        mRepaintEverything(0),
        mRenderEngine(NULL),
        mBootTime(systemTime()),
        mVisibleRegionsDirty(false),
        mHwWorkListDirty(false),
        mAnimCompositionPending(false),
        mDebugRegion(0),
        mDebugDDMS(0),
        mDebugDisableHWC(0),
        mDebugDisableTransformHint(0),
        mDebugInSwapBuffers(0),
        mLastSwapBufferTime(0),
        mDebugInTransaction(0),
        mLastTransactionTime(0),
        mBootFinished(false),
        mPrimaryHWVsyncEnabled(false),
        mHWVsyncAvailable(false),
        mDaltonize(false)
{
    // 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;
        }
    }
}

构造方法很简单,只是都其成员进行初始化,读取一些配置信息,比如是否开启DDMS的调试。 接下来通过init方法对该对象进行初始化。这个初始化过程会做大量比较重要的工作。

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
//sf的初始化方法
void SurfaceFlinger::init() {
    status_t err;
    Mutex::Autolock _l(mStateLock);

    // initialize EGL for the default display
    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);//获取默认的显示设备
    eglInitialize(mEGLDisplay, NULL, NULL);//为默认的显示设备初始EGL环境

    // Initialize the H/W composer object.  There may or may not be an
    // actual hardware composer underneath.
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));//创建合成对象

    // First try to get an ES2 config
    err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
            &mEGLConfig);

    if (err != NO_ERROR) {
        // If ES2 fails, try ES1
        err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(),
                EGL_OPENGL_ES_BIT, &mEGLConfig);
    }
   ……
    EGLint r,g,b,a;
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE,   &r);
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE,  &b);
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_ALPHA_SIZE, &a);

    // get a RenderEngine for the given display / config (can't fail)
    mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig);//通过给定的设备创建渲染引擎

    // retrieve the EGL context that was selected/created
    mEGLContext = mRenderEngine->getEGLContext();//获取EGL context

    // figure out which format we got
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
            EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);

    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
            "couldn't create EGLContext");

    // initialize our non-virtual displays
  //初始化所有的非虚拟显示设备
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // set-up the displays that are already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            // All non-virtual displays are currently considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];
          //为显示设备创建BufferQueue用来管理其帧缓冲区 并通过FramebufferSurface进行管理
            sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, allocateHwcDisplayId(type), isSecure, token,
                    fbs, bq,
                    mEGLConfig);//为每个实体设备创建显示设备对象
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                // FIXME: currently we don't get blank/unblank requests
                // for displays other than the main display, so we always
                // assume a connected display is unblanked.
                ALOGD("marking display %d as acquired/unblanked", i);
                hw->acquireScreen();
            }
            mDisplays.add(token, hw);
        }
    }

    // make the GLContext current so that we can create textures when creating Layers
    // (which may happens before we render something)
    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);//将EGL context和默认的显示设备关联

    // start the EventThread
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true);//创建绘图延时对象
    mEventThread = new EventThread(vsyncSrc);//负责管理绘图延时Vsync信号
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, false);//创建合成延时对象
    mSFEventThread = new EventThread(sfVsyncSrc);//负责管理合成延时Vsync信号
    mEventQueue.setEventThread(mSFEventThread);

    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

     ……
}

在init方法中,sf做了以下的事: 1.为默认的显示设备初始EGL环境 2.创建合成对象 3.初始化所有的非虚拟显示设备 4.创建绘图延时Vysnc源 及 合成延时Vysnc源

void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();
    mEventTube = mEvents->getDataChannel();
    mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
            MessageQueue::cb_eventReceiver, this);//为sf的vsync信号注册事件回调
}

需要注意的是在main方法中创建的SurfaceFlinger是个强引用对象,所以在第一次调用同时也会会触发onFirstRef方法,这个方法会对SF的mEventQueue成员进行初始化。它是一个MessageQueue对象,负责SF的消息管理。

void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);
}

void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
    mFlinger = flinger;//持有sf的引用
    mLooper = new Looper(true);//为其创建一个Looper对象
    mHandler = new Handler(*this);//创建Handler
}

最后调用sf的run方法,这个方法会进入一个循环,不断等待消息的到来并进行处理

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

frameworks/native/services/surfaceflinger/MessageQueue.cpp
void MessageQueue::waitMessage() {
    do {
        IPCThreadState::self()->flushCommands();
        int32_t ret = mLooper->pollOnce(-1);//内部会调用MessageQueue的handleMessage方法对消息进行处理
        switch (ret) {
            case ALOOPER_POLL_WAKE:
            case ALOOPER_POLL_CALLBACK:
                continue;
            case ALOOPER_POLL_ERROR:
                ALOGE("ALOOPER_POLL_ERROR");
            case ALOOPER_POLL_TIMEOUT:
                // timeout (should not happen)
                continue;
            default:
                // should not happen
                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                continue;
        }
    } while (true);
}

//通过消息的handler对消息进行处理
void MessageBase::handleMessage(const Message&) {
    this->handler();
    barrier.open();
};

SF的消息来源有两种,一个是Vsync信号,这是通过注册的cb_eventReceiver事件回调来处理的,另一种可能是应用进程或者说客户端的消息,比如创建Layer的请求,就是通过发送消息的方式来处理的。

frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{
    class MessageCreateLayer : public MessageBase {//继承子messagbase
        SurfaceFlinger* flinger;
        Client* client;
        sp<IBinder>* handle;
        sp<IGraphicBufferProducer>* gbp;
        status_t result;
        const String8& name;
        uint32_t w, h;
        PixelFormat format;
        uint32_t flags;
    public:
        MessageCreateLayer(SurfaceFlinger* flinger,
                const String8& name, Client* client,
                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
                sp<IBinder>* handle,
                sp<IGraphicBufferProducer>* gbp)
            : flinger(flinger), client(client),
              handle(handle), gbp(gbp),
              name(name), w(w), h(h), format(format), flags(flags) {
        }
        status_t getResult() const { return result; }
        virtual bool handler() {//实现了handler 这个方法用于接收方处理消息
            result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);
            return true;
        }
    };

    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
    mFlinger->postMessageSync(msg);
    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}