Android图形系统的分析与移植--一、Android GUI系统简介

时间:2022-03-28 06:50:26

1  综述

Android的GUI系统由C语言框架和JAVA语言框架组成。对下层,Android的GUI系统通过调用显示输出设备和输入设备的驱动,从而将Android的软件系统和底层的硬件联系起来。对上层,Android的GUI系统提供了Java层次的绘图结构,Android的Java框架层调用这些绘图接口来构建各种UI元素,这些绘图接口也可以供Java应用程序层来调用。

Android的GUI系统架构图如图1所示:

Android图形系统的分析与移植--一、Android GUI系统简介

图1    GUI系统框架图

其中驱动包括FrameBuffer驱动,Event输入驱动等。

由上图可知,libui是提供接口的框架库,其他的库大部分通过继承并实现libui中定义的类来实现相应的功能。因此,理解libui的构造对于了解GUI的整体框架存在必然性。以下就来介绍一下该库。

2  libui库                                                                                      

libui是Android在本地层次一个框架性质的集成库,它不仅是现实的中枢,也是整个AndroidGUI系统的中枢。

这个库提供了一些接口,由其他的库通过类继承方式来实现,而调用者只需要调用libui库的接口即可。libui库包含了颜色格式,Egl窗口(用户显示),按键及事件处理,Surface(显示界面),Overlay(显示叠加层接口),Camera(照相机接口)等多个方面的定义。

libui库中包含的内容如下:

1)       Format(颜色格式))部分

这个部分本身定义颜色空间的枚举类型和数据结构,它需要重用pixelflinger中的一些数据格式的定义。

2)       Native Windows(本地窗口)部分

本部分用于实现一个本地显示的接口,也就是实现一个egl_native_window_t类,程序通过调用从而实现基本的显示功能。

3)       Key/Event(按键和时间处理)部分

本部分是系统输入的基础,其中定义按键的映射,通过操作Event时间设备来实现获取系统的输入。

4)       Surface(显示界面)部分

本部分定义了显示界面较高层次的接口,包含部分显示界面的管理功能。

5)       Overlay(显示部分的叠加层)部分

定义了一个叠加的显示输出层接口,覆盖在主显示层之上,常用于视频输出。

6)       Camera(照相机)部分

定义摄像头的框架和接口。

3  显示输出与硬件的接口

显示输出接口最终需要与硬件交互,对于Linux操作系统,就是要和驱动程序打交道。这两部分原本也是属于“硬件抽象层”的内容,由于Android中使用的是FrameBuffer的标准显示驱动,因此本部分内容在libui库中使用标准方式来实现。

对于Android的显示部分,需要实现的接口是egl_native_window_t,它是一个OpenGL结构,也是给libEGL使用的。

Android使用标准的FrameBuffer作为驱动程序,同时也在本地框架中提供了系统和FrameBuffer驱动程序之间的适配层,即硬件抽象层。这个部分主要在Gralloc模块中实现调用标准的FrameBuffer驱动,它是系统和FrameBuffer设备之间的接口,以硬件模块的形式存在。Gralloc被libui库调用。

Gralloc模式是显示模块的实现,其中,framebuffer.cpp用于基于FrameBuffer的显示实现。其中定义了帧缓冲区为双缓冲:

// numbers ofbuffers for page flipping

#defineNUM_BUFFERS 2

……

//使用FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO的ioctl()接口来获取驱动程序的基本信息,并调用mmap()将驱动程序的内存映射到用户空间

structfb_fix_screeninfo finfo;

    if (ioctl(fd, FBIOGET_FSCREENINFO,&finfo) == -1)

        return -errno;

structfb_var_screeninfo info;

    if (ioctl(fd, FBIOGET_VSCREENINFO,&info) == -1)

        return -errno;

//RequestNUM_BUFFERS screens (at lest 2 for page flipping)

info.yres_virtual= info.yres * NUM_BUFFERS;

libui对gralloc模块实现了调用,在FrameBufferNativeWindow.cpp中打开了gralloc设备。

FramebufferNativeWindow::FramebufferNativeWindow()

      :BASE(),fbDev(0),grDev(0),mUpdateOnDemand(false)

{

hw_module_tconst* module;

if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {

int stride;

int err;

err = framebuffer_open(module,&fbDev);

LOGE_IF(err,"couldn't open framebuffer HAL (%s)", strerror(-err));

err =gralloc_open(module, &grDev);

LOGE_IF(err,"couldn't open gralloc HAL (%s)", strerror(-err));

// ......

}