一、前言:
之前讲述了native层如何使用SurfaceFlinger
,我们只是看到了简单的API调用,从本文开始,我们逐步进行SurfaceFlinger
内部结构的分析。话不多说,莱茨狗~
二、类图:
2.1、总体架构:
先看下SurfaceFlinger
的关键成员和我们BootAnimation
侧关键成员如何对应起来,这不是严格的UML类图,但是这么画我觉着很容易理解,就先这么画了。
可以看出:
SurfaceFlinger
侧会为BootAnimation
创建一个Client,其实,SF会为每个APP都创建一个Client;SurfaceFlinger
侧有一个BufferQueueLayer
(Layer的子类)对应APP侧的SurfaceControl
,允许有一个APP有多个Layer,同时,SF会生成多个SurfaceControl
;BufferQueueLayer
是一个buffer队列,队列有一个消费者mConsumer
和一个生产者mProducer
;- APP侧的
SurfaceControl
当中有一个Surface
; Surface
当中又有一个数组mSlots
表示64个buffer,对应SF当中其实也有这么一个数组,如果数组来管理这些buffer,这个是比较复杂的流程,后面单独写一篇文章介绍;
2.2、代理关系:
上面看到好多类似于SurfaceCompser
的字眼,到底啥关系呢?我给你画个图:
熟悉Binder机制的朋友都应该能看懂,Bpxxxx一般就是代理类,Bnxxxx一般就是本地类,这样APP侧调用mClient就像调用Client一模一样的,底层Binder帮你处理了。一种RPC的思想。
三、APP连接SurfaceFlinger:
前面画了静态的类图,接下来我们看下APP如何去和SurfaceFlinger建立连接。
-
APP侧获得
SurfaceFlinger
服务:-
在
BootAnimation
构造函数中,我们会通过mSession = new SurfaceComposerClient();
来获取SF的代理类。BootAnimation::BootAnimation(sp<Callbacks> callbacks) : Thread(false), mClockEnabled(true), mTimeIsAccurate(false), mTimeFormat12Hour(false), mTimeCheckThread(nullptr), mCallbacks(callbacks) { // SurfaceFlinger在客户端的代理 mSession = new SurfaceComposerClient(); // 。。。删除非关键代码 }
-
-
强引用SF服务:
-
强引用时候就会执行
SurfaceComposerClient::onFirstRef()
;void BootAnimation::onFirstRef() { // 将当前 BootAnimation 对象链接到图形服务的死亡通知。这意味着如果图形服务崩溃或退出,当前对象将收到通知。 status_t err = mSession->linkToComposerDeath(this); if (err == NO_ERROR) { // 预加载开机动画文件 preloadAnimation(); // 。。。 } }
-
里面会调用
conn = sf->createConnection();
这里面的sf表示SurfaceFlinger
,调用这个方法就可以在SF当中创建一个Client了。void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); if (sf != nullptr && mStatus == NO_INIT) { sp<ISurfaceComposerClient> conn; // 调用这句之后,SF侧会创建一个Client来对应APP conn = sf->createConnection(); if (conn != nullptr) { mClient = conn; mStatus = NO_ERROR; } } }
-
BpSurfaceComposer
当中发起Binder调用:virtual sp<ISurfaceComposerClient> createConnection() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); // 发起Binder调用 remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply); return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); }
-
SurfaceFlinger
侧创建Client:SurfaceFlinger
端通过onTransact
收到CREATE_CONNECTION
消息并处理:status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t credentialCheck = CheckTransactCodeCredentials(code); if (credentialCheck != OK) { return credentialCheck; } // 调用了父类BnSurfaceComposer的方法去处理消息 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); // ... }
看到没有,转手就调用了父类的
onTransact
方法:status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case CREATE_CONNECTION: { // 处理链接,创建Client CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = IInterface::asBinder(createConnection()); reply->writeStrongBinder(b); return NO_ERROR; } // 。。。 } // 。。。 }
由于C++的多态性,父类指针指向子类对象,因此这个
createConnection
方法属于子类SurfaceFlinger
的:sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { return initClient(new Client(this)); }
至此,
Client
就创建好了。
-
四、总结:
本文主要讲了SurfaceFlinger内部几个非常重要的概念,并且,分析了APP和SurfaceFlinger建立连接的时候,SurfaceFlinger干了啥,后续再分析:如何获取画布,如何往画布上作图,如何提交已经做好图的画布,并且会专门分析buffer管理。