SurfaceFlinger学习

SurfaceFlinger服务负责绘制Android应用程序的UI,它运行在Android系统的System进程中,它负责管理Android系统的帧缓冲区(Frame Buffer)。Android应用程序为了能够将自己的UI绘制在系统的帧缓冲区上,它们就必须要与SurfaceFlinger服务进行通信,如图所示:

Android应用程序与SurfaceFlinger服务是运行在不同的进程中的,因此,它们采用Binder进程间通信机制来进行通信。如图所示,每一个Android应用程序与SurfaceFlinger服务都有一个连接,这个连接都是通过一个类型为ClientBinder对象来描述的。这些Client对象是Android应用程序连接到SurfaceFlinger服务的时候由SurfaceFlinger服务创建的,而当Android应用程序成功连接到SurfaceFlinger服务之后,就可以获得一个对应的Client对象的Binder代理接口了。有了这些Binder代理接口之后,Android应用程序就可以通知SurfaceFlinger服务来绘制自己的UI了。

Android应用程序在通知SurfaceFlinger服务来绘制自己的UI的时候,需要将UI元数据传递给SurfaceFlinger服务,例如,要绘制UI的区域、位置等信息。一个Android应用程序可能会有很多个窗口,而每一个窗口都有自己的UI元数据,因此,Android应用程序需要传递给SurfaceFlinger服务的UI元数据是相当可观的。在这种情况下,通过Binder进程间通信机制来在Android应用程序与SurfaceFlinger服务之间传递UI元数据是不合适的,在每一个Android应用程序与SurfaceFlinger服务之间的连接上加上一块用来传递UI元数据的匿名共享内存:

结构化匿名共享内存:

具体实现:

在每一个SharedClient里面,有至多31SharedBufferStackSharedBufferStack是共享缓冲区堆栈。首先,Shared表明这个堆栈共享的。由Android应用程序和SurfaceFlinger服务所共享。其次,Buffer表明这个堆栈的内容是用来描述UI元数据缓冲区。再者,Stack表明用来描述UI元数据的缓冲区是需要按照一定的规则来访问的。综合起来,就可以认为每一个SharedBufferStack就是用来描述一系列需要按照一定规则来访问的缓冲区。在SurfaceFlinger服务中,每一个SharedBufferStack都对应一个Surface,即一个窗口。

假设图中的SharedBufferStack5Buffer,其中,Buffer-1Buffer-2是已经使用了的,而Buffer-3Buffer-4Buffer-5是空闲的。指针headtail分别指向空闲缓冲区列表的头部和尾部,而指针queue_head指向已经使用了的缓冲区列表的头部。从这里就可以看出,从指针tailhead之间的Buffer即为空闲缓冲区表,而从指针headqueue_head之间的Buffer即为已经使用了的缓冲区列表。图中的5Buffer是循环使用的。

SharedBufferStack中的缓冲区只是用来描述UI元数据的,真正的UI数据保存在GraphicBuffer中。因此,为了完整地描述一个UISharedBufferStack中的每一个已经使用了的缓冲区都对应有一个GraphicBuffer,用来描述真正的UI数据。当SurfaceFlinger服务缓制Buffer-1Buffer-2的时候,就会找到与它们所对应的GraphicBuffer,这样就可以将对应的UI绘制出来了。当一个已经被使用了的Buffer被绘制了之后,它就重新变成一个空闲的Buffer了。

ActivitySurface创建过程分析

对于在Java层实现的Android应用程序窗口来说,它也需要请求SurfaceFlinger服务为它创建绘图表面,这个绘图表面使用一个Surface对象来描述。由于在Java层实现的Android应用程序窗口还要接受WindowManagerService服务管理,所以,在Java层实现的Android应用程序窗口的绘图表面是通过两个Surface对象来描述,一个是在应用程序进程这一侧创建的,另一个是在WindowManagerService服务这一侧创建的,它们对应于SurfaceFlinger服务这一侧的同一个Layer对象,如图所示:

一个应用程序窗口分别位于应用程序进程和WindowManagerService服务中的两个Surface对象虽然都是用来操作位于SurfaceFlinger服务中的同一个Layer对象的,但是它们的操作方式却不一样。具体来说,位于应用程序进程这一侧的Surface对象负责绘制应用程序窗口的UI,即往应用程序窗口的图形缓冲区填充UI数据,而位于WindowManagerService服务这一侧的Surface对象负责设置应用程序窗口的属性,例如位置、大小等属性。这两种不同的操作方式分别是通过C++层的Surface对象和SurfaceControl对象来完成的,因此,位于应用程序进程和WindowManagerService服务中的两个Surface对象的用法是有区别的。之所以会有这样的区别,是因为绘制应用程序窗口是独立的,由应用程序进程来完成,而设置应用程序窗口的属性却需要全局考虑,即需要由WindowManagerService服务来统筹安排。

Surface对象创建步骤:

1. 应用程序进程请求WindowManagerService服务为一个应用程序窗口创建一个Surface对象;

2. WindowManagerService服务请求SurfaceFlinger服务创建一个Layer对象,并且获得一个ISurface接口;

3. WindowManagerService服务将获得的ISurface接口保存在其内部的一个Surface对象中,并且将该ISurface接口返回给应用程序进程;

4. 应用程序进程得到WindowManagerService服务返回的ISurface接口之后,再将其封装成其内部的另外一个Surface对象中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值