APP下载

Android图形系统的分析与移植*

2010-06-11叶炳发孟小华

电信科学 2010年2期
关键词:缓冲区调用底层

叶炳发,孟小华

(暨南大学计算机系 广州 510632)

1 引言

Android作为第一个完整、开放、免费的手机平台,自推出以来就是业界的热门话题,由于拥有良好的可移植性和强大的功能,在嵌入式设备方面的应用表现出良好的势头。在图形显示方面,Android建立在Linux上,但并没有像一些桌面 Linux使用GTK(GIMP Toolkit)组建XWindows(一个多平台的图形用户接口),也没有使用Cairo向量图形链接库实现图形显示,而是使用了专为Android而改良的一种2D向量图形处理函数库Skia。在3D图形方面是基于嵌入式3D图形算法标准OpenGL/ES实现的,该库可以使用硬件加速。然而,虽然Google开放了Android的源代码,但相关技术文档很少,而且图形系统的实现原理比较复杂,所以本文集中对Android图形系统的底层原理进行研究。

2 Android图形显示原理

2.1 图形系统组成

Android SDK的图形包主要包括android.graphics、android.view、android.widget和 android.opengl,前 3 个是用于 2D的图形开发,基于 SGL(Skia graphics library)。android.opengl是用于3D的图形开发,基于OpenGL/ES。

Skia是一个开放源码的2D向量图形处理函数库,包含字型、坐标转换以及点阵图,有着高效能且简洁的表现,在Android平台中搭配OpenGL/ES与特定的硬件特征强化了显示效果。OpenGL/ES是OpenGL的一个子集,是一个跨平台图形库,是专门为嵌入式系统而设计的。

Android图形系统的组成如图1所示。上层应用调用2D和3D图形库对Surface Manager提供的Surface进行绘制,通过Surface Manager的合成器SurfaceFlinger对各个Surface进行合成,并由EGL接口实现在Framebuffer设备上的显示。

2.2 Surface Manager的工作原理

在Android的图形系统中,Surface Manager是一个重要组成,Surface Manager对上层提供Surface给应用进行绘制,管理对显示子系统的访问,对来自多个应用的2D和3D图像进行无缝的合成后传给底层的EGL进行处理,Surface Manager的工作原理如图2所示。

Surface Manager为Application准备一个或多个Surface后,把Surface传给 Application,让 Application可以在上面作图形处理。应用程序先通过调用图形库提供基础的绘制图形原语和JNI函数,然后又通过Native Method的绘制图形原语调用2D和3D的图形库对Surface进行绘制。

在Android平台下,每个Surface都有一个Front Buffer和一个Back Buffer,每个窗口都以一个Surface对象作为基础。每个Surface又对应一个Layer,SurfaceFlinger将各个Layer的Front Buffer合成后绘制到Frame Buffer上。

关于SurfaceFlinger,在Surface Manager中用于管理逻辑上众多的Surface,其功能特点如下:

·SurfaceFlinger在一个系统范围内合成Surface的功能,并把合成后的显示内容传给帧缓冲设备;

·SurfaceFlinger能一起合成来自多个程序的2D或3D显示的Surface;

·Surface通过Android的IPC机制Binder以缓冲的形式进行递交。

2.3 Surface Manager的实现

从Surface Manager工作原理分析,可以理解Application与Surface Manager是以C/S的模式进行交互的,Application处理Surface的部分是客户端,而Surface Manager提供服务,它们之间通过Android的IPC机制Binder来协助完成,如图3所示。

在Binder中,主要包括两个方面:本地(native),如BnSurfaceFlingerClient,这是一个需要被继承和实现的类;代理(proxy),如 BpSurfaceFlingerClient,这是一个在接口框架中被实现,但是在接口中没有体现的类。在客户端中,BpSurfaceFlingerClient被调用,通过与BnSurfaceFlinger-Client通信,而 BpSurfaceFlingerClient和 BnSurfaceFlinger-Client派生自 ISurfaceFlingerClient,BClient派生自 BnSurface-FlingerClient。

在客户端中通过类SurfaceComposerClient,调用BnSurfaceComposer和BnSurface来响应服务端BpSurface-Composer和BpSurface,并通过调用 BpSurfaceFlingerClient来调用服务端的BnSurfaceFlingerClient,由此完成了客户端和服务端的交互。在交互中的3个接口分别介绍如下。

ISurfaceFlingerClient:派生出BpSurfaceFlingerClient和BnSurfaceFlingerClient,由 BClient实现,通过调用createSurface函数创建一个Surface供Application应用。

ISurface:派生出BpSurface和BnSurface,主要完成对Surface的处理,在 Surface(派生自 BnSurface)的函数 lock、unlockAndPost等,实现了Surface在双缓冲的处理,SurfaceBuffer(派生自Surface)实现了Layer上的处理。

IS urfaceComposer:派生出BpSurfaceComposer和BnSurfaceComposer,SurfaceFlinger(派生自BnSurface Composer)主要为合成器SurfaceFlinger(Surface Manager的组成部分)对Surface合成的相关处理提供实现方法。

3 Android的双缓冲技术

在Android平台中,双缓冲技术分别在Surface的处理和底层Framebuffer的处理中使用到,在对Framebuffer处理的双缓冲技术根据OpenGL的标准实现,而对Surface处理的双缓冲技术则有所不同,下面将对两种双缓冲技术进行比较。

3.1 OpenGL中的双缓冲技术

在OpenGL中利用双缓冲技术,分配两个帧缓冲区,在连续显示三维曲面时,一个帧缓冲区中的数据执行绘制曲面命令的同时,另一个帧缓冲区中的数据进行图形显示。当前可见视频缓冲称为前台视频缓冲,不可见的、正在绘图的视频缓冲称为后台视频缓冲。当后台视频帧缓冲中的数据要求显示时,OpenGL就将它拷贝到前台视频帧缓冲,显示硬件不断地读可见视频缓冲中的内容,并把结果显示在屏幕上。应用双缓冲,每一帧三维曲面只在绘制完成后才显示出来,所以观察者可以看到每一帧完整三维曲面,而不是曲面的绘制过程。

3.2 Surface中的双缓冲技术

每个Surface中都带有两个帧缓冲区,分别称为Front Buffer和Back Buffer,与OpenGL中双缓冲技术有所不同,当绘制Back Buffer后需要显示时,并没有将Back Buffer中的数据拷贝到Front Buffer中,而是直接显示Back Buffer中的数据到屏幕中,从而最大限度地减少了数据的复制。

图4是使用Canvas绘制Surface的原理,具体过程如下:

·创建一个bitmap与Canvas关联起来;

·把准备显示的图形提交到Canvas上;

· lockCanvas,锁定 Canvas;

·drawCanvas,把bitmap中的数据写入到Back Buffer中;

· unlockCanvasAndPost,解锁 Canvas,Back Buffer替换Front Buffer,替换后Back Buffer作为前台缓冲,Front Buffer作为后台缓冲。

4 底层接口与驱动移植

4.1 Android中的EGL接口

OpenGL/ES为附加功能和可能的平台特性开发了扩展机制,但仍然需要一个可以让OpenGL/ES和本地视窗系统交互且平台无关的层。EGL是OpenGL/ES和底层Native平台视窗系统之间的接口,是为OpenGL/ES提供平台独立性而设计。OpenGL/ES本质上是一个图形渲染管线的状态机,而EGL则是用于监控这些状态以及维护Frame Buffer和其他渲染Surface的外部层。

在Android的底层源代码中,egl_native_window_t是一个提供了对本地窗口的所有定义以及用于EGL操作本地窗口的所有方法的类。EGLNativeSurface派生自egl_native_window_t,EGLDisplaySurface派生自 EGLNativeSurface。EGLDisplay-Surface通过函数 mapFrameBuffer打开 Framebuffer设备,并创建两个缓冲区,函数swapBuffer把后台视频缓冲区复制到前台视频缓冲区。DisplayHardware类中初始化了EGL,SurfaceFlinger使用了DisplayHardware去和本地窗口打交道。

4.2 Android帧缓冲驱动的移植

Android是基于Linux的,但在Linux的帧缓冲驱动中并没有直接支持双缓冲,修改驱动包括两个方面:一是划分两个缓冲区;二是添加缓冲区的切换功能。本文是在PXA270上进行研究的,对应的驱动文件是/drivers/video/pxafb.c。

在Android中,double buffer设计成上下两个buffer的模式,在函数 pxafb_setmode()“var->yres_virtual=var->yres”修改为“var->yres_virtual=var->yres*2”,在检查参数的函数pxafb_check_var()中“var->yres_virtual=max(var->yres_virtual,var->yres)”修 改 为 “var->yres_virtual=max(var->yres_virtual,var->yres*2)”。相对应的缓冲长度也要修改为默认的两边,即在函数pxafb_decode_mode_info()中添加“smemlen*=2;”。

当一个缓冲区已写好,在切换时就需要调用到pan函数,该函数将一个新的yoffset传给LCD控制器。在结构体fb_ops pxafb_ops中添加pan函数,即插入“.fb_pan_display=pxafb_pan_display,”到fb_ops pxafb_ops中。在初始化帧缓冲的函数pxafb_init_fbinfo()中,将“fbi->fb.fix.ypanstep=0;”修改为“fbi->fb.fix.ypanstep=1;”,这里是说明驱动需要用到pan函数。以下是需要添加或修改的函数。

5 结束语

对Android的应用开发来说,图形开发是其中一个主要工作,了解Android图形系统的工作原理可以对应用程序性能上的提供有所帮助。在Android移植到其他嵌入式设备中,Android图形系统的底层驱动移植是其中一个关键部分,通过对底层图形接口以及对帧缓冲驱动移植的研究,将更有效地实现Android在其他嵌入式设备上的移植。

1 宋宝华.Linux设备驱动开发详解.北京:人民邮电出版社,2008

2 姚昱旻,刘卫国.Android的架构与应用开发研究.计算机系统应用,2008(11)

3 Patrick Brady.Anatomy&Physiology of an Android.http://sites.google.com/site/io/anatomy--physiology-of-an-android

4 David Blythe,Affie Munshi.OpenGL ES 1.0.02 Specification.http://www.khronos.org/registry/gles/specs/1.0/opengles_spec_1_0.pdf

猜你喜欢

缓冲区调用底层
航天企业提升采购能力的底层逻辑
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
基于网络聚类与自适应概率的数据库缓冲区替换*
基于系统调用的恶意软件检测技术研究
关键链技术缓冲区的确定方法研究
初涉缓冲区
回到现实底层与悲悯情怀
中国底层电影研究探略
利用RFC技术实现SAP系统接口通信