美文网首页
SurfaceFlinger源码分析一

SurfaceFlinger源码分析一

作者: 梧叶已秋声 | 来源:发表于2022-08-25 17:21 被阅读0次

    Android图形显示系统(GUI)是个非常复杂的一部分,涉及到Activity,WindowManagerService,Choreographer,VSync ,Jank,View,Surface,SurfaceFlinger等。
    大致如下:

    https://www.jianshu.com/p/e4b19fc36a0e
    本文仅涉及SurfaceFlinger相关分析。
    下面带着这四个问题点去分析。

    Android应用程序是如何与SurfaceFlinger服务建立连接的?
    用来描述Android应用程序的UI元数据的SharedClient是如何创建的?
    Android应用程序是如何请求SurfaceFlinger服务 创建 一个Surface的?
    Android应用程序是如何请求SurfaceFlinger服务 渲染 一个Surface的?

    1. Android应用程序是如何与SurfaceFlinger服务建立连接的?

    Activity显示过程中,WindowManagerService 类addWindow 方法首先创建了 WindowState 对象,然后调用了其 attach() 方法。

    //  http://aosp.opersys.com/xref/android-12.0.0_r2/raw/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
    
        final Session mSession;
        void attach() {
            if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
            mSession.windowAddedLocked();
        }
    

    然后调用了 windowAddedLocked()

    //  http://aosp.opersys.com/xref/android-12.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/wm/Session.java#638
    class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
        final WindowManagerService mService;
        SurfaceSession mSurfaceSession;
        void windowAddedLocked() {
           ....
                mSurfaceSession = new SurfaceSession();
                mService.mSessions.add(this);
           ....
        }
    }
    
    // http://aosp.opersys.com/xref/android-12.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
    final ArraySet<Session> mSessions = new ArraySet<>();
    

    这里重点如下:
    1.创建了 SurfaceSession
    2.将 Session 对象添加到 WindowManagerService 类 mSessions 中。

    下面来看看SurfaceSession

    // http://aosp.opersys.com/xref/android-12.0.0_r2/raw/frameworks/base/core/java/android/view/SurfaceSession.java
    /**
     * An instance of this class represents a connection to the surface
     * flinger, from which you can create one or more Surface instances that will
     * be composited to the screen.
     * {@hide}
     */
    public final class SurfaceSession {
        // Note: This field is accessed by native code.
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        private long mNativeClient; // SurfaceComposerClient*
    
        private static native long nativeCreate();
        private static native void nativeDestroy(long ptr);
    
        /** Create a new connection with the surface flinger. */
        @UnsupportedAppUsage
        public SurfaceSession() {
            mNativeClient = nativeCreate();
        }
    
        /* no user serviceable parts here ... */
        @Override
        protected void finalize() throws Throwable {
            try {
                kill();
            } finally {
                super.finalize();
            }
        }
    
        /**
         * Remove the reference to the native Session object. The native object may still exist if
         * there are other references to it, but it cannot be accessed from this Java object anymore.
         */
        @UnsupportedAppUsage
        public void kill() {
            if (mNativeClient != 0) {
                nativeDestroy(mNativeClient);
                mNativeClient = 0;
            }
        }
    }
    

    这是一个hide标注的类,编译的时候会隐藏,说明不想让人调用。行数不多,所以都贴上来。
    声明了private static native long nativeCreate();,然后构造函数调用了nativeCreate表示用到了JNI,实际的实现在C++里。
    那么就要寻找Java对应的native函数。JNI中Java对应的Cpp的文件规则一般是
    [包名]_[类名].cpp,也就是说对应android_view_SurfaceSession.cpp文件。

    //http://aosp.opersys.com/xref/android-12.0.0_r2/xref/frameworks/base/core/jni/android_view_SurfaceSession.cpp
    static jlong nativeCreate(JNIEnv* env, jclass clazz) {
        SurfaceComposerClient* client = new SurfaceComposerClient();
        client->incStrong((void*)nativeCreate);
        return reinterpret_cast<jlong>(client);
    }
    

    incStrong涉及到智能指针相关概念,这里可以理解为 增加对象的强引用计数的作用,也就是SurfaceComposerClient对象 强引用计数 +1。

    创建了SurfaceComposerClient,但SurfaceComposerClient构造函数为空。
    reinterpret_cast用于任意类型的转换,允许将任意指针转换到其他指针类型。
    指向client的指针 强转为指向 long 的指针(JNI中对应的名字是jlong),返回到 Java。

    image.png

    但是调用inStrong会触发onFirstRef方法。这个函数是要重点关注的。

    // http://aosp.opersys.com/xref/android-12.0.0_r2/xref/frameworks/native/libs/gui/SurfaceComposerClient.cpp#1782
    
    sp<SurfaceComposerClient> mClient;
    
    SurfaceComposerClient::SurfaceComposerClient()
        : mStatus(NO_INIT)
    {
    }
    
    SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
        : mStatus(NO_ERROR), mClient(client)
    {
    }
    
    
    void SurfaceComposerClient::onFirstRef() {
        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
        if (sf != nullptr && mStatus == NO_INIT) {
            sp<ISurfaceComposerClient> conn;
            conn = sf->createConnection();
            if (conn != nullptr) {
                mClient = conn;
                mStatus = NO_ERROR;
            }
        }
    }
    
    

    onFirstRef 中初始化了ISurfaceComposerISurfaceComposerClient
    要弄清楚这2个是什么。

    // frameworks/native/libs/gui/SurfaceComposerClient.cpp
    /*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
        ComposerService& instance = ComposerService::getInstance();
        Mutex::Autolock _l(instance.mLock);
        if (instance.mComposerService == nullptr) {
            if (ComposerService::getInstance().connectLocked()) {
                ALOGD("ComposerService reconnected");
            }
        }
        return instance.mComposerService;
    }
    
    // frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
    sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
        const sp<Client> client = new Client(this);
        return client->initCheck() == NO_ERROR ? client : nullptr;
    }
    
    // frameworks/native/libs/gui/ISurfaceComposer.cpp
        virtual sp<ISurfaceComposerClient> createConnection()
        {
            Parcel data, reply;
            data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
            remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
            return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
        }
    

    先分析getComposerService,再看createConnection
    1.getComposerService
    调用ComposerService::getComposerService()会走到connectLocked(),然后调用
    waitForService<ISurfaceComposer>(name),初始化instance.mComposerService,而这个nameconnectLocked中定义了const String16 name("SurfaceFlinger")

    这里实际是通过ServiceManagerSurfaceFlinger这个String,获取到了SurfaceFlinger服务。

    // frameworks/native/include/private/gui/ComposerService.h
     sp<ISurfaceComposer> mComposerService;
    
    //frameworks/native/libs/gui/SurfaceComposerClient.cpp
    ComposerService::ComposerService()
    : Singleton<ComposerService>() {
        Mutex::Autolock _l(mLock);
        connectLocked();
    }
    
    bool ComposerService::connectLocked() {
        const String16 name("SurfaceFlinger");
        mComposerService = waitForService<ISurfaceComposer>(name);
        if (mComposerService == nullptr) {
            return false; // fatal error or permission problem
        }
    
        // Create the death listener.
      .......
        return true;
    }
    
    
    //frameworks/native/libs/fakeservicemanager/ServiceManager.cpp
    sp<IBinder> ServiceManager::waitForService(const String16& name) {
        return checkService(name);
    }
    
    
    // frameworks/native/libs/binder/IServiceManager.cpp
    sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
    {
        sp<IBinder> ret;
        if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
            return nullptr;
        }
        return ret;
    }
    
    
    
    // frameworks/native/cmds/servicemanager/ServiceManager.cpp
    Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
        *outBinder = tryGetService(name, false);
        // returns ok regardless of result for legacy reasons
        return Status::ok();
    }
    
    sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
        auto ctx = mAccess->getCallingContext();
    
        sp<IBinder> out;
        Service* service = nullptr;
        if (auto it = mNameToService.find(name); it != mNameToService.end()) {
            service = &(it->second);
    
            if (!service->allowIsolated) {
                uid_t appid = multiuser_get_app_id(ctx.uid);
                bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
    
                if (isIsolated) {
                    return nullptr;
                }
            }
            out = service->binder;
        }
    
        if (!mAccess->canFind(ctx, name)) {
            return nullptr;
        }
    
        if (!out && startIfNotFound) {
            tryStartService(name);
        }
    
        if (out) {
            // Setting this guarantee each time we hand out a binder ensures that the client-checking
            // loop knows about the event even if the client immediately drops the service
            service->guaranteeClient = true;
        }
    
        return out;
    }
    
    
    

    binder通讯架构如下所示。


    https://blog.csdn.net/codefly/article/details/17058607
    http://gityuan.com/2015/11/21/binder-framework/

    https://www.cnblogs.com/roger-yu/p/15714247.html
    SurfaceFlinger作为典型的Binder系统服务,遵循Binder服务设计的一般原则:
    Interface接口:ISurfaceComposer 、ISurfaceComposerClient
    Bp客户端:BpSurfaceComposer、BpSurfaceComposerClient
    Bn服务端:BnSurfaceComposer、BnSurfaceComposerClient
    服务实现:SurfaceFlinger、Client

    mComposerService定义是ISurfaceComposer,实际从ServiceManager返回的是BpSurfaceComposer

    mComposerService 代表了SurfaceFlinger服务的代理客户端。

    2.sf->createConnection()
    sf代表的是SurfaceFlinger服务。那么就应该调用 SurfaceFlinger.cpp中的SurfaceFlinger::createConnection()

    // frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
    sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
        const sp<Client> client = new Client(this);
        return client->initCheck() == NO_ERROR ? client : nullptr;
    }
    
    

    关于怎么到SurfaceFlinger.cpp的,因为remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply)

    // frameworks/native/libs/gui/ISurfaceComposer.cpp
        virtual sp<ISurfaceComposerClient> createConnection()
        {
            Parcel data, reply;
            data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
            remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
            return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
        }
    

    SurfaceFlinger端通过onTransact接口收到CREATE_CONNECTION消息后,实际调用了父类BnSurfaceComposer::onTransact接口进行动作分发,这里会再调到SurfaceFlingercreateConnection方法。

    createConnection这里以SurfaceFlinger为参数,新建了ClientClient继承自BnSurfaceComposerClientexplicit关键字用于修饰只有一个参数的类构造函数。~= default函数表示析构函数。
    Client::Client(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger)相当于Client::Client(const sp<SurfaceFlinger>& flinger) {mFlinger= flinger;}
    这种写法是类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表)... { 类的初始化 }使用初始化列表比使用赋值语句效率高。C++中有很多有意思的写法。

    //frameworks/native/services/surfaceflinger/Client.cpp
    class Client : public BnSurfaceComposerClient
    {
    public:
        explicit Client(const sp<SurfaceFlinger>& flinger);
        ~Client() = default;
    
        status_t initCheck() const;
       .....
    // constant
      sp<SurfaceFlinger> mFlinger;
       .....
    }
    //http://aosp.opersys.com/xref/android-12.0.0_r2/xref/frameworks/native/services/surfaceflinger/Client.cpp#40
    Client::Client(const sp<SurfaceFlinger>& flinger)
        : mFlinger(flinger)
    {
    }
    
    status_t Client::initCheck() const {
        return NO_ERROR;
    }
    
    

    因此,conn定义是ISurfaceComposerClient,实际创建的对象是BnSurfaceComposerClient

    回到我们一开始的问题,Android应用程序是如何与SurfaceFlinger服务建立连接的?

    通过SurfaceComposerClient类来与SurfaceFlinger服务建立一个连接了。

    WindowStateClient流程是
    WindowState.attach() ->Session ->SurfaceSession ->nativeCreate->onFirstRef->getComposerService(获取surfaceflinger 服务)和createConnection(以surfaceflinger 服务为参数new Client)

    SurfaceSession中的mNativeClient,持有 surfaceflinger服务的client,这样就联系起来了。

    // frameworks/base/core/java/android/view/SurfaceSession.java
        private long mNativeClient; // SurfaceComposerClient*
    
      /** Create a new connection with the surface flinger. */
        @UnsupportedAppUsage
        public SurfaceSession() {
            mNativeClient = nativeCreate();
        }
    

    参考链接:
    Android应用程序与SurfaceFlinger服务的关系概述和学习计划
    Android 源码 图形系统之 WindowState attach
    Android图形系统(六)-app与SurfaceFlinger服务连接过程
    Android智能指针
    Android 12(S) 图像显示系统 - 应用建立和SurfaceFlinger的沟通桥梁(三)
    SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程

    相关文章

      网友评论

          本文标题:SurfaceFlinger源码分析一

          本文链接:https://www.haomeiwen.com/subject/fiktnrtx.html