Android图形系统(六)-app与SurfaceFlinger服务连接过程

经过上一篇的概览,我们对Android图形系统渲染流程有了一个大致的了解,这篇开始做细节分析。那么先来总结下app与SurfaceFlinger服务连接过程。

经过前面的activity 、window 、view 的分析我们大致了解了Activity的显示过程。其实Surface的创建过程与Activity的显示过程密不可分。

那么就从Activity.makeVisible 开始捋下流程:

1 Activity.makeVisible getWindowManager() 并执行addView。

2 经过WindowManagerImpl 和 WindowManagerGlobal addView , 最终创建了ViewRootImpl

3 ViewRootImpl 内部会new Surface() ,它是一个Parcelable对象,可在进程间传递,但目前仅是一个空壳,还未被赋值。
同时,通过WindowManagerGlobal.getWindowSession()获取了Session实例,准备好了与WMS通信,并且Session内有个成员变量SurfaceSession值得关注,它的初始化是在Session的windowAddedLocked方法,先埋个伏笔。

4 根据流程我们知道,最终ViewRootImpl会在走setView, 在这个方法中开始了两个流程:

    requestLayout() 开启了绘制流程。

    mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, 
          getHostVisibility(), mDisplay.getDisplayId(),
          mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
          mAttachInfo.mOutsets, mInputChannel);       binder ipc 让WMS执行添加并显示window操作。

我们先来看看mWindowSession.addToDisplay,这个过程最终是在WMS执行addWindow方法:

          addWindow(…){
                ...
                //创建 WindowState  , WindowState是系统层面对Window管理的一个封装类,与Window一一对应的。
                WindowState win = new WindowState(...);
                …
                //别的都不看了,重点关注attach方法
                win.attach();
                ...
           }

         //WindowState.java
        void attach() {
             mSession.windowAddedLocked();//mSession 是 Session
        }

我们之前埋过伏笔的,windowAddedLocked创建了SurfaceSession 对象,并将当前 Session 添加到 WMS.mSessions 成员变量。SurfaceSession 的创建会调用 JNI,在 JNI 调用 nativeCreate()。

从这里开始要细说下了,这是应用程序与SurfaceFlinger建立连接的关键点:

跟踪到android_view_SurfaceSession.cpp 的nativeCreate()方法,创建了SurfaceComposerClient 对象,并且将这个对象赋值给类型为sp<SurfaceComposerClient>的智能指针mSession时,就会导致SurfaceComposerClient类的成员函数onFirstRef被调用:

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

SurfaceComposerClient类的成员函数getComposerService用来获得SurfaceFlinger服务的一个代理接口.

sp<ISurfaceComposer> ComposerService::getComposerService() {
       return ComposerService::getInstance().mComposerService;
}

ComposerService类是单例模式,当我们第一次调用它的静态函数getInstance的时候,它就会在构造函数中获得SurfaceFlinger服务的一个代理接口,并且保存在它的成员变量mComposerService中,同时会通过这个代理接口的成员函数getCblk来获得一块匿名共享内存mServerCblkMemory。这块匿名共享内存是由SurfaceFlinger服务创建的,用来描述系统显示屏的信息,例如,显示屏的个数、大小、方向、密度等等信息。

ComposerService::ComposerService()
: Singleton<ComposerService>() {
   const String16 name("SurfaceFlinger");
   while (getService(name, &mComposerService) != NO_ERROR) {
       usleep(250000);
   }

   mServerCblkMemory = mComposerService->getCblk();
   mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
           mServerCblkMemory->getBase());
}

这时候sm有值了,在接着onFirstRef()往下执行:

sp<ISurfaceComposerClient> conn = sm->createConnection();
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
   sp<ISurfaceComposerClient> bclient;
   sp<Client> client(new Client(this));
   status_t err = client->initCheck();
   if (err == NO_ERROR) {
       bclient = client;
   }
   return bclient;
}

是不是感觉特别绕,下面来简单总结下:

首先ComPoserService作为client 与 SurfaceFlinger server进行binder IPC , 获取到SurfaceFlinger创建的Client对象,它相当于是SurfaceFlinger内部对应用程序客户端的封装对象,而Client与SurfaceComposerClient又互为binder ipc的两端,SurfaceComposerClient为client端,Client为server端。

这样,应用进程成功通过SurfaceComposerClient与SurfaceFlinger建立了连接。

下篇分析app请求SurfaceFlinger创建Surface过程。

参考:
https://blog.csdn.net/Luoshengyang/article/details/7857163
https://blog.csdn.net/armwind/article/details/73436532

禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容