Android应用程序请求SurfaceFlinger服务创建Surface的过程分析
前面我们已经学习过Android应用程序与SurfaceFlinger服务的连接过程了。连接上SurfaceFlinger服务之后,Android应用程序就可以请求SurfaceFlinger服务创建Surface。而当有了Surface后,Android应用程序就可以用来渲染自己的UI了。在本文中,我们将详细分析Android应用程序请求SurfaceFlinger服务创建Surface的过程。
在讲述Android应用程序请求SurfaceFlinger服务创建Surface之前,我们首先了解一个Surface是由什么组成的。我们可以将Surface理解为一个绘图表面,Android应用程序负责往这个绘图表面填内容,而SurfaceFlinger服务负责将这个绘图表面的内容取出来,并且渲染在显示屏上。
在SurfaceFlinger服务这一侧,绘图表面使用Layer类来描述,Layer类的实现如图1所示。

图1 Layer类的实现
Layer类继承了LayerBaseClient类;LayerBaseClient类继承了LayerBase类;LayerBase类继续了RefBase类。从这些继承关系就可以看出,我们可以通过Android系统的智能指针来引用Layer对象,从而可以自动地维护它们的生命周期。
Layer类内部的成员变量mUserClientRef指向了一个ClientRef对象,这个ClientRef对象内部有一个成员变量mControlBlock,它指向了一个SharedBufferServer对象。从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析一文可以知道,SharedBufferServer类是用来在SurfaceFlinger服务这一侧描述一个UI元数据缓冲区堆栈的,即在SurfaceFlinger服务中,每一个绘图表面,即一个Layer对象,都关联有一个UI元数据缓冲区堆栈。
LayerBaseClient类内部有一个类型为LayerBaseClient::Surface的弱指针,它引用了一个Layer::SurfaceLayer对象。这个Layer::SurfaceLayer对象是一个Binder本地对象,它是SurfaceFlinger服务用来与Android应用程序建立通信的,以便可以共同维护一个绘图表面。
Layer::SurfaceLayer类继承了LayerBaseClient::Surface类,它的实现如图2所示。

图2 SurfaceLayer类的实现
理解这个图需要了解Android系统的Binder进程间通信机制,具体可以参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。从这里就可以看出,Layer::SurfaceLayer类实现了ISurface接口,而Android应用程序就是通过这个接口来和SurfaceFlinger服务共同维护一个绘图表面的。
Layer::SurfaceLayer类内部有两个成员变量mFlinger和mOwner,前者指向了SurfaceFlinger服务,而后者指向了其宿主Layer对象。
ISurface接口定义在文件frameworks/base/include/surfaceflinger/ISurface.h中,它有一个重要的成员函数requestBuffer,如下所示:
图3 BpSurface类的实现
理解这个图同样需要了解Android系统的Binder进程间通信机制,具体可以参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。
以上都是从SurfaceFlinger服务这一侧来理解一个Surface,下面我们再从Android应用程序这一侧来理解一个Surface。
在Android应用程序这一侧,每一个绘图表面都使用一个Surface对象来描述,每一个Surface对象都是由一个SurfaceControl对象来创建的。Surface类和SurfaceControl类的关系以及实现如图4所示。

图4 Surface类和SurfaceControl类的关系以及实现
SurfaceControl类的成员变量mClient是一个类型为SurfaceComposerClient的强指针,它指向了Android应用程序进程中的一个SurfaceComposerClient单例对象。在前面Android应用程序与SurfaceFlinger服务的连接过程分析一文中,我们已经看到过SurfaceComposerClient类的作用了,Android应用程序主要就是通过它来和SurfaceFlinger服务建立连接的,连接的结果就是得到一个类型为Client的Binder代理对象,保存它的成员变量mClient中。
SurfaceControl类的成员变量mSurface是一个类型为ISurface的强指针,它指向了一个类型为BpSurface的Binder代理对象,而这个Binder代理对象引用的是一个Layer::SurfaceLayer对象。当Android应用程序请求SurfaceFlinger服务创建一个绘图表面的时候,SurfaceFlinger服务就会在内部创建一个Layer::SurfaceLayer对象,并且将这个Layer::SurfaceLayer对象的一个Binder代理对象返回来给Android应用程序,然后Android应用程序再将这个Binder代理对象保存在一个SurfaceControl对象的成员变量mSurface中。
SurfaceControl类的成员变量mSurfaceData是一个类型为Surface的强指针,它指向了一个Surface对象。
Surface类就是用来在Android应用程序这一侧描述绘图表面的,它的成员变量mSurface与它的宿主类SurfaceControl的成员变量mSurface指向的是同一个Binder代理对象,即它们都引用了在SurfaceFlinger服务内部所创建的一个类型为Layer::SurfaceLayer的Binder本地对象。
Surface类的成员变量mClient指向了Android应用程序进程中的一个SurfaceClient单例对象。在前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析一文中,我们已经介绍过SurfaceClient类的实现了,Android应用程序就是通过它来请求SurfaceFlinger服务创建共享UI元数据的,并且可以通过它来请求SurfaceFlinger服务渲染一个绘图表面。
Surface类的成员变量mSharedBufferClient指向了一个SharedBufferClient对象。从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析一文可以知道,SharedBufferClient类是用来在Android应用程序这一侧描述一个UI元数据缓冲区堆栈的,即在Android应用程序中,每一个绘图表面,即一个Surface对象,都关联有一个UI元数据缓冲区堆栈。
Surface类继承了EGLNativeBase类,而EGLNativeBase类又继承了ANativeWindow类。我们知道,Android系统是通过OpenGL库来绘制UI的。OpenGL库在绘制UI的时候,需要底层的系统提供一个本地窗口给它,以便它可以将UI绘制在这个本地窗口上。Android系统为OpenGL库定提供的本地窗口使用ANativeWindow类来描述,Surface类通过EGLNativeBase类间接地继承了ANativeWindow类,因此,Surface类也是用来描述OpenGL绘图所需要的一个本地窗口的。从这个角度出发,我们可以将Surface类看作OpenGL库与Android的UI系统之间的一个桥梁。
讨论到这里,我们就可以知道,一个绘图表面,在SurfaceFlinger服务和Android应用程序中分别对应有一个Layer对象和一个Surface对象,这两个对象在内部分别使用一个SharedBufferServer对象和一个SharedBufferClient对象来描述这个绘图表面的UI元数据缓冲堆栈。在前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析一文中,我们已经分析过这个UI元数据的创建过程了,接下来,我们再简要看一下SharedBufferServer类和SharedBufferClient类的定义。
SharedBufferServer类和SharedBufferClient类均是从SharedBufferBase类继承下来的,如图5所示。

图5 SharedBufferBase、SharedBufferServer和SharedBufferClient的关系
在基类SharedBufferBase中,有三个成员变量mSharedClient、mSharedStack和mIdentity。成员变量mSharedClient指向一块UI元数据缓冲区,即一个SharedClient对象;成员变量mSharedStack指向一个UI元数据堆栈,即一个SharedBufferStack对象;成员变量mIdentity用来描述一个绘图表面的ID。
在前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析一文提到,每一个与UI相关的Android应用程序内部都有一个唯一的SharedClient对象,这个SharedClient对象内部有一个SharedBufferStack数组surfaces,SharedBufferServer类的成员变量mSharedStack所指向的SharedBufferStack对象,正是成员变量mSharedClient所指向的一个SharedClient对象内部的一个SharedBufferStack数组的一个元素,这一点可以从SharedBufferServer类的构造函数实现来看出。
SharedBufferServer类的构造函数frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp文件中,如下所示:
图6 SharedBufferClient眼中的SharedBufferStack
在Android应用程序这一侧,当它需要渲染一个Surface时,它就会首先找到对应的SharedBufferClient对象,然后再调用它的成员函数dequeue来请求分配一个UI元数据缓冲区。有了这个UI元数据缓冲区之后,Android应用程序再调用这个SharedBufferClient对象的成员函数setDirtyRegion、setCrop和setTransform来设置对应的Surface的裁剪区域、纹理坐标以及旋转方向。此外,Android应用程序还会请求SurfaceFlinger服务为这个Surface分配一个图形缓冲区,以便可以往这个图形缓冲区写入实际的UI数据。最后,Android应用程序就可以调用这个SharedBufferClient对象的成员函数queue把前面已经准备好了的UI元数据缓冲区加入到它所描述的一个UI元数据缓冲区堆栈的待渲染队列中,以便SurfaceFlinger服务可以在合适的时候对它进行渲染。这个过程我们在下一篇文章中再详细分析。
SharedBufferServer类的成员变量mNumBuffers的含义可以参考前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文中的图7,如下所示。

图7 SharedBufferServer眼中的SharedBufferStack
当SurfaceFlinger服务需要渲染一个Surface的时候,它就会找到对应的一个SharedBufferServer对象,然后调用它的成员函数getQueueCount来检查它所描述的一个UI元数据缓冲区堆栈的待渲染队列的大小。如果这个大小大于0,那么SurfaceFlinger服务就会继续调用它的成员函数retireAndLock来取出队列中的第一个UI元数据缓冲区,以及调用它的成员函数getDirtyRegion、getCrop和getTransform来获得要渲染的Surface的裁剪区域、纹理坐标和旋转方向。最后,SurfaceFlinger服务就可以结合这些信息来将保存这个Surface的图形缓冲区中的UI数据渲染在显示屏中。这个过程我们同样在下一篇文章中再详细分析。
SharedBufferServer类的另外一个成员变量mBufferList指向了一个BufferList对象,这个BufferList对象是用来管理SharedBufferServer类所描述的一个UI元数据缓冲区堆栈的,接下来我们就简要分析它的定义。
BufferList类定义在frameworks/base/include/private/surfaceflinger/SharedBufferStack.h文件中,如下所示:
图8 Android应用程序请求SurfaceFlinger服务创建Surface的过程
这个过程可以划分为20个步骤,接下来我们就详细分析每一个步骤。
Step 1. SurfaceComposerClient.createSurface
SharedBufferClient::SharedBufferClient(SharedClient* sharedClient, int surface, int num, int32_t identity) : SharedBufferBase(sharedClient, surface, identity), mNumBuffers(num), tail(0){ SharedBufferStack& stack( *mSharedStack ); tail = computeTail(); queued_head = stack.head;} 这个函数定义在文件frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp中。SharedBufferClient类的构造函数主要是用来初始化成员变量tail和queued_head的值。这两个成员变量的含义可以参考前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文中的图6,这里不再详述。
这里我们需要注意的是,这里的参数sharedClient指向了一个SharedClient对象,这个SharedClient对象与在前面Step 18中用来创建SharedBufferServer对象的SharedClient对象描述的是同一块匿名共享内存,而且这里的参数surface与在前面Step 18中用来创建SharedBufferServer对象的token的值是相等的,这意味着这一步所创建的SharedBufferClient对象与前面Step 19所创建的SharedBufferServer对象描述的是同一个SharedBufferStack对象,即同一个UI元数据缓冲区堆栈,并且这个UI元数据缓冲区堆栈已经在前面的Step 19中初始化好了。
至此,Android应用程序请求SurfaceFlinger服务创建Surface的过程就分析完成了。我们需要重点掌握的是,当Android应用程序请求SurfaceFlinger服务创建一个Surface的时候,需要在SurfaceFlinger服务这一侧创建一个Layer对象、一个Layer::SurfaceLayer对象和一个SharedBufferServer对象,同时又需要在Android应用程序这一侧创建一个SurfaceControl对象、一个Surface对象和一个SharedBufferClient对象。掌握了这些知识之后,在接下来的一篇文章中,我们就可以分析Android应用程序请求SurfaceFlinger服务渲染Surface的过程了,敬请期待!
- 1楼melvinchan59分钟前
- 牛人辛苦,深夜还在写博客