您的位置:首页 > 产品设计 > UI/UE

Android图形系统之libui

2012-04-12 20:10 253 查看
1. libui简介

libui是Android图形库的本地框架,负责提供图形界面(Surface)的框架。libui不仅仅负责图形界面框架,
还提供处理事件输入、摄像头输出、Overlay显示等框架,是整个图形用户交互(GUI)系统的中枢。
头文件位置 /frameworks/base/include/ui

源文件文章 /frameworks/base/libs/ui

编译生成动态链接库libui.so
2. libui库包含内容

1)Camera相关框架及底层接口

2)Event / Key event事件处理

3)Overlay相关框架和底层接口

4)定义一些图形显示相关数据结构(Rect、Region和PixelFormat)

5)Framebuffer管理和显存分配

6)Surface图形界面框架

主要分析一下显示控制机制及图形界面框架。
3. Framebuffer管理和显存分配

3.1设备初始化

libui定义了FramebufferNativeWindow类,在构造函数中加载Gralloc硬件模块,并通过该模块提供的接口打
开Linux的Framebuffer设备,同时将打开Gralloc模块。设备打开后,将初始化FramebufferNativeWindow的
参数,将显示缓冲区设置为2,同时向系统申请两块NativeBuffer结构用于存储显示设备的双缓冲,再调用
Gralloc模块的alloc接口分配显存空间。以下为部分初始化代码:

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

err = framebuffer_open(module, &fbDev);

err = gralloc_open(module, &grDev);

// initialize the buffer FIFO

mNumBuffers = 2;

mNumFreeBuffers = 2;

mBufferHead = mNumBuffers-1;

buffers[0] = new NativeBuffer(

fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);

buffers[1] = new NativeBuffer(

fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);

err = grDev->alloc(grDev, fbDev->width, fbDev->height, fbDev->format,

GRALLOC_USAGE_HW_FB, &buffers[0]->handle, &buffers[0]->stride);

err = grDev->alloc(grDev, fbDev->width, fbDev->height, fbDev->format,

GRALLOC_USAGE_HW_FB, &buffers[1]->handle, &buffers[1]->stride);

… …

3.2 共享式分配显存

相对于Gralloc模块采用独立内存空间作为显示缓冲区,libui提供了一套通过ashmem机制,和系统主存共享分
配显存的方案。这种方案适用于物理内存较少且对显示要求低的设备。该策略通过宏定义
GRALLOC_USAGE_HW_MASK进行判断,如果标志位没有被置位,则初始化sw_gralloc_handle_t结构体。

sw_gralloc_handle_t::alloc负责申请共享内存,根据图形格式计算需要申请的图形尺寸,计算公式为
size = bpp * w * h,另外需要保证size为PAGE_SIZE对齐。调用ashmem_create_region函数申请空间,调
用ashmem_set_prot_region设置参数,最后用mmap获取申请空间的内存地址。

int fd = ashmem_create_region("sw-gralloc-buffer", size);

int prot = PROT_READ;

if (usage & GRALLOC_USAGE_SW_WRITE_MASK)

prot |= PROT_WRITE;

ashmem_set_prot_region(fd, prot) ;

void* base = mmap(0, size, prot, MAP_SHARED, fd, 0);

sw_gralloc_handle_t::registerBuffer会判断当前进程是否与sw_gralloc_handle_t相同,若不相同需要
重新mmap,获取新的内存地址。

if (hnd->pid != getpid()) {

void* base = mmap(0, hnd->size, hnd->prot, MAP_SHARED, hnd->fd, 0);

hnd->base = intptr_t(base);

}
4. libui中的Surface图形界面框架

libui库提供了Surface图形界面框架,包括上层应用的调用接口和于SurfaceFlinger库的通信接口,图形界面
的具体实现由SurfaceFlinger库完成。Android上层应用的调用接口主要包含SurfaceComposerClient、
SurfaceControl和Surface三个主要数据结构。

4.1 创建SurfaceComposerClient客户端

上层启动一个新的图形会话,首先要建立一个SurfaceComposerClient对象,用来创建图形会话客户端。
SurfaceComposerClient在其构造函数中调用getComposerService(),返回ISurfaceComposer接口,在调用
ISurfaceComposer:createConnection(),通过binder和SurfaceFlinger库通讯,最终SurfaceFlinger库返
回一个ISurfaceFlingerClient接口。







4.2 创建一个Surface

创建SurfaceComposerClient对象后,可以调用createSurface()创建一个新的Surface,实际上是调用
ISurfaceFlingerClient接口的createSurface(),通过binder进入SurfaceFlinger创建真正的显示Layer。
创建成功后将返回一个SurfaceControl类型的对象。




4.3 获取Surface和ISurface

SurfaceControl对象可使用getSurface()获取Surface对象。这两个数据结构分工不同,SurfaceControl主
要负责设置图形界面的参数,Surface则提供了控制图形界面的接口。Surface可以通过getISurface()获取服
务器端ISurface的接口,利用ISurface的接口,通过binder进程间通讯机制和服务器端传输Surface数据。




4.4 客户端和服务端模型

图中Server下层即SurfaceFlinger实现,这里没有列出。解释一下我理解的客户和服务端模型,上层图形应用
程序利用SurfaceComposerClient、SurfaceControl及Surface对象向服务端申请Surface,获取控制Surface
的接口ISurfaceXXX,利用该接口提供的Binder进程通讯机制和服务端进行通讯和数据交换。服务端指libui提
供的Surface框架和libsurfaceflinger库,系统启动时将SurfaceFlinger注册为系统服务,负责处理所有客
户端拥有的Surface,决定当前显示内容及数据更新情况。





转:http://blog.sina.com.cn/s/blog_60862cad01011eqx.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: