android graphic(3)—surfaceflinger的启动流程

来源:互联网 发布:win7网络加速器 编辑:程序博客网 时间:2024/05/16 11:22

  • 如何启动
  • 执行流程
    • new SurfaceFlinger
    • init函数
    • run函数
      • 给SF发消息
      • SF处理消息


这篇文章只分析SF消息驱动流程的建立,不涉及具体的功能实现,关于SF和HWC如何交互后续分析,基于android 4.4,以下将surfaceflinger简称为SF。

如何启动

android 4.4中SF在init.rc中启动,如下所示:

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

可以看出,SF是/system/bin/下的一个应用程序,在makefile中搜索LOCAL_MODULE:= surfaceflinger即可找到具体的makefile和代码,

#首先是个SF的动态库LOCAL_MODULE:= libsurfaceflingerinclude $(BUILD_SHARED_LIBRARY)# 其次是surfaceflinger,LOCAL_SRC_FILES:= \    main_surfaceflinger.cpp LOCAL_SHARED_LIBRARIES := \    libsurfaceflinger \    libcutils \    liblog \    libbinder \    libutilsLOCAL_MODULE:= surfaceflingerinclude $(BUILD_EXECUTABLE)

从上面makefile就能看出来,首先有个动态库libsurfaceflinger.so,然后SF只是对库的一个“封装调用”,多了一个main_surfaceflinger.cpp,里面仅有个main函数,下面展开。

执行流程

只关注SF流程,不关注binder线程等。

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);    // start the thread pool    sp<ProcessState> ps(ProcessState::self());    ps->startThreadPool();    // instantiate surfaceflinger    // ①    sp<SurfaceFlinger> flinger = new SurfaceFlinger();#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();    // publish surface flinger    sp<IServiceManager> sm(defaultServiceManager());    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);    // run in this thread    // ③    flinger->run();    return 0;}

main函数主要的内容包含三方面,逐步分析。

new SurfaceFlinger

首先,new了一个SF,并使用sp指针,所以我们需要关注SF类中是否实现了onFirstRef()函数。

sp<SurfaceFlinger> flinger = new SurfaceFlinger();

构造函数中初始化一些值,

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),        mDebugFps(0),        mDebugDisableTransformHint(0),        mDebugInSwapBuffers(0),        mLastSwapBufferTime(0),        mDebugInTransaction(0),        mLastTransactionTime(0),        mBootFinished(false),        mPrimaryHWVsyncEnabled(false),        mHWVsyncAvailable(false),        mDaltonize(false){//一些调试的变量等}

SF确实实现了onFirstRef()函数,

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

调用MessageQueue的init,在MessageQueue中建了一个Looper和Handler,注意不是java中的,native实现的。 到后面就可以看到SF的核心就是接收消息,处理消息。

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

init函数

init中主要创建了OpenGL ES环境,对显示器的初始化等。

void SurfaceFlinger::init() {    ALOGI(  "SurfaceFlinger's main thread ready to run. "            "Initializing graphics H/W...");    status_t err;    Mutex::Autolock _l(mStateLock);    // initialize EGL for the default display    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);    eglInitialize(mEGLDisplay, NULL, NULL);    // 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);    }    if (err != NO_ERROR) {        // still didn't work, probably because we're on the emulator...        // try a simplified query        ALOGW("no suitable EGLConfig found, trying a simpler query");        err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), 0, &mEGLConfig);    }    if (err != NO_ERROR) {        // this EGL is too lame for android        LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");    }    // print some debugging info    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);    ALOGI("EGL informations:");    ALOGI("vendor    : %s", eglQueryString(mEGLDisplay, EGL_VENDOR));    ALOGI("version   : %s", eglQueryString(mEGLDisplay, EGL_VERSION));    ALOGI("extensions: %s", eglQueryString(mEGLDisplay, EGL_EXTENSIONS));    ALOGI("Client API: %s", eglQueryString(mEGLDisplay, EGL_CLIENT_APIS)?:"Not Supported");    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);    // 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();    // 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];            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);    // start the EventThread    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,            vsyncPhaseOffsetNs, true);    mEventThread = new EventThread(vsyncSrc);    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,            sfVsyncPhaseOffsetNs, false);    mSFEventThread = new EventThread(sfVsyncSrc);    mEventQueue.setEventThread(mSFEventThread);    mEventControlThread = new EventControlThread(this);    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);    // set a fake vsync period if there is no HWComposer    if (mHwc->initCheck() != NO_ERROR) {        mPrimaryDispSync.setPeriod(16666667);    }    // initialize our drawing state    mDrawingState = mCurrentState;    // set initial conditions (e.g. unblank default device)    initializeDisplays();    // start boot animation    startBootAnim();}

最后部分启动了开机动画程序bootanim,肯定是SF启动起来后才能去执行绘画相关的进程。

void SurfaceFlinger::startBootAnim() {    // start boot animation    property_set("service.bootanim.exit", "0");    property_set("ctl.start", "bootanim");}

run函数

run函数非常简单,但却是SF的核心,是个while循环,循环处理消息等。

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

可以看到,接收处理消息的关键在mLooper->pollOnce(-1);

void MessageQueue::waitMessage() {    do {        IPCThreadState::self()->flushCommands();        int32_t ret = mLooper->pollOnce(-1);        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);}

给SF发消息

首先关注如何给SF发送消息,以Client创建surface为例,

status_t Client::createSurface(        const String8& name,        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,        sp<IBinder>* handle,        sp<IGraphicBufferProducer>* gbp){    /*     * createSurface must be called from the GL thread so that it can     * have access to the GL context.     */    class MessageCreateLayer : public MessageBase {        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; }        //handler是执行消息动作的地方,        virtual bool 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);    //调用SF的postMessageSync发送同步消息    mFlinger->postMessageSync(msg);    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();}

类MessageBase就是封装了类似于一个Handler,里面有个Barrier,我们能够猜到,这个Barrier 肯定是用来进行同步发送消息的,利用Barrier 去等待”wait”。

class MessageBase : public MessageHandler{public:    MessageBase();    // return true if message has a handler    virtual bool handler() = 0;    // waits for the handler to be processed    void wait() const { barrier.wait(); }protected:    virtual ~MessageBase();private:    virtual void handleMessage(const Message& message);    mutable Barrier barrier;};

MessageBase的handleMessage函数,可以看到MessageBase的handler()函数是真正消息处理的地方,执行完成后,调用barrier.open();,打开barrier,这样调用barrier.wait()的地方就能退出了。

void MessageBase::handleMessage(const Message&) {    this->handler();    barrier.open();};

接着分析mFlinger->postMessageSync(msg);,这是给SF发同步消息的入口,当然也可以发异步消息,实现是类似的,

        status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,                nsecs_t reltime, uint32_t flags) {            //向mEventQueue,即MessageQueue中发送消息            status_t res = mEventQueue.postMessage(msg, reltime);            //这里等着,同步就在同步函数中等着            if (res == NO_ERROR) {                msg->wait();            }            return res;        }

可以看到在同步发送消息中,barrier在postMessageSync函数中一直等着呢(wait),等待SF调用handleMessage()函数去将barrier这个栅栏打开(open)。

SF处理消息

上面提到,处理消息的关键就在mLooper->pollOnce(-1);函数中,而pollOnce又会调用pollInner,只摘取了处理消息的一段,

int Looper::pollInner(int timeoutMillis) {  // Invoke pending message callbacks.    mNextMessageUptime = LLONG_MAX;    while (mMessageEnvelopes.size() != 0) {        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);        if (messageEnvelope.uptime <= now) {            // Remove the envelope from the list.            // We keep a strong reference to the handler until the call to handleMessage            // finishes.  Then we drop it so that the handler can be deleted *before*            // we reacquire our lock.            { // obtain handler                sp<MessageHandler> handler = messageEnvelope.handler;                Message message = messageEnvelope.message;                //把头删除啊                mMessageEnvelopes.removeAt(0);                mSendingMessage = true;                mLock.unlock();#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS                ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",                        this, handler.get(), message.what);#endif                          //处理消息啊                handler->handleMessage(message);            } // release handler            mLock.lock();            mSendingMessage = false;            result = ALOOPER_POLL_CALLBACK;        } else {            // The last message left at the head of the queue determines the next wakeup time.            mNextMessageUptime = messageEnvelope.uptime;            break;        }    }}

从上面代码可以看到,发给SF的消息被封装在MessageEnvelope结构中,SF一直在mMessageEnvelopes队列中从头部取出消息,然后执行,即handler->handleMessage(message);

void MessageBase::handleMessage(const Message&) {    this->handler();    //打开栅栏    barrier.open();};

调用handleMessage执行handler(),所以SF创建Surface的核心代码就是SF的createLayer函数,

            result = flinger->createLayer(name, client, w, h, format, flags,                    handle, gbp);

执行完成后,打开barrier。

0 0