Android图形系统之libui

转自: http://hi.baidu.com/aokikyon/item/061db04c46d42d0c6dc2f00e


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.csdn.net/DroidPhone/archive/2010/10/28/5972568.aspx

http://blog.csdn.net/yili_xie/archive/2009/11/12/4803527.aspx


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值