求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
Android核心分析
 

发布于2011-09-30

 

Android核心分析(26)-----Android GDI之SurfaceFlinger

SurfaceFinger按英文翻译过来就是Surface投递者。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.1 DisplayHardware &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

以Surface的Z-order序列排列的LayerBase数组,该数组是层显示遮挡的依据。在每个层计算自己的可见区域时,从Z-order 顶层开始计算,是考虑到遮挡区域的裁减,自己之前层的可见区域就是自己的不可见区域。而绘制Layer时,则从Z-order底层开始绘制,这个考虑到透明层的叠加。

4 SurfaceFlinger的运行框架

我们从前面的章节<Android Service>的基本原理可以知道,SurfaceFlinger的运行框架存在于:threadLoop,他是SurfaceFlinger的主循环体。SurfaceFlinger在进入主体循环之前会首先运行: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的可见区域和被覆盖区域。裁剪输出范围计算-

在生成裁剪区域的时候,根据Z_order依次,每个Layer在计算自己在屏幕的可显示区域时,需要经历如下步骤:

1)以自己的W,H给出自己初始的可见区域

2)减去自己上面窗口所覆盖的区域

在绘制时,Layer将根据自己的可将区域做相应的区域数据Copy。

(3)handleRepaint()

composeSurfaces(需要刷新区域):

根据每个Layer的可见区域与需要刷新区域的交集区域从Z-Order序列从底部开始绘制到主Surface上。

(4)postFramebuffer()

(DisplayHardware)hw.flip(mInvalidRegion);

eglSwapBuffers(display,mSurface) :将mSruface投递到屏幕。

5 总结

现在SurfaceFlinger干的事情利用下面的示意图表示出来:


相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
 
分享到
 
 
     


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...