Android SurfaceFlinger 学习之路(四)----SurfaceFlinger服务的启动与连接过程

http://windrunnerlihuan.com/2017/05/13/Android-SurfaceFlinger-%E5%AD%A6%E4%B9%A0%E4%B9%8B%E8%B7%AF-%E5%9B%9B-SurfaceFlinger%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%90%AF%E5%8A%A8%E4%B8%8E%E8%BF%9E%E6%8E%A5%E8%BF%87%E7%A8%8B/



       上一篇我们分析了Android的开机动画启动流程,这一篇我们基于上一篇的基础,分析一下SurfaceFlinger的启动,还有连接它的过程。

SurfaceFlinger的启动

启动概述

       SurfaceFlinger服务是一个独立进程,并且负责统一管理设备的帧缓冲区。通过上一篇开机动画流程分析,我们可以在init.rc中找到SurfaceFlinger服务配置的地方,位于system/core/rootdir/Init.rc中:

1
2
3
4
5
service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote

       在硬件设备/system/bin/下,可以找到SurfaceFlinger的应用程序。我们查看源码frameworks/native/services/surfaceflinger/Android.mk文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
###############################################################
# build surfaceflinger's executable
include $(CLEAR_VARS)

LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
# SurfaceFlinger启动文件
LOCAL_SRC_FILES:= \
    main_surfaceflinger.cpp 

LOCAL_SHARED_LIBRARIES := \
    libsurfaceflinger \
    libcutils \
    liblog \
    libbinder \
    libutils
    
# SurfaceFlinger是个动态库
LOCAL_MODULE:= surfaceflinger

ifdef TARGET_32_BIT_SURFACEFLINGER
LOCAL_32_BIT_ONLY := true
endif

include $(BUILD_EXECUTABLE)

       从Makefile文件可以看出,相关依赖和主文件会被编译成libsurfaceflinger.so,然后SurfaceFlinger是对库的一个“封装调用”,里面有个main_surfaceflinger.cpp,我们可以沿着它的main函数往下分析。

       启动流程大概如下图,我才刚刚学了时序图,不知道画的对不对。。。。

启动过程

       SurfaceFlinger的main函数在framework/native/services/surfaceflinger/main_surfaceflinger.cpp中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int main(int, char**) {
    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    //在该进程设置了binder线程池最大数为4
    ProcessState::self()->setThreadPoolMaxThreadCount(4);

    // start the thread pool
    //这里其实只是将当前线程加入到这个Binder线程池中去
    sp ps(ProcessState::self());
    ps->startThreadPool();

    // instantiate surfaceflinger
    //创建一个SurfaceFlinger强引用对象
    sp 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
    //调用SurfaceFlinger的init函数
    flinger->init();

    // publish surface flinger
    //把SurfaceFlinger服务注册到ServiceManager中
    sp sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

    // run in this thread
    //运行这个UI渲染流程
    flinger->run();

    return 0;
}

       main函数包含以下几件事情:

  1. 调用当前进程中的ProcessState单例的成员函数startThreadPool来启动一个Binder线程池,将线程池最大数量设为4,并且调用当前线程中的IPCThreadState单例来将当前线程加入到前面所启动的Binder线程池中去;
  2. 创建一个SurfaceFlinger的对象,并赋给他的强引用指针;
  3. 执行SurfaceFlinger的init函数;
  4. 将SurfaceFlinger服务注册到ServiceManager当中;
  5. 运行SurfaceFlinger的UI渲染流程。

       比较重要的步骤就是创建SurfaceFlinger对象,执行init函数,和运行UI渲染流程。我们逐个分析。

创建SurfaceFlinger对象

       new一个SurfaceFlinger对象,并赋给强引用指针。我们先看看它的构造函数,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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),//主显屏硬件VSync信号关闭
        mHWVsyncAvailable(false),
        mDaltonize(false),
        mHasColorMatrix(false)
{
    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");
}

       构造函数中主要初始化一系列变量,没什么重要信息。SurfaceFlinger类继承了BnSurfaceComposer类,而后者是一个实现了ISurfaceComposer接口的Binder本地对象类。

       由于Service Manager的Binder代理对象的成员函数addService的第二个参数是一个类型为IBinder的强指针引用。当一个对象第一次被一个强指针引用时,那么这个对象的成员函数onFirstRef就会被调用。因此,接下来前面所创建的SurfaceFlinger实例的成员函数onFirstRef就会被调用,以便可以继续执行初始化操作。我们继续查看:

1
2
3
4
5
6
7
8
// mEventQueue在SurfaceFlinger.h中定义
// these are thread safe
mutable MessageQueue mEventQueue;

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

       MessageQueue 类在frameworks/native/services/surfaceflinger/MessageQueue.h中定义,实现位于frameworks/native/services/surfaceflinger/MessageQueue.cpp中,init函数如下:

1
2
3
4
5
6
void MessageQueue::init(const sp& flinger)
{
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}

       调用MessageQueue的init,在MessageQueue中建了一个Looper和Handler,注意不是Java中的,native实现的。到后面就可以看到SF的核心就是接收消息,处理消息。对于消息处理,可以参考之前的一片文章Android消息处理零散分析。

调用init函数

       回到SurfaceFlinger.cpp中,继续分析init函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
void SurfaceFlinger::init() {
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");

    status_t err;
    Mutex::Autolock _l(mStateLock);
    
    //初始化OpenGL 图形库相关配置
    // initialize EGL for the default display 将EGL初始化成默认的显示,默认是主屏幕,编号为0
    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(this));
            
    // get a RenderEngine for the given display / config (can't fail)
    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());

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

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

    // initialize our non-virtual displays
    //创建显示设备对象
    for (size_t i=0 ; 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 token = mBuiltinDisplays[i];

            sp producer;
            sp consumer;
            BufferQueue::createBufferQueue(&producer, &consumer,
                    new GraphicBufferAlloc());

            sp fbs = new FramebufferSurface(*mHwc, i,
                    consumer);
            int32_t hwcId = allocateHwcDisplayId(type);
            sp hw = new DisplayDevice(this,
                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
                    fbs, producer,
                    mRenderEngine->getEGLConfig());
            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 %zu as acquired/unblanked", i);
                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
            }
            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
    //启动EventThread。监听和处理SurfaceFlinger中的事件
    //app的VSync信号
    sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc);
    //SF的VSync信号
    sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, true, "sf");
    mSFEventThread = new EventThread(sfVsyncSrc);
    //SF的VSync信号控制逻辑也要放入mEventQueue消息队列
    mEventQueue.setEventThread(mSFEventThread);
    //VSync信号闸刀控制线程
    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

    // set a fake vsync period if there is no HWComposer
    //如果硬件设备检测有问题,或者没有硬件设备驱动提供Vsync信号,则设置软件VSync信号
    if (mHwc->initCheck() != NO_ERROR) {
        mPrimaryDispSync.setPeriod(16666667);
    }

    // initialize our drawing state
    mDrawingState = mCurrentState;

    // set initial conditions (e.g. unblank default device)
    //初始化显示设备,调用initializeDisplays完成
    initializeDisplays();

    // start boot animation
    //启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程
    startBootAnim();
}

       init函数主要做了以下事情:

  1. 初始化OpenGL ES图形库;
  2. 创建显示设备的抽象代表,负责和显示设备打交道;
  3. 创建显示设备对象;
  4. 启动EventThread。监听和处理SurfaceFlinger中的事件;
  5. 设置软件VSync信号周期;
  6. 初始化显示设备,调用initializeDisplays完成;
  7. 启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程。

       其中初始化OpenGL ES可以参考Android SurfaceFlinger 学习之路(二)—-SurfaceFlinger概述,后期如果有机会再次会细讲。创建显示设备我们后面分析管理图形缓冲区时候会细讲。还有VSync信号,后面会单独开章节分析。这里我们大概过一个流程。

执行run函数

       然后继续往下看,执行SurfaceFlinger的run函数:

1
2
3
4
5
6
7
8
9
void SurfaceFlinger::run() {
    do {
        waitForEvent();
    } while (true);
}

void SurfaceFlinger::waitForEvent() {
    mEventQueue.waitMessage();
}

       run函数非常简单,但却是SF的核心,是个while循环,循环处理消息等。
       然后又调用了EventQueue的waitMessage方法,记住这里是在主线程中循环调用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void MessageQueue::waitMessage() {
    do {
        //flushCommands主要是清理工作的
        IPCThreadState::self()->flushCommands();
        //pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息
        int32_t ret = mLooper->pollOnce(-1);
        switch (ret) {
            case Looper::POLL_WAKE:
            case Looper::POLL_CALLBACK:
                continue;
            case Looper::POLL_ERROR:
                ALOGE("Looper::POLL_ERROR");
            case Looper::POLL_TIMEOUT:
                // timeout (should not happen)
                continue;
            default:
                // should not happen
                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                continue;
        }
    } while (true);
}

       我们来看下waitMessage方法,flushCommands主要是清理工作的,和Binder驱动的交互关了。而pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息。这里的消息只有自己在Handler中发的消息,还有在setEventThread中自己添加的fd。

消息处理

给SurfaceFlinger发送消息

       我们以SurfaceFlinger与客户端通信创建Surface为例,看看如何给SurfaceFlinger发送消息。这个我们下面会讲到,这里先举个栗子。

       从上一篇开机动画的简述流程可以得知,BootAnimation的readyToRun函数中有一句:

1
2
3
// create the native surface
//调用SurfaceComposerClient对象mSession的成员函数createSurface可以获得一个SurfaceControl对象control
sp control = session()->createSurface(String8("BootAnimation"),

       BootAnimation类的成员函数session用来返回BootAnimation类的成员变量mSession所描述的一个SurfaceComposerClient对象。通过调用SurfaceComposerClient对象mSession的成员函数createSurface可以获得一个SurfaceControl对象control。
       SurfaceComposerClient类的成员函数createSurface首先调用内部的Binder代理对象mClient(frameworks/native/services/surfaceflinger/Client.cpp)来请求SurfaceFlinger返回一个类型为(class Handle : public BBinder, public LayerCleaner)Binder代理对象(封装了SurfaceFlinger的sp指针和Layer对象)handle,和一个IGraphicBufferProducer的sp指针(封装了SurfaceFlinger的sp指针)gbp,接着再使用这两个对象来创建一个SurfaceControl对象。创建出来的SurfaceControl对象的成员变量handle就指向了从SurfaceFlinger返回来的类型为Handle 的Binder代理对象。有了这个Binder代理对象之后,SurfaceControl对象就可以和SurfaceFlinger服务通信了。

       我们关注的就是Client的createSurface函数,frameworks/native/services/surfaceflinger/Client.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp* handle,
        sp* 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* handle;
        sp* 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* handle,
                sp* 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 msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
    //调用SF的postMessageSync发送同步消息
    mFlinger->postMessageSync(msg);
    return static_cast( msg.get() )->getResult();
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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()的地方就能退出了。实现位于framework/native/services/surfaceflinger/MessageQueue.cpp中:

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

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

1
2
3
4
5
6
7
8
9
10
status_t SurfaceFlinger::postMessageSync(const sp& 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)。

SurfaceFlinger处理消息

       从上面waitMessage得知,消息处理都位于里面无限循环处的的int32_t ret = mLooper->pollOnce(-1);我们追寻到Looper中的pollOnce函数,位于system/core/libutils/Looper.cpp中:

1
2
3
4
5
6
7
8
9
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    int result = 0;
    for (;;) {
        
        ......

        result = pollInner(timeoutMillis);
    }
}

       函数中,而pollOnce又会调用pollInner:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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 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),这个即是我们上面提到的framework/native/services/surfaceflinger/MessageQueue.cpp中:

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

       调用handleMessage执行handler(),所以SurfaceFlinger创建Surface的核心代码就是SurfaceFlinger的createLayer函数,回到刚才的createSurface函数中的片段:

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

       执行完成后,打开barrier。

       这个只是个简单例子,我们后续会详细讲解它的消息处理流程。

SurfaceFlinger服务连接过程

概述

       第一篇文章描述Android应用程序和SurfaceFlinger服务的关系时提到,每一个有UI的Android应用程序都需要与SurfaceFlinger服务建立一个连接,以便可以通过这个连接来请求SurfaceFlinger服务为它创建和渲染Surface。我们将以Android系统的开机动画应用程序为例,详细描述Android应用程序是如何与SurfaceFlinger服务建立连接的。

       从从上一篇文章可以知道,Android系统的开机动画是主要一个BootAnimation对象来实现,这个BootAnimation对象在构造的时候,会在内部创建一个SurfaceComposerClient对象来负责创建一个到SurfaceFlinger服务的连接。

       BootAnimation类的构造函数实现在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中:

1
2
3
4
BootAnimation::BootAnimation() : Thread(false), mZip(NULL)
{
    mSession = new SurfaceComposerClient();
}

       mSession是BootAnimation类的成员变量,它是一个类型为SurfaceComposerClient的强指针,即sp < SurfaceComposerClient > 。在SurfaceComposerClient类内部,有一个类型为sp< ISurfaceComposerClient >的成员变量mClient,如下图:

       SurfaceComposerClient类的成员变量mClient指向的实际上是一个类型为BpSurfaceComposerClient的Binder代理对象,而这个类型为BpSurfaceComposerClient的Binder代理对象引用的是一个类型为Client的Binder本地对象,位于frameworks/native/services/surfaceflinger/Client.cpp。类型为Client的Binder本地对象是由SurfaceFlinger服务来负责创建的,并且运行在SurfaceFlinger服务中,用来代表使用SurfaceFlinger服务的一个客户端,即一个与UI相关的Android应用程序

       由于Client类和BpSurfaceComposerClient类分别是一个Binder本地对象类和一个Binder代理对象类,它们都是根据Android系统在应用程序框架层提供的Binder进程间通信库来实现的。类图如下:

       Client类的实现结构图

       BpSurfaceComposerClient类的实现结构图

       Client类和BpSurfaceComposerClient类均实现了类型为ISurfaceComposerClient的Binder接口。ISurfaceComposerClient接口有个createSurface接口,它们定义在文件frameworks/base/include/surfaceflinger/ISurfaceComposerClient.h中,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
class ISurfaceComposerClient : public IInterface
{
/*
     * Requires ACCESS_SURFACE_FLINGER permission
     */
    virtual status_t createSurface(
            const String8& name, uint32_t w, uint32_t h,
            PixelFormat format, uint32_t flags,
            sp* handle,
            sp* gbp) = 0;

}

       在接下来的文章中,我们再详细分析ISurfaceComposerClient接口的成员函数createSurface的实现。

理解了SurfaceComposerClient、Client以及BpSurfaceComposerClient这三个类的关系之后,接下来我们就可以分析Android系统的开机动画应用程序bootanimation是如何与SurfaceFlinger服务建立连接的。

       SurfaceComposerClient类继承了RefBase类,因此,当BootAnimation类在构造函数创建了一个SurfaceComposerClient对象,并且将这个对象赋值给类型为sp< SurfaceComposerClient >的智能指针mSession时,就会导致SurfaceComposerClient类的成员函数onFirstRef被调用,而SurfaceComposerClient类的成员函数onFirstRef在调用的过程中,就会在应用程序bootanimation与SurfaceFlinger服务建立一个连接。这个流程如下:

       接下来,我们就详细分析每一个步骤。

获取SurfaceFlinger服务代理接口

       进入frameworks/native/libs/gui/SurfaceComposerClient.cpp中,找到onFristRef函数:

1
2
3
4
5
6
7
8
9
10
void SurfaceComposerClient::onFirstRef() {
    sp sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

       SurfaceComposerClient类的成员函数getComposerService用来获得SurfaceFlinger服务的一个代理接口,它的实现同样位于frameworks/native/libs/gui/SurfaceComposerClient.cpp中:

1
2
3
4
5
6
7
8
9
10
/*static*/ sp ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
        ALOGD("ComposerService reconnected");
    }
    return instance.mComposerService;
}

       ComposerService类是单例模式,当我们第一次调用它的静态函数getInstance的时候,它就会在构造函数中获得SurfaceFlinger服务的一个代理接口,并且保存在它的成员变量mComposerService中,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ComposerService::ComposerService()
: Singleton() {
    Mutex::Autolock _l(mLock);
    connectLocked();
}

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast(this));
    mComposerService->asBinder()->linkToDeath(mDeathObserver);
}

       在ComposerService类的构造函数中,会获得SurfaceFlinger服务的代理接口。

连接SurfaceFlinger服务

       回到SurfaceComposerClient类的成员函数onFirstRef中,由于SurfaceFlinger服务实现了ISurfaceComposer接口,因此,我们可以将前面获得的SurfaceFlinger服务的代理接口赋值给一个类型为ISurfaceComposer的强指针sm,并且调用它的成员函数createConnection来请求SurfaceFlinger服务创建一个连接,即创建一个类型为Client的Binder对象,并且将这个Binder对象的一个代理接口conn返回来。SurfaceComposerClient类获得了SurfaceFlinger服务返回来的Client代理接口conn之后,就将它保存自己的成员变量mClient中,这样开机动画应用程序bootanimation后续就可以通过它来请求SurfaceFlinger创建和渲染Surface了。

       接下来,我们就继续分析SurfaceFlinger服务的成员函数createConnection的实现,以便可以了解它是如何为Android应用程序创建一个连接的。

       进入SurfaceFlinger.cpp中查看createConnection函数:

1
2
3
4
5
6
7
8
9
10
sp SurfaceFlinger::createConnection()
{
    sp bclient;
    sp client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}

       它的实现很简单,只是创建了一个类型为Client的Binder对象client,并且获得它的一个ISurfaceComposerClient接口,最后将这个ISurfaceComposerClient接口,即一个Client代理对象,返回给开机动画应用程序bootanimation。

       接下来,我们再继续分析Client对象的创建过程,,即Client类的构造函数的实现:

1
2
3
4
Client::Client(const sp& flinger)
    : mFlinger(flinger)
{
}

       这个很简单,就是保存了SurfaceFlinger的强引用对象。
       回到SurfaceFlinger类的成员函数createConnection中,它将一个指向了一个Client对象的ISurfaceComposerClient接口返回到开机动画应用程序bootanimation之后,开机动画应用程序bootanimation就可以将它封装成一个类型为BpSurfaceComposerClient的Binder代理对象。

       类型为BpSurfaceComposerClient的Binder代理对象的封装过程实现在SurfaceFlinger服务的Binder代理对象类BpSurfaceComposer的成员函数createConnection中,位于frameworks/native/libs/gui/ISurfaceCompose.cpp中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class BpSurfaceComposer : public BpInterface
{
public:

 ......
 virtual sp createConnection()
    {
        uint32_t n;
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
        return interface_cast(reply.readStrongBinder());
    }
......
}

       interface_cast是一个模板函数,它定义在framework/native/include/binder/IInterface.h文件中:

1
2
3
4
5
template<typename INTERFACE>
inline sp interface_cast(const sp& obj)
{
    return INTERFACE::asInterface(obj);
}

       从这里就可以看出,当模板参数为ISurfaceComposerClient的时候,模板函数interface_cast实际就是通过调用ISurfaceComposerClient类的静态成员函数asInterface来将参数obj所描述的一个Binder代理对象,即一个BpBinder对象,封装成一个BpSurfaceComposerClient对象。

       ISurfaceComposerClient类的静态成员函数asInterface是由frameworks/native/libs/gui/ISurfaceComposerClient.cpp文件中的IMPLEMENT_META_INTERFACE宏来定义的,如下所示:

1
IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");

       IMPLEMENT_META_INTERFACE宏展开后,得到ISurfaceComposerClient类的静态成员函数asInterface的实现如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
android::sp ISurfaceComposerClient::asInterface(const android::sp& obj)       {                                                                                         
    android::sp intr;                                                        
        
    if (obj != NULL) {                                                                         
        intr = static_cast(                                                      
                    obj->queryLocalInterface(ISurfaceComposerClient::descriptor).get());    
            
        if (intr == NULL) {                    
            intr = new BpSurfaceComposerClient(obj);                                            
        }                                              

    return intr;                                      
}

       参数obj是从BpSurfaceComposer类的成员函数createConnection传进来的,它指向的实际上是一个BpBinder对象。当我们调用一个BpBinder对象的成员函数queryLocalInterface时,获得的是一个NULL指针,因此,ISurfaceComposerClient类的静态成员函数asInterface最后就会将参数obj所指向的一个BpBinder对象封装成一个BpSurfaceComposerClient对象,并且返回给调用者。

       至此,开机动画应用程序bootanimation就通过SurfaceComposerClient类来与SurfaceFlinger服务建立一个连接了。

小结

       本篇主要学习了SurfaceFlinger的启动和连接过程,应该算不太难的部分。下几节我们将逐步分析消息处理、创建surface、管理GraphicBuffer、VSync信号、Fence机制等等内容。






你可能感兴趣的:(Android,SurfaceFlinger)