美文网首页
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