现在的位置: 首页 > 综合 > 正文

Android SurfaceFlinger分析

2017年12月24日 ⁄ 综合 ⁄ 共 2526字 ⁄ 字号 评论关闭

SufaceFlinger的构成并不是太复杂,复杂的是他的客户端建构。SufaceFlinger主要功能是:
1) 将Layers (Surfaces)内容的刷新到屏幕上
2) 维持Layer的Zorder序列,并对Layer 最终输出做出裁剪计算。
3) 响应Client要求,创建Layer与客户端的Surface连接
4) 接收Client 要求,修改Layer属性(输出大小,Alpha 等设定)
但是作为投递者的实际意义,我们首先需要知道的是如何投递,投掷物,投递路线,投递目的地。

1 SurfaceFlinger的基本组成框架

SurfaceFlinger 管理对象为:
mClientsMap:管理客户端与服务端的连接。
ISurface,IsurfaceComposer:AIDL 调用接口实例
mLayerMap:服务端的Surface的管理对象。
mCurrentState.layersSortedByZ :以Surface的Z-order 序列排列的Layer数组。
graphicPlane缓冲区输出管理
OpenGL ES:图形计算,图像合成等图形库。
gralloc.xxx.so 这是个跟平台相关的图形缓冲区管理器。
pmem Device:提供共享内存,在这里只是在gralloc.xxx.so 可见,在上层被gralloc.xxx.so 抽象了。

2 SurfaceFinger Client 和服务端对象关系图

Client端与SurfaceFlinger 连接图:

Client对象:一般在客户端都是通过SurfaceComposerClient来跟SurfaceFlinger打交道。

3 主要对象说明
3.1DisplayHardware&FrameBuffer
SurfaceFlinger需要操作到屏幕,需要建立一个屏幕硬件缓冲区管理框架。Android在设计支持时,考虑多个屏幕的情况,引入了graphicPlane的概念。在SurfaceFlinger上有一个graphicPlane数组,每一个graphicPlane对象都对应一个DisplayHardware.在当前的Android ( 2.1 ) 版本的设计中, 系统支持一个graphicPlane ,所以也就支持一个DisplayHardware。
SurfaceFlinger,Hardware硬件缓冲区的数据结构关系图。

3.2 Layer

method:setBuffer在SurfaceFlinger端建立显示缓冲区。这里的缓冲区是指的HW性质的,PMEM设备文件映射的内存。
1)layer的绘制
void Layer::onDraw(const Region& clip) const
{
int index = mFrontBufferIndex;
GLuint textureName = mTextures[index].name;

drawWithOpenGL(clip, mTextures[index]);
}
3.2 mCurrentState.layersSortedByZ
以Surfac 的Z-orde 序列排列的LayerBase数组,该数组是层显示遮挡的依据。在每个层计算自己的可见区域时,从Z-order顶层开始计算,考虑到遮挡区域的裁减,自己之前层的可见区域就是自己的不可见区域。而绘制Layer 时,则从Z-order 底层开始绘制,这个考虑到透明层的叠加。

4SurfaceFlinger的运行框架
SurfaceFlinger的运行框架存在于:threadLoop,他是SurfaceFlinger的主循环体。SurfaceFlinge 在进入主循环之前会首先运行:SurfaceFlinger::readyToRun()。
4.1 SurfaceFlinger::readyToRun()
(1)建立GraphicPanle
(2)建立FrameBufferHardware(确定输出目标)
初始化:OpenGL ES
建立兼容的mainSurface.利用eglCreateWindowSurface。
建立OpenGL ES 进程上下文。
建立主Surface(OpenGL ES)。DisplayHardware的Init() @DisplayHardware.cpp 函数对OpenGL做了初始化,并创建主Surface。主Surface,因为所有的Layer在绘制时,都需要先绘制在这个主Surface 上,最后系统才将主Surface 的内容”投掷”到真正的屏幕上。
(3)主Surface的绑定
1)在DisplayHandware初始完毕后,hw.makeCurrent()将主Surface,OpenGL ES进程上下文绑定到SurfaceFlinger的上下文中,
2)之后所有的SurfaceFlinger 进程中使用EGL的所有的操作目的地都是mSurface @DisplayHardware。这样,在OpenGL 绘制图形时,主Surface被记录在进程的上下文中,看不到显式的主Surfce相关参数的传递。下面是Layer-Draw,Hardware.flip 的动作示意图:

4.2 ThreadLoop

(1)handleTransaction(…):主要计算每个Layer有无属性修改,如果有修改需要重画。
(2)handlePageFlip()
computeVisibleRegions:根据Z-Order 序列计算每个Layer的可见区域和被覆盖区域。
每个Layer在计算自己在屏幕的可显示区域时,
需要经历如下步骤:
1)以自己的W,H 给出自己初始的可见区域
2)减去自己上面窗口所覆盖的区域

(3)handleRepaint()
composeSurfaces(需要刷新区域):根据每个Layer 的可见区域与需要刷新区域的交集区域从Z-Order序列从底部开始绘制到主Surface 上。
(4)postFramebuffer()
(DisplayHardware)hw.flip(mInvalidRegion);
eglSwapBuffers(display,mSurface) :将mSruface 投递到屏幕。
5 总结
现在SurfaceFlinger 干的事情利用下面的示意图表示出来

抱歉!评论已关闭.