Android显示系统(10)- SurfaceFlinger内部结构

发布于:2024-12-18 ⋅ 阅读:(38) ⋅ 点赞:(0)

Android显示系统(01)- 架构分析
Android显示系统(02)- OpenGL ES - 概述
Android显示系统(03)- OpenGL ES - GLSurfaceView的使用
Android显示系统(04)- OpenGL ES - Shader绘制三角形
Android显示系统(05)- OpenGL ES - Shader绘制三角形(使用glsl文件)
Android显示系统(06)- OpenGL ES - VBO和EBO和VAO
Android显示系统(07)- OpenGL ES - 纹理Texture
Android显示系统(08)- OpenGL ES - 图片拉伸
Android显示系统(09)- SurfaceFlinger的使用
Android显示系统(10)- SurfaceFlinger内部结构
Android显示系统(11)- 向SurfaceFlinger申请Surface
Android显示系统(12)- 向SurfaceFlinger申请Buffer
Android显示系统(13)- 向SurfaceFlinger提交Buffer

一、前言:

之前讲述了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建立连接。

  1. 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();
          // 。。。删除非关键代码
      }
      
  2. 强引用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管理。


网站公告

今日签到

点亮在社区的每一天
去签到