Android图形系统之libui

时间:2021-01-04 15:57:06

1. libui简介
   
libuiAndroid图形库的本地框架,负责提供图形界面(Surface)的框架。libui不仅仅负责图形界面框架,

   还提供处理事件输入、摄像头输出、Overlay显示等框架,是整个图形用户交互(GUI)系统的中枢。

   头文件位置 /frameworks/base/include/ui
   
源文件文章 /frameworks/base/libs/ui
   
编译生成动态链接库libui.so

2. libui库包含内容
   
1Camera相关框架及底层接口
   
2Event / Key event事件处理
   
3Overlay相关框架和底层接口
   
4)定义一些图形显示相关数据结构(RectRegionPixelFormat
   
5Framebuffer管理和显存分配
   
6Surface图形界面框架


 
主要分析一下显示控制机制及图形界面框架。

3. Framebuffer管理和显存分配
 3.1
设备初始化
   
libui定义了FramebufferNativeWindow类,在构造函数中加载Gralloc硬件模块,并通过该模块提供的接口打

   LinuxFramebuffer设备,同时将打开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,另外需要保证sizePAGE_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

   SurfaceControlSurface三个主要数据结构。
 4.1
创建SurfaceComposerClient客户端
   
上层启动一个新的图形会话,首先要建立一个SurfaceComposerClient对象,用来创建图形会话客户端。

   SurfaceComposerClient在其构造函数中调用getComposerService(),返回ISurfaceComposer接口,在调用

   ISurfaceComposer:createConnection(),通过binderSurfaceFlinger库通讯,最终SurfaceFlinger库返

   回一个ISurfaceFlingerClient接口。

Android图形系统之libui

   


 4.2 创建一个Surface
   
创建SurfaceComposerClient对象后,可以调用createSurface()创建一个新的Surface,实际上是调用 

   ISurfaceFlingerClient接口的createSurface(),通过binder进入SurfaceFlinger创建真正的显示Layer

   创建成功后将返回一个SurfaceControl类型的对象。

Android图形系统之libui

   

 4.3 获取SurfaceISurface
   
SurfaceControl对象可使用getSurface()获取Surface对象。这两个数据结构分工不同,SurfaceControl

   要负责设置图形界面的参数,Surface则提供了控制图形界面的接口。Surface可以通过getISurface()获取服

   务器端ISurface的接口,利用ISurface的接口,通过binder进程间通讯机制和服务器端传输Surface数据。

Android图形系统之libui

      

 4.4 客户端和服务端模型
   
图中Server下层即SurfaceFlinger实现,这里没有列出。解释一下我理解的客户和服务端模型,上层图形应用

   程序利用SurfaceComposerClientSurfaceControlSurface对象向服务端申请Surface,获取控制Surface

   的接口ISurfaceXXX,利用该接口提供的Binder进程通讯机制和服务端进行通讯和数据交换。服务端指libui

   供的Surface框架和libsurfaceflinger库,系统启动时将SurfaceFlinger注册为系统服务,负责处理所有客

   户端拥有的Surface,决定当前显示内容及数据更新情况。

   Android图形系统之libui

 

转:http://blog.sina.com.cn/s/blog_60862cad01011eqx.html