Chinaunix首页 | 论坛 | 博客
  • 博客访问: 257824
  • 博文数量: 49
  • 博客积分: 1231
  • 博客等级: 少尉
  • 技术积分: 967
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-02 00:04
个人简介

-->软硬件结合的系统级开发工程师,带过团队,爱好心理学,哲学,艺术...偶像:达芬奇

文章存档

2014年(2)

2013年(4)

2012年(15)

2011年(28)

分类: 嵌入式

2012-09-18 10:49:41

 
Android系统图形显示系统分析!
 

[主要内容:]

  ● FrameBuffer 简介

  ● Andoird GDI基本原理及其总体框架

  ● Android 图形显示系统分析

  ● 总结


一. FrameBuffer 简介
 
1. Framebuffer特点:
 
(1)Framebuffer是显卡的抽象描述
 
(2)Framebuffer是显示内存的一个映像,存放一帧的图象数据
 
(3)Framebuffer本身不具备任何运算数据的能力
 
(4)Framebuffer为显示设备提供的一个接口,可以读写,定位,mmap()此设备
 
(5)FrameBuffer的设备是与vesa 2.0标准兼容显卡的帧缓冲设备(线性帧缓冲意味着CPU能访问显卡的每一位)
 
(6)运行Framebuffer时要设置内核的启动显示模式,通过内核参数vga=xxx实现
 
(7)在Framebuffer启动开始时,显示一只胖胖的小企鹅微标
 
(8) 通常嵌入式设备中一般有fb0,fb1两个设备,缺省的FrameBuffer的设备通常指向/dev/fb0, 一般的主设备号是29,被系统用来确定驱动程式,次设备号被驱动程式用来确定具体的设备
 
(9) 在PC机里有显卡,Framebuffer默认状态下是未开启,系统启动时直接定位到显卡驱动设备号上,由X-Server服务来完成图形的显示
 
(10) 在Android环境,framebuffer设备不是像linux系统一样的 /dev/fb0,而是 /dev/graphics/fb0
 
2. Framebuffer上图象的显示过程:
 
(1)系统初始化/dev/fbx设备,用户打开/dev/fbx设备,使用mmap()系统调用映射framebuffer内存空间到用户空间,用户直接用 memcpy()复制图像数据到framebuffer
 
(2)DMA(Direct Memory Access,直接内存存取)探测到framebuffer数据发生变动,启动DMA传输图像数据到IPU(Image Porcess Unit,图像处理单元)
 
(3)DMA探测到framebuffer数据发生变动,启动DMA传输图像数据到IPU
 
(4)IPU再根据framebuffer驱动设置的处理模式对像素数据进行一系列处理,比如framebuffer使用了overlay framebuffer那就启动overlay处理单元混合两个framebuffer的数据。
 
(5)同时IPU还会封装显示的像素数据,以配合LCD显示模块的接口
 
(6)IPU处理完数据后,送到 显示器的接口,在显示器接口时序模块产生的时序信号同步下,一起输出到LCD驱动芯片。
 
3. Framebuffer的感性认识
 
例:Framebuffer抓屏功能的实现
 
 生成一个图片文件:cp /dev/fb0  myfile.bin
 显示这个图片文件:cat myfile.bin > /dev/fb0
 
二. Andoird GDI基本原理及其总体框架
 
1. 对GDI的理解:
 
  GDI(Graphics Device Interface)就是图形设备接口的意思。它的主要任务是负责系统与绘图程序之间的信息交换,处理所有视窗程序的图形输出。
 
2. GDI的工作原理:
 
  GDI主要管理图形图像的输出,在实际的产品使用中,我们需要在物理屏幕上输出不同的窗口,而每个窗口认为自己独占屏幕的使用,对所有窗口输出,应用程序不会关心物理屏幕是否被别的窗口占用,而只是关心自己在本窗口的输出,至于输出是否能在屏幕上看见,则需要GDI来管理。
 
 
  从上图可以看出,GDI对显示驱动的底层,提供了一个抽象概念,GDI输出抽象成了文本,画笔,位图操作等设备无关的操作,让应用程序员只需要面对逻辑的设备上下文进行输出操作,而不要涉及到具体输出设备。
 
3. Android相关GDI的源码文件:
 
frameworks/base/core/jni/android_view_Surface.cpp
frameworks/base/core/java/android/view/surface.java
frameworks/base/graphics
frameworks/base/libs/ui
frameworks/base/libs/surfaceflinger_client
external/skia
 
4. Andoird系统GDI的总体框架:
 
 
 
三. Android图形显示系统分析
 
让我们先看下屏幕简约图:
    每个应用程序对应着一个或多个图形界面,每个界面我们都称做一个Surface,或者说是Windows的另一种说法。我们能看到四个Surface,一个是Home界面,还有红、绿、蓝分别代表3个Surface,而两个Button实际是Home Surface里的内容。
  每个Surface都有它的大小、位置、以及Surface要显示的内容。这就需要一个结构来记录应用程序界面的位置,大小,以及一个buffer 来记录需要显示的内容,所以这就是我们surface 的概念。
  Surface 实际我们可以把它理解成一个容器,这个容器记录着应用程序界面的控制信息,比如说大小啊,位置啊,而它还有buffer 来专门存储需要显示的内容。
  各个Surface 之间可能有重叠,比如说在上面的简略图中,绿色覆盖了蓝色,而红色又覆盖了绿色和蓝色以及下面的Home ,而且还具有一定透明。在屏幕平面的垂直方向还有一个Z 轴,所有的surface 根据在Z 轴上的坐标来确定前后,这样就可以描述各个surface 之间的上下覆盖关系了,而这个在Z 轴上的顺序,图形上有个专业术语叫Z-order 。
   Z-order解决了Surface之间的上下覆盖关系,那么Surface的重合,还有带透明信息Surface显示是怎么做成的呀?这就需要用到了SurfaceFlinger来解决问题,把各个Surface合成一个主Surface,最后把这个主Surface的内容发送到Framebuffer,这样屏幕上就看到了想要的效果。

1. Surface的合成
 
  Surface的合成一般有两种方式,一种采用硬件的方式来合成,叫覆盖合成,另一种是采用软件的方式,这就是SurfaceFlinger合成。
 
2. SurfaceFlinger合成技术

  每个应用程序可能有一个或者多个Surface ,创建一个surface 分为两个过程,一个是在SurfaceFlinger 这边为每个应用程序(Client) 创建一个管理 结构,另一个就是创建存储内容的buffer ,以及在这个buffer 上的一系列画图之类的操作。
  因为SurfaceFlinger 要管理多个应用程序的多个窗口界面,这里的SurfaceFlinger就相当与X-Server,为了进行管理它提供了一个Client 类,每个来请求服务的应用程序就对应了一个Client 。为应用程序创建一个 Client 以后,下面需要做的就是为这个 Client 分配 Surface , Flinger 为每个 Client提供了 8M 的空间 ,包括控制信息和存储内容的 buffer 。
  而每个应用程序的窗口就是 z 轴上的一个 layer ,创建 Layer 的过程,首先是由这个应用程序的 Client 根据应用程序的 pid 生成一个唯一的 layer ID ,然后根据大小,位置,格式啊之类的信息创建出Layer 。 layer 提供了对窗口控制信息的操作,以及内容的处理( 调用 opengl 或者 skia) ,也就是说 SurfaceFlinger 只是控制什么时候应该进行这些信息的处理以及处理的过程,所有实际的处理都是在 layer 中进行的,可以理解为创建一个 Surface就是创建一个 Layer。

  Android 提供了 4 种类型的 layer 供选择,每个 layer 对应一种类型的窗口,并对应这种窗口相应的操作: norm layer, LayerBlur , LayerBuffer ,LayerDim。这里要重点说一下norm layer Layer :
  Norm Layer 是 Android 种使用最多的一种 Layer ,一般的应用程序在创建surface 的时候都是采用的这样的 layer ,了解 Normal Layer 可以让我们知道Android 进行 display 过程中的一些基础原理。 Normal Layer 为每个 Surface分配两个 buffer : front buffer 和 back buffer ,这个前后是相对的概念,他们是可以进行 Flip 的。 Front buffer 用于 SurfaceFlinger 进行显示,而 Back buffer 用于应用程序进行画图,当 Back buffer 填满数据 (dirty) 以后,就会 flip , back buffer 就变成了 front buffer 用于显示,而 front buffer就变成了 back buffer 用来画图,这两个 buffer 的大小是根据 surface 的大小格式动态变化的。
  两个 buffer flip 的方式是 Android display 中的一个重要实现方式,实现了双缓冲的模式,不只是每个 Surface 这么实现,最后写入 FB 的main surface 也是采用的这种方式。Surface 创建以后,应用程序就可以在 buffer 中画图了。
 
  一般来说画图的过程需要重绘 Surface 上的所有像素,因为一般情况下显示过后的像素是不做保存的,不过也可以通过设定来保存一些像素,而只绘制部分像素,这里就涉及到像素的拷贝了,需要将 Front buffer 的内容拷贝到 Back buffer 。在 SurfaceFlinger 服务实现中像素的拷贝是经常需要进行的操作,而且还可能涉及拷贝过程的转换,比如说屏幕的旋转,翻转等一系列操作。

 
四. 总结

1. 显示系统总结:
 
(1)Surface是图形界面
 
(2)Surface的实现是双缓冲显示机制
 
(3)一个应用程序有一个或多个Surface
 
(4)Surface通过创建一个显示层来进行图象的绘制
 
(5)Surface与SurfaceFlinger通过会话的方式进行通信
 
(6)SurfaceFlinger作用相当于X-Server服务

 
2. 显示系统主要架构图:
 
 
 
 
 
*参考:
阅读(6271) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~