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


这篇文章只分析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:= libsurfaceflinger

include $(BUILD_SHARED_LIBRARY)

# 其次是surfaceflinger,
LOCAL_SRC_FILES:= \
    main_surfaceflinger.cpp 

LOCAL_SHARED_LIBRARIES := \
    libsurfaceflinger \
    libcutils \
    liblog \
    libbinder \
    libutils

LOCAL_MODULE:= surfaceflinger

include $(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。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值